> For the complete documentation index, see [llms.txt](https://titan-exchange.gitbook.io/titan/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://titan-exchange.gitbook.io/titan/developer-doc/developers-portal/errors.md).

# Errors

HTTP response codes and error bodies for the Titan Developers Portal.

Errors originate from two layers. Platform errors, covering authentication and limits, return a JSON envelope with a machine-readable code. Routing errors describe the swap request itself.

## Debugging

Every response includes an `x-amzn-requestid` header. Quote responses also carry an `id` field, and `404` responses carry `quoteId.tag`. Include both values when reporting an issue.

```typescript
const res = await fetch(`${API}/api/v1/quote/swap?${params}`, { headers });

if (!res.ok) {
  const requestId = res.headers.get('x-amzn-requestid');
  const body = await res.text();
  console.error(`[${res.status}] request=${requestId} body=${body}`);
}
```

## HTTP status codes

| Code  | Description  | Meaning                                                                                                                                                                                                       |
| ----- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200` | Success      | Request completed successfully.                                                                                                                                                                               |
| `400` | Bad Request  | A parameter is missing, malformed or out of bounds. Malformed parameters return a plain-text body naming the field; out-of-bounds values return a JSON body with an engine code.                              |
| `401` | Unauthorized | The `x-api-key` header is missing, unknown or revoked. A request with no key returns this rather than being treated as anonymous.                                                                             |
| `403` | Forbidden    | The method or path does not exist. All endpoints are `GET`; `curl -d` converts a request to `POST`.                                                                                                           |
| `404` | Not Found    | No provider could build a route. See [Routing errors](#routing-errors).                                                                                                                                       |
| `429` | Rate Limited | The plan rate limit or the monthly credit allowance was exceeded. The error code distinguishes them. See [Plans, Rate Limits & Credits](/titan/developer-doc/developers-portal/plans-rate-limits-credits.md). |

## Platform error codes

Returned as a JSON envelope:

```json
{ "error": { "code": "rate_limited" } }
```

| Code                  | Status | Trigger                                              | Resolution                                                                                                         |
| --------------------- | ------ | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `invalid_api_key`     | `401`  | Missing, unknown or revoked key                      | Verify the header and that the key is active. Confirm the hostname — a distributor JWT returns the same code here. |
| `rate_limited`        | `429`  | More than `rps × 60` requests in the last 60 seconds | Wait `retry-after` seconds before retrying.                                                                        |
| `allowance_exhausted` | `429`  | Monthly credit allowance spent                       | Retrying does not resolve this. Upgrade the plan or wait for the period to roll over.                              |

A `403` originates from the API edge rather than the routing engine and uses a different shape:

```json
{ "message": "Missing Authentication Token" }
```

Despite the wording, this indicates an unknown method or path, not an authentication failure.

## Routing errors

A malformed or missing parameter returns `400` as plain text, naming the field:

```
Failed to deserialize query string: inputMint: Base58 string too short
Failed to deserialize query string: missing field `userPublicKey`
Failed to deserialize query string: amount: number too large to fit in target type
```

A well-formed parameter outside its accepted range returns `400` as JSON with an engine code. Bounds are published by [`/api/v1/info`](/titan/developer-doc/developers-portal/reference/info-venues-providers.md#info).

```json
{ "code": 7, "message": "Number of requested quotes out of bounds, must be in [1, 10], given: 11" }
```

When no provider can build a route, the response is `404` with code `-7` and the pricing context a successful response would carry:

```json
{
  "code": -7,
  "message": "No acceptable routes found from enabled providers, see `metadata.errors` for more information",
  "quoteId": { "kind": "Swap", "tag": "d99e36c2-d95a-4674-84bc-9c0953e14966", "seq": 0 },
  "metadata": {
    "errors": { "Titan": "Other", "Titan-DART": "NoRoutesFound" },
    "inputMintDecimals": 9,
    "outputMintDecimals": 6,
    "inputPriceUSD": 100.69250955835294,
    "outputPriceUSD": 0.9998180872066792
  }
}
```

`metadata.errors` reports one reason per provider that attempted the route. It is present when providers were engaged and absent when the request failed validation first — a `404` without it indicates a request-level problem, most commonly a `userPublicKey` that is not a usable wallet.

To resolve `-7`, relax the routing filters: `dexes`, `excludeDexes`, `venueAllowlist`, `onlyDirectRoutes` and `providers`. Verify the amount is large enough to route. An unrecognized `dexes` label produces this error rather than a `400`; take valid labels from `/api/v1/venues`.

## Identifying the layer

| Response body                                | Layer    | Meaning                              |
| -------------------------------------------- | -------- | ------------------------------------ |
| `{"error":{"code":...}}`                     | Platform | Key, plan or request rate            |
| `{"message":"Missing Authentication Token"}` | Edge     | Unknown method or path               |
| `Failed to deserialize...` (plain text)      | Engine   | Malformed or missing parameter       |
| `{"code":N,"message":...}` (`400`)           | Engine   | Parameter out of bounds              |
| `{"code":-7,...}` (`404`)                    | Engine   | Parameters valid, no route available |

Per-provider error reasons and the wire-level codes shared with Titan Direct are documented in the [Swap API error reference](/titan/developer-doc/swap-api/reference/error-codes.md).
