> ## Documentation Index
> Fetch the complete documentation index at: https://docs.turtle.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Tokens

> Retrieve supported tokens for targetTokenId and rewardTokenId selection on a specific chain

<Note>
  All requests require an API key via the `X-API-Key` header.
  See [Authentication](/sdk/authentication/api-keys) for details.
</Note>

## Overview

`GET /v1/streams/tokens` returns the active tokens supported for stream creation on a specific chain.

Use this endpoint in two different ways:

* To resolve the tokens that can be used as `targetTokenId` inside stream `customArgs`.
* To resolve the tokens that can be used as `rewardTokenId` for token-based streams.

For reward-token selection, use the tokens where `isAllowedRewardToken` is `true`.

<Info>
  The `chainId` query parameter for this endpoint is the decimal EVM chain ID.
</Info>

## Supported Chains by Use Case

### `targetTokenId` chains

For `targetTokenId`, this endpoint can be queried with any of the following decimal chain IDs.

#### Mainnet

| Chain           | Decimal chainId |
| --------------- | --------------- |
| `Abstract`      | `2741`          |
| `Arbitrum`      | `42161`         |
| `Avalanche`     | `43114`         |
| `Base`          | `8453`          |
| `BeraChain`     | `80094`         |
| `Blast`         | `81457`         |
| `BSC`           | `56`            |
| `Ethereum`      | `1`             |
| `Fraxtal`       | `238`           |
| `Gnosis`        | `100`           |
| `HyperEVM`      | `999`           |
| `Ink`           | `57073`         |
| `Katana`        | `747474`        |
| `Linea`         | `59144`         |
| `Linea-Sepolia` | `59141`         |
| `Manta`         | `169`           |
| `Mantle`        | `5000`          |
| `Metis`         | `1088`          |
| `Mezo`          | `31612`         |
| `Mode Network`  | `34443`         |
| `Monad`         | `143`           |
| `Optimism`      | `10`            |
| `Peaq`          | `3338`          |
| `Plasma`        | `9745`          |
| `Polygon`       | `137`           |
| `Polygon zkEVM` | `1101`          |
| `Scroll`        | `534352`        |
| `Sonic`         | `146`           |
| `Swell`         | `1923`          |
| `TAC`           | `239`           |
| `Unichain`      | `130`           |
| `Worldchain`    | `480`           |
| `XLayer`        | `196`           |
| `Zircuit`       | `48900`         |
| `ZkSync`        | `324`           |

#### Testnet

| Chain           | Decimal chainId |
| --------------- | --------------- |
| `Sepolia`       | `11155111`      |
| `Linea-Sepolia` | `59141`         |

### `rewardToken` chains

This same endpoint is also used for `rewardToken`, but stream creation currently supports `rewardToken` only on these 5 networks:

#### Mainnet

| Chain       | Decimal chainId |
| ----------- | --------------- |
| `Ethereum`  | `1`             |
| `Base`      | `8453`          |
| `Avalanche` | `43114`         |
| `BSC`       | `56`            |

#### Testnet

| Chain     | Decimal chainId |
| --------- | --------------- |
| `Sepolia` | `11155111`      |

Sepolia is included here specifically so you can test stream creation with `rewardToken` before moving to mainnet.

If you need TURTLE test tokens on Sepolia (`0xa78559593289728719bc46e7559ebdee5bc5ef7a`) for testing, please contact the Turtle team to request them.

On any of those supported networks, a stream can use both values on the same chain: a `rewardToken` for the reward asset and a `targetTokenId` inside `customArgs` for the tracked target token. The difference is not that they must belong to different chains. The difference is that `rewardToken` is currently limited to this smaller subset, while `targetTokenId` supports the broader list above.

## Endpoint

