DevelopersAPI reference

Business units API

REST endpoints for business units 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 business unitsGET /organizations/{organizationId}/business-unitsread
Create a business unitPOST /organizations/{organizationId}/business-unitswrite
Get a business unitGET /organizations/{organizationId}/business-units/{businessUnitId}read
Change a business unitPATCH /organizations/{organizationId}/business-units/{businessUnitId}write
Delete a business unitDELETE /organizations/{organizationId}/business-units/{businessUnitId}sensitive
Accounting tracking choices for unitsGET /organizations/{organizationId}/integrations/accounting-trackingread
List branchesGET /organizations/{organizationId}/business-locationsread
Create a branchPOST /organizations/{organizationId}/business-locationswrite
Change a branchPATCH /organizations/{organizationId}/business-locations/{businessLocationId}write
Delete a branchDELETE /organizations/{organizationId}/business-locations/{businessLocationId}sensitive

List business units

GET /organizations/{organizationId}/business-units

The business's units (ServiceTitan-style divisions such as HVAC Service, HVAC Install, Plumbing), active first, with their branding, default tax, online booking limits and accounting mapping. Empty for a business that does not use units. includeInactive adds retired ones. Use the ids as businessUnitId on jobs, quotes, invoices, memberships, requests and campaigns, and as the filter of the board, lists and reports. Read-only.

PermissionbusinessUnits.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolbusinessUnits_list (toolset settings)

Parameters

NameInTypeRequiredDescription
includeInactivequerybooleanNo

Example

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

Response

200: the answer's fields
FieldTypeDescription
itemsarray of object
items[].idstring
items[].namestring
items[].tradestring or null
items[].activeboolean
items[].businessLocationIdstring or null
items[].businessLocationobject or null
items[].businessLocation.idstring
items[].businessLocation.namestring
items[].phonestring or null
items[].emailstring or null
items[].logoUrlstring or null
items[].invoiceFooterstring or null
items[].defaultTaxRatenumber or null
items[].onlineBookableboolean
items[].bookingThresholdPercentinteger or null
items[].windowThresholdsobject
items[].qboClassIdstring or null
items[].qboClassNamestring or null
items[].qboDepartmentIdstring or null
items[].qboDepartmentNamestring or null
items[].xeroTrackingCategoryIdstring or null
items[].xeroTrackingCategoryNamestring or null
items[].xeroTrackingOptionIdstring or null
items[].xeroTrackingOptionNamestring or null
items[].technicianCountintegerTechnicians whose home or allowed unit it is.
items[].serviceTypeCountintegerService types that default to it.
items[].createdAtstring (date-time)
items[].updatedAtstring (date-time)

Create a business unit

POST /organizations/{organizationId}/business-units

Adds a unit. Names are unique per business. Nothing moves into it by itself: set it as the default unit of service types (PATCH /service-types/{id} defaultBusinessUnitId) and the home unit of technicians (PATCH /technicians/{id} homeBusinessUnitId), and new jobs follow. Existing records are never backfilled.

PermissionbusinessUnits.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolbusinessUnits_create (toolset settings)

Request body

FieldTypeRequiredDescription
namestringYesUp to 120 characters.
tradestring or nullNoThe trade, free text ("HVAC", "Plumbing"). Up to 60 characters.
activebooleanNoInactive units keep their history but cannot be chosen for new work.
businessLocationIdstring or nullNoThe branch it belongs to (GET /business-locations); null = none.
phonestring or nullNoShown on its invoices and quotes instead of the business's. Up to 40 characters.
emailempty string or string (email) or nullNoShown on its invoices and quotes instead of the business's.
logoUrlstring or nullNoAn https image URL shown on its invoices and quotes instead of the business logo.
invoiceFooterstring or nullNoText at the foot of its invoices and quotes (licence numbers, terms). Up to 2000 characters.
defaultTaxRatenumber or nullNoPercent: its new invoices and quotes use it when the property has no rate. 0–100.
onlineBookablebooleanNoFalse: online booking does not offer the service types whose default unit it is.
bookingThresholdPercentinteger or nullNoStop online booking in a window once its utilisation would pass this; null = the business default. 10–300.
windowThresholdsobjectNoPer planning window: window start → percent, e.g. { "08:00": 80 }.
qboClassIdstring or nullNoQuickBooks Class id its invoices carry. Up to 100 characters.
qboClassNamestring or nullNoUp to 200 characters.
qboDepartmentIdstring or nullNoQuickBooks Location (Department in the API) id its invoices carry. Up to 100 characters.
qboDepartmentNamestring or nullNoUp to 200 characters.
xeroTrackingCategoryIdstring or nullNoXero tracking category; with an option, replaces the integration's default tracking on its invoices. Up to 100 characters.
xeroTrackingCategoryNamestring or nullNoUp to 200 characters.
xeroTrackingOptionIdstring or nullNoUp to 100 characters.
xeroTrackingOptionNamestring or nullNoUp to 200 characters.

