Skip to the content

Errors

Every error has the same shape: a stable code to branch on, a message for people, and a request id to quote to support.

The error shape

JSON
{
  "error": {
    "code": "validation_failed",
    "message": "Some fields are missing or invalid.",
    "request_id": "req_0f3a9c1b2d4e5f60718293a4b5c6d7e8",
    "fields": [
      {
        "field": "to.city",
        "message": "Enter the city"
      },
      {
        "field": "parcels.0.weight_grams",
        "message": "Too small: expected number to be >=1"
      }
    ],
    "docs_url": "https://app.evipostal.com/docs/errors#validation_failed"
  }
}
  • code never changes meaning. Branch on it, not on the message.
  • fields appears on validation_failed: one entry per field, with a dotted path such as to.city.
  • request_id is also in the X-Request-Id header of every answer.
  • Errors never contain a carrier's own wording, internal details or another business's data.

Every code

Error codes
CodeStatusWhat it means and what to do
invalid_request400The request body could not be read. Send valid JSON with Content-Type: application/json.
validation_failed400One or more fields are missing or invalid. fields lists each one.
idempotency_key_required400This request moves money or books a shipment. Send an Idempotency-Key header.
request_too_large413The request body is larger than 256 KB.
authentication_required401No API key was sent. Send Authorization: Bearer <your secret key>.
invalid_api_key401The API key is not recognised. Check you copied the whole key.
api_key_revoked401The API key was revoked or has expired. Create or roll a key in the developer portal.
insufficient_scope403The API key does not have the scope this request needs. The message names the scope.
production_access_required403Production access is not enabled for this business yet. Use a sandbox key, or request production access.
application_disabled403The application this key belongs to is turned off in the developer portal.
not_found404No such object for this application and environment.
conflict409The object is not in a state that allows this request. The message says why.
rate_expired409The rate has expired. Request fresh rates and book one of them.
idempotency_key_in_use409A request with this Idempotency-Key is still being processed. Retry after a moment.
idempotency_key_reused422This Idempotency-Key was already used with a different request. Use a new key for a new request.
booking_failed422The carrier did not accept the booking. Nothing was charged. Request fresh rates and try again, or choose another rate.
label_not_ready409The label is still being prepared by the carrier. Retry after the Retry-After interval.
unsupported_operation422The carrier behind this shipment does not support this operation through EviPostal.
insufficient_funds402Your EviPostal wallet cannot cover this shipment. Add funds in the dashboard, then book again.
rate_limited429Too many requests. Wait for the Retry-After interval.
carrier_unavailable503The carriers did not respond. Nothing was booked or charged. Retry later.
internal_error500Something went wrong on our side. Retry, and quote the request_id if it keeps happening.

Safe to retry as they are: rate_limited, idempotency_key_in_use, label_not_ready (after Retry-After), carrier_unavailable and internal_error. Retry bookings with the same Idempotency-Key.