# Error Reference

This page documents all error responses returned by the XOXNO Aggregator API, including HTTP status codes, causes, and resolution steps.

## Error Response Format

All API errors return a JSON body with an `error` field:

```json
{
  "error": "<error message>"
}
```

There is no nested `code` field; the error string is the canonical identifier. Match errors using substring checks against the patterns documented below.

***

## Application Errors (HTTP 400)

These errors indicate a problem with the request parameters. They will not resolve with a retry.

### Unknown Input Token

**Trigger**: The `from` parameter contains a token identifier the router does not recognize.

```json
{
  "error": "unknown token_in 'INVALID-123456'"
}
```

| Field         | Value                                                                                                                                                  |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| HTTP status   | `400`                                                                                                                                                  |
| Error pattern | `"unknown token_in"`                                                                                                                                   |
| Cause         | Token not found in the router's token registry                                                                                                         |
| Resolution    | Verify the token identifier format (`TICKER-hexcode`). Use [pair-config](/developers/aggregator-api/pair-config.md) to confirm the token is supported. |

***

### Unknown Output Token

**Trigger**: The `to` parameter contains an unrecognized token identifier.

```json
{
  "error": "unknown token_out 'INVALID-123456'"
}
```

| Field         | Value                                                                                                              |
| ------------- | ------------------------------------------------------------------------------------------------------------------ |
| HTTP status   | `400`                                                                                                              |
| Error pattern | `"unknown token_out"`                                                                                              |
| Cause         | Token not found in the router's token registry                                                                     |
| Resolution    | Verify the token identifier format. Use [pair-config](/developers/aggregator-api/pair-config.md) to check support. |

***

### No Route Found

**Trigger**: Both tokens are known, but no liquidity path connects them in the current pool graph.

```json
{
  "error": "routing failed: no path between tokens"
}
```

| Field         | Value                                                                                                                                                                                  |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| HTTP status   | `400`                                                                                                                                                                                  |
| Error pattern | `"no path between tokens"`                                                                                                                                                             |
| Cause         | Insufficient liquidity or no pool chain linking the token pair                                                                                                                         |
| Resolution    | Check [pair-config](/developers/aggregator-api/pair-config.md). Try common intermediate tokens (WEGLD, USDC). Consider that newly listed tokens may not yet have sufficient liquidity. |

***

### Invalid Amount

**Trigger**: The `amountIn` or `amountOut` value is not a valid unsigned integer.

```json
{
  "error": "invalid amount_in: expected unsigned integer amount"
}
```

| Field         | Value                                                                                                                           |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| HTTP status   | `400`                                                                                                                           |
| Error pattern | `"invalid amount_in"` or `"invalid amount_out"`                                                                                 |
| Cause         | Amount is fractional, negative, zero, or non-numeric                                                                            |
| Resolution    | Pass amounts as stringified integers in the token's smallest units (no decimals). Example: `"1000000000000000000"` for 1 WEGLD. |

***

### Ambiguous Amount

**Trigger**: Both `amountIn` and `amountOut` are provided in the same request.

```json
{
  "error": "specify either amount_in or amount_out, not both"
}
```

| Field         | Value                                                                                                     |
| ------------- | --------------------------------------------------------------------------------------------------------- |
| HTTP status   | `400`                                                                                                     |
| Error pattern | `"specify either amount_in or amount_out"`                                                                |
| Cause         | The API cannot resolve direction when both amounts are specified                                          |
| Resolution    | Remove one of the two parameters. Use `amountIn` for a forward quote and `amountOut` for a reverse quote. |

***

### Missing Amount

**Trigger**: Neither `amountIn` nor `amountOut` is present in the request.

```json
{
  "error": "amount_in or amount_out must be provided"
}
```

| Field         | Value                                                     |
| ------------- | --------------------------------------------------------- |
| HTTP status   | `400`                                                     |
| Error pattern | `"amount_in or amount_out must be provided"`              |
| Cause         | No amount parameter was supplied                          |
| Resolution    | Add either `amountIn` or `amountOut` to the query string. |

***

### Simulation Failed

**Trigger**: The router found candidate paths but simulation failed for all of them.

```json
{
  "error": "simulation failed"
}
```

