API
The Tenor GraphQL API exposes markets, positions, offers, and portfolio analytics in a single flexible query interface, so a client can fetch related data across markets and maturities in one request. It aggregates onchain data from the Tenor indexer, so integrators do not need to run a separate indexer.
Every operation in this reference has a runnable example. Open a page, edit the query or variables, and press Run to call the live endpoint from the page.
Endpoint
POST https://api.tenor.finance/graphql
All operations are POST requests with a JSON body containing query and, where the operation takes arguments, variables.
curl https://api.tenor.finance/graphql \
--header 'Content-Type: application/json' \
--data '{"query":"{ marketSummary { totalLentUsd totalBorrowedUsd } }"}'
Access
Read queries are served without an API key. The endpoint sends access-control-allow-origin: *, so browser clients can call it directly without a proxy.
For elevated limits or write access, contact contact@tenor.finance.
Rate limits
Responses carry x-ratelimit-* headers describing three concurrent windows. Read these headers rather than hardcoding the numbers below, which are current observed values and may change.
| Header prefix | Limit | Window |
|---|---|---|
x-ratelimit-*-short | 25 requests | 1 second |
x-ratelimit-*-medium | 150 requests | 10 seconds |
x-ratelimit-* | 1000 requests | Longer rolling window |
Each prefix reports -limit, -remaining, and -reset (seconds until the window rolls over).
Query complexity
Every response includes a complexity estimate against a per-request budget:
{
"data": { },
"extensions": { "complexity": { "estimated": 104, "max": 1000 } }
}
Complexity grows with the number of fields selected and the page size requested. Requests over the budget are rejected, so prefer several narrow queries over one deeply nested query that fetches fields you do not use. The console on each operation page reports the complexity of the query you ran.
Pagination
List operations take first and skip, and return an items array alongside pageInfo:
| Field | Description |
|---|---|
countTotal | Total rows matching the query, ignoring pagination |
count | Rows returned in this response |
limit | The first value applied |
skip | The skip value applied |
Value encoding
BigIntfields are returned as JSON strings or numbers holding unscaled integers. Divide by the relevant token'sdecimalsbefore display.- USD-denominated fields are scaled by 18 decimals.
- Rate fields typed
Floatare decimal fractions, so0.0447is 4.47%. - Timestamps are Unix seconds.
Errors
GraphQL errors return HTTP 200 with an errors array; the status field carries the machine-readable code.
{
"errors": [
{
"message": "Field \"name\" is not defined by type \"Chain\".",
"status": "GRAPHQL_VALIDATION_FAILED"
}
]
}
| Status | Meaning |
|---|---|
GRAPHQL_VALIDATION_FAILED | The document does not match the schema — check field and argument names |
BAD_USER_INPUT | The document is valid but an argument value was rejected |
INTERNAL_SERVER_ERROR | The request failed server-side |
Schema introspection
The endpoint answers standard introspection queries, so GraphQL tooling can generate types and autocomplete against it:
curl https://api.tenor.finance/graphql \
--header 'Content-Type: application/json' \
--data '{"query":"{ __schema { queryType { name } } }"}'
This reference documents the operations most integrations need. Introspection lists the full set.