Skip to main content
Money flows through two objects: proposals (quotes the buyer approves before work proceeds) and invoices (the bill for completed work). Both are created by suppliers through this API.
Neither endpoint is available to internal-service-team keys; quoting and invoicing are for third-party suppliers billing a buyer.
All examples assume:

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.
Behavior to know:
  • locationId, buyerFacilityId, and buyerCompanyId are derived from the work order; you cannot set them.
  • Unset tax fields and section totals default to "0".
  • requestForProposalId defaults to the work order’s RFP when omitted.
  • proposalPdfLink, if sent, must be a valid URL. attachments take FileDetails from the file upload endpoint.
  • Passing an id updates an existing proposal.
Track the outcome by re-fetching: 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 as draft (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.
Details that bite:
  • poNumber defaults to the work order’s PO number.
  • serviceCallIds defaults to all service calls on the work order when omitted or empty; set it explicitly when billing a subset of visits.
  • taxLineItems are 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.
  • autoPublishOnApproval opts 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 id updates 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.
Each precondition failing returns 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

  1. Work order reaches quoting: submit a proposal, wait for awarded.
  2. Complete the work through service-call check-out.
  3. Create the draft invoice; generate your PDF.
  4. Once the work order shows Completed, upload_and_publish.
  5. Poll invoice status until paid, and reconcile against markedPaidAt.