# List Swap Routes

Get the destination chains and tokens configured for a source token — use it to populate the "To" selector of a swap UI.

## Overview

Swap routes are a catalogue that administrators maintain through the `/v1/admin/swap-routes` endpoints. Each route links a source chain and token to a destination chain and token. This endpoint returns the active routes for one source token.

- **Authentication is optional.** With a valid Bearer token you get your tenant's routes; if your tenant has none for that source token, the system tenant's routes are returned instead. Without a token — or with an invalid or expired one — the request is not rejected and you get the system tenant's routes.
- `fromToken` is matched case-insensitively. `fromChain` may be a chain name or a numeric chain ID; a known numeric ID is converted to the chain name.
- `isTestnet` is accepted but does not currently filter the result.
- Results are cached on the server for up to 5 minutes.

> 💡 Routes describe what your UI should offer. [Get Quote](https://docs.aureahub.com/docs/swap-quote.md) does not check them, so a listed route can still fail to quote — for example when LI.FI has no route at that moment.

## Endpoint

### `GET /v1/swap/routes`

Authentication: none (public endpoint).

Returns the active destination routes for a source token. A Bearer token is optional.

**Query parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `fromChain` | string | yes | Source chain name (e.g. `polygon`) or numeric chain ID. |
| `fromToken` | string | yes | Source token address: `0x` + 40 hex characters, or a Solana base58 address (32–44 characters). |
| `isTestnet` | string | no | `true` or `false`. Accepted; not currently used to filter routes. |

**Responses**

`200` OK

```json
{
  "data": [
    {
      "id": "…",
      "toChain": "gnosis",
      "toToken": {
        "address": "0x…",
        "symbol": "…",
        "name": "…",
        "decimals": 18,
        "logoUri": null,
        "isNative": false
      }
    }
  ]
}
```

`400` Bad Request

```json
{
  "error": "Bad Request",
  "message": "Request validation failed"
}
```

`422` Invalid fromToken

```json
{
  "statusCode": 422,
  "error": "ValidationError",
  "message": "Invalid query parameters",
  "details": [ { "path": ["fromToken"], "message": "Invalid token address format" } ]
}
```

A missing `fromChain` or `fromToken` returns `400`; a malformed `fromToken` returns `422`. Routes are ordered by `toChain`, then by token symbol. When a destination token is not found in the token registry, `toToken` carries placeholders: `symbol` and `name` are the first 8 characters of the address, `decimals` is `18`, `logoUri` is `null` and `isNative` is `false`.

## Implementation

```javascript
async function getSwapDestinations({ fromChain, fromToken, token }) {
  const params = new URLSearchParams({ fromChain, fromToken });
  const res = await fetch(`https://api.aureahub.com/v1/swap/routes?${params}`, {
    // Optional: send the user's token to get tenant-specific routes
    headers: token ? { Authorization: `Bearer ${token}` } : {}
  });
  const body = await res.json();
  if (!res.ok) throw new Error(`Routes error ${res.status}: ${body.message}`);
  return body.data; // [{ id, toChain, toToken: { address, symbol, name, decimals, logoUri, isNative } }]
}

// Populate the "To" selector for the chosen source token
async function populateToSelect(selectEl, { fromChain, fromToken }, token) {
  const routes = await getSwapDestinations({ fromChain, fromToken, token });
  selectEl.innerHTML = '';
  for (const route of routes) {
    const opt = document.createElement('option');
    opt.value = JSON.stringify({ toChain: route.toChain, toToken: route.toToken.address });
    opt.textContent = `${route.toToken.symbol} on ${route.toChain}`;
    selectEl.appendChild(opt);
  }
}
```

---

Web version: https://docs.aureahub.com/#swap-routes-list
