REST endpoints for jobs in ServFlo: 16 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.servflo.ai/api. Every call needs Authorization: Bearer sfk_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
Jobs, by scheduled date, filtered by text, status, date, technician (the lead or anyone on a visit's crew), customer or property, paged with limit/offset and a total. Each job carries its field status times (onMyWayAt, arrivedAt, startedAt, completedAt). A job's date, time, technician and status are its next open visit's. A technician sees only the jobs they are on a visit's crew of. Read-only. Use GET /schedule for a date range on the calendar.
SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED or CANCELLED. A job's status is its next open visit's. One of SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED, CANCELLED.
items[].priority
enum
One of LOW, NORMAL, HIGH, URGENT.
items[].scheduledDate
string
The next open visit's day, YYYY-MM-DD.
items[].scheduledTime
string or null
Hh: MM
items[].durationMinutes
integer
items[].priceCents
integer
Job price before tax, in integer cents.
items[].address
string or null
items[].notes
string or null
items[].completionNotes
string or null
What was done.
items[].recurrenceInterval
enum or null
One of WEEKLY, BIWEEKLY, MONTHLY, QUARTERLY, YEARLY.
items[].recurrenceParentId
string or null
items[].onMyWayAt
string (date-time) or null
items[].arrivedAt
string (date-time) or null
items[].startedAt
string (date-time) or null
items[].completedAt
string (date-time) or null
items[].signedBy
string or null
Who signed the work off on site.
items[].signedAt
string (date-time) or null
items[].businessUnitId
string or null
items[].customFields
any
Custom field values by key (definitions: GET /custom-fields?entity=JOB).
items[].weatherSensitive
boolean or null
Plans around the weather: overrides the service type; null follows it.
items[].createdAt
string (date-time)
items[].updatedAt
string (date-time)
items[].customer
object
items[].customer.id
string
Customer id.
items[].customer.name
string
items[].customer.phone
string or null
items[].technician
object or null
items[].technician.id
string
Technician id (GET /technicians).
items[].technician.name
string
items[].technician.color
string
Calendar colour, #rrggbb.
items[].serviceType
object or null
items[].serviceType.id
string
items[].serviceType.name
string
items[].serviceType.color
string
items[].businessUnit
object or null
The business unit.
items[].businessUnit.id
string
items[].businessUnit.name
string
items[].asset
object or null
items[].asset.id
string
items[].asset.name
string
items[].asset.serialNumber
string
items[].property
object or null
items[].property.id
string
Property id.
items[].property.name
string or null
items[].property.address
string or null
items[].property.city
string or null
items[].property.taxRate
number or null
items[].nextJobId
string or null
After an update: the next occurrence booked when a recurring job completed.
items[].margin
object or null
With includeMargin and costing.read only: the job's margin.
Books a job (JOB-n) for a customer. Address defaults to the equipment's property, then the customer's address; duration and price default to the service type's. With requestId, that request becomes CONVERTED and points at the job. Nothing is sent to the customer. Call GET /customers, /service-types and /technicians/options first for the ids.
Permission
jobs.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tool
jobs_create (toolset scheduling, in the default set)
SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED or CANCELLED. A job's status is its next open visit's. One of SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED, CANCELLED.
priority
enum
One of LOW, NORMAL, HIGH, URGENT.
scheduledDate
string
The next open visit's day, YYYY-MM-DD.
scheduledTime
string or null
Hh: MM
durationMinutes
integer
priceCents
integer
Job price before tax, in integer cents.
address
string or null
notes
string or null
completionNotes
string or null
What was done.
recurrenceInterval
enum or null
One of WEEKLY, BIWEEKLY, MONTHLY, QUARTERLY, YEARLY.
recurrenceParentId
string or null
onMyWayAt
string (date-time) or null
arrivedAt
string (date-time) or null
startedAt
string (date-time) or null
completedAt
string (date-time) or null
signedBy
string or null
Who signed the work off on site.
signedAt
string (date-time) or null
businessUnitId
string or null
customFields
any
Custom field values by key (definitions: GET /custom-fields?entity=JOB).
weatherSensitive
boolean or null
Plans around the weather: overrides the service type; null follows it.
createdAt
string (date-time)
updatedAt
string (date-time)
customer
object
customer.id
string
Customer id.
customer.name
string
customer.phone
string or null
technician
object or null
technician.id
string
Technician id (GET /technicians).
technician.name
string
technician.color
string
Calendar colour, #rrggbb.
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
businessUnit
object or null
The business unit.
businessUnit.id
string
businessUnit.name
string
asset
object or null
asset.id
string
asset.name
string
asset.serialNumber
string
property
object or null
property.id
string
Property id.
property.name
string or null
property.address
string or null
property.city
string or null
property.taxRate
number or null
nextJobId
string or null
After an update: the next occurrence booked when a recurring job completed.
One job with its customer, property (with access notes and hazards), equipment, technician, notes, checklist, materials used, invoices, forms (with answers and what is still missing), field status times, the customer's sign-off (signedBy, signedAt) and photoCount. A technician gets 404 for a job not assigned to them. Read-only. Get job ids from GET /jobs or GET /schedule.
SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED or CANCELLED. A job's status is its next open visit's. One of SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED, CANCELLED.
priority
enum
One of LOW, NORMAL, HIGH, URGENT.
scheduledDate
string
The next open visit's day, YYYY-MM-DD.
scheduledTime
string or null
Hh: MM
durationMinutes
integer
priceCents
integer
Job price before tax, in integer cents.
address
string or null
notes
string or null
completionNotes
string or null
What was done.
recurrenceInterval
enum or null
One of WEEKLY, BIWEEKLY, MONTHLY, QUARTERLY, YEARLY.
recurrenceParentId
string or null
onMyWayAt
string (date-time) or null
arrivedAt
string (date-time) or null
startedAt
string (date-time) or null
completedAt
string (date-time) or null
signedBy
string or null
Who signed the work off on site.
signedAt
string (date-time) or null
businessUnitId
string or null
customFields
any
Custom field values by key (definitions: GET /custom-fields?entity=JOB).
weatherSensitive
boolean or null
Plans around the weather: overrides the service type; null follows it.
createdAt
string (date-time)
updatedAt
string (date-time)
customer
object
customer.id
string
Customer id.
customer.name
string
customer.phone
string or null
technician
object or null
technician.id
string
Technician id (GET /technicians).
technician.name
string
technician.color
string
Calendar colour, #rrggbb.
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
businessUnit
object or null
The business unit.
businessUnit.id
string
businessUnit.name
string
asset
object or null
asset.id
string
asset.name
string
asset.serialNumber
string
property
object or null
property.id
string
Property id.
property.name
string or null
property.address
string or null
property.city
string or null
property.taxRate
number or null
property.gateCode
string or null
property.accessInstructions
string or null
property.safetyNotes
string or null
property.petsOnSite
boolean
property.petNotes
string or null
property.contactName
string or null
property.contactPhone
string or null
property.latitude
number or null
property.longitude
number or null
nextJobId
string or null
After an update: the next occurrence booked when a recurring job completed.
notesLog
array of object
Internal notes, newest first.
notesLog[].id
string
Job note id.
notesLog[].jobId
string
notesLog[].content
string
notesLog[].authorUserId
string or null
notesLog[].createdAt
string (date-time)
checklist
array of object
checklist[].id
string
Checklist item id.
checklist[].jobId
string
checklist[].label
string
checklist[].checked
boolean
checklist[].sortOrder
integer
materials
array of object
materials[].id
string
Material line id.
materials[].jobId
string
materials[].materialId
string or null
materials[].pricebookItemId
string or null
materials[].description
string or null
materials[].unit
string or null
materials[].quantity
number
materials[].unitCostCents
integer
The unit PRICE billed for this line (the original API's name), in integer cents.
materials[].costCents
integer or null
Our unit cost in cents (costing.read only).
materials[].locationId
string or null
The stock location it was drawn from.
materials[].createdAt
string (date-time)
materials[].material
object
The original API's material shape; id null for a pricebook-only line.
materials[].material.id
string or null
materials[].material.name
string
materials[].material.unit
string
materials[].pricebookItem
object or null
materials[].pricebookItem.id
string
materials[].pricebookItem.code
string or null
materials[].pricebookItem.kind
enum
One of SERVICE, MATERIAL, EQUIPMENT, FEE.
materials[].location
object or null
materials[].location.id
string
materials[].location.name
string
materials[].location.kind
enum
One of WAREHOUSE, TRUCK.
invoices
array of object
Invoices for the job (INV-n).
invoices[].id
string
invoices[].identifier
string
INV-n
invoices[].status
enum
DRAFT (not issued), SENT (issued, money due), PAID, OVERDUE (past dueDate) or CANCELLED. One of DRAFT, SENT, PAID, OVERDUE, CANCELLED.
invoices[].totalCents
integer
quotes
array of object
Quotes the job came from (Q-n).
quotes[].id
string
quotes[].identifier
string
Q-n
quotes[].status
enum
DRAFT → SENT (customer can answer at /q/{publicToken}) → APPROVED / CHANGES_REQUESTED / DECLINED; APPROVED → CONVERTED (job or invoice made). SENT past validUntil becomes EXPIRED. One of DRAFT, SENT, APPROVED, CHANGES_REQUESTED, DECLINED, CONVERTED, EXPIRED, ARCHIVED.
requests
array of object
requests[].id
string
requests[].identifier
string
assessmentRequests
array of object
assessmentRequests[].id
string
assessmentRequests[].identifier
string
visits
array of object
The job's visits in order.
visits[].id
string
Visit id (for /jobs/{jobId}/visits/{visitId}/…).
visits[].jobId
string
visits[].scheduledDate
string or null
YYYY-MM-DD; null = not scheduled yet.
visits[].scheduledTime
string or null
Hh: MM
visits[].durationMinutes
integer
visits[].status
enum
SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED or CANCELLED. A job's status is its next open visit's. One of SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED, CANCELLED.
visits[].notes
string or null
visits[].sortOrder
integer
visits[].routeOrder
integer or null
visits[].onMyWayAt
string (date-time) or null
visits[].trackingToken
string or null
The customer's tracking link token (/t/{token}), made on On my way.
visits[].arrivedAt
string (date-time) or null
visits[].startedAt
string (date-time) or null
visits[].completedAt
string (date-time) or null
visits[].createdAt
string (date-time)
visits[].updatedAt
string (date-time)
visits[].crew
array of object
Technicians on the visit, lead first.
visits[].crew[].technicianId
string
visits[].crew[].isLead
boolean
visits[].crew[].name
string
visits[].crew[].color
string
forms
any
The job's forms with their fields, answers, status and missing required fields (as GET /jobs/{jobId}/forms).
photoCount
integer
membership
object or null
The Member badge: the customer's membership that covers the job.
membership.membershipId
string
membership.identifier
string
MEM-n
membership.planName
string
membership.priority
boolean
The plan flags its members' work as priority on the board.
membership.dueMonth
string or null
YYYY-MM when the job is an included member visit; null for other work for a member.
membership.dueDate
string or null
YYYY-MM-DD when the member visit is on a week cadence (every N weeks); null for month-based visits.
Changes any job field (only those sent): reschedule, re-price, change customer, equipment or status. Date, time, duration, technician and status apply to the visit the job mirrors (its next open visit); COMPLETED closes the job (its other open visits are cancelled) and CANCELLED cancels every open visit. Completing a recurring job books its next occurrence once; nextJobId names it. Field staff use POST /jobs/{jobId}/status and dispatchers POST /jobs/{jobId}/assign for the narrower changes.
Permission
jobs.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tool
jobs_update (toolset scheduling, in the default set)
SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED or CANCELLED. A job's status is its next open visit's. One of SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED, CANCELLED.
priority
enum
One of LOW, NORMAL, HIGH, URGENT.
scheduledDate
string
The next open visit's day, YYYY-MM-DD.
scheduledTime
string or null
Hh: MM
durationMinutes
integer
priceCents
integer
Job price before tax, in integer cents.
address
string or null
notes
string or null
completionNotes
string or null
What was done.
recurrenceInterval
enum or null
One of WEEKLY, BIWEEKLY, MONTHLY, QUARTERLY, YEARLY.
recurrenceParentId
string or null
onMyWayAt
string (date-time) or null
arrivedAt
string (date-time) or null
startedAt
string (date-time) or null
completedAt
string (date-time) or null
signedBy
string or null
Who signed the work off on site.
signedAt
string (date-time) or null
businessUnitId
string or null
customFields
any
Custom field values by key (definitions: GET /custom-fields?entity=JOB).
weatherSensitive
boolean or null
Plans around the weather: overrides the service type; null follows it.
createdAt
string (date-time)
updatedAt
string (date-time)
customer
object
customer.id
string
Customer id.
customer.name
string
customer.phone
string or null
technician
object or null
technician.id
string
Technician id (GET /technicians).
technician.name
string
technician.color
string
Calendar colour, #rrggbb.
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
businessUnit
object or null
The business unit.
businessUnit.id
string
businessUnit.name
string
asset
object or null
asset.id
string
asset.name
string
asset.serialNumber
string
property
object or null
property.id
string
Property id.
property.name
string or null
property.address
string or null
property.city
string or null
property.taxRate
number or null
nextJobId
string or null
After an update: the next occurrence booked when a recurring job completed.
Destructive: deletes the job with its notes, checklist and materials; invoices made from it stay, unlinked. Its equipment history keeps a 'job deleted' entry. Cannot be undone; to stop a visit without losing it, set its status to CANCELLED instead.
Permission
jobs.delete (Owner, Admin, Dispatcher)
Risk
sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tool
jobs_delete (toolset scheduling)
Approval
Over MCP, this tool always waits for your approval in ServFlo. See Approvals.
POST /organizations/{organizationId}/jobs/{jobId}/status
The field technician's update: move the job to SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED or CANCELLED (any to any) and/or save completion notes. IN_PROGRESS stamps startedAt and starts the technician's job clock (stopping travel); COMPLETED is refused (400) while a form on the job lacks required answers, stamps completedAt, stops the job clock and books a recurring job's next occurrence once (nextJobId). Technicians may only change their own jobs (404 otherwise). Equipment history records the change. Nothing is sent to the customer. POST …/start and …/complete are the same with a clearer name.
Permission
jobs.work (Owner, Admin, Dispatcher, Technician)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tool
jobs_setStatus (toolset scheduling, in the default set)
SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED or CANCELLED. A job's status is its next open visit's. One of SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED, CANCELLED.
priority
enum
One of LOW, NORMAL, HIGH, URGENT.
scheduledDate
string
The next open visit's day, YYYY-MM-DD.
scheduledTime
string or null
Hh: MM
durationMinutes
integer
priceCents
integer
Job price before tax, in integer cents.
address
string or null
notes
string or null
completionNotes
string or null
What was done.
recurrenceInterval
enum or null
One of WEEKLY, BIWEEKLY, MONTHLY, QUARTERLY, YEARLY.
recurrenceParentId
string or null
onMyWayAt
string (date-time) or null
arrivedAt
string (date-time) or null
startedAt
string (date-time) or null
completedAt
string (date-time) or null
signedBy
string or null
Who signed the work off on site.
signedAt
string (date-time) or null
businessUnitId
string or null
customFields
any
Custom field values by key (definitions: GET /custom-fields?entity=JOB).
weatherSensitive
boolean or null
Plans around the weather: overrides the service type; null follows it.
createdAt
string (date-time)
updatedAt
string (date-time)
customer
object
customer.id
string
Customer id.
customer.name
string
customer.phone
string or null
technician
object or null
technician.id
string
Technician id (GET /technicians).
technician.name
string
technician.color
string
Calendar colour, #rrggbb.
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
businessUnit
object or null
The business unit.
businessUnit.id
string
businessUnit.name
string
asset
object or null
asset.id
string
asset.name
string
asset.serialNumber
string
property
object or null
property.id
string
Property id.
property.name
string or null
property.address
string or null
property.city
string or null
property.taxRate
number or null
nextJobId
string or null
After an update: the next occurrence booked when a recurring job completed.
POST /organizations/{organizationId}/jobs/{jobId}/assign
Sets the job's technician, or clears it with technicianId: null: the visit the job mirrors (its next open visit) gets that technician as its lead, or no crew. For crews and other visits use PUT /jobs/{jobId}/visits/{visitId}/crew. Get technician ids from GET /technicians/options. Nothing is sent to anyone.
Permission
jobs.assign (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tool
jobs_assign (toolset scheduling, in the default set)
SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED or CANCELLED. A job's status is its next open visit's. One of SCHEDULED, CONFIRMED, IN_PROGRESS, COMPLETED, CANCELLED.
priority
enum
One of LOW, NORMAL, HIGH, URGENT.
scheduledDate
string
The next open visit's day, YYYY-MM-DD.
scheduledTime
string or null
Hh: MM
durationMinutes
integer
priceCents
integer
Job price before tax, in integer cents.
address
string or null
notes
string or null
completionNotes
string or null
What was done.
recurrenceInterval
enum or null
One of WEEKLY, BIWEEKLY, MONTHLY, QUARTERLY, YEARLY.
recurrenceParentId
string or null
onMyWayAt
string (date-time) or null
arrivedAt
string (date-time) or null
startedAt
string (date-time) or null
completedAt
string (date-time) or null
signedBy
string or null
Who signed the work off on site.
signedAt
string (date-time) or null
businessUnitId
string or null
customFields
any
Custom field values by key (definitions: GET /custom-fields?entity=JOB).
weatherSensitive
boolean or null
Plans around the weather: overrides the service type; null follows it.
createdAt
string (date-time)
updatedAt
string (date-time)
customer
object
customer.id
string
Customer id.
customer.name
string
customer.phone
string or null
technician
object or null
technician.id
string
Technician id (GET /technicians).
technician.name
string
technician.color
string
Calendar colour, #rrggbb.
serviceType
object or null
serviceType.id
string
serviceType.name
string
serviceType.color
string
businessUnit
object or null
The business unit.
businessUnit.id
string
businessUnit.name
string
asset
object or null
asset.id
string
asset.name
string
asset.serialNumber
string
property
object or null
property.id
string
Property id.
property.name
string or null
property.address
string or null
property.city
string or null
property.taxRate
number or null
nextJobId
string or null
After an update: the next occurrence booked when a recurring job completed.
Every VISIT scheduled from start to end (inclusive, YYYY-MM-DD), ordered by date and time, shaped like a job (id is the job's) with the visit's date, time, duration, status and field times, plus visitId, crew, visitNumber/visitCount, routeOrder and the job's own jobStatus. technicianId filters to visits whose crew includes that technician; a technician sees only the visits they are on. Read-only.
POST /organizations/{organizationId}/jobs/{jobId}/materials
Adds a material line to the job, by pricebook item (pricebookItemId, GET /pricebook/items) or original material (materialId, GET /materials). The line snapshots the item's name, unit, price (unitCostCents, the unit price billed: the original API's name) and cost, frozen on the job; a negative quantity records a return. STOCK: a MATERIAL or EQUIPMENT item is drawn from the truck of the job's technician, else the default warehouse (negative stock is allowed and flagged in stock.negative). Invoicing the job (POST /jobs/{jobId}/invoice) bills these lines.
Permission
jobs.work (Owner, Admin, Dispatcher, Technician)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
Destructive: removes a material line from the job and puts what it used back where it was drawn from (a RETURN movement). Invoices already made from the job keep their lines.
Permission
jobs.work (Owner, Admin, Dispatcher, Technician)
Risk
sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tool
jobs_deleteMaterial (toolset scheduling)
Approval
Over MCP, this tool always waits for your approval in ServFlo. See Approvals.
POST /organizations/{organizationId}/jobs/{jobId}/invoice
Creates a DRAFT invoice (INV-n): one line for the service at the job's price and one per material used; deposits on the quote the job came from move onto it. Nothing is sent; share it with POST /invoices/{invoiceId}/link. Returns the invoice.