API error messages

Error handling explains the HTTP status codes and the
operational failure reasons reported during a delivery. This page is the other
half: the messages the API returns in the errors array, what causes each
one, and what to do about it.

{ "errors": ["no asset kinds available, please try again later"] }

Read the message, not only the status

The same underlying problem is reported with different status codes depending on
which endpoint you called. no asset kinds available is a 404 from
POST /v3/parcels/estimate and a 409 from POST /v1/parcels/ship, and both
mean the same thing. If you branch on the status code alone, the two look like
unrelated failures.

Branch on the message. Treat the status code as the retry hint it is: only 5xx
is worth retrying unchanged.

Most of these are configuration, not bad requests

The single most common misreading is treating a coverage or configuration error
as a malformed request, and spending days checking a payload that was correct
all along. If your request works for one account and fails for another with the
same body, the payload is not the problem — the account, the area or the
shipping type configuration is. See
Coverage and availability.


Coverage and fleet

no asset kinds available, please try again later

  • Status: 404 on POST /v3/parcels/estimate, 409 on POST /v1/parcels/ship
  • Cause: there is no vehicle type enabled for this route at this moment. Either no fleet is operating in that area right now, or your account has not been enabled for that area at all.
  • Solution: check the pickup point with GET /v1/shipping_types/available first. If the pickup point is not covered, this is account configuration and needs us to enable the area — the request will never succeed on its own. If it is covered, the fleet is momentarily unavailable and retrying later will work.

outside operation area

  • Status: 404
  • Cause: the pickup or dropoff location falls outside every area we operate in.
  • Solution: validate the location before creating the parcel. Coordinates just outside a boundary look correct on a map but are not covered.

pickup and dropoff are not in same region

  • Status: 409
  • Cause: both points are covered, but they belong to different operating regions, and a single parcel cannot cross between them.
  • Solution: split the journey, or use a shipping type designed for inter-region transport if one is available to you.

region not supported, please check addresses and the coordinates provided

  • Status: 404
  • Cause: the coordinates resolve to a region we do not serve.
  • Solution: check that latitude and longitude are not swapped. Swapped coordinates usually land in a region that does not exist for us.

country not supported, please check addresses and the coordinates provided

  • Status: 404
  • Cause: the location resolves to a country where we do not operate.
  • Solution: as above, verify the coordinates before assuming the country is unsupported.

address not found, please check addresses and the coordinates provided

  • Status: 404
  • Cause: the address could not be geocoded.
  • Solution: send lat/lon instead of, or in addition to, the text address. Coordinates are unambiguous; free-text addresses are not.

Account and shipping type configuration

configuration missing

  • Status: 409
  • Cause: the shipping type exists and is visible to you, but it has not been fully configured for your account in this area.
  • Solution: this cannot be fixed from the client side. Report it with your client id, the shipping type id and the pickup coordinates.

pricing group configuration is missing

  • Status: 409
  • Cause: there is no price configured for this combination of account, area and shipping type.
  • Solution: as above — account configuration, report it with the same details.

invalid shipping type

  • Status: 409
  • Cause: the shipping_type_id is not configured for the region of the request. It may be perfectly valid somewhere else.
  • Solution: call GET /v1/shipping_types/available for the pickup location you are about to use. Available shipping types are per location, not per account.

shipping_type not found

  • Status: 409
  • Cause: the shipping_type_id does not exist.
  • Solution: send an id exactly as GET /v1/shipping_types/available returned it for that pickup location. The id is opaque and its shape differs per environment — readable names such as express_default in sandbox, UUIDs in production — so it is never guessable: read it, do not build it, and do not reuse a sandbox id against production. Note the response wraps the list in available_shipping_types.

no product available for parcels

  • Status: 400
  • Cause: no product matches the parcel for this account.
  • Solution: check the weight and dimensions against what your shipping type supports, then check the account configuration.

products not configured for the given shipping type and client

  • Status: 409
  • Cause: the shipping type has no products set up for your account.
  • Solution: account configuration, report it.

no estimations available, please try again

  • Status: 404
  • Cause: no price could be produced for this request, usually because one of the configuration problems above applies further down.
  • Solution: check coverage on the pickup point first; if it is covered, report it with the full request body.

The parcel does not fit

no asset kinds suitable for the parcel dimensions and weight found

  • Status: 404
  • Cause: every available vehicle is too small for what you declared.
  • Solution: check the units. weight.unit is g and dimensions are cm: declaring 2000 in grams is 2 kg, but 2000 in the wrong unit is two tonnes and fits in nothing.

parcel does not fit asset

  • Status: 422
  • Cause: same problem, reported at shipment time.
  • Solution: as above.

no asset kind suitable for the route duration found

  • Status: 404
  • Cause: the route is too long for the vehicles available for that shipping type.
  • Solution: use a shipping type intended for longer distances, if one is available to you.

distance too far

  • Status: 422
  • Cause: the distance between pickup and dropoff exceeds what this shipping type allows.
  • Solution: as above.

Parcel state

