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

# Troubleshooting

> Solutions for common errors and issues with the Codex API

<Tip>
  Can't find your issue here? Try our integrated AI assistant at the top of the page, or reach out on [Discord](https://discord.gg/9ZB7zcWuBY).
</Tip>

## Authentication Errors

<AccordionGroup>
  <Accordion title="Error: &#x22;Your API key was not found&#x22; / UNAUTHENTICATED / 401">
    Your API key is missing, invalid, or expired.

    **Fixes:**

    * Verify you're passing the key in the `Authorization` header: `"Authorization": "your-api-key"`
    * For short-lived tokens (JWTs), use the `Bearer` prefix: `"Authorization": "Bearer <token>"`
    * Check that your key hasn't been deactivated on the [dashboard](https://dashboard.codex.io)
    * If using the SDK, ensure you're passing the key correctly: `new Codex("your-api-key")`

    ```typescript theme={null}
    // Secret key — no prefix needed
    fetch("https://graph.codex.io/graphql", {
      headers: { "Authorization": "your-api-key" }
    })

    // Short-lived token — Bearer prefix required
    fetch("https://graph.codex.io/graphql", {
      headers: { "Authorization": "Bearer eyJhbGciOi..." }
    })
    ```
  </Accordion>

  <Accordion title="&#x22;Not authorized: please upgrade your plan&#x22;">
    You're trying to use a feature that isn't available on your current plan. Common cases:

    * **`holders` query** — requires a Growth or Enterprise plan
    * **WebSocket subscriptions** — require a Growth or Enterprise plan
    * **`tokenTopTraders`** — requires a Growth or Enterprise plan

    Upgrade your plan on the [billing page](https://dashboard.codex.io/dashboard/billing?utm_source=codex\&utm_medium=docs\&utm_campaign=troubleshooting).
  </Accordion>

  <Accordion title="Previously working API key suddenly returns errors">
    * Check that you haven't exceeded your plan's monthly request limit — overages are charged at the same rate as your plan
    * Verify the key is still active on the [dashboard](https://dashboard.codex.io)
    * If using a short-lived token, it may have expired — generate a new one with `createApiTokens`
  </Accordion>
</AccordionGroup>

## WebSocket & Subscription Errors

<AccordionGroup>
  <Accordion title="Socket closed with event 4403 Forbidden">
    The server rejected your WebSocket connection. Common causes:

    * **Wrong plan:** Subscriptions require a Growth or Enterprise plan
    * **Missing auth:** You must pass your API key in the `connection_init` payload, not as a URL parameter
    * **Exceeded connection limit:** Growth plans are limited to 300 concurrent WebSocket connections

    ```typescript theme={null}
    // Correct — auth in connection_init payload
    const client = createClient({
      url: "wss://graph.codex.io/graphql",
      connectionParams: {
        Authorization: "your-api-key",
      },
    });
    ```
  </Accordion>

  <Accordion title="Socket closed with event 4401 / Subscribing before connection_ack">
    You're sending a `subscribe` message before the server has acknowledged your connection. You **must** wait for the `connection_ack` message before subscribing.

    ```javascript theme={null}
    webSocket.onmessage = (event) => {
      const data = JSON.parse(event.data);
      if (data.type === "connection_ack") {
        // Only NOW is it safe to subscribe
        webSocket.send(JSON.stringify({
          id: "1",
          type: "subscribe",
          payload: { query: "subscription { ... }" }
        }));
      }
    };
    ```

    If you're using the [SDK](/sdk) or `graphql-ws`, this is handled automatically.
  </Accordion>

  <Accordion title="WebSocket disconnects after a period of inactivity">
    Connections require periodic heartbeat messages to stay alive.

    * **SDK users:** Heartbeats are handled automatically
    * **Custom implementations:** Send a `ping` message periodically. See the [graphql-ws protocol](https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md#ping) for details
  </Accordion>

  <Accordion title="403 errors appearing intermittently on an active subscription">
    If your connection works initially but starts returning 403 errors:

    * You may have hit your plan's connection limit (300 for Growth plans) — check if you have stale connections that weren't properly closed
    * Ensure you close subscriptions and connections when they're no longer needed
    * Deactivating an API key does **not** close active subscriptions — they persist until disconnected
  </Accordion>

  <Accordion title="I can't send queries through WebSockets — only subscriptions work">
    Correct — WebSocket connections are for subscriptions (real-time updates) only. Use HTTP POST requests to `https://graph.codex.io/graphql` for queries and mutations. See the [Subscriptions concept](/concepts/subscriptions) for more details.
  </Accordion>
</AccordionGroup>

## GraphQL Validation Errors

These errors mean your query has a field or argument that doesn't exist on the type you're querying. The error message tells you exactly what's wrong.

<AccordionGroup>
  <Accordion title="Cannot query field &#x22;isVerified&#x22; on type &#x22;EnhancedToken&#x22;">
    There is no `isVerified` response field. Codex uses `isScam` instead — `isScam: false` is the equivalent of a token being "verified."

    * **To filter** for verified tokens: use `isVerified: true` in `filterTokens` filters
    * **To read** verification status: use `isScam` on the token object

    ```graphql theme={null}
    # Filter for verified tokens
    filterTokens(filters: { isVerified: true }) {
      results {
        token {
          name
          isScam  # false = verified
        }
      }
    }
    ```

    See the [FAQ](/extra/faq#data-coverage--methodology) for more details.
  </Accordion>

  <Accordion title="Cannot query field &#x22;X&#x22; on type &#x22;Y&#x22; — general fix">
    This means the field doesn't exist on the type. Common mistakes:

    | You wrote                      | Fix                                                                                                          |
    | ------------------------------ | ------------------------------------------------------------------------------------------------------------ |
    | `token { marketCap }`          | `marketCap` is on `TokenFilterResult`, not `EnhancedToken`. Use `filterTokens` to get it                     |
    | `token { priceChange5m }`      | `priceChange5m` is only on `PairMetadata`. `TokenFilterResult` has `priceChange1`/`4`/`12`/`24` but not `5m` |
    | `pair { factoryAddress }`      | `factoryAddress` is not a field on `Pair`                                                                    |
    | `detailedPairStats { pairId }` | Use `pairAddress` instead                                                                                    |
    | `tokenInfo { thumbHashUrl }`   | Use `imageThumbUrl` instead                                                                                  |

    Use our [explorer](https://explorer.codex.io) which has autocomplete to discover available fields, or browse the [GraphQL Reference](/api-reference/introduction).
  </Accordion>

  <Accordion title="Unknown argument &#x22;inputs&#x22; on field — Did you mean &#x22;input&#x22;?">
    Some fields use `input` (singular) while others use `inputs` (plural). Check the exact parameter name in the [API reference](/api-reference/introduction).

    Common ones:

    * `onPricesUpdated` uses `input` (singular) containing a list of tokens
    * `getTokenPrices` uses `inputs` (plural)
    * `token` uses `input` (singular)
  </Accordion>

  <Accordion title="Unknown argument &#x22;rankings&#x22; on field &#x22;Query.filterTokenWallets&#x22;">
    `filterTokenWallets` does not support a `rankings` argument. It uses `filters` and pagination parameters (`cursor`, `limit`). Only `filterTokens` and `filterPairs` support `rankings`.
  </Accordion>

  <Accordion title="Field &#x22;token0&#x22; must not have a selection since type &#x22;String!&#x22; has no subfields">
    On the `Pair` type, `token0` and `token1` are strings (token addresses), not objects. If you want token metadata from a pair query, use `pairMetadata` with `enhancedToken0` / `enhancedToken1` instead.

    ```graphql theme={null}
    # Wrong — token0 is a String on Pair
    pair { token0 { name symbol } }

    # Right — use pairMetadata for enriched token data
    pairMetadata(pairId: "...") {
      enhancedToken0 { name symbol }
      enhancedToken1 { name symbol }
    }
    ```
  </Accordion>

  <Accordion title="GraphQL syntax errors (IDENT, LBRACE, COLON)">
    These are query syntax errors, usually from:

    * **Missing colons** between field names and arguments — `unexpected token - got: IDENT want one of: [COLON]`
    * **Template literals not rendering** — if you're using a tool like n8n, Make, or Retool, ensure your template syntax (`{{ }}`) isn't conflicting with GraphQL
    * **Missing closing braces** — count your `{` and `}` to make sure they match

    Test your query in the [explorer](https://explorer.codex.io) first to verify the syntax is correct before using it in code.
  </Accordion>
</AccordionGroup>

## Null or Empty Results

<AccordionGroup>
  <Accordion title="getTokenPrices returns [null] for a token">
    Common causes:

    * **Token hasn't traded yet** — Codex only has price data for tokens with trading activity
    * **Pre-graduation launchpad token** — bonding curve tokens may not have a price available via `getTokenPrices`. Use `onLaunchpadTokenEventBatch` for launchpad token prices, or `filterTokens` which includes `priceUSD` for launchpad tokens
    * **Wrong address format** — for Tron, use the hex (0x) address, not the base58 (T...) address
    * **Wrong networkId** — verify you're using the correct network ID for the chain
  </Accordion>

  <Accordion title="filterTokens returns empty results">
    * **Filters too narrow** — loosen your filters and add them back one at a time to identify which one is excluding results
    * **Launchpad graduation filters** — `launchpadGraduationPercent` uses `gt`/`lt`/`gte`/`lte`, make sure your range isn't excluding everything (e.g., `gt: 100` won't match anything since graduation maxes at 100)
    * **Missing network filter** — without a `network` filter, results come from all chains which may dilute what you expect
    * **Scam filtering** — tokens flagged as potential scams are excluded by default. Add `includeScams: true` to include them
  </Accordion>

  <Accordion title="Null fields in subscription responses (balanceUsd, socialLinks, etc.)">
    Some fields can legitimately be `null`:

    * **`balanceUsd`** in `onBalanceUpdated` — may be null if the token doesn't have a price yet
    * **`socialLinks`** (twitter, telegram, website) — not all tokens have social links. We source these from 10+ providers but they may not be available for newer tokens
    * **`mintable` / `freezable`** — a `null` value could mean either "not mintable" or "we don't have this data." Check `isMintableValid` / `isFreezableValid` to distinguish between the two
    * **`circulatingSupply`** — may be null for tokens where we haven't been able to determine circulating supply
  </Accordion>

  <Accordion title="getTokenBars / getBars returns null">
    * Verify the `from` and `to` timestamps are Unix timestamps (seconds, not milliseconds)
    * Check that the token/pair had trading activity during the requested time range
    * `getTokenBars` has limited historical data — it may not cover older time ranges
    * For older historical data, use `getBars` with a specific pair address instead
  </Accordion>

  <Accordion title="getDetailedPairStats returns null for some pairs">
    Not all pairs have detailed stats available. This typically happens with very low volume or newly created pairs. Try querying a different pair for the same token using `listPairsWithMetadataForToken`.
  </Accordion>

  <Accordion title="getTokenEvents returns null / DOWNSTREAM_SERVICE_ERROR">
    * `getTokenEvents` queries the top pair by default — if the token has multiple pairs, events on other pairs won't appear. Use `listPairsWithMetadataForToken` to find all pairs
    * If you're getting a `DOWNSTREAM_SERVICE_ERROR`, this is usually a temporary issue. Retry after a few seconds
    * Verify the token address and networkId are correct
  </Accordion>

  <Accordion title="filterTokenWallets returns empty results for a wallet that holds the token">
    `filterTokenWallets` only tracks wallets that acquired tokens via DEX swaps. If a wallet received tokens via a direct transfer (not a swap), it won't appear in results. Use the `balances` query instead for a complete view of token holdings.
  </Accordion>
</AccordionGroup>

## Connection Limits & Rate Limits

<AccordionGroup>
  <Accordion title="How many WebSocket connections can I have?">
    Growth plans support up to 300 concurrent WebSocket connections. Enterprise has no hard limit — contact us for guidance. For full guidance on capacity per connection, see [Rate Limits & Connection Limits](https://docs.codex.io/concepts/rate-limits) and [Subscriptions](https://docs.codex.io/concepts/subscriptions).
  </Accordion>

  <Accordion title="How do connections vs subscriptions work?">
    * A **connection** is a single WebSocket to `wss://graph.codex.io/graphql`
    * A **subscription** is a single `subscribe` message on that connection (e.g., one `onPriceUpdated` for one token)
    * You can run multiple subscriptions on one connection — just send additional `subscribe` messages
    * Some subscriptions accept multiple tokens (e.g., `onPricesUpdated` can watch up to 25 tokens)

    See [Subscriptions](/concepts/subscriptions) for full details.
  </Accordion>

  <Accordion title="HTTP 400 from too many items in a batch request">
    Some queries have limits on array inputs:

    * `getTokenPrices` — max 25 tokens per request
    * `filterTokens` — max 200 results per request
    * `filterWallets` — has a limit on wallet addresses per request

    Split large requests into smaller batches.
  </Accordion>

  <Accordion title="What are the rate limits?">
    Rate limits depend on your plan. See [Rate Limits & Connection Limits](https://docs.codex.io/concepts/rate-limits) for the full breakdown by plan and tips on optimizing usage. If you're consistently hitting rate limits, also see [Optimization](https://docs.codex.io/concepts/optimization).
  </Accordion>
</AccordionGroup>

## Data Discrepancies

<AccordionGroup>
  <Accordion title="Liquidity values are lower than other platforms">
    Codex reports the liquidity of the **base token side** of the pool only. Other platforms typically double this by including both sides. To get the "total" liquidity, add both pooled amounts together. We report single-sided liquidity because we believe it more accurately represents the actual backing.
  </Accordion>

  <Accordion title="Prices differ from DexScreener / Birdeye / other platforms">
    Codex chart prices reflect the **current pool price** (based on reserves), not the last executed trade price. Other platforms often show the last trade price. Both are valid — they just measure different things. Trade prices for individual transactions are available in `getTokenEvents`.

    Note: this also explains why event prices and chart prices differ for the same token — events show the executed price of the transaction, while the chart shows the current pool price.
  </Accordion>

  <Accordion title="Tron tokens returning no data">
    Codex requires the hex (ERC20) address format for Tron tokens, not the base58 format shown on Tron explorers.

    * Base58: `TXYZabc123...` (what you see on explorers)
    * Hex: `0x41abc123...` (what Codex requires)

    Convert between formats using: [https://tronweb.network/docu/docs/API%20List/utils/address/](https://tronweb.network/docu/docs/API%20List/utils/address/)
  </Accordion>

  <Accordion title="Native tokens (ETH, SOL, BNB) — which address to use?">
    Codex uses the **wrapped** versions of native tokens (WETH, WSOL, WBNB). Prices are 1:1 with the native token. Use the wrapped token address in your queries.
  </Accordion>
</AccordionGroup>

## Still Stuck?

* Test your queries in the [explorer](https://explorer.codex.io) — it has autocomplete and will show validation errors instantly
* Browse the [GraphQL Reference](/api-reference/introduction) for exact field names and types
* Check the [FAQ](/extra/faq) for questions about data coverage and best practices
* Ask on [Discord](https://discord.gg/9ZB7zcWuBY) — the team and community are active