Example

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

Response

201: the answer's fields
FieldTypeDescription
idstring
namestring
tradestring or null
activeboolean
businessLocationIdstring or null
businessLocationobject or null
businessLocation.idstring
businessLocation.namestring
phonestring or null
emailstring or null
logoUrlstring or null
invoiceFooterstring or null
defaultTaxRatenumber or null
onlineBookableboolean
bookingThresholdPercentinteger or null
windowThresholdsobject
qboClassIdstring or null
qboClassNamestring or null
qboDepartmentIdstring or null
qboDepartmentNamestring or null
xeroTrackingCategoryIdstring or null
xeroTrackingCategoryNamestring or null
xeroTrackingOptionIdstring or null
xeroTrackingOptionNamestring or null
technicianCountintegerTechnicians whose home or allowed unit it is.
serviceTypeCountintegerService types that default to it.
createdAtstring (date-time)
updatedAtstring (date-time)

Get a business unit

GET /organizations/{organizationId}/business-units/{businessUnitId}

One business unit with its branding, default tax, online booking limits, accounting mapping and how many technicians and service types use it. Read-only.

PermissionbusinessUnits.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolbusinessUnits_get (toolset settings)

Parameters

NameInTypeRequiredDescription
businessUnitIdpathstringYes

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/business-units/{businessUnitId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
namestring
tradestring or null
activeboolean
businessLocationIdstring or null
businessLocationobject or null
businessLocation.idstring
businessLocation.namestring
phonestring or null
emailstring or null
logoUrlstring or null
invoiceFooterstring or null
defaultTaxRatenumber or null
onlineBookableboolean
bookingThresholdPercentinteger or null
windowThresholdsobject
qboClassIdstring or null
qboClassNamestring or null
qboDepartmentIdstring or null
qboDepartmentNamestring or null
xeroTrackingCategoryIdstring or null
xeroTrackingCategoryNamestring or null
xeroTrackingOptionIdstring or null
xeroTrackingOptionNamestring or null
technicianCountintegerTechnicians whose home or allowed unit it is.
serviceTypeCountintegerService types that default to it.
createdAtstring (date-time)
updatedAtstring (date-time)

Change a business unit

PATCH /organizations/{organizationId}/business-units/{businessUnitId}

Changes the fields sent. Branding shows on the unit's invoices and quotes at once (customer-visible); onlineBookable and the thresholds change what online booking offers at once; the accounting mapping applies to invoices pushed from now on. active: false retires it.

PermissionbusinessUnits.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolbusinessUnits_update (toolset settings)

Parameters

NameInTypeRequiredDescription
businessUnitIdpathstringYes

Request body

FieldTypeRequiredDescription
namestringNoUp to 120 characters.
tradestring or nullNoThe trade, free text ("HVAC", "Plumbing"). Up to 60 characters.
activebooleanNoInactive units keep their history but cannot be chosen for new work.
businessLocationIdstring or nullNoThe branch it belongs to (GET /business-locations); null = none.
phonestring or nullNoShown on its invoices and quotes instead of the business's. Up to 40 characters.
emailempty string or string (email) or nullNoShown on its invoices and quotes instead of the business's.
logoUrlstring or nullNoAn https image URL shown on its invoices and quotes instead of the business logo.
invoiceFooterstring or nullNoText at the foot of its invoices and quotes (licence numbers, terms). Up to 2000 characters.
defaultTaxRatenumber or nullNoPercent: its new invoices and quotes use it when the property has no rate. 0–100.
onlineBookablebooleanNoFalse: online booking does not offer the service types whose default unit it is.
bookingThresholdPercentinteger or nullNoStop online booking in a window once its utilisation would pass this; null = the business default. 10–300.
windowThresholdsobjectNoPer planning window: window start → percent, e.g. { "08:00": 80 }.
qboClassIdstring or nullNoQuickBooks Class id its invoices carry. Up to 100 characters.
qboClassNamestring or nullNoUp to 200 characters.
qboDepartmentIdstring or nullNoQuickBooks Location (Department in the API) id its invoices carry. Up to 100 characters.
qboDepartmentNamestring or nullNoUp to 200 characters.
xeroTrackingCategoryIdstring or nullNoXero tracking category; with an option, replaces the integration's default tracking on its invoices. Up to 100 characters.
xeroTrackingCategoryNamestring or nullNoUp to 200 characters.
xeroTrackingOptionIdstring or nullNoUp to 100 characters.
xeroTrackingOptionNamestring or nullNoUp to 200 characters.

Example

curl -X PATCH "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/business-units/{businessUnitId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Dana Whitfield","trade":"string","active":true}'

Response

