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.
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.
Permission
jobs.work (Owner, Admin, Dispatcher, Technician)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
Equipment already at the property; omit to add new equipment.
name
string or null
No
New equipment's name, e.g. Furnace. Up to 200 characters.
serialNumber
string
No
Serial number or VIN; omit to leave it as it is (new equipment: not recorded). Up to 200 characters.
equipmentTypeId
string or null
No
New equipment's type (packet equipmentTypes).
ownership
enum or null
No
New 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.
customFields
object
No
Custom 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.
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.
Permission
jobs.work (Owner, Admin, Dispatcher, Technician)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.