# Error codes

Every error code and status of the REST API and the MCP server in one table.

Section: Commerce · Reference
Canonical URL: https://docs.omniretailconnect.nl/commerce/reference/error-codes

## Error codes at a glance

REST errors are `{"error": {"code", "message"}}` with the status shown. MCP tool errors carry the same `code` values inside a `tools/call` result with `isError: true`; MCP transport errors are plain HTTP or JSON-RPC errors. Branch on the code, not on the message.

*Error codes*

| Code | REST status | Meaning |
| --- | --- | --- |
| `unauthenticated` | 401 | REST: missing, malformed, unknown, revoked or expired token, or a token without the `api` channel. Without a valid token every request under `/api/v1` (any method, any path, the bare prefix, malformed percent-encoding or invalid UTF-8) answers this identical `401`; only `GET /api/v1/openapi.json` is public. MCP answers `401` `{"message":"Unauthorized."}` for the same causes (channel `mcp`). |
| `forbidden_scope` | 403 | The token lacks the scope for the endpoint, tool or option (for example email search without `commerce.read.pii`). MCP: tool error with the same code. An MCP write tool is not shown to a token without its write scope, and calling it answers JSON-RPC `-32602`. |
| `https_required` | 403 | Production and the request is not secure. MCP: HTTP `403`, JSON-RPC `-32600`. If you already use https, the operator should check the reverse-proxy configuration. |
| `not_found` | 404 | The resource does not exist, or the path is unknown (REST, with a valid token). A switched-off interface answers the shop's normal 404 for `GET` and `405` for `POST`, `PUT`, `PATCH` and `DELETE`. MCP: tool error with the same code for a missing product, SKU, image, order or category. |
| `method_not_allowed` | 405 | REST: a method the path does not support; `Allow` lists the methods of the path (`GET, HEAD`, plus `POST`, `PUT`, `PATCH` or `DELETE` on the write paths). MCP: `GET` or `DELETE` on the endpoint (use `POST`). |
| `—` | 413 | MCP only: request body above 256 KiB (64 KiB before server 1.6.0). |
| `uri_too_long` | 414 | REST only: URL longer than the URL cap (4096 bytes by default). |
| `conflict` | 409 | Writes (MCP write tools and REST write endpoints): stock is managed by an external inventory provider (`set_stock`), the shop gets its products from the PIM (`create_product`), an order, discount or page is in a state the action does not allow (an order that is not an unpaid draft, a used discount code, a discount code that is taken, a stale `expected_updated_at` on a page, an `idempotency_key` reused with other data), or the data changed during the call or stayed locked by another change. MCP: tool error with the same code. |
| `invalid_argument` | 422 | Failed validation, unknown parameter or argument, bad cursor, missing or conflicting identifiers, range too long; for write tools also a taken SKU, name, code or slug, a refused image URL, a date that does not exist, or a rule of the thing you write (a sale price not below the regular price, a block that breaks the rules of its type). MCP: tool error with the same code. |
| `field_owned_by_pim` | 422 | Writes (MCP write tools and REST write endpoints): the field, image or category placement belongs to the PIM on a product linked to the PIM. MCP: tool error with the same code. |
| `too_many_requests` | 429 | A per-IP or per-token rate limit was exceeded. Has `Retry-After`. MCP body: `{"message":"Too Many Attempts."}`. Branch on the status code and `Retry-After`, not on the message text. MCP write tools also answer this code as a tool error when the token made more than 30 write calls in a minute (`Too many write requests. Try again in a minute.`, no `Retry-After`). |
| `internal_error` | 500 | Unexpected failure. The message is always `An internal error occurred.` MCP: tool error with the same code. |

Details and examples: [Errors and status codes](https://docs.omniretailconnect.nl/commerce/getting-started/errors.md).

## MCP JSON-RPC codes

*JSON-RPC error codes*

| Code | Meaning |
| --- | --- |
| `-32700` | Unparsable JSON (HTTP `400`). |
| `-32600` | The body is not a JSON-RPC object (`400`), HTTPS is required (`403`), or the body is too large (`413`). |
| `-32601` | Unknown method (`404`). |
| `-32602` | Invalid `params` for `tools/list` or `tools/call`, (`400`); a `tools/call` for an unknown tool name also answers `-32602`. |
