400 INVALID_REQUEST | The body is not valid JSON, has an unknown field, or has trailing content. | Check commas, quotation marks, field spelling, and Content-Type: application/json. |
400 SANDBOX_ONLY_FIELD | A live key sent the sandbox field on a delivery. | Remove sandbox from live requests; it works only with a test key. |
400 IDEMPOTENCY_KEY_REQUIRED | A create request has no idempotency key. | Add a unique Idempotency-Key header. |
401 INVALID_API_KEY | The bearer token is missing, incomplete, or unknown. | Send Authorization: Bearer <complete-key> from your backend. |
401 ENVIRONMENT_MISMATCH | The key and base URL are for different environments. | Use a test key with sandbox or a live key with live. |
401 API_KEY_REVOKED | The key was permanently revoked. | Deploy a new key from the developer portal. |
401 API_KEY_EXPIRED | The key passed its expiry time. | Create and deploy a replacement key. |
403 INSUFFICIENT_SCOPE | The key lacks the endpoint’s permission. | Create or rotate a key with the required scope. |
404 NOT_FOUND | The ID is invalid, does not exist, or belongs to another application/business. | Copy the full typed ID and use the key that owns the resource. |
409 IDEMPOTENCY_CONFLICT | One idempotency key was used with two different requests. | Use the original body or use a new key for the changed action. |
409 IDEMPOTENCY_IN_PROGRESS | The first request with this key is still running. | Wait for Retry-After, then resend the identical request. |
409 EXTERNAL_ID_CONFLICT | This application already used that external_id. | Fetch the existing delivery or use a new external ID. |
409 DELIVERY_NOT_CANCELLABLE | Pickup already happened. | Do not retry cancellation; follow the delivery status instead. |
409 SANDBOX_TRANSITION_INVALID | The requested test status skipped or reversed a step. | Follow the allowed sandbox status order one step at a time. |
409 SIMULATION_NOT_APPLICABLE | The sandbox scenario does not fit the delivery’s payment type or current status. | Pick a scenario from the scenario table that fits, or start from a fresh delivery. |
409 SIMULATION_RUNNING | An automatic simulation is running on this sandbox delivery. | Stop it with DELETE /test-helpers/deliveries/{id}/simulation, then change the delivery by hand. |
422 VALIDATION_ERROR | A supplied field has an invalid value. | Read message, then compare the body with the endpoint schema. |
422 RECIPIENT_SHAPE_CONFLICT | The delivery mixed inline recipient fields with recipient IDs, or supplied only one ID. | Send either an inline recipient or both recipient_id and recipient_address_id. |
422 PICKUP_SHAPE_CONFLICT | The delivery or quote sent both an inline pickup and a pickup_location_id. | Send one or the other. |
422 PICKUP_LOCATION_NOT_FOUND | pickup_location_id is malformed or not one of this business’s pickup locations. | List pickup locations and use an id from there. |
422 PICKUP_LOCATION_INACTIVE | The pickup location was switched off. | Reactivate it with PATCH /pickup-locations/{id} or use another. |
422 PICKUP_LOCATION_INCOMPLETE | The location (usually a warehouse added in the merchant app) has no contact or coordinates. | Set contact, latitude and longitude with PATCH /pickup-locations/{id}. |
422 COD_GOODS_VALUE_REQUIRED | A COD delivery has no positive goods value. | Add a positive payment.goods_value; omit it for non-COD payments. |
422 BULK_VALIDATION_FAILED | At least one item in a bulk request is invalid, so nothing was created. | Read error.details.errors; each entry gives the item’s 0-based index, a code, and a message. Fix those items, then resend the corrected batch with a new Idempotency-Key. |
422 DUPLICATE_EXTERNAL_ID | Two items in one bulk request share an external_id. Reported inside BULK_VALIDATION_FAILED. | Give each item its own external_id, or remove the duplicate item. |
429 SIMULATION_LIMIT | This application already has 100 running sandbox simulations. | Wait for some to finish, or stop ones you no longer need. |
429 RATE_LIMIT_EXCEEDED | Too many requests were sent in the current window. | Stop for Retry-After seconds, then resume more slowly. |
503 QUOTE_UNAVAILABLE | Live pricing is temporarily unavailable. | Retry with backoff. Do not invent a delivery fee. |
500 INTERNAL_SERVER_ERROR | HaulStow hit an unexpected failure. | Retry safely and include X-Request-ID if contacting support. |