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 .
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.
Permission businessUnits.read (Owner, Admin, Dispatcher, Technician, Member)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool businessUnits_list (toolset settings)
Name In Type Required Description includeInactivequery boolean No
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /business-units" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description 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[].technicianCountinteger Technicians whose home or allowed unit it is. items[].serviceTypeCountinteger Service types that default to it. items[].createdAtstring (date-time) items[].updatedAtstring (date-time)
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.
Permission businessUnits.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool businessUnits_create (toolset settings)
Field Type Required Description namestring Yes Up to 120 characters. tradestring or null No The trade, free text ("HVAC", "Plumbing"). Up to 60 characters. activeboolean No Inactive units keep their history but cannot be chosen for new work. businessLocationIdstring or null No The branch it belongs to (GET /business-locations); null = none. phonestring or null No Shown on its invoices and quotes instead of the business's. Up to 40 characters. emailempty string or string (email) or null No Shown on its invoices and quotes instead of the business's. logoUrlstring or null No An https image URL shown on its invoices and quotes instead of the business logo. invoiceFooterstring or null No Text at the foot of its invoices and quotes (licence numbers, terms). Up to 2000 characters. defaultTaxRatenumber or null No Percent: its new invoices and quotes use it when the property has no rate. 0–100. onlineBookableboolean No False: online booking does not offer the service types whose default unit it is. bookingThresholdPercentinteger or null No Stop online booking in a window once its utilisation would pass this; null = the business default. 10–300. windowThresholdsobject No Per planning window: window start → percent, e.g. { "08:00": 80 }. qboClassIdstring or null No QuickBooks Class id its invoices carry. Up to 100 characters. qboClassNamestring or null No Up to 200 characters. qboDepartmentIdstring or null No QuickBooks Location (Department in the API) id its invoices carry. Up to 100 characters. qboDepartmentNamestring or null No Up to 200 characters. xeroTrackingCategoryIdstring or null No Xero tracking category; with an option, replaces the integration's default tracking on its invoices. Up to 100 characters. xeroTrackingCategoryNamestring or null No Up to 200 characters. xeroTrackingOptionIdstring or null No Up to 100 characters. xeroTrackingOptionNamestring or null No Up to 200 characters.
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"}'
201: the answer's fields Field Type Description 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 technicianCountinteger Technicians whose home or allowed unit it is. serviceTypeCountinteger Service types that default to it. createdAtstring (date-time) updatedAtstring (date-time)
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.
Permission businessUnits.read (Owner, Admin, Dispatcher, Technician, Member)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool businessUnits_get (toolset settings)
Name In Type Required Description businessUnitIdpath string Yes
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /business-units/{businessUnitId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description 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 technicianCountinteger Technicians whose home or allowed unit it is. serviceTypeCountinteger Service types that default to it. createdAtstring (date-time) updatedAtstring (date-time)
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.
Permission businessUnits.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool businessUnits_update (toolset settings)
Name In Type Required Description businessUnitIdpath string Yes
Field Type Required Description namestring No Up to 120 characters. tradestring or null No The trade, free text ("HVAC", "Plumbing"). Up to 60 characters. activeboolean No Inactive units keep their history but cannot be chosen for new work. businessLocationIdstring or null No The branch it belongs to (GET /business-locations); null = none. phonestring or null No Shown on its invoices and quotes instead of the business's. Up to 40 characters. emailempty string or string (email) or null No Shown on its invoices and quotes instead of the business's. logoUrlstring or null No An https image URL shown on its invoices and quotes instead of the business logo. invoiceFooterstring or null No Text at the foot of its invoices and quotes (licence numbers, terms). Up to 2000 characters. defaultTaxRatenumber or null No Percent: its new invoices and quotes use it when the property has no rate. 0–100. onlineBookableboolean No False: online booking does not offer the service types whose default unit it is. bookingThresholdPercentinteger or null No Stop online booking in a window once its utilisation would pass this; null = the business default. 10–300. windowThresholdsobject No Per planning window: window start → percent, e.g. { "08:00": 80 }. qboClassIdstring or null No QuickBooks Class id its invoices carry. Up to 100 characters. qboClassNamestring or null No Up to 200 characters. qboDepartmentIdstring or null No QuickBooks Location (Department in the API) id its invoices carry. Up to 100 characters. qboDepartmentNamestring or null No Up to 200 characters. xeroTrackingCategoryIdstring or null No Xero tracking category; with an option, replaces the integration's default tracking on its invoices. Up to 100 characters. xeroTrackingCategoryNamestring or null No Up to 200 characters. xeroTrackingOptionIdstring or null No Up to 100 characters. xeroTrackingOptionNamestring or null No Up to 200 characters.
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}'
200: the answer's fields Field Type Description 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 technicianCountinteger Technicians whose home or allowed unit it is. serviceTypeCountinteger Service types that default to it. createdAtstring (date-time) updatedAtstring (date-time)
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.
Permission businessUnits.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 businessUnits_delete (toolset settings)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description businessUnitIdpath string Yes
curl -X DELETE "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /business-units/{businessUnitId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description oktrue
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.
Permission businessUnits.manage (Owner, Admin)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool businessUnits_accountingOptions (toolset settings)
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /integrations/accounting-tracking" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description providerenum or null The connected accounting system; null = none. One of QUICKBOOKS, XERO. connectedboolean False 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 object QuickBooks 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
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.
Permission businessUnits.read (Owner, Admin, Dispatcher, Technician, Member)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool businessLocations_list (toolset settings)
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /business-locations" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description 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
POST /organizations/{organizationId}/business-locations
Adds a branch. Put units in it with PATCH /business-units/{id} businessLocationId.
Permission businessUnits.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool businessLocations_create (toolset settings)
Field Type Required Description namestring Yes Up to 120 characters. addressstring or null No Up to 500 characters. phonestring or null No Up to 40 characters. activeboolean No
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"}'
201: the answer's fields Field Type Description idstring namestring addressstring or null phonestring or null activeboolean createdAtstring (date-time) updatedAtstring (date-time) _countobject _count.unitsinteger
PATCH /organizations/{organizationId}/business-locations/{businessLocationId}
Changes the fields sent (name, address, phone, active). Its units stay in it; nothing else changes.
Permission businessUnits.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool businessLocations_update (toolset settings)
Name In Type Required Description businessLocationIdpath string Yes
Field Type Required Description namestring No Up to 120 characters. addressstring or null No Up to 500 characters. phonestring or null No Up to 40 characters. activeboolean No
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"}'
200: the answer's fields Field Type Description idstring namestring addressstring or null phonestring or null activeboolean createdAtstring (date-time) updatedAtstring (date-time) _countobject _count.unitsinteger
DELETE /organizations/{organizationId}/business-locations/{businessLocationId}
Deletes a branch; its units stay, without a branch.
Permission businessUnits.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 businessLocations_delete (toolset settings)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description businessLocationIdpath string Yes
curl -X DELETE "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /business-locations/{businessLocationId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description oktrue