Errors
All errors share a single envelope shape and an HTTP status code that follows standard semantics. Use the type field for programmatic branching, the code field for fine-grained handling, and the message field only for human-facing logs.
Error envelope#
Every 4xx and 5xx response carries a JSON body with an error object. The envelope is stable — additional fields may be added over time but existing ones will not change shape.
{
"error": {
"type": "validation_error",
"code": "missing_field",
"message": "Field 'pickup_address' is required.",
"field": "pickup_address",
"request_id": "req_01HW8Q..."
}
}HTTP status codes#
| Code | Name | Meaning |
|---|---|---|
| 200 | OK | Request succeeded. |
| 201 | Created | A new resource (e.g. shipment) was created. |
| 204 | No Content | Request succeeded; no body is returned. |
| 400 | Bad Request | The request body was malformed or failed validation. |
| 401 | Unauthorized | Secret Key is missing, invalid, or revoked. |
| 403 | Forbidden | The key is valid but lacks permission for this resource. |
| 404 | Not Found | The referenced resource does not exist. |
| 409 | Conflict | The request conflicts with the current state (e.g. duplicate idempotency key). |
| 422 | Unprocessable Entity | The request is syntactically valid but semantically rejected. |
| 429 | Too Many Requests | Rate limit exceeded — retry with backoff. |
| 500 | Internal Server Error | Something went wrong on our side. Safe to retry idempotent operations. |
| 503 | Service Unavailable | Temporary outage or maintenance. Retry with backoff. |
Idempotency#
All POST endpoints accept an Idempotency-Key header. Sending the same key with the same request body within 24 hours returns the original response without creating a duplicate resource. Sending the same key with a different body returns 409 Conflict.
Idempotency-Key: 9c3a1f2b-7b1c-4e0f-9b1a-2f3e5c8a4d10Rate limits#
Each Secret Key is limited to 120 requests per minute per environment. Exceeding the limit returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait before retrying.
request_id. Include it when reporting issues to Shop.mn — it is the fastest way for our team to trace the request through our logs.