# Error Reference

# Error Reference

All Gett API error responses follow [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) — *Problem Details for HTTP APIs*. Every error includes machine-readable fields that let API consumers and AI agents make deterministic retry, backoff, and escalation decisions without parsing prose.

## Response Format

### Content Negotiation

The API selects the response format based on the `Accept` header:

| Accept Header | Response Format | Content-Type |
|---|---|---|
| `application/problem+json` | JSON (default) | `application/problem+json` |
| `application/json` | JSON | `application/problem+json` |
| `text/markdown` | Markdown with YAML frontmatter | `text/markdown` |
| `*/*` or omitted | JSON (default) | `application/problem+json` |

### JSON Response

```json
{
  "type": "https://developer.gett-tech.com/errors/CATALOGSET_REQUIRED",
  "title": "Bad Request",
  "status": 400,
  "detail": "Cart creation requires a catalogSetId.",
  "instance": "/v1/marketfront/orders/validate",
  "requestId": "req_abc123",
  "timestamp": "2026-03-11T14:30:00.000Z",
  "errorCode": "CATALOGSET_REQUIRED",
  "errorCategory": "validation",
  "retryable": false
}
```

### `type` URI Template

The `type` URI is dereferenceable — fetch it (or follow the link) to read the documentation for that error class.

| Template | Example |
|---|---|
| `/errors/{errorCode}` | `/errors/CATALOGSET_REQUIRED`, `/errors/PAYMENT_TOKEN_INVALID` |

All errors — gateway-originated and domain-alike — carry a named `errorCode` slug. Gateway errors use stable codes such as `INVALID_REQUEST`, `UNAUTHENTICATED`, and `RATE_LIMITED`. All URIs live under `https://developer.gett-tech.com/`.

**Important:** error pages are organised by `errorCode` slug (e.g. `STORE_NOT_FOUND`), not by HTTP status code. Multiple distinct codes can share the same HTTP status — for example, `CATALOGSET_REQUIRED` and `CLIENT_IP_INVALID` both return `400`, but each has its own dedicated page describing the cause, context, and recommended action. The `type` URI in the Problem Details response (RFC 9457) is dereferenceable directly to that code's documentation page.

### Markdown Response

Request with `Accept: text/markdown` to receive a compact format optimized for AI agents and LLMs:

```markdown
---
status: 503
errorCategory: server_error
retryable: true
retryAfter: 60
requestId: req_abc123
---
# Service Unavailable
## What Happened
A dependency is temporarily unavailable.
## What You Should Do
Wait for the number of seconds indicated by retryAfter, then retry.
```

:::note[Not available on a 429]
A `429` is generated by the gateway ahead of the API, so it does not pass through the negotiation
described here and always returns its own JSON shape. See [429 Too Many Requests](/errors/RATE_LIMITED).
:::

## Fields

### Standard Members (RFC 9457)

| Field | Type | Description |
|---|---|---|
| `type` | `string` | Dereferenceable URI pointing to documentation for this error class — see [URI template](#type-uri-template) |
| `title` | `string` | Short, human-readable summary |
| `status` | `integer` | HTTP status code |
| `detail` | `string` | Explanation specific to this occurrence |
| `instance` | `string` | The request path that produced this error |

### Extension Members

| Field | Type | Description |
|---|---|---|
| `requestId` | `string` | Unique request identifier — include when contacting support |
| `timestamp` | `string` | ISO 8601 timestamp of when the error occurred |
| `errorCode` | `string` | Domain-specific error code (e.g. `CATALOGSET_REQUIRED`, `CARD_EXPIRED`) |
| `errorCategory` | `string` | Machine-readable category for agent decision-making |
| `retryable` | `boolean` | Whether retrying the request can succeed |
| `retryAfter` | `integer` | Seconds to wait before retrying (present when applicable) |
| `errors` | `array` | Validation error details (present on 400/422 responses) |

## Error Categories

| Category | Meaning | Agent Action |
|---|---|---|
| `validation` | Invalid request body or parameters | Fix request and retry |
| `authentication` | Missing or invalid credentials | Fix API key or JWT |
| `authorization` | Insufficient permissions | Contact account owner |
| `not_found` | Resource does not exist | Verify ID or path |
| `conflict` | Conflicting operation (e.g., duplicate order) | Do not retry |
| `rate_limit` | Rate limit exceeded | Wait the seconds given in the `Retry-After` **header** — a 429 carries no `retryAfter` body field |
| `payment` | Payment processing issue | Retry or use different payment method |
| `idempotency` | `Idempotency-Key` reused with a different body, or an earlier attempt on it is still in flight | Different body: use a fresh key, or replay the same body. Still in flight: retry the **same** key |
| `server_error` | Unexpected server error | Retry with exponential backoff |

## HTTP Status Code Errors

- [400 Bad Request](/errors/INVALID_REQUEST)
- [401 Unauthorized](/errors/UNAUTHENTICATED)
- [403 Forbidden](/errors/FORBIDDEN)
- [404 Not Found](/errors/NOT_FOUND)
- [409 Conflict](/errors/CONFLICT)
- [422 Unprocessable Entity](/errors/VALIDATION_FAILED)
- [429 Too Many Requests](/errors/RATE_LIMITED)
- [500 Internal Server Error](/errors/INTERNAL_ERROR)
- [502 Bad Gateway](/errors/UPSTREAM_UNAVAILABLE)
- [503 Service Unavailable](/errors/SERVICE_UNAVAILABLE)
