balance and status. Syncing invoices without a way to represent payments or an authoritative outstanding balance leaves those features with no reliable way to know what a customer still owes.
This page defines the required AR data contract. For the payables side, see Accounts payable API.
Wait for exception evaluation
exceptionsLastEvaluatedAt is a read-only, nullable timestamp on customer invoices, carrier invoices, and remittances. A null or absent value means evaluation has not completed. Do not treat an empty exceptions list as permission to approve, release for billing, or send while this value is missing.
Require a non-null timestamp and the existing exception and approval conditions. A populated timestamp does not mean the record passed its checks. Attempts to approve or send before evaluation finishes are blocked, including exception overrides. Purchase orders are excluded. Historical records may have a documented rollout baseline; ordinary later recalculations retain the previous timestamp until completion.
A customer invoice that was already evaluated can return to a null timestamp when Upwell invalidates its earlier result. For example, this happens when a connected TMS sends a newer version of a DRAFT or CREATED invoice that is not yet approved to send. It also happens when a CANCELLED, WRITE_OFF, or REFUNDED invoice is reactivated. Upwell then re-evaluates the invoice and populates the timestamp again. Treat a null timestamp as not ready to send, whether the invoice was never evaluated or is being re-evaluated. A null timestamp is not a hold or an exception, so do not cache an earlier non-null value as permission to send.
External systems such as Transport Pro may synchronize a customer invoice from DRAFT to CREATED even while evaluation is pending. This status change does not approve the invoice for sending or mark its checks complete; Upwell approval and delivery remain blocked until evaluation completes.
To use Upwell’s checks when deciding which drafts to release for billing, include "exceptionsLastEvaluatedAt": { "_isNull": false } in the where filter of POST /api/rest/invoices/search, alongside the existing blocking-exception filters. The external system owns its release decision. Prebilling supporting-document uploads remain independent.
The lifecycle
1
A shipment becomes an invoice
You create an invoice for a customer and link the shipments it bills. New invoices start in
CREATED.2
Charges go on it
Invoice line items carry the priced rows — line haul, fuel, accessorials — and sum to the invoice total.
3
It clears review
Rules and exceptions can hold an invoice back. Once it’s clean it’s approved for sending — either automatically or through the invoice approval queue.
4
It goes out
Delivery happens by email, customer portal, EDI, or print — or the invoice is rolled into a statement or list bill instead of being sent alone.
5
Cash comes back and gets applied
A customer payment records what arrived. Its line items say which invoices the money applies to. Upwell recalculates each invoice’s balance and moves it to
PART_PAID or PAID.Keep outstanding balances accurate
Use one of the following balance models. Do not mix a partial payment history with invoice balance snapshots: both systems would be trying to explain the same balance from incomplete data.Payment-ledger model (recommended)
This is the standard model for API integrations and gives Upwell a complete audit trail:- Create each new invoice with
balanceequal tototalAmount. - Create a customer payment when money is received.
- Create one customer payment line item for every invoice the payment applies to. A payment header without line items does not affect any invoice.
- Correct or delete the original payment line item when an application is changed, voided, returned, or removed. Changing only a payment or line-item
statusdoes not unapply its amount. - Backfill open invoices and all payment applications that contribute to their current balances before enabling statements or reminders. Continue syncing both invoices and applications after cutover.
Payment and payment-line-item statuses are useful integration metadata, but a line item’s amount is what applies cash in the standard model. Create the linked line item only when the application should reduce the invoice balance.
Authoritative-balance model
If your source system cannot provide a complete payment-application ledger, it must provide the current outstanding balance and matching paid state for every invoice instead. Coordinate this model with Upwell before implementation; externally owned balances require integration-specific handling so local payment events and source-system snapshots cannot overwrite one another. At minimum, the source must:- send
balancein integer cents whenever the amount owed changes; - send a matching
status(PART_PAID,PAID, or the appropriate open lifecycle status); - backfill current balances and statuses before statements are enabled;
- publish corrections and reversals, not only forward-moving payments; and
- provide stable
sourceSystemandsourceSystemIdvalues so updates target the original invoice.
What statements use
Statement generation reads each stored invoicebalance; it does not independently reconstruct what is owed from the source system. The invoice must also be linked to the correct customerId and have the dates and status required by the selected statement filter.
The default All outstanding filter includes OPEN, APPROVED, OVERDUE, DISPUTED, PART_PAID, SENT, VIEWED, and DELIVERED. It excludes PAID, CANCELLED, and draft CREATED invoices. Use the All outstanding including created preset only when drafts are intentionally statement-ready.
Before turning on statements, reconcile at least one full customer account and then the cutover population:
- the sum of invoice balances in Upwell equals the source system’s customer balance;
- every fully paid invoice has a zero balance and
PAIDstatus; - every partially paid invoice has the expected remaining balance and
PART_PAIDstatus; - voided or returned applications reopen the invoice when money is owed again; and
- invoice
issueDateanddueDatevalues produce the expected aging buckets.
The objects
Invoice vs. carrier invoice — same word, opposite directions of money. An invoice (
inv_) is you billing your customer. A carrier invoice (cari_) is a carrier billing you. Throughout these docs an unqualified “invoice” is always the customer one. See Core concepts.Before any of this works
Receivables reference records that have to exist first:- Customers — who you bill. Sync before invoices. Note that deleting a customer also deletes their invoices, so deactivate instead.
- Shipments — the load being billed.
- Documents — how supporting paperwork gets attached.
- Rules — optional, but this is how you hold invoices that shouldn’t go out yet.
Guides for this side
Manage customer invoices
Create invoices, add line items, attach documents, link shipments.
Record customer payments
Create a remittance with its line items and reconcile it.
Receivables management
The AR dashboard, aging, and collections workflow.
Remittances
How remittance data arrives and gets matched.
Payment reminders
Automated follow-up on overdue invoices.
Online payments
Let customers pay from the portal.

