Errors
Handle Melo API failures consistently and decide when requests are safe to retry.
All API errors use the same JSON envelope:
{
"type": "WAREHOUSE_NOT_FOUND",
"message": "Warehouse not found",
"code": 404
}| Field | Description |
|---|---|
type | Stable machine-readable error identifier when provided by the API. |
message | Human-readable description intended for developers. |
code | HTTP status code repeated in the response body. |
Status codes
| Code | Meaning | Client behavior |
|---|---|---|
400 | Invalid input or invalid resource state | Correct the request; do not retry unchanged. |
401 | Missing, invalid, expired, or revoked credentials | Refresh the token when expired; otherwise stop and inspect credentials. |
403 | The merchant cannot access the resource | Do not retry without changing credentials or resource ownership. |
404 | The requested resource does not exist | Verify the identifier and environment. |
409 | The request conflicts with the resource's current state | Read the resource's current state; do not retry unchanged. |
429 | Rate limit exceeded | Back off and retry later. See Rate limits. |
500 | Unexpected server failure | Retry with exponential backoff when the operation is safe to repeat. |
Malformed requests are rejected with a 400 rather than a server error: an identifier in the URL that is not a UUID returns INVALID_PARAMETER, and a missing or malformed body returns VALIDATION_ERROR with the offending field named in message.
Rate limits
Limits are applied per client, and exceeding one returns 429 with type RATE_LIMIT_EXCEEDED.
| Scope | Limit |
|---|---|
| All authenticated endpoints | 300 requests per minute |
POST /options | 60 requests per minute |
POST /auth/token, per client | 10 requests per 15 minutes |
Access tokens are valid for one hour, so a healthy integration needs very few token requests. Cache the token until it expires rather than requesting one per call.
Common business errors
| Type | Endpoint | Meaning |
|---|---|---|
WAREHOUSE_NOT_FOUND | Warehouse operations, options, create transfer | The pickup or destination warehouse ID does not exist. |
WAREHOUSE_NOT_ACTIVE | Options | The pickup or destination warehouse is disabled. |
WAREHOUSE_LOCATION_MISSING | Options | The pickup or destination warehouse has no location set. |
WAREHOUSE_HAS_TRANSFERS_ASSOCIATED | Delete warehouse | Historical transfers, as pickup or destination, prevent deletion. |
PICKUP_OUT_OF_SERVICE_AREA | Options | The pickup location, or the pickup warehouse's location, is outside the area we collect parcels from. Returned with 400. |
DESTINATION_OUT_OF_SERVICE_AREA | Options | The destination, or the destination warehouse's location, is outside the area we deliver to. Returned with 400. |
NO_PRODUCTS_FOUND | Options | No delivery product is available for the request. |
MATCHMAKING_NOT_FOUND | Create transfer | The quote ID does not exist. |
PICKUP_CONTACT_REQUIRED | Create transfer | The quote starts from a custom pickup location and the request has no pickupContact. Returned with 400; the quote stays usable. |
PICKUP_CONTACT_NOT_ALLOWED | Create transfer | The quote starts from a warehouse, which supplies its own contact, and the request has a pickupContact. Returned with 400; the quote stays usable. |
MATCHMAKING_INCORRECT_STATUS | Create transfer | The quote has already been consumed or is not pending. |
QUOTE_EXPIRED | Create transfer | The quote is older than 10 minutes. Request a new one. |
PRODUCT_NOT_FOUND | Create transfer | The product key was not returned by that quote. |
DELIVERY_OPTION_PRICE_NOT_FOUND | Create transfer | The selected product has no payable price. |
TRANSFER_NOT_FOUND | Get transfer, cancel transfer | The transfer does not exist or is not an API-created transfer. |
UNAUTHORIZED | Options, create transfer, get transfer, cancel transfer | A warehouse or the transfer belongs to another merchant. |
TRANSFER_NOT_CANCELLABLE | Cancel transfer | Shipping has started, or the transfer is already failed or cancelled. Returned with 409. |
INVALID_PARAMETER | Any endpoint with an ID in the path | The identifier is not a valid UUID. |
VALIDATION_ERROR | Any endpoint with a body | The request body failed validation. |
RATE_LIMIT_EXCEEDED | Any endpoint | Too many requests. See Rate limits. |
Retry safety
GET requests are safe to retry. Token and quote requests may be retried after transient network failures. Transfer creation changes state and charges the merchant balance, so treat a timeout as an unknown result and avoid automatic retries until you can establish whether the transfer was created. Cancelling a transfer is safe to retry: if the first attempt succeeded, the retry returns 409 TRANSFER_NOT_CANCELLABLE and GET /transfer/{transferId} shows state: failed.