REST endpoints for subcontracts in ServFlo: 12 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}/projects/{projectId}/subcontracts
Bids (accepted ones are committed), bills with the payments recorded and lien waivers, and per sub: committed, billed, paid and owed. ServFlo records payments; it never pays a sub. Read-only.
Permission subcontractors.bills (Owner, Admin)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool subcontracts_get (toolset projects)
Name In Type Required Description projectIdpath string Yes The project (GET /projects).
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger
POST /organizations/{organizationId}/projects/{projectId}/subcontracts/bids
A subcontractor's price for work on the project (optionally a phase). Accept it with PATCH …/bids/{bidId}.
Permission subcontractors.bills (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool subcontracts_addBid (toolset projects)
Name In Type Required Description projectIdpath string Yes The project (GET /projects).
Field Type Required Description vendorIdstring Yes The subcontractor (a vendor; GET /subcontractors). phaseIdstring or null No amountCentsinteger Yes Money in integer cents (12500 = 125.00). -100000000–100000000. scopestring or null No Up to 5000 characters. receivedOnempty string or string or null No
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts/bids" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"vendorId":"vendor_id","amountCents":12500}'
201: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger
PATCH /organizations/{organizationId}/projects/{projectId}/subcontracts/bids/{bidId}
ACCEPTED commits the amount (and puts the sub on the bid's phase when it has none); DECLINED; or change the amount, scope or phase.
Permission subcontractors.bills (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool subcontracts_updateBid (toolset projects)
Name In Type Required Description projectIdpath string Yes The project (GET /projects). bidIdpath string Yes
Field Type Required Description statusenum No One of SUBMITTED, ACCEPTED, DECLINED. amountCentsinteger No Money in integer cents (12500 = 125.00). -100000000–100000000. scopestring or null No Up to 5000 characters. phaseIdstring or null No
curl -X PATCH "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts/bids/{bidId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"status":"SUBMITTED","amountCents":12500,"scope":"string"}'
200: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger
DELETE /organizations/{organizationId}/projects/{projectId}/subcontracts/bids/{bidId}
Destructive: removes a subcontractor's bid from the project (an accepted bid stops counting as committed).
Permission subcontractors.bills (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 subcontracts_deleteBid (toolset projects)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description projectIdpath string Yes The project (GET /projects). bidIdpath string Yes
curl -X DELETE "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts/bids/{bidId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger
POST /organizations/{organizationId}/projects/{projectId}/subcontracts/bills
What a subcontractor billed for the project: it counts in SUBCONTRACTORS actuals and in what the sub is owed.
Permission subcontractors.bills (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool subcontracts_addBill (toolset projects)
Name In Type Required Description projectIdpath string Yes The project (GET /projects).
Field Type Required Description vendorIdstring Yes The subcontractor (a vendor; GET /subcontractors). phaseIdstring or null No numberstring or null No Up to 100 characters. billDateempty string or string or null No dueDateempty string or string or null No amountCentsinteger Yes Money in integer cents (12500 = 125.00). -100000000–100000000. descriptionstring or null No Up to 5000 characters.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts/bills" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"vendorId":"vendor_id","amountCents":12500}'
201: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger
PATCH /organizations/{organizationId}/projects/{projectId}/subcontracts/bills/{billId}
Number, dates, amount (not below what was paid), description or phase.
Permission subcontractors.bills (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool subcontracts_updateBill (toolset projects)
Name In Type Required Description projectIdpath string Yes The project (GET /projects). billIdpath string Yes
Field Type Required Description phaseIdstring or null No numberstring or null No Up to 100 characters. billDatestring No A calendar date in the business's own calendar, YYYY-MM-DD. dueDateempty string or string or null No amountCentsinteger No Money in integer cents (12500 = 125.00). -100000000–100000000. descriptionstring or null No Up to 5000 characters.
curl -X PATCH "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts/bills/{billId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"phaseId":"phase_id","number":"string","billDate":"2026-11-03"}'
200: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger
DELETE /organizations/{organizationId}/projects/{projectId}/subcontracts/bills/{billId}
Destructive: removes a bill without payments.
Permission subcontractors.bills (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 subcontracts_deleteBill (toolset projects)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description projectIdpath string Yes The project (GET /projects). billIdpath string Yes
curl -X DELETE "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts/bills/{billId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger
POST /organizations/{organizationId}/projects/{projectId}/subcontracts/bills/{billId}/payments
Records a payment the business made outside ServFlo (check, ACH, cash, card): NEVER moves money. Not more than is left on the bill. Attach the lien waiver with POST …/files (category LIEN_WAIVER, subPaymentId).
Permission subcontractors.bills (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool subcontracts_recordPayment (toolset projects)
Name In Type Required Description projectIdpath string Yes The project (GET /projects). billIdpath string Yes
Field Type Required Description amountCentsinteger Yes Money in integer cents (12500 = 125.00). -100000000–100000000. paidOnempty string or string or null No methodenum No One of CHECK, ACH, CASH, CARD, OTHER. Default CHECK. referencestring or null No Up to 100 characters. notestring or null No Up to 2000 characters.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts/bills/{billId}/payments" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"amountCents":12500}'
201: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger paymentIdstring
DELETE
/organizations/{organizationId}/projects/{projectId}/subcontracts/payments/{subPaymentId}
Destructive: removes a recorded payment (its lien waiver stays in the files).
Permission subcontractors.bills (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 subcontracts_deletePayment (toolset projects)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description projectIdpath string Yes The project (GET /projects). subPaymentIdpath string Yes
curl -X DELETE "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/subcontracts/payments/{subPaymentId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description bidsarray of object bids[].idstring bids[].vendorIdstring bids[].amountCentsinteger bids[].statusstring billsarray of object bills[].idstring bills[].vendorIdstring bills[].amountCentsinteger bills[].paidCentsinteger bills[].owedCentsinteger bills[].paymentsarray of object bills[].payments[].idstring bills[].payments[].amountCentsinteger bills[].payments[].hasLienWaiverboolean bySubcontractorarray of object bySubcontractor[].vendorIdstring bySubcontractor[].owedCentsinteger totalsobject totals.owedCentsinteger
GET /organizations/{organizationId}/projects/{projectId}/sub-links
The live view-only links of subs on the project. Read-only.
Permission subcontractors.read (Owner, Admin, Dispatcher, Member)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool subcontracts_links (toolset projects)
Name In Type Required Description projectIdpath string Yes The project (GET /projects).
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/sub-links" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields An array of objects:
Field Type Description idstring vendorIdstring urlstring
POST /organizations/{organizationId}/projects/{projectId}/sub-links
Grants access: a link (/sub/{token}) where the subcontractor sees the project's name and address, their phases and the files shared with subs; never prices or the customer's details. Returns the live link when there is one.
Permission subcontractors.manage (Owner, Admin, Dispatcher)Risk sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.MCP tool subcontracts_createLink (toolset projects)Approval Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals .
Name In Type Required Description projectIdpath string Yes The project (GET /projects).
Field Type Required Description vendorIdstring Yes The subcontractor (a vendor; GET /subcontractors).
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/sub-links" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"vendorId":"vendor_id"}'
201: the answer's fields Field Type Description idstring urlstring
POST /organizations/{organizationId}/projects/{projectId}/sub-links/revoke
Revokes access: the sub's link stops working.
Permission subcontractors.manage (Owner, Admin, Dispatcher)Risk sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.MCP tool subcontracts_revokeLink (toolset projects)Approval Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals .
Name In Type Required Description projectIdpath string Yes The project (GET /projects).
Field Type Required Description vendorIdstring Yes The subcontractor (a vendor; GET /subcontractors).
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /projects/{projectId}/sub-links/revoke" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"vendorId":"vendor_id"}'
200: the answer's fields Field Type Description oktrue