REST endpoints for requests in ServFlo: 11 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.
Service requests (REQ-n) newest first: from the online booking form, the customer portal or entered by staff. Filter by text, status, source or customer; paged with a total. Read-only.
Where it came from: MANUAL (staff), ONLINE_BOOKING, PORTAL, FIELD (a technician's lead) or PHONE (taken by the AI receptionist on a call). One of MANUAL, ONLINE_BOOKING, PORTAL, FIELD, PHONE.
items[].leadTechnicianId
string or null
The technician who sent a FIELD lead.
items[].sourceJobId
string or null
The job a FIELD lead came from.
items[].leadUrgency
enum or null
One of NOW, SOON, LATER.
items[].status
enum
NEW → ASSESSMENT_SCHEDULED / QUOTED → CONVERTED (a job was booked), or ARCHIVED. One of NEW, ASSESSMENT_SCHEDULED, QUOTED, CONVERTED, ARCHIVED.
items[].internalNotes
string or null
items[].jobId
string or null
The job booked from it.
items[].assessmentJobId
string or null
The on-site assessment job.
items[].convertedAt
string (date-time) or null
items[].archivedAt
string (date-time) or null
items[].businessUnitId
string or null
items[].adCampaignId
string or null
The ad campaign that brought it; null when not from an ad.
Records a NEW service request (REQ-n). Name an existing customerId (search GET /customers first), or give contactName (and phone/email) for a new contact; no customer is created until POST /requests/{requestId}/customer. Nothing is sent to anyone.
Permission
requests.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tool
requests_create (toolset sales, in the default set)
Where it came from: MANUAL (staff), ONLINE_BOOKING, PORTAL, FIELD (a technician's lead) or PHONE (taken by the AI receptionist on a call). One of MANUAL, ONLINE_BOOKING, PORTAL, FIELD, PHONE.
leadTechnicianId
string or null
The technician who sent a FIELD lead.
sourceJobId
string or null
The job a FIELD lead came from.
leadUrgency
enum or null
One of NOW, SOON, LATER.
status
enum
NEW → ASSESSMENT_SCHEDULED / QUOTED → CONVERTED (a job was booked), or ARCHIVED. One of NEW, ASSESSMENT_SCHEDULED, QUOTED, CONVERTED, ARCHIVED.
internalNotes
string or null
jobId
string or null
The job booked from it.
assessmentJobId
string or null
The on-site assessment job.
convertedAt
string (date-time) or null
archivedAt
string (date-time) or null
businessUnitId
string or null
adCampaignId
string or null
The ad campaign that brought it; null when not from an ad.
GET /organizations/{organizationId}/requests/{requestId}
One request with its customer, property, quotes and jobs. matchingCustomers lists existing customers with the contact's email or phone, when no customer is linked: link one with PATCH (customerId) rather than creating a duplicate. Read-only.
Where it came from: MANUAL (staff), ONLINE_BOOKING, PORTAL, FIELD (a technician's lead) or PHONE (taken by the AI receptionist on a call). One of MANUAL, ONLINE_BOOKING, PORTAL, FIELD, PHONE.
leadTechnicianId
string or null
The technician who sent a FIELD lead.
sourceJobId
string or null
The job a FIELD lead came from.
leadUrgency
enum or null
One of NOW, SOON, LATER.
status
enum
NEW → ASSESSMENT_SCHEDULED / QUOTED → CONVERTED (a job was booked), or ARCHIVED. One of NEW, ASSESSMENT_SCHEDULED, QUOTED, CONVERTED, ARCHIVED.
internalNotes
string or null
jobId
string or null
The job booked from it.
assessmentJobId
string or null
The on-site assessment job.
convertedAt
string (date-time) or null
archivedAt
string (date-time) or null
businessUnitId
string or null
adCampaignId
string or null
The ad campaign that brought it; null when not from an ad.
createdAt
string (date-time)
updatedAt
string (date-time)
customer
object or null
customer.id
string
customer.name
string
customer.email
string or null
customer.phone
string or null
customer.status
enum
LEAD until the first job, then ACTIVE; ARCHIVED customers leave the lists. One of LEAD, ACTIVE, INACTIVE, ARCHIVED.
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.state
string or null
property.zip
string or null
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
bookedTechnician
object or null
bookedTechnician.id
string
Technician id (GET /technicians).
bookedTechnician.name
string
bookedTechnician.color
string
Calendar colour, #rrggbb.
leadTechnician
object or null
leadTechnician.id
string
Technician id (GET /technicians).
leadTechnician.name
string
leadTechnician.color
string
Calendar colour, #rrggbb.
sourceJob
object or null
sourceJob.id
string
sourceJob.identifier
string
job
object or null
job.id
string
job.identifier
string
JOB-n
job.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.
job.scheduledDate
string
assessmentJob
object or null
assessmentJob.id
string
assessmentJob.identifier
string
JOB-n
assessmentJob.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.
assessmentJob.scheduledDate
string
quotes
array of object
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.
quotes[].title
string
matchingCustomers
array of object
Existing customers with the contact's email or phone (up to 3) while the request has no customer.
Changes the fields sent. status: ARCHIVED archives it; NEW reopens an archived request. To quote or book it use POST /requests/{requestId}/quote, /assessment or POST /jobs with requestId.
Permission
requests.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
Where it came from: MANUAL (staff), ONLINE_BOOKING, PORTAL, FIELD (a technician's lead) or PHONE (taken by the AI receptionist on a call). One of MANUAL, ONLINE_BOOKING, PORTAL, FIELD, PHONE.
leadTechnicianId
string or null
The technician who sent a FIELD lead.
sourceJobId
string or null
The job a FIELD lead came from.
leadUrgency
enum or null
One of NOW, SOON, LATER.
status
enum
NEW → ASSESSMENT_SCHEDULED / QUOTED → CONVERTED (a job was booked), or ARCHIVED. One of NEW, ASSESSMENT_SCHEDULED, QUOTED, CONVERTED, ARCHIVED.
internalNotes
string or null
jobId
string or null
The job booked from it.
assessmentJobId
string or null
The on-site assessment job.
convertedAt
string (date-time) or null
archivedAt
string (date-time) or null
businessUnitId
string or null
adCampaignId
string or null
The ad campaign that brought it; null when not from an ad.
POST /organizations/{organizationId}/requests/{requestId}/customer
Creates a LEAD customer (and a property from the address) from the request's contact when the request has none, and links it; returns the request. Check matchingCustomers on GET /requests/{requestId} first to avoid duplicates.
Permission
requests.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
Where it came from: MANUAL (staff), ONLINE_BOOKING, PORTAL, FIELD (a technician's lead) or PHONE (taken by the AI receptionist on a call). One of MANUAL, ONLINE_BOOKING, PORTAL, FIELD, PHONE.
leadTechnicianId
string or null
The technician who sent a FIELD lead.
sourceJobId
string or null
The job a FIELD lead came from.
leadUrgency
enum or null
One of NOW, SOON, LATER.
status
enum
NEW → ASSESSMENT_SCHEDULED / QUOTED → CONVERTED (a job was booked), or ARCHIVED. One of NEW, ASSESSMENT_SCHEDULED, QUOTED, CONVERTED, ARCHIVED.
internalNotes
string or null
jobId
string or null
The job booked from it.
assessmentJobId
string or null
The on-site assessment job.
convertedAt
string (date-time) or null
archivedAt
string (date-time) or null
businessUnitId
string or null
adCampaignId
string or null
The ad campaign that brought it; null when not from an ad.
createdAt
string (date-time)
updatedAt
string (date-time)
customer
object or null
customer.id
string
customer.name
string
customer.email
string or null
customer.phone
string or null
customer.status
enum
LEAD until the first job, then ACTIVE; ARCHIVED customers leave the lists. One of LEAD, ACTIVE, INACTIVE, ARCHIVED.
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.state
string or null
property.zip
string or null
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
bookedTechnician
object or null
bookedTechnician.id
string
Technician id (GET /technicians).
bookedTechnician.name
string
bookedTechnician.color
string
Calendar colour, #rrggbb.
leadTechnician
object or null
leadTechnician.id
string
Technician id (GET /technicians).
leadTechnician.name
string
leadTechnician.color
string
Calendar colour, #rrggbb.
sourceJob
object or null
sourceJob.id
string
sourceJob.identifier
string
job
object or null
job.id
string
job.identifier
string
JOB-n
job.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.
job.scheduledDate
string
assessmentJob
object or null
assessmentJob.id
string
assessmentJob.identifier
string
JOB-n
assessmentJob.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.
assessmentJob.scheduledDate
string
quotes
array of object
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.
quotes[].title
string
matchingCustomers
array of object
Existing customers with the contact's email or phone (up to 3) while the request has no customer.
POST /organizations/{organizationId}/requests/{requestId}/quote
Creates a DRAFT quote for the request (and the customer, if the request is from a new contact); the request becomes QUOTED. Fill the quote with PATCH /quotes/{quoteId}; nothing is sent.
Permission
requests.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP tool
requests_convertToQuote (toolset sales, in the default set)
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.
taxRate
number
Tax rate in percent.
depositPercent
number or null
Deposit asked, as a percent of the total.
depositCents
integer or null
Deposit asked, as a fixed amount in cents.
internalNotes
string or null
publicToken
string
The customer link token: the quote page is /q/{publicToken}.
sentAt
string (date-time) or null
approvedAt
string (date-time) or null
approvedOptionId
string or null
approvedLineIds
array of string
The optional lines the customer kept.
approvedTotalCents
integer or null
Approved total in cents, with tax.
approvedDepositCents
integer or null
Approved deposit in cents.
signatureName
string or null
approvedByStaff
boolean
Staff recorded the approval for the customer.
changesRequestedAt
string (date-time) or null
changesRequestedNote
string or null
declinedAt
string (date-time) or null
declineReason
string or null
jobId
string or null
The job it was converted to.
invoiceId
string or null
The invoice it was converted to.
convertedAt
string (date-time) or null
memberPricingRemoved
boolean
soldByUserId
string or null
soldByTechnicianId
string or null
financingDisabled
boolean
businessUnitId
string or null
customFields
any
Custom field values by key (definitions: GET /custom-fields?entity=QUOTE).
POST /organizations/{organizationId}/requests/{requestId}/assessment
Books a job (JOB-n) noted as the request's on-site assessment, creating the customer if needed; the request becomes ASSESSMENT_SCHEDULED. Nothing is sent to the customer.
Permission
requests.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
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}/requests/{requestId}/confirm-booking
Turns the time a customer booked online (bookedDate, bookedTime on the request) into a job (JOB-n) at that time, creating the customer from the contact when none is linked (link an existing one first with PATCH /requests/{requestId} customerId to avoid a duplicate). The technician defaults to the one the slot holds; pass technicianId (or null) to change it. The request becomes CONVERTED. Only NEW requests with a booked time. Nothing is sent by this call; automations may react to booking.confirmed.
Permission
requests.write (Owner, Admin, Dispatcher)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
GET /organizations/{organizationId}/booking-settings
Whether the public booking form (/book/{slug}) takes requests, whether the customer portal shows completed jobs' photos, and whether customers can sign in to their portal (/c/{slug}). Read-only.
customerSignInEnabled off REVOKES ACCESS: every customer is signed out of their portal at once and /c/{slug} stops offering sign-in (portal links keep working). bookingEnabled off: the public booking form and /api/public/book/{slug} answer 404 and take no requests; on: anyone with the link can send a request. portalShowJobPhotos on EXPOSES the before/after/general photos of completed jobs to customers in their portal (never ISSUE photos or signatures). Send either or both. Needs settings.manage (owners and admins).
Permission
settings.manage (Owner, Admin)
Risk
sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tool
bookingSettings_update (toolset settings)
Approval
Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals.