Welcome to the Upwell API
The Upwell REST API provides programmatic access to the core functionality of the Upwell platform — accounts payable automation, accounts receivable management, and document processing for logistics and freight companies. The endpoint reference in this section is generated directly from Upwell’s live OpenAPI specification, so it always reflects the current request and response shapes. Objects are listed alphabetically — a neutral order that deliberately implies nothing about importance. To see which objects belong together, start with the overview for the side you’re building:Accounts payable
Money out — bills, carrier invoices, approvals, and payments to carriers.
Accounts receivable
Money in — customer invoices, delivery, and applying remittances.
https://api.upwell.com
Base URL (staging): https://staging.api.upwell.com
Path prefix: /api/rest/
OpenAPI specification: app.upwell.com/openapi.json
Download the OpenAPI specification to import the API into Postman or generate a
client for your language. It is the same filtered spec this reference is built
from and is updated with every release.
Start here
Authentication
Get an API key and authenticate your requests.
Integration patterns
Idempotent upserts, integer-cents money, and the two-step document upload.
Submit a carrier invoice
Create a carrier invoice and attach its documents via the API.
Purchase orders & vendor invoices
Upload and manage parsed purchase orders and vendor invoices.
Track processing status
Know when a carrier invoice is received, processed, or flagged.
Outbound webhooks
Subscribe to events and authenticate the deliveries you receive.
Error handling
HTTP status codes, real error shapes, and retry guidance.
API conventions
- RESTful design — standard HTTP methods (
GET,POST,PUT,PATCH,DELETE). - JSON — all requests and responses are JSON.
- Authentication — API-key based, sent in the
Authorizationheader. See the Authentication guide. - Money is integer cents — monetary fields are integers in cents, never floating-point dollars. See Money & payloads.
- Pagination is
limit+offset, and the defaultlimitis 10 — a listGETwith no parameters returns only the first ten records, with nothing marking the response as truncated (a few endpoints default to 100). Always passlimit/offsetexplicitly when syncing or reconciling. Server-side filtering lives on thePOST /<resource>/searchendpoints (Integration patterns). sourceSystem+sourceSystemIdis your external key — the pair that ties an Upwell record back to yours, unique per tenant. It is not a blanket upsert:POSTonce, then update with the method that resource accepts (below), and check the per-resource retry semantics in Idempotency & retries before you build retries. Addresses are the exception — they have no external key at all.- Updates are
PUTon most resources andPATCHon ten of them — there is no resource that accepts both, so sending the wrong verb fails rather than falling back. These ten takePATCH:bill_line_items,carrier_invoice_approval_requests,documents,invoice_line_items,purchase-order-line-items,purchase-orders,shipment_line_items,vendor-invoice-line-items,vendor-invoices, andvendors. Everything else updates withPUT. Each endpoint’s reference page in the sidebar shows the verb it accepts. - Child records nest under a
datakey, on create only — aPOSTbody can create a record’s children in the same call. The wrapper is{ "data": [ … ] }for a list (a customer’saddresses, an invoice’sinvoiceLineItems) and{ "data": { … } }for a single slot (a shipment’spickupAddress). Each of these fields links to its own schema in the reference below — expand it to see the exact child shape. Update bodies take no nested children:PUTsets scalar columns on the record itself, so a child has to be written with its own endpoint. See Working with addresses for the full pattern.
Authentication
All API requests must include your API key in theAuthorization header — bare, or with a
Bearer prefix (both are accepted). See the
Authentication guide for how to obtain, scope, and rotate keys.
Responses
Successful responses return JSON keyed by the resource the endpoint operates on — a single object under its singular name ({ "carrierInvoice": { ... } }) or a list
under its plural one ({ "carrierInvoices": [ ... ] }).
Four list endpoints return a count alongside the rows, under an …Aggregate key:
GET /invoices and GET /customers (as invoicesAggregate and customersAggregate),
and the two invoice queues, which both
use invoicesAggregate. Every other list endpoint returns rows only, so page until you
get a short page rather than expecting a total.
A single-resource GET for an id that doesn’t exist returns 200 with a null
resource, not a 404. The exact shape for each endpoint is documented on its
reference page in the sidebar. Errors follow the format described in
Error handling.
Getting started
- Obtain your API key.
- Skim Integration patterns for the conventions above.
- Browse the endpoint reference in the sidebar, or follow a developer guide.
- Handle errors using the Error handling reference.