| Field         | Value                                                                                                       |
| ------------- | ----------------------------------------------------------------------------------------------------------- |
| HTTP status   | `400`                                                                                                       |
| Error pattern | `"simulation failed"`                                                                                       |
| Cause         | Typically caused by extremely low pool liquidity, an amount that would drain a pool, or overflow conditions |
| Resolution    | Reduce the trade size. Check that neither pool involved is near-empty.                                      |

***

## Infrastructure Errors

### Rate Limit Exceeded (HTTP 429)

**Trigger**: More than 100 requests per second from a single IP.

```json
{
  "error": "rate limit exceeded"
}
```

| Field       | Value                                                                                                          |
| ----------- | -------------------------------------------------------------------------------------------------------------- |
| HTTP status | `429`                                                                                                          |
| Cause       | Request rate exceeds 100 req/s per IP                                                                          |
| Resolution  | Implement exponential backoff. Use `includePaths=false` for high-frequency polling to reduce per-request cost. |

***

### Service Unavailable (HTTP 503)

**Trigger**: The service is starting up or pool data has not yet been loaded.

```json
{
  "error": "service unavailable"
}
```

| Field       | Value                                                                       |
| ----------- | --------------------------------------------------------------------------- |
| HTTP status | `503`                                                                       |
| Cause       | Cold start or pool data refresh in progress                                 |
| Resolution  | Retry with backoff. The service typically initializes within 10–30 seconds. |

***

## Error Summary Table

| Error message pattern                        | HTTP | Retryable | Resolution                            |
| -------------------------------------------- | ---- | --------- | ------------------------------------- |
| `"unknown token_in"`                         | 400  | No        | Fix token identifier                  |
| `"unknown token_out"`                        | 400  | No        | Fix token identifier                  |
| `"no path between tokens"`                   | 400  | No        | Use pair-config, try different tokens |
| `"invalid amount_in"`                        | 400  | No        | Pass integer in smallest units        |
| `"specify either amount_in or amount_out"`   | 400  | No        | Remove one amount parameter           |
| `"amount_in or amount_out must be provided"` | 400  | No        | Add an amount parameter               |
| `"simulation failed"`                        | 400  | Sometimes | Reduce amount; retry once             |
| HTTP 429                                     | 429  | Yes       | Exponential backoff                   |
| HTTP 503                                     | 503  | Yes       | Retry with backoff                    |

***

## Best Practices

### Validate Tokens Before Quoting

Call [pair-config](/developers/aggregator-api/pair-config.md) before requesting a quote to catch unknown tokens and missing routes early. This produces a better user experience than surfacing raw API error strings.

```javascript
async function getValidatedQuote(from, to, amountIn) {
  const config = await fetch(
    `https://swap.xoxno.com/api/v1/pair-config?from=${from}&to=${to}`
  ).then(r => r.json());

  if (!config.supported) {
    // Provide a user-friendly message before hitting the quote endpoint
    throw new Error(config.error === 'unknown tokenOut'
      ? `Token ${to} is not supported`
      : `No route available between ${from} and ${to}`
    );
  }

  return fetch(`https://swap.xoxno.com/api/v1/quote?from=${from}&to=${to}&amountIn=${amountIn}`)
    .then(r => r.json());
}
```

### Handle 429 with Exponential Backoff

```javascript
async function fetchWithBackoff(url, maxRetries = 4) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url);

    if (response.status !== 429 && response.status !== 503) {
      return response;
    }

    if (attempt < maxRetries - 1) {
      const delay = 200 * Math.pow(2, attempt); // 200ms, 400ms, 800ms, 1600ms
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }

  throw new Error('Request failed after maximum retries');
}
```

### Use `includePaths=false` for Price Polling

Applications that poll quote prices at high frequency (e.g., updating a UI with real-time rates) should omit path details:

```javascript
const priceUrl = `https://swap.xoxno.com/api/v1/quote?\
from=${tokenIn}&to=${tokenOut}&amountIn=${amount}&includePaths=false`;
```

This reduces response payload size and avoids unnecessary computation on the server side.

***

## Related Topics

* [Quote Endpoint](/developers/aggregator-api/quote.md) — Full parameter reference
* [Pair Configuration](/developers/aggregator-api/pair-config.md) — Token validation
* [Integration Guide](/developers/aggregator-api/integration-guide.md) — Retry logic and error handling patterns


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xoxno.com/developers/aggregator-api/error-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
