Saltar al contenido
SendIt está en desarrollo y todavía no opera comercialmente · SendIt is in development and not yet commercially available.
SendItdocs
English
Esc
navigateopen⌘Jpreview
En esta página

Errors & response format

The standard response envelope, the error object, and how to resolve every code the API can return.

Every API response shares the same structure, whether it succeeds or fails. Learn it once and it applies to every endpoint.

The response envelope

Successful responses wrap the result in data, with optional metadata in meta:

{
  "success": true,
  "data": { "id": "clxq1w2e3r4t5y6u7i8o9p0a", "status": "DRAFT" },
  "meta": { "page": 1, "limit": 20, "total": 47, "totalPages": 3 }
}

Errors carry success: false and an error object:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "errors": {
        "contactName": ["contactName must be longer than or equal to 1 characters"],
        "postalCode": ["Postal code must be 4-6 digits"]
      }
    },
    "timestamp": "2026-07-17T12:00:00.000Z",
    "requestId": "req_abc123"
  }
}
Field Description
code Stable, machine-readable code — program against this, not message
message Human-readable description; may change without notice
details Error-specific context (invalid fields, hints, IDs)
timestamp When the error occurred
requestId Request identifier — include it when contacting support

Every error code

HTTP Code When it happens How to resolve it
400 VALIDATION_ERROR Body or params failed validation Check details.errors: it lists each invalid field and why
400 INVALID_INPUT Invalid combination (e.g. address by ID and inline at once) Check details; send exactly one variant per field. Some cases carry a more specific code in details.code
400 API_VERSION_UNSUPPORTED You asked for an API version that reached its sunset date Move to the current version. See versioning
401 UNAUTHORIZED Credential missing or malformed Send your key in X-API-Key or Authorization: Bearer
401 INVALID_API_KEY Key doesn’t exist or was revoked Verify the key; generate a new one if revoked
401 EXPIRED_API_KEY Key expired Generate a new key and update your integration
402 INSUFFICIENT_BALANCE Wallet can’t cover the operation Fund your wallet and retry
403 FORBIDDEN Valid credential without sufficient permissions (role or org) Use a credential with the right role/organization
403 INSUFFICIENT_SCOPE Key is missing scopes (listed in details) Add the missing scopes to the key
403 IP_NOT_ALLOWED Source IP is not on the key’s allowlist Add the IP to the key’s ipAllowlist or call from an allowed IP
403 PLAN_LIMIT_REACHED You hit your plan’s cap (API keys, webhook endpoints, or members) Upgrade your plan; details carries resource, limit, and plan — see plans
403 SOLE_OWNER_OF_ORGANIZATION You are deleting your account while sole OWNER of a team organization Transfer ownership to another member, then retry
404 RESOURCE_NOT_FOUND Resource doesn’t exist or belongs to another organization Verify the ID and your key’s organization
409 SHIPMENT_ALREADY_PROCESSED Shipment is no longer in an editable state Check the current status; only DRAFT shipments can be edited
409 IDEMPOTENCY_KEY_REUSED Idempotency-Key reused with a different body or endpoint Use a fresh key for each distinct operation
409 IDEMPOTENCY_KEY_IN_USE A concurrent request with the same key is still in flight Wait a moment and retry with the same key
409 SHIPMENT_LABEL_IN_PROGRESS Two concurrent purchases on the same shipment Retry in 1–2 seconds
410 RATES_EXPIRED The shipment’s rates expired (24 h) GET /v1/shipments/:id/rates to refresh, then pick a new rateId
422 CARRIER_NOT_SUPPORTED You asked to track a carrier SendIt cannot poll Use DHL, FEDEX, or ESTAFETA. See trackers
422 CARRIER_CREDENTIALS_REQUIRED That carrier needs account credentials to track Connect your credentials. See carrier accounts
422 ONE_CALL_BUY_RATES_PENDING Carriers took longer than 8 s to quote during a one-call buy Poll ratesPollUrl and buy with the rateId
422 ONE_CALL_BUY_NO_MATCHING_RATE No rate matched your purchase selection Pick one from details.availableRates
429 RATE_LIMIT_EXCEEDED You exceeded the request limit Honor Retry-After with exponential backoff — see rate limits
500 INTERNAL_ERROR Server error Retry; if it persists, contact support with the requestId
502 CARRIER_ERROR The carrier failed to generate the label Any charge was already refunded; retry or pick another rate
503 CHECKOUT_NOT_CONFIGURED The plan you requested has no self-serve checkout Contact sales for that plan

Handle errors by code, not by message

const res = await fetch(url, options);
const body = await res.json();

if (!body.success) {
  switch (body.error.code) {
    case "RATES_EXPIRED":
      // refresh rates and retry
      break;
    case "INSUFFICIENT_BALANCE":
      // notify your operations team
      break;
    default:
      log.error(body.error.requestId, body.error.code);
  }
}

Check details.code too

Some validations return 400 INVALID_INPUT with a more specific code nested in error.details.code. Read it when you need to tell the exact case apart:

details.code When it happens
PRECONDITION_FAILED An order’s If-Match does not match its current etag
ORDER_HAS_ACTIVE_LABELS You tried to cancel an order that still has valid labels
SHIPMENTS_NOT_FOUND A batch references shipments that do not exist or are not yours
PRODUCT_NOT_FOUND A line item points at a product that does not exist
LINE_ITEM_INCOMPLETE An inline line item is missing name or unitPrice

¿Te ha resultado útil esta página?