DevelopersAPI reference

Technicians API

REST endpoints for technicians in ServFlo: 10 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
List technicians with open job countsGET /organizations/{organizationId}/techniciansread
Create a technicianPOST /organizations/{organizationId}/technicianswrite
Active technicians, for pickersGET /organizations/{organizationId}/technicians/optionsread
Update a technicianPATCH /organizations/{organizationId}/technicians/{technicianId}write
Delete a technicianDELETE /organizations/{organizationId}/technicians/{technicianId}sensitive
Link a member's account to a technicianPOST /organizations/{organizationId}/technicians/{technicianId}/linksensitive
Unlink a technician's accountDELETE /organizations/{organizationId}/technicians/{technicianId}/linksensitive
List technicians' time offGET /organizations/{organizationId}/time-offread
Add time offPOST /organizations/{organizationId}/time-offwrite
Delete time offDELETE /organizations/{organizationId}/time-off/{timeOffId}sensitive

List technicians with open job counts

GET /organizations/{organizationId}/technicians

Every technician (active and inactive) with contact details, calendar colour and openJobCount. Read-only. Use GET /technicians/options for pickers.

Permissiontechnicians.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP tooltechnicians_list (toolset team)

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/technicians" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
idstringTechnician id.
organizationIdstring
namestring
emailstring or null
phonestring or null
colorstringCalendar colour, #rrggbb.
activeboolean
userIdstring or nullThe linked ServFlo account, if any.
invitedEmailstring or null
invitedAtstring (date-time) or null
workStartTimestringWorking day start, HH:MM (24-hour).
workEndTimestringWorking day end, HH:MM (24-hour).
homeAddressstring or null
homeLatitudenumber or null
homeLongitudenumber or null
workDaysarray of integerWorking weekdays, 0 = Sunday … 6 = Saturday.
onlineBookableboolean
hourlyCostCentsinteger or nullLoaded hourly cost in cents (costing.read only).
hourlyPayCentsinteger or nullHourly pay in cents (costing.read only).
homeBusinessUnitIdstring or null
customFieldsanyCustom field values by key (definitions: GET /custom-fields?entity=TECHNICIAN).
createdAtstring (date-time)
updatedAtstring (date-time)
businessUnitIdsarray of string
openJobCountintegerJobs still open on their plate.

Create a technician

POST /organizations/{organizationId}/technicians

Adds a technician (a person jobs are assigned to; not a sign-in account). Returns the technician.

Permissiontechnicians.write (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tooltechnicians_create (toolset team, in the default set)

Request body

FieldTypeRequiredDescription
namestringYes
customFieldsobjectNoTechnician custom field values (GET /custom-fields?entity=TECHNICIAN), e.g. licence number or van; required ones are checked on create.
emailempty string or string (email) or nullNo
phonestring or nullNo
colorstringNo
activebooleanNo
workStartTimestringNoStart of their working day, HH:MM (default 08:00); the dispatch board warns outside it.
workEndTimestringNoEnd of their working day, HH:MM (default 17:00).
homeAddressstring or nullNoWhere their day starts when not at the business (route planning); geocoded after saving. Up to 500 characters.
homeLatitudenumber or nullNoHome base pinned by hand (WGS84). -90–90.
homeLongitudenumber or nullNo-180–180.
hourlyCostCentsinteger or nullNoBurdened cost of one hour of their time, cents (job costing). Hidden from roles without costing.read. 0–10000000.
hourlyPayCentsinteger or nullNoTheir hourly pay, cents. Hidden from roles without costing.read. 0–10000000.
workDaysarray of integerNoDays they work, 0 = Sunday … 6 = Saturday (default Monday–Friday): online booking offers only these. Up to 7 items.
onlineBookablebooleanNoWhether online booking may offer and assign their time (default true).
homeBusinessUnitIdstring or nullNoTheir home business unit (GET /business-units): new jobs they are assigned default to it when the service type names none. Up to 100 characters.
businessUnitIdsarray of stringNoOther units they may work for (replaces the list). With no units at all they work for every unit. Up to 100 items.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/technicians" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Dana Whitfield"}'

Response

