Skip to main content
A shipment is created against a branch and a pickup location, both identified by codes that belong to your merchant company. Read them from /v2/external/branches and /v2/external/pickup-locations rather than hard-coding them.

Estimate a price

Pricing is a separate, side-effect-free call. It commits nothing.
A 503 here means the routing provider is unavailable. It is a transient condition — retry with backoff. It is never reported as a successful estimate with a guessed price.

Create a shipment

POST /v2/external/shipments requires an Idempotency-Key. See Idempotency and ETags for the key’s grammar and replay semantics.
Every field above is required. A few are worth calling out: A 201 means the shipment was created. A 200 means this exact request was already processed and you are seeing the original result — see idempotency.

Lifecycle

A shipment moves through these states:
Treat state as a value to read, not a sequence to assume. DISPATCH_UNRESOLVED and DELIVERY_FAILED are ordinary outcomes, and a shipment can be cancelled from several states.

List and filter

Supported filters are state and externalReference.

Pagination

Collections are cursor-paginated and bounded.
  • limit defaults to 25 and maxes at 100. A value outside 1..100 is rejected with 400, never silently clamped.
  • cursor is the opaque page.nextCursor from the previous response.
  • page.hasMore is exactly nextCursor != null.
A cursor is bound to the tenant, parent resource, filter, and sort of the query that produced it. Presenting it to a different query is rejected with 400 INVALID_CURSOR. To change a filter, start a new first page.

Retrieve one

An unknown shipment, or one outside your company’s tenancy, is rejected rather than returned. See Errors for how to tell the cases apart from the machine code.