parcel state is invalid

  • Status: 409
  • Cause: the parcel is not in a state that allows this operation. Estimating, shipping, cancelling and deleting each require a specific starting state.
  • Solution: read the parcel with GET /v1/parcels/{id} and check where it actually is before retrying. See Parcels life cycle.

invalid state

  • Status: 409
  • Cause: the same thing, from the shared error path. A parcel in READY_TO_PICKUP cannot be deleted, for example — it is already committed to a driver.
  • Solution: cancel rather than delete a parcel that is already on its way, and read the current state first.

already exist

  • Status: 409
  • Cause: a parcel with this external_id already exists for your account.
  • Solution: this is the deduplication key doing its job. The response tells you which parcels already exist, so use them rather than creating new ones. See Limits and reliability.

a precondition has failed

  • Status: 409
  • Cause: a requirement for this operation was not met. Generic by design, because the precondition is checked downstream.
  • Solution: report it with the full request body; there is not enough in the message to act on alone.

Account and authentication

no default user for payments

  • Status: 422
  • Cause: your account has no payment method configured, so no shipment can be requested. Creating parcels keeps working, which is why this usually surfaces only at POST /v1/parcels/ship.
  • Solution: add a payment method to the account. In sandbox, ask us — sandbox accounts are set up by us and a real card is not the answer.

user disabled

  • Status: 422
  • Cause: the account requesting the shipment is disabled.
  • Solution: nothing in the request will fix this. Report it with your organisation id; generating new credentials will not help, because the credentials are not the problem.

unauthorized

  • Status: 403
  • Cause: the token is valid but the account is not allowed to use this resource — typically the Logistics product is not enabled for those credentials.
  • Solution: if authentication succeeds and the resource returns 403 or 401, ask us to enable the product for that client id rather than regenerating keys.

shipping type not available / shipping type not enabled

  • Status: 403
  • Cause: the shipping type is not enabled for your account.
  • Solution: use one returned by GET /v1/shipping_types/available for that location.

client_id not valid / client not found

  • Status: 400
  • Cause: the client id in the request does not match a known account.
  • Solution: check you are sending production credentials to production and sandbox credentials to sandbox. The two environments have separate accounts and separate data.

requester_id is not in uuid format

  • Status: 400
  • Cause: requester_id must be a UUID.
  • Solution: send the UUID from your account, not an email or a name.

Scheduling

missing delivery window

  • Status: 422
  • Cause: this shipping type requires a delivery window and none was sent.
  • Solution: add the window. Same-day and next-day types generally require one; express does not.

delivery window not in the same day

  • Status: 422
  • Cause: the window you sent spans more than one day.
  • Solution: send a window contained within a single day.

missing location info

  • Status: 422
  • Cause: neither a usable address nor coordinates were provided for one of the points.
  • Solution: send coordinates. At least one of address or coordinates is required, and coordinates are the reliable one.

Request shape

invalid argument, please check addresses and coordinates provided

  • Status: 400
  • Cause: a field failed validation before the request reached the delivery logic.
  • Solution: this one really is the payload. Check required fields, coordinate ranges and units.

bad arguments

  • Status: 400
  • Cause: as above, from the shared error path.
  • Solution: as above.

not found / parcels not found

  • Status: 404
  • Cause: the resource does not exist, or it does not belong to the account you authenticated with.
  • Solution: parcels are scoped to their owner. A parcel id from another account of yours returns 404 here, which is intentional and not a bug.

Webhook subscription

callback_url is required

  • Status: 400
  • Cause: the subscription request had no callback_url.
  • Solution: the field is callback_url, and the event type is hook. Unknown fields are ignored rather than rejected, so a request that spells them any other way arrives empty and fails here. Send {"callback_url": "…", "hook": "parcel"} — see Notifications.

callback_url must be an http(s) URL with a public host

  • Status: 400
  • Cause: the URL is malformed, uses a scheme other than http or https, or points at a host we cannot reach — localhost, a private address, or an internal name.
  • Solution: register a publicly resolvable URL. A tunnel is fine for testing; your own machine's address is not.

hook is required

  • Status: 400
  • Cause: no event type was given.
  • Solution: send hook with one of parcel, parcelLocation or proofCodeGenerated.

hook must be one of: parcel, parcelLocation, proofCodeGenerated

  • Status: 400
  • Cause: the event type is not one a client can subscribe to.
  • Solution: use one of the three. The names are case sensitive.

Shipment options

shipping type not enabled for return

  • Status: 400
  • Cause: you asked for with_return on a shipping type that does not have round trips enabled. Returns are configured per shipping type, not per account.
  • Solution: this needs enabling on our side. Ask us for the shipping type you use, quoting your client id. See Shipment options.

Server side

internal server error

  • Status: 500
  • Cause: something failed on our side. The real cause is not spelled out on purpose.
  • Solution: retry with backoff. If it persists, report it with the request body and roughly when it happened, so we can find it in our logs.

unavailable

  • Status: 503
  • Cause: the service, or something it depends on, is temporarily unavailable.
  • Solution: retry with exponential backoff.

Did this page help you?