← Back to Developers
Overview
The API uses standard HTTP status codes and a consistent error format. Rate limiting protects the system and ensures fair usage.
Error Response Format
All errors return this structure:
{
"ok": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description",
"details": { "field": "validation error" }
}
}
The details field only appears on validation errors with field-specific messages.
Error Codes
Authentication Errors
| HTTP | Code | Cause | Fix |
| 401 | UNAUTHORIZED | Missing or invalid token | Check the Authorization: Bearer <token> header, or generate a new token if the old one was revoked |
| 400 | MISSING_TENANT | Missing X-Tenant header | Add X-Tenant: CLIENT_ID - the Client ID is on Settings → API / Web Services |
| 404 | TENANT_NOT_FOUND | X-Tenant value doesn't match any active client | Double-check the Client ID value and try again |
| 403 | FORBIDDEN | Token valid but lacks the required permission | Update the API user's permissions |
Validation Errors
| HTTP | Code | Cause | Fix |
| 400 | VALIDATION_ERROR | Missing or invalid fields | Check the details object for specific field errors |
Example:
{
"ok": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed.",
"details": {
"sender.company": "Sender company is required.",
"package.weight": "Weight must be greater than 0."
}
}
}
Resource Errors
| HTTP | Code | Cause | Fix |
| 404 | NOT_FOUND | Shipment, pickup, or service doesn't exist | Check the AWB/ID and try again |
| 409 | CONFLICT | Business logic violation | Check the message - e.g., can't cancel a delivered shipment |
Rate Limiting
| HTTP | Code | Cause | Fix |
| 429 | RATE_LIMITED | Too many requests in the current window | Wait until the Retry-After time, then retry |
Plan & Feature Errors
| HTTP | Code | Cause | Fix |
| 403 | TRIAL_EXPIRED | Trial period ended | Upgrade the subscription plan |
| 403 | PLAN_UPGRADE_REQUIRED | Current plan doesn't include API access | Upgrade to a plan that includes REST API |
Server Errors
| HTTP | Code | Cause | Fix |
| 500 | INTERNAL_ERROR | Unexpected server error | Retry after a brief delay. If persistent, contact the operator. |
Rate Limiting
Limits
| Setting | Value |
| Default limit | 60 requests per minute |
| Window | 1-minute rolling window |
| Scope | Per API user (not per token) |
| Custom limit | Configurable per user by the administrator |
Response Headers
Every API response includes rate limit headers:
| Header | Description |
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Reset | Unix timestamp when the current window resets |
When Rate Limited
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 60
X-RateLimit-Reset: 1711324800
{
"ok": false,
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again in 45 seconds."
}
}
Wait until the Retry-After seconds have elapsed before retrying.
Best Practices
- Batch operations - create multiple shipments in sequence rather than parallel bursts.
- Cache service lists - services rarely change; fetch once and cache locally.
- Respect Retry-After - do not send repeated requests after a 429; use exponential backoff.
- Monitor headers - watch
X-RateLimit-Limit to stay under the threshold.
Troubleshooting
"UNAUTHORIZED" on every request
- Verify the
Authorization header format: Bearer <token> (with a space after "Bearer").
- Confirm the token hasn't been revoked.
- Ensure requests go to
https://api.livecourier.com/v1/ - tenant subdomains don't serve the API.
- Tokens don't expire; if yours stopped working it was revoked or the API user was deactivated/deleted.
"MISSING_TENANT" or "TENANT_NOT_FOUND"
- Every request needs the
X-Tenant header alongside Authorization.
- Copy the Client ID from Settings → API / Web Services or the customer detail page.
"FORBIDDEN" despite valid token
- The API user lacks the required permission for this endpoint.
- Ask the administrator to update permissions in the customer's API Access section.
- Check whether the subscription plan includes API access.
"VALIDATION_ERROR" on shipment creation
- Read the
details object - it lists exactly which fields are invalid.
- Required fields:
sender.company, sender.country, recipient.company, recipient.country, package.weight, and service_id or service_code.
- Country codes must be 2-letter ISO codes (US, CA, GB, etc.).
- Weight must be a positive number.
Rate quote returns no rates
- Verify the service has rate tables and zone tables configured.
- Check that origin/destination fall within configured zones.
- If the API user is linked to a customer, verify the customer has access to the requested service.
Label download returns error
- The shipment must exist and not be cancelled.
- If using a carrier service (FedEx), the carrier submission must have succeeded.
- Internal labels are generated for non-carrier services automatically.
Tips
- Always check the
ok field first - true means success, false means error.
- Log the full error response during development for debugging.
- The
code field is machine-readable (use it for programmatic error handling); message is human-readable.
- All timestamps in responses use ISO 8601 format.