Authentication
Every request authenticates with a bearer token. Scopes control what each token can do; test and live modes are fully separate; rotation never breaks in-flight requests.
Bearer tokens
Every API request must include an Authorization: Bearer <token> header. Tokens are minted at Settings → API tokens. The secret is shown once on creation — copy it before navigating away.
Authorization: Bearer shp_live_8a3f...c91b
Content-Type: application/jsonToken shape
shp_test_…— test-mode token. Hits carrier test endpoints (no real money, stub tracking codes).shp_live_…— production token. Real carrier calls, real money, real labels.
Both prefixes are 64 characters long after the underscore. The prefix is meaningful and safe to log; the suffix is the secret and must be treated like a password.
Never put tokens in URLs
400 token_in_query.Scopes
Each token carries a list of scopes that gate which endpoints it can call. Scopes are namespaced read:<resource> / write:<resource>; write implies read on the same resource. Pick the narrowest scope set the integration actually needs.
Available scopes
read:shipments
GET /labels, GET /labels/{id}, GET /trackers/{id}
Read-only access to your shipment history.
write:shipments
All write endpoints — quote, create, refund, void
Implies read:shipments. Use for full lifecycle integrations.
read:addresses
GET /addresses (when launched)
Read your saved sender + recipient addresses.
write:addresses
POST /addresses/verify, POST /addresses
Verify + persist addresses to your address book.
read:webhooks
GET /webhooks, GET /events
Read your webhook subscriptions + event history.
write:webhooks
POST /webhooks, DELETE /webhooks/{id}
Create + delete webhook subscriptions.
Insufficient scope
403 insufficient_scope. The error body includes requiredScope so you know which scope to add or which token to mint.Test vs live mode
Tokens are mode-specific. Test-mode and live-mode data are completely isolated — you cannot read live shipments with a test token, and a test-mode label can never become a real carrier shipment. The two modes share the same code path, so anything that works in test mode works identically in live.
- Test mode hits our carrier sandbox - returns stub tracking codes and never bills the carrier or you.
- Live mode hits real carrier networks. A successful
POST /labels/createcall charges your account. - Mode is determined by the token prefix —
shp_test_vsshp_live_. There is no separate "mode" header.
Rotation
Mint a new token, deploy it, then revoke the old one. The two tokens can be live simultaneously for as long as you need to cut over — there is no rate limit on having multiple active tokens. Recommended rotation cadence: every 90 days for live tokens, no rotation needed for test tokens.
- Visit Settings → API tokens and click
+ New token. Copy the secret. - Update your application's secret store (Vercel env, Doppler, AWS Secrets Manager, etc.) with the new token.
- Redeploy or restart your application.
- Click
Revokeon the old token. Any in-flight requests using the old token are immediately rejected with401 token_revoked.
Compromised tokens
If a token leaks (committed to git, posted in a Slack channel, seen in a screenshot) revoke it immediately at Settings → API tokens. Revocation is instant — all subsequent requests with that token return 401 token_revoked. We do not log token values server-side, so we cannot tell you what calls were made with the compromised token; check your own application logs.
Audit log
lastUsedAttimestamp + the IP address of the most recent request. If a revoked token shows recent activity from an unexpected IP, that's a signal to audit your secret-management chain.Common errors
401 missing_authorization— noAuthorizationheader at all.401 invalid_token— header present but the token doesn't match any record. Check for typos / whitespace.401 token_revoked— token was valid but has been revoked.403 insufficient_scope— token is valid but missing the scope this endpoint requires. The response body includesrequiredScope.403 wrong_mode— token was minted for the other mode (e.g. test token on a live-mode resource id).
See Errors for the full status-code reference.