Skip to main content
Can’t find your issue here? Try our integrated AI assistant at the top of the page, or reach out on Discord.

Authentication Errors

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
  • If using the SDK, ensure you’re passing the key correctly: new Codex("your-api-key")
// 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..." }
})
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.
  • 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
  • If using a short-lived token, it may have expired — generate a new one with createApiTokens

WebSocket & Subscription Errors

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
// Correct — auth in connection_init payload
const client = createClient({
  url: "wss://graph.codex.io/graphql",
  connectionParams: {
    Authorization: "your-api-key",
  },
});
You’re sending a subscribe message before the server has acknowledged your connection. You must wait for the connection_ack message before subscribing.
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 or graphql-ws, this is handled automatically.
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 for details
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
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 for more details.

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.
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
# Filter for verified tokens
filterTokens(filters: { isVerified: true }) {
  results {
    token {
      name
      isScam  # false = verified
    }
  }
}
See the FAQ for more details.
This means the field doesn’t exist on the type. Common mistakes:
You wroteFix
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 which has autocomplete to discover available fields, or browse the GraphQL Reference.
Some fields use input (singular) while others use inputs (plural). Check the exact parameter name in the API reference.Common ones:
  • onPricesUpdated uses input (singular) containing a list of tokens
  • getTokenPrices uses inputs (plural)
  • token uses input (singular)
filterTokenWallets does not support a rankings argument. It uses filters and pagination parameters (cursor, limit). Only filterTokens and filterPairs support rankings.
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.
# 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 }
}
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 first to verify the syntax is correct before using it in code.

Null or Empty Results

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
  • Filters too narrow — loosen your filters and add them back one at a time to identify which one is excluding results
  • Launchpad graduation filterslaunchpadGraduationPercent 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
  • 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
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.
  • 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
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.

Connection Limits & Rate Limits

  • Growth plans: 300 concurrent WebSocket connections
  • Enterprise plans: No hard limit — contact the team if you need guidance
Each connection can handle multiple subscriptions (~25 recommended per connection). So 300 connections with 25 subscriptions each = up to 7,500 concurrent subscriptions.The limit is per account, not per API key.
  • 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 for full details.
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.
Rate limits depend on your plan. If you’re hitting rate limits:
  • Batch requests where possible (e.g., getTokenPrices accepts multiple tokens)
  • Cache responses that don’t change frequently (token metadata, social links)
  • Use subscriptions instead of polling for real-time data
  • Contact the team on Discord for custom rate limits if needed

Data Discrepancies

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.
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.
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/
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.

Still Stuck?

  • Test your queries in the explorer — it has autocomplete and will show validation errors instantly
  • Browse the GraphQL Reference for exact field names and types
  • Check the FAQ for questions about data coverage and best practices
  • Ask on Discord — the team and community are active