Every v5 error response uses the same envelope:
{
"error": {
"code": "validation_failed",
"message": "Human-readable summary.",
"details": {
"field": ["Per-field error message"]
}
}
}The HTTP status gives the broad category. The error.code tells you what specifically happened. Branch on the code, not the message text.
| Code | What to do |
|---|---|
validation_failed | Fix error.details before retrying. |
unauthenticated, token_expired, token_revoked | Issue or select a valid token. |
scope_missing | Re-issue a token with the missing scope. |
insufficient_credits | Top up credits before purchasing labels. |
too_many_requests | Retry with exponential backoff. |
conflict, *_in_use, not_voidable, not_cancellable | Inspect the resource state and retry only after it changes. |
internal_error | Retry; contact support with the request ID if persistent. |
The API Reference documents the full error vocabulary.
Every v5 endpoint that creates or charges accepts an optional Idempotency-Key header. Generate a unique value per logical operation and reuse the same key only when retrying the exact same request body.
KEY=$(uuidgen)
curl -X POST "$STALLION_BASE_URL/labels" \
-H "Authorization: Bearer $STALLION_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d '{ ... }'Behavior:
- Same key and same body within 24 hours returns the original response with
Idempotent-Replay: true. - Same key with a different body returns
409 idempotency_conflict. 5xxresponses are not cached, so transient infrastructure failures can be retried with the same key.
Use this header for shipment creation, label purchase, pickups, LTL bookings, credit top-ups, product classification, and manufacturer verification.