Read API
Everything this site shows comes from an indexer we run: a Cloudflare Worker that reads Robinhood Chain and keeps the result in a database. The same endpoints our pages call are open to you — no key, no sign-up, CORS open to any origin. They are a convenience, not an authority: every number below can be re-derived from the contracts, and when the indexer is wrong or down, the chain is still right.
Base URL
https://api.artificialgatointelligence.com/api
All responses are JSON with ok: true on success and
{ "ok": false, "error": "..." } with a 4xx or 5xx status otherwise. Every endpoint
is GET. Amounts are returned in the quote asset, not in dollars: prices in dollars
are a presentation layer of this site, built from the rates in /api/stats.
Endpoints
GET /api/statsprices. This is the only place the dollar
rates come from.GET /api/launches?limit= 1-200 (default 50), ?offset=,
?sort= newest | progress | volume |
holders | trending (24 h volume in dollars).
Each token carries its price, phase, progress, supply, pool reserves
(pool_token_f, pool_quote_f), its live holders count and
its last 24 h (trades24h, volume24hQuote, volume24hUsd,
change24hPct).GET /api/coin/:tokenholders, stats24h and
supplyBreakdown, the supply split described under Trust — liquidity,
burned, creator, protocol and market, with the top-10 concentration measured on the market
share alone. stats24h also splits the day into buys / sells,
buy_volume_quote / sell_volume_quote and distinct
buyers / sellers.GET /api/trades?limit= 1-60 (default 20).GET /api/trades/:token?limit= 1-200 (default 50). Curve trades and pool
trades both appear; the curve field is null for the ones that happened in the
Uniswap pool.GET /api/candles/:token?res= 1m | 5m | 15m |
1h, ?limit= 1-1000 (default 200). There is no daily resolution:
build it by grouping hourly candles, which is what this site does.GET /api/holders/:token?limit= 1-500 (default 100), ?offset=.
Read the tag field before drawing conclusions: an address may be
the pool, the curve, the locker, the hook, the burn address or the creator. The largest
"holder" of a graduated token is normally the pool, and calling that a whale is the most
common mistake made about this data.GET /api/wallet/:addresscost object — avg, paid,
bought, sold, received, pnl,
pnlPct, since — built from the buys and sells this indexer
recorded, in the asset the token is paired with. It is null when there are no
indexed buys: tokens that arrived by transfer have no cost, and reporting zero would say they
were free.GET /api/traders?window=24h | 7d | 30d answers a different
question over a different table: how much each wallet moved in that window
(bought, sold, traded), and it carries
no profit figure — measuring profit backwards needs what a position was
worth when the window opened, which we do not have. Without a window it is the all-time
table below. Each carries paid, received, value,
pnl, pnlPct, trades, the stack of tokens it trades
(tokens, up to six { token, symbol }, and tokensTotal) and a
tag when the address is the pool, the curve, the escrow or a creator.
?limit= 1-50 (default 10), ?sort=value (default) or paid.
Read movedOut first: when a wallet bought and then moved the tokens
to another address without selling, pnl is null, because those tokens
still exist somewhere this indexer cannot follow and calling that a total loss would be wrong.GET /api/burns/:tokenTransfer to 0x…dEaD —
newest first, with amountF, the running total cumulativeF,
pctOfSupply and the transaction hash. ?limit= 1-500 (default 100)
caps the rows returned; total, totalCount and totalPct
always describe every burn, not just the page.
Without a token the endpoint lists recent burns across tokens and
total, totalCount and every row’s cumulativeF are
null — adding up burns of different tokens would be adding different units.GET /api/profile/:addressname, a color from a fixed
palette (with its colorHex), an optional one-line bio, an X handle
(x, stored bare, plus the xUrl we build from it — we never store
a URL somebody else could point anywhere) and, if it uploaded one, pfpUrl. A wallet that
never set anything still gets a deterministic color (isDefaultColor: true),
so every address renders the same on the site, in the bot and in cards.
GET /api/profiles?addresses=a,b,c returns up to 100 at once.GET /api/thesis/:tokentext, the
timestamp and price it was posted at, balanceThen,
balanceNow (0 if the author sold since; null if unknown),
likes and the author profile. A thesis whose author no longer holds is
closed, with the author’s last sale as closePrice and the move since
posting as closedPct. Newest first, or ?sort=likes;
?viewer=0x… adds likedByViewer; ?limit= 1-200
(default 50), ?offset=.GET /api/holders/:token/pnl?addresses=a,b,cbalance, first-seen
since, buys, sells, paid, received,
avgEntry (null without indexed buys, as in /api/wallet) and
its thesis on that token, if any. It is what the holders table of a coin page reads.GET /api/trader/:addresstrades, firstSeen, lastSeen,
avgHoldSeconds, openPositions, its bestTrades in dollars
(pnlUsd, pnlPct, avgEntryMcUsd, open,
movedOut), its badges (creator, graduate,
burner, diamond, early), its theses,
mostLikedThesis and launches. Built from the per-wallet aggregates the
indexer maintains, so it never rescans the trade log.GET /api/follows/:addressfollowing, followingCount) and how many follow it
(followers). Follows are public and signed, like everything else a wallet writes here.GET /api/crews · GET /api/crew/:idmemberCount; ?member=0x… answers which crew one wallet is in
(null for none). One wallet belongs to at most one crew, so that “this
wallet’s crew” always has an answer.GET /api/search?q=tokens by symbol, name or address and traders by
profile name or address. Hidden tokens never appear, the same filter the hub applies.GET /api/feedevents,
newest first, each with a kind (trade | thesis |
launch | burn), a stable id and a timestamp.
?since= (unix seconds) returns only what is newer; ?limit= 1-200
(default 100). Poll it every few seconds; ask with since a minute behind what you last
saw, because the indexer runs behind the chain.POST /api/profile · POST /api/profile/pfp ·
POST /api/thesis · POST /api/thesis/delete ·
POST /api/thesis/like · POST /api/follow ·
POST /api/crew · POST /api/crew/join ·
POST /api/telegram/linkpersonal_sign signature from the wallet it concerns, over a fixed text that spells
out the exact change (the site builds it; identidad.js is the reference). Signed
text always names the thing, never its database id: you sign “Join the crew
‘Gatos’”, not a number you cannot check. A thesis,
and a like on one, also require a non-zero balance on chain at that moment. Names are unique
(case-insensitive, 409 when taken) and can change once every 30 days
(429 with Retry-After). Pictures are PNG, JPEG or WebP up to
512 KB and 2048 px, and are served with a fixed content type. Every write is
rate-limited per wallet and per IP.Limits, caching and what we promise
- Rate limit. 300 requests per minute per IP. Over it you get
429with aRetry-Afterheader. The limit is generous on purpose and enforced approximately: it exists to stop scraping, not to police normal use. - Cache. Responses carry
Cache-Control; most are good for 10-30 seconds at the edge. Honour it — polling faster gets you the same bytes and counts against your limit. - Freshness. The indexer runs every minute.
/api/statsreports its cursor and the chain head so you can see how far behind it is. - Degraded mode. If our database is unavailable, most reads are served from a
snapshot in object storage and the response carries
X-AGI-Degradadowith the timestamp of that snapshot. The live-trades endpoint is the exception: it fails rather than serve stale data, because a frozen "live" feed is worse than none. - Stability. We will add fields without warning and we will try not to remove or rename them. This is a best-effort promise from a small project, not an SLA: if you build something that matters on it, pin what you read and handle a field going missing.
- No authority. If our numbers and the chain disagree, the chain is right. Nothing here should be the only source for a transaction you sign.
- One gotcha. Cloudflare's bot protection sits in front of this Worker and
rejects some default user agents with a
403— Python'surllibis one of them. Send any user agent of your own and it goes through.
An example
curl 'https://api.artificialgatointelligence.com/api/launches?limit=5&sort=volume'
Nothing that moves money goes through this API. Launching a token, trading and claiming fees are transactions you sign against the contracts — see Launching a token, Trading on the curve and Claiming fees.