Neither endpoint is available to internal-service-team keys; quoting and invoicing are for third-party suppliers billing a buyer.
Money is strings, in sections
Proposals and invoices share a line-item structure. Amounts are strings that must parse as numbers (“450.00”, not 450.00 as a float; senders should format with two decimals and parse as decimals). The sections are labor, material, travel, freight, and misc (proposals add incurred cost), each carrying its own line items, tax rate, and...TotalBeforeTax, rolling up to before-tax, tax, and after-tax totals. Travel, freight, and misc lines are simple { "description", "amount" } objects.
Proposals (quotes)
POST /v1/supplier/quote/proposals creates the proposal directly in pending status under your facility; there is no separate submit step. Required: workOrderId and totalAfterTax.
locationId,buyerFacilityId, andbuyerCompanyIdare derived from the work order; you cannot set them.- Unset tax fields and section totals default to
"0". requestForProposalIddefaults to the work order’s RFP when omitted.proposalPdfLink, if sent, must be a valid URL.attachmentstakeFileDetailsfrom the file upload endpoint.- Passing an
idupdates an existing proposal.
status moves from pending to awarded or declined (decline reasons appear in declineNotes). List with GET /v1/supplier/quote/proposals, read one with GET /v1/supplier/quote/proposals/{id}.
Invoices
The lifecycle
Invoices start asdraft (invisible to the buyer), get published into pending, then the buyer moves them through approved and processing to paid (or disputes them). Your integration creates the draft and publishes it; from pending onward you are mostly reading status.
Create the draft
POST /v1/supplier/invoice/invoices requires workOrderId; locationId, buyerFacilityId, buyerCompanyId, spendCategoryId, and problemTypeId are all derived from it.
poNumberdefaults to the work order’s PO number.serviceCallIdsdefaults to all service calls on the work order when omitted or empty; set it explicitly when billing a subset of visits.taxLineItemsare validated against the invoice currency’s allowed tax types (currently only CAD supports them: GST/HST/PST); anything else is rejected.invoicePDFLink(a valid URL) becomes the invoice’s single PDF entry if you host the PDF yourself; most integrations use the upload endpoint below instead.autoPublishOnApprovalopts this invoice into auto-publishing when the work order completes.- Saving an invoice can transition the associated work order’s status per the invoice-to-work-order status mapping. A save-level validation failure returns
406. - Passing an
idupdates an existing invoice (drafts only, in practice; buyer-side statuses are not yours to edit).
Upload the PDF and publish
POST /v1/supplier/invoice/file/upload_and_publish/{invoiceId} does both steps at once: the uploaded PDF (multipart part file, max 512 MB) becomes the invoice’s single PDF, and the status moves to pending.
400: your facility must own the invoice, the associated work order must be in Completed display status, and supplier invoice editing must be allowed by the buyer’s configuration.
Read and reconcile
GET /v1/supplier/invoice/invoices (filterable, e.g. ?status=pending) and GET /v1/supplier/invoice/invoices/{id}. Third-party suppliers see masked records with buyer-private fields blanked. Poll status to drive your AR ledger: approvedAt, processedAt, and markedPaidAt timestamp the buyer’s progress.
End-to-end billing flow
- Work order reaches quoting: submit a proposal, wait for
awarded. - Complete the work through service-call check-out.
- Create the draft invoice; generate your PDF.
- Once the work order shows Completed,
upload_and_publish. - Poll invoice status until
paid, and reconcile againstmarkedPaidAt.