Clients should branch on:
- HTTP status
errorCode- optional
fieldanddetails
Machine-readable contract:
Related docs:
#Canonical error shape
json
{
"errorCode": "VALIDATION_ERROR",
"message": "Request validation failed.",
"field": "orderIds",
"details": {
"issues": [
{
"path": "orderIds",
"message": "Array must contain at least 1 element(s)",
"code": "too_small"
}
]
}
}#Fields
| Field | Required | Meaning |
|---|---|---|
errorCode |
yes | Stable machine-readable error code |
message |
yes | Human-readable explanation |
field |
no | Single field path when one field is primarily responsible |
details |
no | Structured context for correction or reconciliation |
#How to use errors
For human developers:
- read
message - use
fieldanddetailsto find the bad input or invalid state
For AI agents and automation clients:
- treat
errorCodeas the primary control signal - use
detailsfor correction or retry policy - do not build retry logic from
messagetext alone
#Validation and request errors
#400 INVALID_REQUEST
Meaning:
- the body is not valid JSON
Example:
json
{
"errorCode": "INVALID_REQUEST",
"message": "Request body must be valid JSON."
}Retry guidance:
- safe retry without correction: no
- fix the request serialization first
#400 VALIDATION_ERROR
Meaning:
- JSON parsed, but the payload failed schema validation
Example:
json
{
"errorCode": "VALIDATION_ERROR",
"message": "Request validation failed.",
"field": "batchId",
"details": {
"issues": [
{
"path": "batchId",
"message": "String must contain at least 3 character(s)",
"code": "too_small"
}
]
}
}Typical causes:
- missing required fields
- wrong types
- empty
orderIds - malformed line items during order sync
Retry guidance:
- safe retry without correction: no
- inspect
details.issuesand correct the payload
#Authentication and scope errors
#401 INVALID_API_KEY
Meaning:
- the bearer API key is missing or invalid
Example:
json
{
"errorCode": "INVALID_API_KEY",
"message": "Missing API key."
}Retry guidance:
- safe retry without correction: no
- send a valid
Authorization: Bearer <api-key>header
#403 INVALID_ACCOUNT_SCOPE
Meaning:
- the body
accountIddoes not match the authenticated API key scope
Example:
json
{
"errorCode": "INVALID_ACCOUNT_SCOPE",
"message": "Payload accountId does not match API key scope.",
"details": {
"apiKeyAccountId": "acc_123",
"payloadAccountId": "acc_999"
}
}Retry guidance:
- safe retry without correction: no
- use the correct key or correct
accountId
#400 INVALID_ACCOUNT_SCOPE
Meaning:
- current planning references, typically
warehouseIdorbrokerId, are outside the current account scope
Example:
json
{
"errorCode": "INVALID_ACCOUNT_SCOPE",
"message": "Warehouse or broker is outside the current account scope."
}Retry guidance:
- safe retry without correction: no
- correct the referenced warehouse or broker
#Reference and lookup errors
#400 INVALID_ORDER_REFERENCE
Meaning:
- one or more requested order IDs could not be resolved
Example:
json
{
"errorCode": "INVALID_ORDER_REFERENCE",
"message": "One or more orders could not be resolved.",
"details": {
"requestedOrderIds": ["ord_123", "ord_missing"],
"foundOrderIds": ["ord_123"]
}
}Retry guidance:
- safe retry without correction: no
- confirm that order sync succeeded and that planning uses EntryGo order IDs
#404 NOT_FOUND
Meaning:
- the requested export batch or customs package was not found in the authenticated account scope
Example:
json
{
"errorCode": "NOT_FOUND",
"message": "Export batch not found."
}Retry guidance:
- safe retry without correction: usually no
- verify the resource ID and account scope
#State and idempotency errors
#409 INVALID_EXPORT_STATE
Meaning:
- the requested transition is not valid from the export's current lifecycle state
Example:
json
{
"errorCode": "INVALID_EXPORT_STATE",
"message": "Export batch cannot be executed from current state.",
"details": {
"currentState": "COMPLETED"
}
}Retry guidance:
- safe retry without correction: usually no
- call
GET /api/exports/{id}and use inspect as the source of truth before acting again
#409 IDEMPOTENCY_CONFLICT
Meaning:
- the same idempotency key was already used for a different logical payload
Example:
json
{
"errorCode": "IDEMPOTENCY_CONFLICT",
"message": "Idempotency-Key was already used with a different execute payload.",
"details": {
"batchId": "batch_123"
}
}Retry guidance:
- safe retry without correction: no
- either resend the original request with the same key or generate a new key for a genuinely new logical operation
#Safe retry vs fix-required
| Situation | Safe retry without changing request? | Recommended action |
|---|---|---|
| Network timeout after order sync, plan, or execute | yes, if you reuse the same idempotency key | retry the same logical write, then inspect if needed |
400 INVALID_REQUEST |
no | fix JSON serialization |
400 VALIDATION_ERROR |
no | correct the request body |
401 INVALID_API_KEY |
no | fix authentication |
403 INVALID_ACCOUNT_SCOPE |
no | fix account scoping |
400 INVALID_ORDER_REFERENCE |
no | sync or reference the correct orders |
404 NOT_FOUND |
usually no | verify the ID and scope |
409 INVALID_EXPORT_STATE |
usually no | inspect current export state first |
409 IDEMPOTENCY_CONFLICT |
no | reuse the original request or mint a new key for a new operation |
#Practical retry model
For write endpoints:
- always send
Idempotency-Key - if the client loses the response, retry the same request with the same key
- after any ambiguous write, call
GET /api/exports/{id}if you already know the export ID
For read endpoints:
- ordinary safe retries are fine
- prefer inspect for export-state reconciliation
#Notes for AI agents and automation clients
- Treat
errorCodeas the routing key for remediation. - Use
fieldanddetailsto build correction prompts or retry policies. - Never assume an operation failed permanently just because the client missed the response to a write; reconcile via idempotent retry and inspect.
- When state is unclear,
GET /api/exports/{id}is the best recovery surface.