<CodeGroup>
  ```bash curl theme={null}
  curl -X GET "https://earn.turtle.xyz/v1/streams/tokens?chainId=1" \
    -H "X-API-Key: pk_live_xxxxx"
  ```

  ```typescript TypeScript theme={null}
  const chainId = 1;

  const response = await fetch(
    `https://earn.turtle.xyz/v1/streams/tokens?chainId=${chainId}`,
    {
      headers: { 'X-API-Key': process.env.TURTLE_SECRET_KEY! },
    }
  );

  const data = await response.json();
  ```
</CodeGroup>

**Query Parameters**

<ParamField query="chainId" type="integer" required>
  Decimal EVM chain ID. This is required. Use the decimal `chainId` values listed above.
</ParamField>

## Response Example

```json theme={null}
{
  "tokens": [
    {
      "id": "56b0fab0-5c3e-49f6-a0a7-57e38d5ea999",
      "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      "name": "USD Coin",
      "symbol": "USDC",
      "decimals": 6,
      "chainId": 1,
      "logoUrl": "https://cdn.example.com/tokens/usdc.png",
      "isAllowedRewardToken": true
    },
    {
      "id": "9f6ef77b-3ea5-4d2c-8d64-91e9e4c8b123",
      "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "name": "Tether USD",
      "symbol": "USDT",
      "decimals": 6,
      "chainId": 1,
      "logoUrl": "https://cdn.example.com/tokens/usdt.png",
      "isAllowedRewardToken": false
    }
  ]
}
```

## Response Fields

```typescript theme={null}
tokens: SupportedToken[]
```

<ResponseField name="tokens" type="SupportedToken[]">
  List of active tokens that can be used for streams on the requested chain.
</ResponseField>

### `SupportedToken` fields

<ResponseField name="id" type="uuid">
  Unique token identifier in Turtle's config catalog.
</ResponseField>

<ResponseField name="address" type="string">
  Token contract address.
</ResponseField>

<ResponseField name="name" type="string">
  Token name.
</ResponseField>

<ResponseField name="symbol" type="string">
  Token symbol.
</ResponseField>

<ResponseField name="decimals" type="integer">
  Decimal precision used by the token.
</ResponseField>

<ResponseField name="chainId" type="integer">
  Decimal EVM chain ID for the token.
</ResponseField>

<ResponseField name="logoUrl" type="string">
  Token logo URL.
</ResponseField>

<ResponseField name="isAllowedRewardToken" type="boolean">
  Whether the token can be used as `rewardTokenId` for token-based stream creation on that chain.
</ResponseField>

## Important Notes

<AccordionGroup>
  <Accordion title="chainId is required">
    Requests without `chainId`, or with `chainId = 0`, are rejected with `400 Invalid Argument`.
  </Accordion>

  <Accordion title="Only active non-native tokens are returned">
    The handler excludes inactive tokens and filters out native assets, so this endpoint returns the currently usable non-native token set for stream creation.
  </Accordion>

  <Accordion title="rewardToken and targetTokenId can coexist on the same chain">
    A stream can use both a `rewardToken` and a `targetTokenId` on the same supported network. The distinction here is support scope, not mutual exclusion: `rewardToken` is currently limited to the 5-chain subset listed above, while `targetTokenId` supports the broader chain list documented on this page.
  </Accordion>

  <Accordion title="Use `isAllowedRewardToken == true` for reward-token selection">
    When selecting a `rewardTokenId` for `POST /v1/streams/`, choose one of the returned tokens where `isAllowedRewardToken` is `true`. Tokens with `isAllowedRewardToken = false` can still be valid for other use cases such as `targetTokenId`, but not as the stream reward token.
  </Accordion>

  <Accordion title="Use the decimal chainId from this page">
    When calling this endpoint, send the decimal EVM `chainId` shown in the tables above.
  </Accordion>
</AccordionGroup>

## Error Handling

<AccordionGroup>
  <Accordion title="Missing or invalid API key">
    **Status Code:** 401 Unauthorized

    ```json theme={null}
    {
      "error": "Invalid API key"
    }
    ```

    **Solution:** Pass a valid `X-API-Key` header.
  </Accordion>

  <Accordion title="Missing chainId">
    **Status Code:** 400 Bad Request

    ```json theme={null}
    {
      "error": {
        "status": "INVALID_ARGUMENT",
        "error": "chainId is required"
      }
    }
    ```

    **Solution:** Send a valid decimal EVM chain ID in the `chainId` query parameter.
  </Accordion>

  <Accordion title="Unexpected internal error">
    **Status Code:** 500 Internal Server Error

    **Solution:** Retry the request and contact Turtle if the issue persists.
  </Accordion>
</AccordionGroup>