200: the answer's fields
FieldTypeDescription
idstring
namestring
tradestring or null
activeboolean
businessLocationIdstring or null
businessLocationobject or null
businessLocation.idstring
businessLocation.namestring
phonestring or null
emailstring or null
logoUrlstring or null
invoiceFooterstring or null
defaultTaxRatenumber or null
onlineBookableboolean
bookingThresholdPercentinteger or null
windowThresholdsobject
qboClassIdstring or null
qboClassNamestring or null
qboDepartmentIdstring or null
qboDepartmentNamestring or null
xeroTrackingCategoryIdstring or null
xeroTrackingCategoryNamestring or null
xeroTrackingOptionIdstring or null
xeroTrackingOptionNamestring or null
technicianCountintegerTechnicians whose home or allowed unit it is.
serviceTypeCountintegerService types that default to it.
createdAtstring (date-time)
updatedAtstring (date-time)

Delete a business unit

DELETE /organizations/{organizationId}/business-units/{businessUnitId}

Deletes a unit nothing was recorded against (409 when any job, quote, invoice, membership, request or campaign has it: retire it with active: false instead). Its service types and technicians lose it as their default.

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

Parameters

NameInTypeRequiredDescription
businessUnitIdpathstringYes

Example

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

Response

200: the answer's fields
FieldTypeDescription
oktrue

Accounting tracking choices for units

GET /organizations/{organizationId}/integrations/accounting-tracking

What a business unit can map to in the connected accounting system, for the unit editor: QuickBooks Online classes and locations (qbo, Location is Department in QuickBooks), or Xero tracking categories with their options (xero). Only one accounting system is connected at a time; provider is null when neither is, and connected is false (no lists) when the connection needs a reconnect. Save the chosen ids and names on the unit with PATCH /business-units/{businessUnitId} (qboClassId/qboClassName, qboDepartmentId/qboDepartmentName, xeroTrackingCategoryId/Name, xeroTrackingOptionId/Name); invoices of the unit pushed afterwards carry them. 409 when the accounting system cannot be reached. Read-only.

PermissionbusinessUnits.manage (Owner, Admin)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolbusinessUnits_accountingOptions (toolset settings)

Example

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

Response

200: the answer's fields
FieldTypeDescription
providerenum or nullThe connected accounting system; null = none. One of QUICKBOOKS, XERO.
connectedbooleanFalse when none is connected or the connection needs a reconnect.
qboobject or null
qbo.classesarray of object
qbo.classes[].idstring
qbo.classes[].namestring
qbo.departmentsarray of objectQuickBooks Locations.
qbo.departments[].idstring
qbo.departments[].namestring
xeroobject or null
xero.trackingCategoriesarray of object
xero.trackingCategories[].idstring
xero.trackingCategories[].namestring
xero.trackingCategories[].optionsarray of object

List branches

GET /organizations/{organizationId}/business-locations

Branches (locations) that group business units, with how many units each has. They share the business's timezone. Read-only.

PermissionbusinessUnits.read (Owner, Admin, Dispatcher, Technician, Member)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolbusinessLocations_list (toolset settings)

Example

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

Response

200: the answer's fields
FieldTypeDescription
itemsarray of object
items[].idstring
items[].namestring
items[].addressstring or null
items[].phonestring or null
items[].activeboolean
items[].createdAtstring (date-time)
items[].updatedAtstring (date-time)
items[]._countobject
items[]._count.unitsinteger

Create a branch

POST /organizations/{organizationId}/business-locations

Adds a branch. Put units in it with PATCH /business-units/{id} businessLocationId.

PermissionbusinessUnits.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolbusinessLocations_create (toolset settings)

Request body

FieldTypeRequiredDescription
namestringYesUp to 120 characters.
addressstring or nullNoUp to 500 characters.
phonestring or nullNoUp to 40 characters.
activebooleanNo

Example

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

Response

201: the answer's fields
FieldTypeDescription
idstring
namestring
addressstring or null
phonestring or null
activeboolean
createdAtstring (date-time)
updatedAtstring (date-time)
_countobject
_count.unitsinteger

Change a branch

PATCH /organizations/{organizationId}/business-locations/{businessLocationId}

Changes the fields sent (name, address, phone, active). Its units stay in it; nothing else changes.

PermissionbusinessUnits.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolbusinessLocations_update (toolset settings)

Parameters

NameInTypeRequiredDescription
businessLocationIdpathstringYes

Request body

FieldTypeRequiredDescription
namestringNoUp to 120 characters.
addressstring or nullNoUp to 500 characters.
phonestring or nullNoUp to 40 characters.
activebooleanNo

Example

curl -X PATCH "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/business-locations/{businessLocationId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Dana Whitfield","address":"string","phone":"+15555550123"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
namestring
addressstring or null
phonestring or null
activeboolean
createdAtstring (date-time)
updatedAtstring (date-time)
_countobject
_count.unitsinteger

Delete a branch

DELETE /organizations/{organizationId}/business-locations/{businessLocationId}

Deletes a branch; its units stay, without a branch.

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

Parameters

NameInTypeRequiredDescription
businessLocationIdpathstringYes

Example

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

Response

200: the answer's fields
FieldTypeDescription
oktrue

On this page