201: the answer's fields
FieldTypeDescription
idstringTechnician id.
organizationIdstring
namestring
emailstring or null
phonestring or null
colorstringCalendar colour, #rrggbb.
activeboolean
userIdstring or nullThe linked ServFlo account, if any.
invitedEmailstring or null
invitedAtstring (date-time) or null
workStartTimestringWorking day start, HH:MM (24-hour).
workEndTimestringWorking day end, HH:MM (24-hour).
homeAddressstring or null
homeLatitudenumber or null
homeLongitudenumber or null
workDaysarray of integerWorking weekdays, 0 = Sunday … 6 = Saturday.
onlineBookableboolean
hourlyCostCentsinteger or nullLoaded hourly cost in cents (costing.read only).
hourlyPayCentsinteger or nullHourly pay in cents (costing.read only).
homeBusinessUnitIdstring or null
customFieldsanyCustom field values by key (definitions: GET /custom-fields?entity=TECHNICIAN).
createdAtstring (date-time)
updatedAtstring (date-time)

Active technicians, for pickers

GET /organizations/{organizationId}/technicians/options

Active technicians as id, name and colour, for assigning jobs (POST /jobs/{jobId}/assign). Read-only.

Permissiontechnicians.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP tooltechnicians_options (toolset team, in the default set)

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/technicians/options" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
idstringTechnician id.
namestring
colorstring
workStartTimestring
workEndTimestring
homeBusinessUnitIdstring or null
businessUnitIdsarray of string

Update a technician

PATCH /organizations/{organizationId}/technicians/{technicianId}

Changes the fields sent; active: false hides them from pickers while keeping their jobs. Returns the technician.

Permissiontechnicians.write (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tooltechnicians_update (toolset team)

Parameters

NameInTypeRequiredDescription
technicianIdpathstringYes

Request body

FieldTypeRequiredDescription
namestringNo
customFieldsobjectNoTechnician custom field values (GET /custom-fields?entity=TECHNICIAN), e.g. licence number or van; required ones are checked on create.
emailempty string or string (email) or nullNo
phonestring or nullNo
colorstringNo
activebooleanNo
workStartTimestringNoStart of their working day, HH:MM (default 08:00); the dispatch board warns outside it.
workEndTimestringNoEnd of their working day, HH:MM (default 17:00).
homeAddressstring or nullNoWhere their day starts when not at the business (route planning); geocoded after saving. Up to 500 characters.
homeLatitudenumber or nullNoHome base pinned by hand (WGS84). -90–90.
homeLongitudenumber or nullNo-180–180.
hourlyCostCentsinteger or nullNoBurdened cost of one hour of their time, cents (job costing). Hidden from roles without costing.read. 0–10000000.
hourlyPayCentsinteger or nullNoTheir hourly pay, cents. Hidden from roles without costing.read. 0–10000000.
workDaysarray of integerNoDays they work, 0 = Sunday … 6 = Saturday (default Monday–Friday): online booking offers only these. Up to 7 items.
onlineBookablebooleanNoWhether online booking may offer and assign their time (default true).
homeBusinessUnitIdstring or nullNoTheir home business unit (GET /business-units): new jobs they are assigned default to it when the service type names none. Up to 100 characters.
businessUnitIdsarray of stringNoOther units they may work for (replaces the list). With no units at all they work for every unit. Up to 100 items.

Example

curl -X PATCH "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/technicians/{technicianId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Dana Whitfield","customFields":{},"email":"dana@example.com"}'

Response

200: the answer's fields
FieldTypeDescription
idstringTechnician id.
organizationIdstring
namestring
emailstring or null
phonestring or null
colorstringCalendar colour, #rrggbb.
activeboolean
userIdstring or nullThe linked ServFlo account, if any.
invitedEmailstring or null
invitedAtstring (date-time) or null
workStartTimestringWorking day start, HH:MM (24-hour).
workEndTimestringWorking day end, HH:MM (24-hour).
homeAddressstring or null
homeLatitudenumber or null
homeLongitudenumber or null
workDaysarray of integerWorking weekdays, 0 = Sunday … 6 = Saturday.
onlineBookableboolean
hourlyCostCentsinteger or nullLoaded hourly cost in cents (costing.read only).
hourlyPayCentsinteger or nullHourly pay in cents (costing.read only).
homeBusinessUnitIdstring or null
customFieldsanyCustom field values by key (definitions: GET /custom-fields?entity=TECHNICIAN).
createdAtstring (date-time)
updatedAtstring (date-time)

Delete a technician

DELETE /organizations/{organizationId}/technicians/{technicianId}

Destructive: deletes the technician; their jobs stay, unassigned. Prefer active: false (PATCH) to keep history.

Permissiontechnicians.write (Owner, Admin)
Risksensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tooltechnicians_delete (toolset team)
ApprovalOver MCP, this tool always waits for your approval in ServFlo. See Approvals.

Parameters

NameInTypeRequiredDescription
technicianIdpathstringYes

Example

curl -X DELETE "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/technicians/{technicianId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
oktrue
POST /organizations/{organizationId}/technicians/{technicianId}/link

Grants access: links an organization member (GET /members) to this technician record: they then see this technician's jobs, customers and My day, and their time is recorded against it. A member can be linked to one technician only (409). Returns the technician.

Permissiontechnicians.write (Owner, Admin)
Risksensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tooltechnicians_link (toolset team)
ApprovalOver MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals.

Parameters

NameInTypeRequiredDescription
technicianIdpathstringYes

Request body

FieldTypeRequiredDescription
userIdstringYesThe member's user id (GET /members). Up to 200 characters.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/technicians/{technicianId}/link" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"userId":"user_id"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
namestring
emailstring or null
phonestring or null
colorstring
activeboolean
userIdstring or nullThe linked ServFlo account, if any.
invitedEmailstring or null
invitedAtstring (date-time) or null
createdAtstring (date-time)
updatedAtstring (date-time)
DELETE /organizations/{organizationId}/technicians/{technicianId}/link

Revokes access: the account is no longer this technician (it stays a member; change or remove its role in Members). Clears a pending invitation too. Their jobs and time stay.

Permissiontechnicians.write (Owner, Admin)
Risksensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tooltechnicians_unlink (toolset team)
ApprovalOver MCP, this tool always waits for your approval in ServFlo. See Approvals.

Parameters

NameInTypeRequiredDescription
technicianIdpathstringYes

Example

curl -X DELETE "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/technicians/{technicianId}/link" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
namestring
emailstring or null
phonestring or null
colorstring
activeboolean
userIdstring or nullThe linked ServFlo account, if any.
invitedEmailstring or null
invitedAtstring (date-time) or null
createdAtstring (date-time)
updatedAtstring (date-time)

List technicians' time off

GET /organizations/{organizationId}/time-off

Time off that ends on or after from (default today), soonest first, optionally for one technician. Online booking offers no slots in it. Read-only.

Permissiontechnicians.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP tooltimeOff_list (toolset scheduling)

Parameters

NameInTypeRequiredDescription
technicianIdquerystringNo
fromqueryempty string or stringNoOnly time off ending on or after this day.

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/time-off" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
itemsarray of object
items[].idstring
items[].technicianIdstring
items[].startDatestring
items[].endDatestring
items[].startTimestring or null
items[].endTimestring or null
items[].reasonstring or null
items[].createdAtstring (date-time)
items[].technicianobject
items[].technician.idstring
items[].technician.namestring
items[].technician.colorstring

Add time off

POST /organizations/{organizationId}/time-off

Marks a technician away from startDate to endDate (inclusive): whole days, or startTime–endTime on each of those days. Online booking stops offering that time; existing jobs are not moved (check the dispatch board).

Permissiontechnicians.write (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tooltimeOff_create (toolset scheduling)

Request body

FieldTypeRequiredDescription
technicianIdstringYes
startDatestringYesA calendar date in the business's own calendar, YYYY-MM-DD.
endDatestringYesA calendar date in the business's own calendar, YYYY-MM-DD.
startTimestring or nullNoWith endTime: part of each day; omit for whole days.
endTimestring or nullNoA local time of day, HH:MM (24-hour). Blank means 09:00 on new jobs.
reasonstring or nullNoUp to 200 characters.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/time-off" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"technicianId":"technician_id","startDate":"2026-11-03","endDate":"2026-11-03"}'

Response

201: the answer's fields
FieldTypeDescription
idstring
technicianIdstring
startDatestring
endDatestring
startTimestring or null
endTimestring or null
reasonstring or null
createdAtstring (date-time)
technicianobject
technician.idstring
technician.namestring
technician.colorstring

Delete time off

DELETE /organizations/{organizationId}/time-off/{timeOffId}

Destructive: removes the time off; online booking may offer that time again at once.

Permissiontechnicians.write (Owner, Admin)
Risksensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tooltimeOff_delete (toolset scheduling)
ApprovalOver MCP, this tool always waits for your approval in ServFlo. See Approvals.

Parameters

NameInTypeRequiredDescription
timeOffIdpathstringYes

Example

curl -X DELETE "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/time-off/{timeOffId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
oktrue

On this page