DevelopersAPI reference

Field team API

REST endpoints for field team in ServFlo: 2 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.

OperationEndpointRisk
Record equipment on sitePOST /organizations/{organizationId}/jobs/{jobId}/equipmentwrite
Fill a job's or visit's custom fields on sitePOST /organizations/{organizationId}/jobs/{jobId}/custom-fieldswrite

Record equipment on site

POST /organizations/{organizationId}/jobs/{jobId}/equipment

The technician records a unit at the job's property, or the customer's own equipment (a car, a boat; always when the job has no property): its serial number or VIN, make, model, install date, its type's custom fields and notes, for new equipment (name required; equipmentTypeId from the packet's equipmentTypes, else matched from the name; ownership CUSTOMER for the customer's own, else the type's default) or one already on file (assetId, from the job or its packet). Only those details change; required custom fields are not enforced on site; status, warranty and moving equipment stay office work. The job is linked to it when it has none yet (the equipment's history records it). Technicians: their own jobs. Needs the plan's Equipment tracking.

Permissionjobs.work (Owner, Admin, Dispatcher, Technician)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tooljobs_recordEquipment (toolset scheduling)

Parameters

NameInTypeRequiredDescription
jobIdpathstringYes

Request body

FieldTypeRequiredDescription
assetIdstring or nullNoEquipment already at the property; omit to add new equipment.
namestring or nullNoNew equipment's name, e.g. Furnace. Up to 200 characters.
serialNumberstringNoSerial number or VIN; omit to leave it as it is (new equipment: not recorded). Up to 200 characters.
equipmentTypeIdstring or nullNoNew equipment's type (packet equipmentTypes).
ownershipenum or nullNoNew equipment: CUSTOMER = the customer's own (a car, goes with them), PROPERTY = stays with the job's property. Omit for the type's default (customerOwned); a job without a property always records the customer's own. One of PROPERTY, CUSTOMER.
customFieldsobjectNoCustom field values by key (definitions: GET /custom-fields?entity=EQUIPMENT); merged into the saved values on an update, null clears one. Checked against each field's type and options; unknown keys are refused.
manufacturerstring or nullNoUp to 200 characters.
modelstring or nullNoUp to 200 characters.
installationDatestring or nullNoYYYY-MM-DD
notesstring or nullNoUp to 5000 characters.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/jobs/{jobId}/equipment" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"assetId":"asset_id","name":"Dana Whitfield","serialNumber":"string"}'

Response

201: the answer's fields
FieldTypeDescription
idstring
namestring
serialNumberstring
manufacturerstring or null
modelstring or null
installationDatestring or null
statusstring
customerIdstring or nullThe owning customer when it is the customer's own; null: property equipment.
equipmentTypeIdstring or null

Fill a job's or visit's custom fields on site

POST /organizations/{organizationId}/jobs/{jobId}/custom-fields

The technician fills the job's custom fields (entity JOB), or one of its visits' (entity VISIT, with visitId), e.g. a gate code or the filter size found. Values are checked against each field's type and options and merged into the saved ones (null clears one; unknown keys and archived fields are refused); required fields are not enforced on site. A sensitive field's mask (••••) sent back unchanged keeps the stored value; setting a sensitive value is a sensitive call. Imported history is read-only (409). Nothing is sent to the customer. Technicians: their own jobs (404 otherwise). Definitions: the packet's customFields or GET /custom-fields?entity=JOB|VISIT.

Permissionjobs.work (Owner, Admin, Dispatcher, Technician)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tooljobs_saveFields (toolset scheduling)

Parameters

NameInTypeRequiredDescription
jobIdpathstringYes

Request body

FieldTypeRequiredDescription
visitIdstring or nullNoFill this visit's fields (GET /jobs/{jobId}/visits) instead of the job's.
customFieldsobjectYesValues by field key (JOB fields, or VISIT fields with visitId); merged into the saved values, null clears one.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/jobs/{jobId}/custom-fields" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customFields":{}}'

Response

200: the answer's fields
FieldTypeDescription
jobIdstring
visitIdstring or nullThe visit filled; null: the job.
customFieldsobjectAll the record's values after the change (sensitive ones masked as for any answer).

On this page