Errors

All errors follow a consistent envelope format with a machine-readable code and a human-readable message.

Error Format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "orderNumber is required",
    "details": {
      "field": "orderNumber"
    }
  }
}

The details field is optional and provides additional context when available.

Error Codes

CodeHTTP StatusDescription
UNAUTHORIZED401Missing, invalid, revoked, or expired API key
FORBIDDEN403API key lacks the required permission, or resource belongs to another user
NOT_FOUND404The requested resource does not exist
VALIDATION_ERROR400The request body or query parameters are invalid
CONFLICT409The operation conflicts with the current state of the resource
RATE_LIMITED429Rate limit exceeded — see Rate Limiting
INTERNAL_ERROR500An unexpected server error occurred

Common Scenarios

Invalid or Missing API Key (401)

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

Fix: Ensure the Authorization: Bearer <key> header is present and the key is active.

Insufficient Permissions (403)

{
  "error": {
    "code": "FORBIDDEN",
    "message": "API key lacks \"write\" permission"
  }
}

Fix: Use an API key with both read and write permissions, or create a new key with the needed scope.

Resource Not Found (404)

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Order not found"
  }
}

Fix: Verify the resource ID and that it belongs to your account.

Validation Error (400)

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "orderNumber is required"
  }
}

Fix: Check the request body against the endpoint's required fields.

Conflict (409)

Returned when an operation can't proceed due to the resource's current state.

{
  "error": {
    "code": "CONFLICT",
    "message": "Cannot cancel order with active shipments. Void the labels first."
  }
}

Fix: Resolve the conflicting state first (e.g., void the active label before cancelling the order).

Rate Limited (429)

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Try again later."
  }
}

Fix: Wait until the X-RateLimit-Reset timestamp and retry. See Rate Limiting.

Internal Error (500)

{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "Internal server error"
  }
}

Fix: Retry the request. If the error persists, contact support.