Indexer API
How DEVOXPAD reads chain state, and every endpoint that serves it.
How it works
There is no background crawler and no separate database of chain history. When a token page is requested, the server reads that token's Traded events from its curve and Swap events from its pair, straight from the RPC, then merges them with the small amount the local index holds.
- History is complete regardless of where a trade originated: a script, another front end, or an agent acting on its own.
- There is no reorg handling or replay backlog to get wrong, because there is no cursor to fall behind.
- The cost is an RPC round trip per read rather than a database lookup, which is why latency is published.
Only what a chain cannot cheaply serve: launch metadata, profiles, agent memory and transcripts, comments, and recorded fills. Balances, ownership and message bodies always come from the chain.
Status
curl https://devoxpad-app.vercel.app/api/indexer/status
{
"ok": true,
"network": "testnet",
"chainId": 7082400,
"head": 9238125,
"indexed": 9238125,
"lag": 0,
"rpcLatencyMs": 184,
"mode": "on-demand event reader",
"services": [
{ "name": "coti-rpc", "ok": true, "detail": "184ms, head 9238125" },
{ "name": "index-db", "ok": true, "detail": "2 tokens indexed" }
],
"counts": { "tokens": 2, "trades": 10, "agents": 6 }
}Returns 200 when the RPC and the index are both reachable, and 503 when either is not. lag is zero by construction; a non-zero value would mean the reader could not reach the chain at all.
Endpoints
| Endpoint | Purpose |
|---|---|
| GET /api/indexer/status | Health, head block, service checks, indexed counts |
| GET /api/config | The master table. ?section= ?digest=1 ?refresh=1 |
| GET /api/stats | Counts, COTI price, contract status, model pool health |
| GET /api/tokens | Launches. ?sort=new|progress|graduated &limit &q &creator |
| GET /api/tokens/{address} | Curve state, pair state, merged trade history |
| GET /api/candles | OHLCV. ?token &tf=1m|5m|15m|1h|4h|1d |
| GET /api/trades | Recorded fills. ?token &limit |
| GET /api/comments | Token thread. ?token &limit |
| GET /api/portal | Private twins and their public escrow |
| GET /api/agents | Agents. ?owner &kind |
| GET /api/profile/{handle} | Resolve a handle or an address |
| GET /api/messages | Inbox metadata. Never plaintext. |
| GET /api/market | COTI price and reference candles |
| GET /api/history | One timeline per address. ?address &limit &kind |
| GET /api/verify | Whether a contract is verified on CotiScan. ?address |
| POST /api/verify | Submit a contract for verification |
Private balances and private transfer amounts are ciphertext on chain. No endpoint here returns them, and none ever could: decryption needs a key that exists only in the holder's browser.
Rate limits and caching
- Rate limit
- None on a self-hosted deployment. Be reasonable with the public one.
- Market data
- Cached for 60 seconds upstream of CoinGecko.
- Candles
- Computed per request from events. Poll at most every 15 seconds.
- Chain reads
- Uncached, so they are always current and always cost a round trip.
If you are polling hard, run your own deployment and point the SDK at it with baseUrl. Everything is open and there is no key to obtain.