Skip to main content

Label Errors

Purchase failures​

POST/api/v1/shipments/{shipmentId}/labels
SituationStatus
Invalid or no-longer-usable rate id, or other invalid request400
Missing or no-longer-usable bearer token401
Order is already Cancelled, already LabelCreated, or Returned400
Purchase still running when the wait window ends202 — not a failure; read the Order for the outcome
A different purchase is in progress, or the Shipment already has a Label409
The rate, its Shipment, or the Order behind it does not exist for your account404
The carrier rejected the Shipment for something you can correct — address, phone, customs, parcel, or a stale rate422
The carrier is temporarily unavailable503 — nothing to correct; retry later

The request carries no idempotency key, but a repeat is recognized server-side: sending the same purchase request again replays its outcome rather than buying a second Label. For an ambiguous outcome (timeout, connection failure, or any response you cannot attribute to success or failure), reissue the same request within a bounded budget, or read the Order. A request that is not the same purchase is refused with 409 instead of starting a competing one — correct it rather than looping. See Buy a Label for the exact conditions and Retries and Ambiguous Outcomes.

Binary download failures​

GET/api/v1/labels/{labelId}/download
SituationStatus
Label file ready200 (binary body — application/pdf or application/zpl)
File still being generated202 — pending or still generating; the response carries Retry-After (see below)
Invalid request (e.g. unsupported format)400
Missing or no-longer-usable bearer token401
Label not found, or the requested format was never generated for it404
Label generation conflicts with its current state409
Label generation failed, or an internal error occurred500
The carrier is temporarily unavailable503 — nothing to correct; retry later

A 202 is not a failure. The file is still being produced, and the response carries a Retry-After header giving the whole number of seconds to wait before requesting the same download again. Wait for the value that response gives rather than an interval of your own. It is a retry hint, not a completion contract — no retry budget, deadline, or eventual-success guarantee is defined, so keep the attempts bounded. The 202 a Label purchase returns is a different response and carries no such header; see Retries and Ambiguous Outcomes.

This operation does not put every failure in the normal {success, data, errors} JSON envelope. The download itself answers with a flat error object — code, description, category, metadata — but it is not the only producer on the request: authentication, X-SubAccount-Id validation, request binding and unhandled server errors answer around it, and those always use the envelope. Which shape you get therefore depends on the status:

StatusBody
202, 503The flat error object
400, 401The envelope
403No body at all
404, 409, 500Either — both producers can reach these

So for 404, 409 and 500 you must branch on the body you actually received rather than assuming one shape. The two are easy to tell apart: the flat object has a code key at the top level, the envelope has success. Inspect the HTTP status and Content-Type header before treating the body as either JSON or a label file. See Download a Label for working examples.

Cancellation​

DELETE/api/v1/labels/{labelId}
SituationStatus
Label does not exist for your account404
Invalid request400
The Label cannot be cancelled as it stands — its Shipment has no tracking code to cancel against422

The documented result is data.isSuccess. Do not infer provider action, Label state, refund status, or repeat-request safety from that boolean.

Recover safely​

Treat file download failures separately from normal JSON handling. After an ambiguous cancellation response, do not blindly repeat the request; use your application's operational process without treating it as an API recovery flow.

See Order-to-Label Workflow and Retries and Ambiguous Outcomes.