# Error codes

`error.code` in error responses is stable — branch on it, never on the text. `error.docUrl` points at the matching row here.

| Code | Meaning | How to fix |
| --- | --- | --- |
| `AUTH_MISSING_TOKEN` | Missing authentication token | Send `Bearer <token>` in the Authorization header (`?token=` is not accepted on /api/v1). Get a token from POST /api/v1/auth/token with client_id + client_secret in the body. |
| `AUTH_INVALID_TOKEN` | Invalid token | The token is malformed or its signature is wrong. Get a fresh one from POST /api/v1/auth/token; make sure it is not truncated and has no stray spaces. |
| `AUTH_EXPIRED` | Token expired | The token passed its expiry. Fetch a new one; we recommend refreshing automatically shortly before exp. |
| `SCOPE_DENIED` | Operation not permitted | Your channel role does not include this capability. Pick a plan under “Plans & access” and request it — it takes effect as soon as your account manager approves. |
| `WAREHOUSE_DENIED` | Warehouse not permitted | Your channel is not on this warehouse allowlist. Ask your account manager to add the warehouse to your channel, or clear the list to allow all. |
| `AUTHZ_UNAVAILABLE` | Authorization service unavailable | The authorisation service is temporarily unavailable. Retry shortly; if it persists, contact your account manager with the requestId. |
| `VALIDATION_FAILED` | Invalid request parameters | Fix the field named in error.param. Full field specs for every endpoint are at /swagger. |
| `NOT_FOUND` | Not found | That product code / SKU / sheet id does not exist or is misspelled. Double-check and retry. |
| `OWNERSHIP_DENIED` | Document does not belong to you | This document belongs to another channel. You can only read orders / shipments / holds for your own channel. |
| `UPSTREAM_ERROR` | Upstream ERP error | The upstream ERP is temporarily failing. Retry shortly; quote the requestId to support and we can trace that exact call. |
| `UPSTREAM_TIMEOUT` | Upstream timeout | The upstream ERP is slow or unreachable. Please retry shortly. |
| `INTERNAL` | Gateway internal error | An error inside the gateway itself (rare). Contact support with the requestId. |
| `ADMIN_UNAUTHORIZED` | Wrong admin token | Check that x-admin-token matches ADMIN_TOKEN in the server .env file. |
| `ADMIN_DISABLED` | Admin console disabled | ADMIN_TOKEN is not set on the server. Set it and restart. |
| `IDEMPOTENCY_IN_PROGRESS` | An identical request is still running | A previous request with the same Idempotency-Key has not finished. Retry shortly with the SAME key — changing the key risks creating a duplicate. |
| `IDEMPOTENCY_MISMATCH` | Idempotency-Key reused | This key was already used for a request with different content. Use a fresh key per business operation (a UUID, or your own order number). |
| `IDEMPOTENCY_INVALID_KEY` | Invalid Idempotency-Key | The key must be at most 255 characters. A UUID is recommended. |
| `RATE_LIMITED` | Rate limit exceeded | Check the RateLimit-Remaining / Retry-After response headers and back off. Pulling a whole warehouse is expensive (60 points); the incremental endpoint /Changes?since= costs only 1. If you genuinely need more, ask your account manager to raise your quota. |
| `BAD_REQUEST` | Bad request | Check the HTTP method, path and request body. |
| `READ_ONLY_MODE` | This environment is read-only | Writes to the upstream ERP are intentionally disabled here (WRITES_ENABLED=0) so this server is safe to test against. Reads work normally. Use the production environment to place real orders. |
| `ENDPOINT_GONE` | Endpoint retired | The API moved to /api/v1/** (lowercase paths, snake_case parameters). error.message names the replacement; the full list is at /reference or /llms.txt. |
| `WAREHOUSE_UNKNOWN` | Unknown warehouse | Use one of the codes listed by GET /api/v1/warehouses (AU / AUSYD2 / AUSYD1 / CN / CHNZJ1); aliases such as AuStock no longer exist. |
| `UPSTREAM_REJECTED` | Rejected by the ERP | The ERP did not accept this request (insufficient stock, unknown id, invalid field …); the reason is in error.message. Fix and retry; if it keeps happening send the request_id to your contact. |
| `AUTH_BAD_CREDENTIALS` | Wrong credentials | Channel grant: check client_id and client_secret (the secret is shown once at issue time; ask your admin to re-issue if lost). OMS grant (grant_type=password): check your OMS website login account and password. To try things out use sandbox / sandbox. |
| `AUTH_LOCKED` | Too many failed sign-ins — temporarily locked | Repeated wrong passwords lock the OMS account for 15 minutes. Check the account and password, then retry; to try things out use sandbox / sandbox. |
| `DUPLICATE_SUSPECTED` | Possible duplicate drop-ship line | The upstream flags the same recipient + SKU submitted twice in quick succession. If you meant it, use a different client_order_number or retry later. |
| `OMS_LOGIN_REQUIRED` | This endpoint needs an OMS account sign-in | Get a token with POST /api/v1/auth/token using grant_type=password and your OMS account (channel-secret tokens cannot use the ordering flow because allocation rules follow the OMS account). |
| `SHIPPING_REQUIRED` | Shipping info missing | A wholesale order needs a shipping method: pick a shipping_method_id from GET /api/v1/shipping-methods and put it in shipping; for delivery also pick an address_id from GET /api/v1/addresses. You can also set defaults on the OMS site under User → Preferences. |

## Error response

```json
{
  "error": {
    "code": "WAREHOUSE_DENIED",
    "message": "Warehouse not permitted",
    "hint": "…",
    "request_id": "r_8f2c1a",
    "doc_url": "https://connect.everugg.net.au/errors/WAREHOUSE_DENIED"
  }
}
```

The HTTP status is the only success signal; `error.code` is stable, `message` and `hint` follow `Accept-Language`.

---
Markdown source: https://connect.everugg.net.au/reference/errors.md?lang=en · Web page: https://connect.everugg.net.au/reference?sec=errors&lang=en
