@clawhub-nealo-ba9d6b8871
Use when the user wants to query the Codex Supergraph and the server returns a 402 challenge. Pays per query via the MPP 402 challenge flow. Only supports qu...
---
name: codex-gateway
description: >-
Use when the user wants to query the Codex Supergraph and the server returns
a 402 challenge. Pays per query via the MPP 402 challenge flow. Only supports
queries, not mutations or subscriptions.
metadata:
author: codex-data
version: "1.0"
---
# Codex Machine Payment Protocol (MPP)
Use this skill when the Codex Supergraph returns a `402 Payment Required` response. The MPP challenge flow lets you pay per query without needing an API key.
| | |
| --------------------- | --------------------------------------------------------------- |
| HTTP endpoint | `https://graph.codex.io/graphql` |
| Credential header | `Authorization: Payment <base64url-credential>` |
## How it works
1. Send a GraphQL query (no credential).
2. Server returns `402 Payment Required` with `WWW-Authenticate: Payment ...` challenges.
3. Client solves one challenge and retries with `Authorization: Payment <credential>`.
4. Server returns GraphQL data + `Payment-Receipt` header.
## Constraints
- **Query only.** Mutations and subscriptions return `403` in MPP mode.
- If a valid API key or bearer token is also present, API auth takes precedence.
## Rules
- Never print raw credentials.
- Only use MPP for `query` operations.
- **Before constructing any query**, read `references/query-templates.md` below for the correct GraphQL schema. Do not guess query or field names.
## References
| File | Purpose |
| ---- | ------- |
| [../codex-supergraph/references/query-templates.md](../codex-supergraph/references/query-templates.md) | **GraphQL query schema and examples — read before constructing queries** |
| [../codex-supergraph/references/gotchas.md](../codex-supergraph/references/gotchas.md) | Common query failure points |
| [references/gotchas.md](references/gotchas.md) | MPP-specific failure points |
| [rules/wallets.md](rules/wallets.md) | Wallet setup: tempo wallet/request (Tempo) |
| [references/mpp-flow.md](references/mpp-flow.md) | Auth matrix, challenge details, error codes |
FILE:rules/wallets.md
# Wallet Reference
The 402 challenge flow requires a funded wallet to sign payment credentials. Which tool to use depends on the network the challenge specifies.
| Network | Tool | Auth method | Currency |
| ------- | ---- | ----------- | -------- |
| Tempo (chain 4217) | `tempo` (`wallet` + `request` extensions) | Passkey via `tempo wallet login` | USDC |
Pick the tool that matches the network in the `WWW-Authenticate` challenge, then follow the corresponding section below.
---
## Tempo — tempo wallet / tempo request
`tempo` is the Tempo CLI. The `wallet` extension manages identity and funding; the `request` extension is an HTTP client that handles the full MPP 402-challenge flow automatically — it detects the challenge, signs a Tempo transaction, and retries the request in one step.
### Install
```bash
curl -fsSL https://tempo.xyz/install | bash
tempo add wallet
```
### Setup
```bash
tempo wallet login
```
This opens a passkey-based auth flow. No private keys to manage.
### Preflight check
```bash
tempo wallet -t whoami
```
Confirm `ready` is `true` and `balance.available` has sufficient USDC before making paid requests.
### Making a paid request
`tempo request` handles the 402 challenge and payment automatically:
```bash
tempo request -t -X POST \
-H "Content-Type: application/json" \
--json '{"query":"query { getNetworks { id name } }"}' \
https://graph.codex.io/graphql
```
### Session management
Sessions open a payment channel on-chain once, then use off-chain vouchers for subsequent requests (no gas per request):
```bash
tempo wallet -t sessions list # view active sessions
tempo wallet -t sessions close --all # close all sessions when done
```
### Recovery
| Symptom | Action |
| ------- | ------ |
| `No wallet configured` | Run `tempo wallet login` |
| `Insufficient balance` | Tell the user — wallet needs funding |
| `Spending limit exceeded` | Tell the user — key limit reached |
---
## Rules
- **Never print, log, or read private keys.** Tools handle key management internally.
- **Always run a preflight check** before attempting paid requests.
- **If auth fails, fix it automatically** — run `tempo wallet login` as appropriate, then retry.
- **Do not mix tools.** Use tempo for Tempo challenges.
FILE:references/gotchas.md
# Codex MPP Gotchas
Common failure points when using the MPP payment flow.
## Mutations and subscriptions are not supported
MPP only works for `query` operations. Sending a mutation or subscription returns `403`. Use API key auth for those.
## API key takes precedence
If an `Authorization` header with an API key is present, the server uses API key auth and skips the payment flow. Don't mix them.
## Challenges expire
A `WWW-Authenticate` challenge is single-use and short-lived. If you get `invalid-challenge` on retry, request a fresh challenge by repeating the initial request.
## Credential encoding
The credential in `Authorization: Payment <credential>` must be base64url-encoded, not standard base64. A `malformed-credential` error usually means wrong encoding or broken JSON.
## `tempo request` handles the flow automatically
If the user has the Tempo CLI installed, `tempo request` handles the full 402 challenge/payment/retry cycle in one command. Don't manually implement the flow when `tempo request` is available.
## Check wallet balance before making requests
Both `tempo wallet -t whoami` should be run before paid requests. An insufficient balance mid-flow produces confusing errors.
FILE:references/mpp-flow.md
# MPP Auth Flow Reference
## Auth matrix (MPP mode)
| Mode | Headers | Supports | Notes |
| ---- | ------- | -------- | ----- |
| MPP | `Authorization: Payment <credential>` | query only | `402` challenge/credential flow |
## Details
- Initial unpaid query returns `402` with multiple `WWW-Authenticate: Payment ...` challenges.
- Retry with `Authorization: Payment <credential>`.
- Success returns GraphQL data + `Payment-Receipt`.
- Mutation/subscription in MPP mode returns `403`.
- Valid API key/bearer auth takes precedence over the payment flow.
## Common failures
| Symptom | Likely cause | Fix |
| ------- | ------------ | --- |
| 402 + `WWW-Authenticate` | MPP challenge required | Solve one challenge and retry with `Authorization: Payment ...` |
| 402 + `malformed-credential` | Bad base64url or JSON credential | Rebuild credential payload |
| 402 + `invalid-challenge` | Unknown/expired/used challenge | Re-request and solve a fresh challenge |
| 402 + `verification-failed` | Payment proof rejected | Recreate proof for the returned challenge |
| 403 in MPP mode | Mutation or subscription attempt | Use API key/bearer auth for non-query operations |
Use when the user asks about token prices, charts, holders, trending tokens, pair data, prediction markets, or any on-chain analytics from Codex. Also use wh...
---
name: codex-supergraph
description: >-
Use when the user asks about token prices, charts, holders, trending tokens,
pair data, prediction markets, or any on-chain analytics from Codex.
Also use when building GraphQL queries against https://graph.codex.io/graphql.
TRIGGERS: token price, token chart, trending tokens, pair data, holders,
prediction markets, Polymarket, Kalshi, event odds, prediction event,
prediction traders, trader leaderboard, trader PnL, prediction charts,
outcome probability, open interest, prediction categories, betting markets,
market resolution, prediction positions, prediction trades
metadata:
author: codex-data
version: "1.0"
---
# Codex Supergraph Data
## Authentication
Pass `$CODEX_API_KEY` in the `Authorization` header if available. If the server returns `402 Payment Required`, use the codex-gateway skill to handle the payment flow.
If both a local and global copy of this skill exist, the local copy takes precedence.
## Summary
Use this skill to produce valid Codex GraphQL requests using API key authentication.
| | |
| --------------------- | --------------------------------------------------------------- |
| HTTP endpoint | `https://graph.codex.io/graphql` |
| WebSocket endpoint | `wss://graph.codex.io/graphql` |
| Schema (SDL) | `https://graph.codex.io/schema/latest.graphql` |
| Introspection JSON | `https://graph.codex.io/schema/latest.json` |
| API-key auth | `Authorization: <key>` or `Authorization: Bearer <token>` |
## Session preflight (required)
Run once and cache:
```bash
curl -sS https://graph.codex.io/graphql \
-H "Content-Type: application/json" \
-H "Authorization: $CODEX_API_KEY" \
--data-binary '{"query":"query GetNetworks { getNetworks { id name } }"}'
```
Use network IDs from this result before expensive requests.
## Operation selection
| Need | Operation |
| ---- | --------- |
| Networks | `getNetworks` |
| Token discovery/search | `filterTokens` |
| Trending tokens | `filterTokens` with `trendingScore24` ranking |
| Token prices | `getTokenPrices` |
| Pairs for a token | `listPairsWithMetadataForToken` |
| Pair metadata | `pairMetadata` |
| Pair OHLCV | `getBars` |
| Token OHLCV | `getTokenBars` |
| Token events | `getTokenEvents` |
| Maker events | `getTokenEventsForMaker` |
| Wallet leaders | `filterTokenWallets` |
| Wallet chart/stats | `walletChart`, `detailedWalletStats` |
| Holders | `holders` |
| Top-10 concentration | `top10HoldersPercent` |
| Live single price | `onPriceUpdated` |
| Live multi-price | `onPricesUpdated` |
| Live token events | `onTokenEventsCreated`, `onEventsCreatedByMaker` |
| Live bars/pairs | `onBarsUpdated`, `onPairMetadataUpdated`, `onTokenBarsUpdated` |
| Launchpad streams | `onLaunchpadTokenEventBatch`, `onLaunchpadTokenEvent` |
| Unconfirmed Solana events | `onUnconfirmedEventsCreated` |
| Short-lived keys | `createApiTokens`, `apiTokens`, `apiToken`, `deleteApiToken` |
| Prediction event discovery | `filterPredictionEvents` |
| Prediction market discovery | `filterPredictionMarkets` |
| Prediction event detail | `detailedPredictionEventStats` |
| Prediction market chart | `predictionMarketBars` |
| Prediction multi-market chart | `predictionEventTopMarketsBars` |
| Prediction event chart | `predictionEventBars` |
| Prediction trades | `predictionTrades` |
| Prediction token holders | `predictionTokenHolders` |
| Prediction categories | `predictionCategories` |
| Prediction trader leaderboard | `filterPredictionTraders` |
| Prediction trader profile | `detailedPredictionTraderStats` |
| Prediction trader positions | `filterPredictionTraderMarkets` |
| Prediction trader chart | `predictionTraderBars` |
Default discovery path: start with `filterTokens`.
## Rules
- Never print raw API keys.
- Validate `networkId` first.
- Keep selection sets minimal until shape is confirmed.
- Use `onPricesUpdated` instead of many single-token subscriptions.
## References
| File | Purpose |
| ---- | ------- |
| [references/gotchas.md](references/gotchas.md) | Common failure points — check here first |
| [references/query-templates.md](references/query-templates.md) | Query + websocket templates with examples |
| [references/endpoint-playbook.md](references/endpoint-playbook.md) | Operation selection heuristics by intent |
| [references/apis.md](references/apis.md) | Endpoint/auth matrix, pagination, rate limits |
| [references/prediction-markets.md](references/prediction-markets.md) | Prediction market queries — events, markets, traders, charts |
| [references/tooling-and-mcp.md](references/tooling-and-mcp.md) | Codex Docs MCP setup for coding tools |
FILE:references/gotchas.md
# Codex Supergraph Gotchas
Common failure points. Check here first when a query returns unexpected results.
## Validate against the schema on 400 errors
If a query returns a 400 or GraphQL validation error, fetch the latest schema and check your query against it:
```
https://graph.codex.io/schema/latest.graphql
```
Field names, input shapes, and argument structures change over time. Don't guess — validate.
## Input objects vs flat args
Many queries wrap their arguments in an `input` or `query` object rather than accepting flat args. Common examples:
- `getTokenEvents` takes `query: EventsQueryInput!` (not flat `address`/`networkId`)
- `getTokenEventsForMaker` takes `query: MakerEventsQueryInput!` (not flat `maker`/`address`)
- `filterTokenWallets` takes `input: FilterTokenWalletsInput!`
- `walletChart` takes `input: WalletChartInput!` (with `range: { start, end }`, not `from`/`to`)
- `holders` takes `input: HoldersInput!`
If you get a validation error about missing required args, check whether the schema expects an input wrapper.
## Composite ID formats
Several operations use `address:networkId` composite IDs:
- `getBars` / `getTokenBars`: `symbol` is `pairAddress:networkId`
- `pairMetadata`: `pairId` is `pairAddress:networkId`
- `top10HoldersPercent`: `tokenId` is `tokenAddress:networkId`
- `filterTokenWallets`: `tokenIds` array uses `tokenAddress:networkId`
## `trendingScore24` is a sort attribute, not a field
You can rank by `trendingScore24` in `filterTokens` rankings, but it is not a selectable field on the result type. Don't include it in the selection set.
## `filterTokens` pagination
Max 200 results per call. Use `offset` as an input arg to paginate. The response returns `page` (not `offset`) and `count`.
## `filterTokens` trending queries need `statsType`
When ranking by `trendingScore24`, set `statsType: "FILTERED"` or you'll get zero/null scores. Also use `trendingIgnored: false` and `potentialScam: false` in filters to exclude noise.
## `Event` type has no `priceUsd` field
The `Event` type does not have a `priceUsd` field. Use `token0SwapValueUsd` and `token1SwapValueUsd` for USD values, or `token0ValueBase` and `token1ValueBase` for base token values.
## `holders` response uses `items`, not `holders`
The `HoldersResponse` type returns the holder list in `items`, not a `holders` field. Each `Balance` object has `address`, `balance`, `shiftedBalance`, `balanceUsd` — there is no `sharedPct` field.
## `listPairsWithMetadataForToken` field names
The result type uses `volume` (not `volume24`) and does not have a `price` field.
## `getBars` missing timestamps
Always include `t` in the selection set. Without it the bars are unplottable. The fields are `t o h l c volume`.
## `getBars` max datapoints
Max 1500 datapoints per request. Narrow the time window or increase the resolution if you hit the limit.
## `networkId` validation
Always validate `networkId` against `getNetworks` before using it. A wrong ID returns empty results, not an error. Common IDs: Ethereum=`1`, Solana=`1399811149`, Base=`8453`.
## Subscription fan-out
Use `onPricesUpdated` (batch) instead of opening many `onPriceUpdated` (single) subscriptions. Batch input supports ~25 tokens per subscription.
## Rate limits return 429, not GraphQL errors
Rate limit responses are HTTP 429, not wrapped in GraphQL `errors`. Check the HTTP status, not just the response body.
## Short-lived tokens can't manage themselves
`apiTokens`, `apiToken`, and `deleteApiToken` are not available when authenticated with a short-lived token. Use the long-lived API key for token management.
## Prediction market `bestAskCT` is the implied probability
For stablecoin-collateral markets, `bestAskCT` of 0.65 means 65% implied probability. Prefer CT (Collateral Token) values over USD values.
## Prediction trader ID format
Trader IDs use the format `address:Protocol` (e.g., `0x1234...:Polymarket`). Missing the protocol suffix will return no results.
## Prediction OHLC values are strings
All OHLC fields (`o`, `h`, `l`, `c`) in prediction market bars are strings, not numbers. Parse them to floats before rendering. Timestamps are unix seconds — multiply by 1000 for JavaScript milliseconds.
## `predictionEventBars` has no per-outcome prices
`predictionEventBars` only returns aggregated volume, liquidity, and open interest. For per-outcome price data, use `predictionMarketBars` or `predictionEventTopMarketsBars`.
## `filterPredictionEvents` vs `filterPredictionMarkets`
Events are containers grouping related markets. Use `filterPredictionEvents` for discovery, then `filterPredictionMarkets(eventIds)` for market-level pricing within an event.
## `competitiveScore24h` is markets-only
`competitiveScore24h` is available on `filterPredictionMarkets` but not on `filterPredictionEvents`. It measures how close the outcome prices are.
FILE:references/apis.md
# Codex Supergraph API Reference
## Endpoint model
- HTTP GraphQL: `https://graph.codex.io/graphql`
- WebSocket GraphQL: `wss://graph.codex.io/graphql`
## Auth matrix
| Mode | Headers | Supports | Notes |
| ---- | ------- | -------- | ----- |
| API key | `Authorization: <key>` | query, mutation, subscription | Standard path |
| Short-lived token | `Authorization: Bearer <token>` | query, mutation, subscription | Token-scoped limits |
## Common network IDs
| Network | `networkId` |
| ------- | ----------- |
| Ethereum | `1` |
| Base | `8453` |
| Arbitrum | `42161` |
| Polygon | `137` |
| Tempo | `4217` |
| Optimism | `10` |
| BNB Chain | `56` |
| Avalanche | `43114` |
| Solana | `1399811149` |
Run `getNetworks` once per session for the full list.
## Session preflight
```graphql
query GetNetworks {
getNetworks {
id
name
}
}
```
Use to validate `networkId` before price/event/chart requests.
## Operation matrix
| Task | Operation | Type | Notes |
| ---- | --------- | ---- | ----- |
| Network list | `getNetworks` | Query | Run once per session |
| Discover/search tokens | `filterTokens` | Query | Recommended first step |
| Snapshot token prices | `getTokenPrices` | Query | Weighted price output |
| Pair metadata/stats | `pairMetadata` | Query | Pair id: `pairAddress:networkId` |
| Pair bars (OHLCV) | `getBars` | Query | Keep datapoints bounded |
| Token bars | `getTokenBars` | Query | Aggregate bars |
| Token events | `getTokenEvents` | Query | Historical stream |
| Maker events | `getTokenEventsForMaker` | Query | Wallet scoped |
| Holders | `holders` | Query | Distribution views |
| Top holder concentration | `top10HoldersPercent` | Query | Concentration metric |
| Live token price | `onPriceUpdated` | Subscription | Single token |
| Live token prices | `onPricesUpdated` | Subscription | Multi token batch |
| Live pair stats | `onPairMetadataUpdated` | Subscription | Pair updates |
| Live bars | `onBarsUpdated`, `onTokenBarsUpdated` | Subscription | Chart updates |
| Create short-lived tokens | `createApiTokens` | Mutation | Needs long-lived key |
| Manage short-lived tokens | `apiTokens`, `apiToken`, `deleteApiToken` | Query/Mutation | Not available from short-lived token |
## WebSocket constraints
- Protocol: `graphql-transport-ws`
- Send `connection_init` with `Authorization` in payload
- Wait for `connection_ack`
- Unsubscribe with `complete`
## Common failures
| Symptom | Likely cause | Fix |
| ------- | ------------ | --- |
| 401 / UNAUTHENTICATED | Missing or invalid API auth | Validate key/token and header format |
| 429 / Too Many Requests | Rate limit exceeded | Back off with exponential delay and retry |
| GraphQL validation error | Input shape mismatch | Check operation args and variable types |
See [gotchas.md](gotchas.md) for detailed failure patterns (symbol formats, pagination, rate limits, etc.).
FILE:references/query-templates.md
# Codex Supergraph Query Templates
## 1) Simple query
```bash
curl -sS https://graph.codex.io/graphql \
-H 'Content-Type: application/json' \
-H "Authorization: $CODEX_API_KEY" \
--data-binary @- <<'JSON'
{
"query": "query GetNetworks { getNetworks { id name } }"
}
JSON
```
## 2) Query with variables
```bash
curl -sS https://graph.codex.io/graphql \
-H 'Content-Type: application/json' \
-H "Authorization: $CODEX_API_KEY" \
--data-binary @- <<'JSON'
{
"query": "query GetTokenPrices($inputs: [GetPriceInput!]!) { getTokenPrices(inputs: $inputs) { address networkId priceUsd timestamp } }",
"variables": {
"inputs": [
{ "address": "So11111111111111111111111111111111111111112", "networkId": 1399811149 }
]
}
}
JSON
```
## 3) Token discovery (`filterTokens`)
```graphql
query FilterTokens(
$filters: TokenFilters
$statsType: TokenPairStatisticsType
$rankings: [TokenRanking]
$limit: Int
$offset: Int
) {
filterTokens(
filters: $filters
statsType: $statsType
rankings: $rankings
limit: $limit
offset: $offset
) {
count
page
results {
priceUSD
marketCap
buyVolume24
sellVolume24
volume24
circulatingMarketCap
liquidity
txnCount24
holders
token {
info {
address
name
symbol
networkId
}
}
}
}
}
```
Example variables — top tokens on Solana by volume:
```json
{
"filters": {
"network": [1399811149],
"liquidity": { "gte": 10000 }
},
"rankings": [{ "attribute": "volume24", "direction": "DESC" }],
"limit": 25,
"offset": 0
}
```
Example variables — trending tokens:
```json
{
"filters": {
"volume24": { "lte": 100000000000 },
"liquidity": { "lte": 1000000000 },
"marketCap": { "gte": 500000, "lte": 1000000000000 },
"trendingIgnored": false,
"creatorAddress": null,
"potentialScam": false
},
"statsType": "FILTERED",
"rankings": [{ "attribute": "trendingScore24", "direction": "DESC" }],
"limit": 50,
"offset": 0
}
```
Note: `trendingScore24` is a valid ranking attribute but is not a selectable field on the result type. Sort by it, but don't request it in the selection set.
## 4) Pair metadata (`pairMetadata`)
```graphql
query PairMetadata($pairId: String!) {
pairMetadata(pairId: $pairId) {
id
pairAddress
networkId
liquidity
price
priceChange24
volume24
token0 {
address
symbol
name
}
token1 {
address
symbol
name
}
}
}
```
## 5) Pair bars (`getBars`)
```graphql
query GetBars(
$symbol: String!
$from: Int!
$to: Int!
$resolution: String!
$countback: Int
$removeEmptyBars: Boolean
) {
getBars(
symbol: $symbol
from: $from
to: $to
resolution: $resolution
countback: $countback
removeEmptyBars: $removeEmptyBars
) {
t
o
h
l
c
volume
}
}
```
## 6) Single-token realtime (`onPriceUpdated`)
```graphql
subscription OnPriceUpdated($address: String!, $networkId: Int!) {
onPriceUpdated(address: $address, networkId: $networkId) {
address
networkId
priceUsd
timestamp
blockNumber
}
}
```
## 7) Multi-token realtime (`onPricesUpdated`)
```graphql
subscription OnPricesUpdated($input: [OnPricesUpdatedInput!]!) {
onPricesUpdated(input: $input) {
address
networkId
priceUsd
timestamp
blockNumber
}
}
```
Example variables:
```json
{
"input": [
{ "address": "So11111111111111111111111111111111111111112", "networkId": 1399811149 },
{ "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "networkId": 1 }
]
}
```
## 8) Token bars (`getTokenBars`)
Aggregates OHLCV across top liquidity pairs for a token. Uses same `resolution` values as `getBars`.
```graphql
query GetTokenBars(
$symbol: String!
$from: Int!
$to: Int!
$resolution: String!
$countback: Int
$removeEmptyBars: Boolean
) {
getTokenBars(
symbol: $symbol
from: $from
to: $to
resolution: $resolution
countback: $countback
removeEmptyBars: $removeEmptyBars
) {
t
o
h
l
c
volume
}
}
```
## 9) List pairs for a token (`listPairsWithMetadataForToken`)
```graphql
query ListPairs($tokenAddress: String!, $networkId: Int!) {
listPairsWithMetadataForToken(tokenAddress: $tokenAddress, networkId: $networkId) {
results {
pair {
address
networkId
token0
token1
}
volume
liquidity
}
}
}
```
## 10) Token events (`getTokenEvents`)
```graphql
query GetTokenEvents(
$query: EventsQueryInput!
$cursor: String
$limit: Int
) {
getTokenEvents(
query: $query
cursor: $cursor
limit: $limit
) {
cursor
items {
timestamp
eventType
token0SwapValueUsd
token1SwapValueUsd
token0ValueBase
token1ValueBase
maker
transactionHash
}
}
}
```
Example variables:
```json
{
"query": {
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"networkId": 1
},
"limit": 25
}
```
## 11) Maker events (`getTokenEventsForMaker`)
```graphql
query GetTokenEventsForMaker(
$query: MakerEventsQueryInput!
$cursor: String
$limit: Int
) {
getTokenEventsForMaker(
query: $query
cursor: $cursor
limit: $limit
) {
cursor
items {
timestamp
eventType
token0SwapValueUsd
token1SwapValueUsd
token0ValueBase
token1ValueBase
transactionHash
}
}
}
```
Example variables:
```json
{
"query": {
"maker": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"networkId": 1,
"tokenAddress": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
},
"limit": 25
}
```
## 12) Holders (`holders`)
```graphql
query Holders($input: HoldersInput!) {
holders(input: $input) {
cursor
count
top10HoldersPercent
items {
address
balance
shiftedBalance
balanceUsd
}
}
}
```
## 13) Top-10 holder concentration (`top10HoldersPercent`)
The `tokenId` is a composite ID in `address:networkId` format.
```graphql
query Top10HoldersPercent($tokenId: String!) {
top10HoldersPercent(tokenId: $tokenId)
}
```
Example variables:
```json
{
"tokenId": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2:1"
}
```
## 14) Wallet leaders (`filterTokenWallets`)
```graphql
query FilterTokenWallets($input: FilterTokenWalletsInput!) {
filterTokenWallets(input: $input) {
results {
address
tokenAddress
networkId
amountBoughtUsd1d
amountSoldUsd1d
realizedProfitUsd1d
realizedProfitPercentage1d
buys1d
sells1d
labels
}
}
}
```
Example variables:
```json
{
"input": {
"tokenIds": ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2:1"],
"limit": 25
}
}
```
## 15) Wallet chart (`walletChart`)
```graphql
query WalletChart($input: WalletChartInput!) {
walletChart(input: $input) {
walletAddress
networkId
resolution
data {
timestamp
volumeUsd
realizedProfitUsd
swaps
}
}
}
```
Example variables:
```json
{
"input": {
"walletAddress": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"networkId": 1,
"range": { "start": 1710000000, "end": 1710600000 },
"resolution": "1D"
}
}
```
## 16) WebSocket client (`graphql-ws`)
```typescript
import { createClient } from "graphql-ws";
const client = createClient({
url: "wss://graph.codex.io/graphql",
connectionParams: {
Authorization: process.env.CODEX_API_KEY!,
},
});
const unsubscribe = client.subscribe(
{
query: `
subscription OnPriceUpdated($address: String!, $networkId: Int!) {
onPriceUpdated(address: $address, networkId: $networkId) {
address
networkId
priceUsd
timestamp
blockNumber
}
}
`,
variables: {
address: "So11111111111111111111111111111111111111112",
networkId: 1399811149,
},
},
{
next: (msg) => console.log(msg),
error: (err) => console.error(err),
complete: () => console.log("done"),
}
);
```
FILE:references/endpoint-playbook.md
# Codex Supergraph Endpoint Playbook
Use this map to pick the best operation quickly.
## Discovery and search
| Intent | Preferred query | Notes |
| --- | --- | --- |
| Discover tradable tokens with ranking/filtering | `filterTokens` | Supports phrase search and quality filters; response limit 200. |
| Trending tokens | `filterTokens` | Rank by `trendingScore24` DESC with `statsType: "FILTERED"`. Use `trendingIgnored: false` and `potentialScam: false` filters to exclude noise. |
| Find pairs for a token | `listPairsWithMetadataForToken` | Useful before charting or pair-specific metadata. |
| Find wallet leaders for a token | `filterTokenWallets` | Good for holder quality and top-wallet analysis. |
## Pricing and charts
| Intent | Preferred query | Preferred subscription | Notes |
| --- | --- | --- | --- |
| Get fast current or historical token price snapshots | `getTokenPrices` | `onPriceUpdated` (single token) | Uses aggregate weighted prices unless source pair is provided. |
| Stream prices for many tokens | N/A | `onPricesUpdated` | Batch token inputs in one subscription; start around 25 tokens. |
| Build pair chart candles | `getBars` | `onBarsUpdated` | `getBars` max datapoints is 1500 per request. |
| Build aggregate token chart candles | `getTokenBars` | `onTokenBarsUpdated` | Aggregates across top liquidity pairs. |
| Fetch pair metrics and stat windows | `pairMetadata` | `onPairMetadataUpdated` | Use query for initial load, subscription for live refresh. |
## Events and flows
| Intent | Preferred query | Preferred subscription | Notes |
| --- | --- | --- | --- |
| Fetch token transactions | `getTokenEvents` | `onTokenEventsCreated` | Choose subscription for live feeds. |
| Fetch maker-specific activity | `getTokenEventsForMaker` | `onEventsCreatedByMaker` | Use maker address filters. |
| Track unconfirmed Solana events | N/A | `onUnconfirmedEventsCreated` | Solana-focused unconfirmed flow. |
## Wallet analytics
| Intent | Preferred query | Notes |
| --- | --- | --- |
| Wallet-level chart and performance data | `walletChart`, `detailedWalletStats` | Use date windows and aggregation granularity intentionally. |
| Holder distribution | `holders`, `top10HoldersPercent` | Combine with token metadata for context. |
## Launchpads and high-throughput streams
| Intent | Preferred subscription | Notes |
| --- | --- | --- |
| Launchpad token event firehose | `onLaunchpadTokenEventBatch` | High-frequency stream; isolate connection and proxy through backend. |
| Per-event launchpad updates | `onLaunchpadTokenEvent` | Use when batch handling is not needed. |
## Prediction markets
| Intent | Preferred query | Notes |
| --- | --- | --- |
| Discover trending prediction events | `filterPredictionEvents` | Rank by `trendingScore24h`, `relevanceScore24h`, or `volumeUsd24h`. Filter by `protocol`, `status`, `categories`. |
| Search prediction events by keyword | `filterPredictionEvents` | Use `phrase` parameter. |
| Discover/filter individual markets | `filterPredictionMarkets` | Rank by `competitiveScore24h`, outcome attributes, or `openInterestUsd`. Filter by `eventIds`, `status`, `closesAt`. |
| Prediction event detail page | `detailedPredictionEventStats` | Full metadata, markets list, windowed stats, lifecycle. |
| Event market pricing | `filterPredictionMarkets` | Filter by `eventIds`, rank by `outcome0.bestAskCT` for probability sort. |
| Single market OHLC chart | `predictionMarketBars` | Per-outcome price, bid/ask, volume, OI. Resolutions: min1 through week1. |
| Multi-market probability comparison | `predictionEventTopMarketsBars` | Up to 10 markets in one request. Plot `outcome0.priceCollateralToken.c` per market. |
| Event volume/liquidity/OI chart | `predictionEventBars` | Aggregated across all markets in the event. No per-outcome price data. |
| Prediction trades | `predictionTrades` | Filter by `eventId`, `marketId`, or `traderId`. Cursor-paginated. |
| Outcome token holders | `predictionTokenHolders` | Requires `marketId` and `tokenId`. |
| Prediction categories | `predictionCategories` | Fetch once and cache. Use `slug` for filtering. |
| Trader leaderboard | `filterPredictionTraders` | Rank by profit, win rate, PnL. Filter by volume floors. Search by `phrase`. |
| Trader profile and stats | `detailedPredictionTraderStats` | All-time and windowed stats (statsHour1 through statsDay30). |
| Trader positions | `filterPredictionTraderMarkets` | Bidirectional: by `traderIds` for portfolio, by `marketIds`/`eventIds` for top traders. |
| Trader performance chart | `predictionTraderBars` | Plot `cumulativeRealizedPnlCT` for P&L curve. |
## Auth and token management
| Intent | Preferred mutation/query | Notes |
| --- | --- | --- |
| Create short-lived API tokens | `createApiTokens` | Use long-lived key for creation. |
| List existing API tokens | `apiTokens` | Not available with short-lived keys. |
| Revoke API token | `deleteApiToken` | Use server-side secret key context. |
## Selection heuristics
- Prefer one-shot queries for initial page hydration.
- Add subscriptions only where visible realtime UX exists.
- Choose aggregated endpoints when user intent is token-level, not pool-level.
- Keep fields minimal for first pass; expand only after payload shape is verified.
FILE:references/tooling-and-mcp.md
# Codex Docs Tooling and MCP Setup
Use this when users ask to connect coding assistants to Codex documentation.
## Codex Docs MCP server
MCP URL:
```text
https://docs.codex.io/mcp
```
This MCP server supports documentation search and API guidance. It does not execute Codex API queries directly.
## Cursor
Add to MCP settings:
```json
{
"mcpServers": {
"codex-docs": {
"url": "https://docs.codex.io/mcp"
}
}
}
```
## VS Code
Create `.vscode/mcp.json`:
```json
{
"servers": {
"codex-docs": {
"type": "http",
"url": "https://docs.codex.io/mcp"
}
}
}
```
## Claude Code
```bash
claude mcp add --transport http codex-docs https://docs.codex.io/mcp
```
## Windsurf
Add to `~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"codex-docs": {
"serverUrl": "https://docs.codex.io/mcp"
}
}
}
```
## SDK quick start
```bash
pnpm add @codex-data/sdk
```
```typescript
import { Codex } from "@codex-data/sdk";
const sdk = new Codex(process.env.CODEX_API_KEY!);
```
Use SDK for quick TypeScript integration and built-in subscription handling. Use raw GraphQL for maximum protocol control.
FILE:references/prediction-markets.md
# Prediction Markets
Query templates for prediction market events, markets, traders, and charts.
## Concepts
- **Event**: A container grouping related markets (e.g., "2024 Presidential Election").
- **Market**: An individual binary question within an event (e.g., "Will candidate X win?").
- **Outcome**: Each market has two outcomes (`outcome0`, `outcome1`). `bestAskCT` is the implied probability (0.65 = 65% chance).
- **Collateral Token (CT)**: Prefer CT values over USD for stablecoin-collateral markets since collateral is usually a stablecoin.
- **Trader ID format**: `address:Protocol` (e.g., `0x1234...:Polymarket`).
- **Protocols**: `POLYMARKET`, `KALSHI`.
## 1) Discover prediction market categories
Fetch once and cache. Use `slug` values when filtering events or markets.
```graphql
query PredictionCategories {
predictionCategories {
name
slug
subcategories {
name
slug
subcategories {
name
slug
}
}
}
}
```
## 2) Discover trending events
```graphql
query TrendingEvents {
filterPredictionEvents(
filters: { protocol: [POLYMARKET], status: [OPEN] }
rankings: [{ attribute: trendingScore24h, direction: DESC }]
limit: 20
) {
count
page
results {
id
event {
id
protocol
status
slug
question
description
imageThumbUrl
venueUrl
closesAt
resolvesAt
}
status
markets { id label }
marketCount
categories
trendingScore24h
relevanceScore24h
liquidityUsd
openInterestUsd
volumeUsd24h
volumeChange24h
trades24h
uniqueTraders24h
}
}
}
```
Filter by category with `categories: ["sports"]`. Search by keyword with `phrase: "election"`.
Scoring metrics:
- `trendingScore24h`: Volume + trades + momentum — "what's hot right now"
- `relevanceScore24h`: Factors in liquidity and market maturity — "most important"
- `competitiveScore24h`: Markets only (not events), measures outcome closeness
- All available at 5m, 1h, 4h, 12h, 24h, and 1w windows
## 3) Discover individual markets
```graphql
query CompetitiveMarkets {
filterPredictionMarkets(
filters: { status: [OPEN] }
rankings: [{ attribute: competitiveScore24h, direction: DESC }]
limit: 20
) {
count
results {
id
eventLabel
market {
id
eventId
protocol
label
question
imageThumbUrl
status
closesAt
}
status
outcome0 {
label
bestAskCT
bestBidCT
spreadCT
lastPriceCT
liquidityCT
volumeUsd24h
priceChange24h
}
outcome1 {
label
bestAskCT
bestBidCT
spreadCT
lastPriceCT
liquidityCT
volumeUsd24h
priceChange24h
}
competitiveScore24h
trendingScore24h
liquidityUsd
openInterestUsd
volumeUsd24h
trades24h
priceCompetitiveness
}
}
}
```
Markets within an event, ranked by probability:
```graphql
query EventMarkets {
filterPredictionMarkets(
eventIds: ["yourEventId"]
rankings: [{ outcome: outcome0, outcomeAttribute: bestAskCT, direction: DESC }]
limit: 50
) {
count
results {
id
market { id label question }
outcome0 {
label
bestAskCT
bestBidCT
lastPriceCT
volumeUsd24h
}
outcome1 {
label
bestAskCT
bestBidCT
lastPriceCT
volumeUsd24h
}
volumeUsdAll
liquidityUsd
openInterestUsd
}
}
}
```
High open-interest markets closing soon:
```graphql
query ClosingSoon {
filterPredictionMarkets(
filters: {
status: [OPEN]
closesAt: { lte: 1773700000 }
}
rankings: [{ attribute: openInterestUsd, direction: DESC }]
limit: 20
) {
count
results {
id
market { id label question closesAt resolvesAt }
outcome0 { label bestAskCT lastPriceCT }
outcome1 { label bestAskCT lastPriceCT }
openInterestUsd
liquidityUsd
volumeUsd24h
}
}
}
```
Sort dropdown mappings:
- "Trending" → `trendingScore24h` DESC
- "Most Volume" → `volumeUsd24h` DESC
- "Most Liquidity" → `liquidityUsd` DESC
- "Newest" → `age` ASC
- "Closing Soon" → `closesAt` ASC (with status OPEN filter)
- "Most Competitive" → `competitiveScore24h` DESC (markets only)
## 4) Detailed event stats (event detail page)
```graphql
query DetailedPredictionEventStats {
detailedPredictionEventStats(input: { eventId: "yourEventId" }) {
eventId
lastTransactionAt
predictionEvent {
id
protocol
venueEventId
status
question
url
rulesPrimary
rulesSecondary
tags
opensAt
closesAt
resolvesAt
resolvedAt
resolution { result source }
imageLargeUrl
imageThumbUrl
createdAt
updatedAt
networkId
marketIds
categories { name slug subcategories { name slug } }
}
predictionMarkets {
id
protocol
venueMarketId
eventId
question
label
eventLabel
outcomeLabels
outcomeIds
resolution { result source }
imageThumbUrl
createdAt
opensAt
closesAt
resolvesAt
resolvedAt
networkId
}
statsDay1 {
start
end
statsCurrency {
volumeUsd
volumeCT
openLiquidityUsd
closeLiquidityUsd
openOpenInterestUsd
closeOpenInterestUsd
}
statsNonCurrency { trades uniqueTraders }
statsChange { volumeChange openLiquidityChange openOpenInterestChange tradesChange uniqueTradersChange }
scores { trending relevance }
}
allTimeStats { volumeUsd volumeCT venueVolumeUsd venueVolumeCT }
lifecycle { ageSeconds expectedLifespanSeconds timeToResolutionSeconds isResolved }
}
}
```
## 5) Single market OHLC chart
Supported resolutions: `min1`, `min5`, `min15`, `min30`, `hour1`, `hour4`, `hour12`, `day1`, `week1`.
```graphql
query PredictionMarketBars {
predictionMarketBars(input: {
marketId: "yourMarketId"
from: 1773100000
to: 1773700000
resolution: hour1
}) {
marketId
predictionMarket {
id
label
question
outcomeLabels
eventLabel
}
bars {
t
volumeUsd
volumeCollateralToken
trades
uniqueTraders
openInterestUsd { o h l c }
outcome0 {
trades
buys
sells
volumeUsd
buyVolumeUsd
sellVolumeUsd
priceUsd { o h l c }
priceCollateralToken { o h l c }
liquidityCollateralToken { o h l c }
bidCollateralToken { o h l c }
askCollateralToken { o h l c }
}
outcome1 {
trades
buys
sells
volumeUsd
buyVolumeUsd
sellVolumeUsd
priceUsd { o h l c }
priceCollateralToken { o h l c }
liquidityCollateralToken { o h l c }
bidCollateralToken { o h l c }
askCollateralToken { o h l c }
}
}
}
}
```
Additional parameters: `countback` (last N bars from `to`), `removeEmptyBars` (skip inactive bars).
## 6) Multi-market probability comparison chart
Returns up to 10 markets' OHLC bars in one request. Plot `outcome0.priceCollateralToken.c` for each market as separate colored lines.
```graphql
query TopMarketsByVolume {
predictionEventTopMarketsBars(input: {
eventId: "yourEventId"
from: 1773100000
to: 1773700000
resolution: hour1
limit: 5
rankBy: volumeUsd1w
rankDirection: DESC
}) {
eventId
predictionEvent { id question }
marketBars {
marketId
predictionMarket {
id
label
outcomeLabels
}
bars {
t
outcome0 {
priceCollateralToken { o h l c }
volumeUsd
trades
}
outcome1 {
priceCollateralToken { o h l c }
}
openInterestUsd { o h l c }
volumeUsd
}
}
}
}
```
Ranking options: `rankBy` for market attributes, or `rankByOutcome` + `rankByOutcomeAttribute` for outcome-level sorting. The `marketIds` parameter overrides ranking.
## 7) Event-level aggregated chart
Does not include per-outcome price data. Use for volume, liquidity, and open interest charts.
```graphql
query PredictionEventBars {
predictionEventBars(input: {
eventId: "yourEventId"
from: 1773100000
to: 1773700000
resolution: day1
}) {
eventId
predictionEvent { id question marketIds }
bars {
t
volumeUsd
buyVolumeUsd
sellVolumeUsd
totalVolumeUsd
trades
uniqueTraders
liquidityUsd { o h l c }
openInterestUsd { o h l c }
}
}
}
```
## 8) Recent trades for an event
```graphql
query EventTrades {
predictionTrades(input: { eventId: "yourEventId", limit: 50 }) {
items {
marketId
outcomeId
protocol
tradeType
maker
traderId
timestamp
outcomeIndex
outcomeLabel
priceUsd
priceCollateral
amount
amountUsd
transactionHash
networkId
}
cursor
}
}
```
## 9) Outcome token holders
```graphql
query TokenHolders {
predictionTokenHolders(input: {
marketId: "yourMarketId"
tokenId: "yourTokenId"
limit: 25
}) {
items {
walletAddress
amount
predictionTrader { alias }
}
total
cursor
}
}
```
## 10) Trader leaderboard
```graphql
query TopTraders {
filterPredictionTraders(
rankings: [{ attribute: TOTAL_PROFIT_CT_ALL, direction: DESC }]
limit: 25
) {
count
page
results {
id
trader {
id
venueTraderId
protocol
alias
primaryAddress
profileImageUrl
profileUrl
labels
}
totalVolumeUsdAll
totalProfitUsdAll
totalProfitCTAll
totalTradesAll
activeMarketsCount
pnlPerVolumeAll
biggestWinUsd
biggestLossUsd
firstTradeTimestamp
lastTradeTimestamp
volumeUsd24h
realizedPnlUsd24h
realizedProfitPercentage24h
trades24h
winRate24h
heldTokenAcquisitionCostUsd
}
}
}
```
Ranking attributes available at 12h, 24h, 1w, 1m, and "All" (all-time) windows. Use volume filters (e.g., `totalVolumeUsdAll: { gte: 10000 }`) for meaningful leaderboards. `pnlPerVolumeAll` normalizes profit by capital deployed.
Other leaderboard variants:
- Best win rate: rank by `WIN_RATE_1W` DESC with volume floor filter
- Highest 24h PnL: rank by `REALIZED_PNL_USD_24H` DESC
- Search by alias/address: use `phrase` parameter
## 11) Trader profile and detailed stats
```graphql
query TraderProfile {
detailedPredictionTraderStats(input: {
traderId: "0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket"
}) {
traderId
lastTransactionAt
trader {
id
protocol
venueTraderId
alias
primaryAddress
linkedAddresses
profileImageUrl
profileUrl
labels
totalVolumeUsd
totalVolumeCT
allTimeProfitUsd
allTimeProfitCT
biggestWinUsd
biggestWinCT
biggestLossUsd
biggestLossCT
totalTradesCount
activeMarketsCount
firstTradeTimestamp
lastTradeTimestamp
}
allTimeStats {
totalVolumeUsd
totalVolumeCT
totalProfitUsd
totalProfitCT
}
statsDay1 {
start
end
lastTransactionAt
statsCurrency {
volumeUsd
volumeCT
buyVolumeUsd
sellVolumeUsd
realizedPnlUsd
realizedPnlCT
averageSwapAmountUsd
averageProfitUsdPerTrade
realizedProfitPercentage
heldTokenAcquisitionCostUsd
soldTokenAcquisitionCostUsd
}
statsNonCurrency {
trades
buys
sells
wins
losses
uniqueMarkets
}
statsChange {
volumeChange
realizedPnlChange
tradesChange
winsChange
lossesChange
uniqueMarketsChange
}
}
}
}
```
Windowed stats available: `statsHour1` through `statsDay30`.
## 12) Trader market positions
Open positions sorted by volume:
```graphql
query OpenPositions {
filterPredictionTraderMarkets(
traderIds: ["0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket"]
filters: { hasOpenPosition: true }
rankings: [{ attribute: totalVolumeUsd, direction: DESC }]
limit: 25
) {
count
results {
id
traderId
marketId
eventId
market {
id
eventId
label
question
eventLabel
imageThumbUrl
outcome0Label
outcome1Label
}
hasOpenPosition
totalRealizedPnlUsd
totalRealizedPnlCT
totalVolumeUsd
totalTrades
totalCostBasisUsd
totalSharesHeld
pnlPerVolumeMarket
outcome0 {
outcomeId
isWinningOutcome
sharesHeld
avgEntryPriceUsd
avgEntryPriceCT
costBasisUsd
buys
sells
buyVolumeUsd
sellVolumeUsd
realizedPnlUsd
pnlStatus
}
outcome1 {
outcomeId
isWinningOutcome
sharesHeld
avgEntryPriceCT
costBasisUsd
buys
sells
realizedPnlUsd
pnlStatus
}
}
}
}
```
`filterPredictionTraderMarkets` works bidirectionally — filter by `traderIds` for a portfolio view, or by `marketIds`/`eventIds` for top traders in a market/event.
## 13) Trader performance chart
Plot `cumulativeRealizedPnlCT` for the signature trader P&L curve.
```graphql
query TraderPerformance {
predictionTraderBars(input: {
traderId: "0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket"
from: 1773100000
to: 1773700000
resolution: day1
}) {
traderId
trader {
id
alias
primaryAddress
profileImageUrl
}
bars {
t
trades
buys
sells
uniqueMarkets
volumeUsd
volumeCT
buyVolumeUsd
sellVolumeUsd
wins
losses
realizedPnlUsd
realizedPnlCT
cumulativeRealizedPnlUsd
cumulativeRealizedPnlCT
}
}
}
```
## 14) Trader trade history
```graphql
query TraderTrades {
predictionTrades(input: {
traderId: "0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket"
limit: 50
}) {
items {
marketId
outcomeId
protocol
tradeType
maker
traderId
timestamp
outcomeIndex
outcomeLabel
priceUsd
priceCollateral
amount
amountCollateral
amountUsd
transactionHash
blockNumber
networkId
predictionMarket {
id
label
question
eventLabel
outcomeLabels
}
}
cursor
}
}
```
## Resolution selection guide
| Time Range | Recommended Resolution |
| --- | --- |
| Last hour | min1 |
| Last 4 hours | min5 |
| Last 24 hours | min15 or min30 |
| Last week | hour1 |
| Last month | hour4 or hour12 |
| Last 3 months | day1 |
| All time | day1 or week1 |
## Recommended page data flows
**Event detail page** (run 1–4 in parallel on load):
1. `detailedPredictionEventStats` — metadata, markets, stats
2. `filterPredictionMarkets(eventIds)` — current outcome pricing
3. `predictionEventTopMarketsBars` — multi-market probability chart
4. `predictionEventBars` — volume/liquidity/OI chart
5. `predictionTrades(eventId)` — recent trades
6. `predictionMarketBars` — drill-down on market select
7. `predictionTokenHolders` — on token holder tab
**Trader profile page** (run 1–3 in parallel on load):
1. `detailedPredictionTraderStats` — profile header and summary stats
2. `filterPredictionTraderMarkets(traderIds, hasOpenPosition: true)` — active positions
3. `predictionTraderBars` — cumulative P&L chart
4. `filterPredictionTraderMarkets(traderIds)` — all positions (on tab switch)
5. `predictionTrades(traderId)` — trade history (on tab switch)