Tokens API
Community tokens are the centre of the API: the trending list, portfolios, charts and trade records all resolve to a token. Twelve endpoints return tokens and their derived data.
All paths are relative to https://api.superhero.com. Reads need no authentication and are not
rate-limited.
Endpoints
| Method & path | Query | Returns |
|---|---|---|
GET /api/tokens | order_by, order_direction, collection, limit, page, search, owner_address, creator_address, factory_address | Paginated TokenDto list |
GET /api/tokens/{address} | None | One TokenDto |
GET /api/tokens/{address}/holders | limit, page | Paginated holder rows |
GET /api/tokens/{address}/transactions | interval, start_date, end_date, convertTo, mode | Aggregated trade series |
GET /api/tokens/{address}/history | interval, convertTo, limit, page | OHLC candles, as a bare array |
GET /api/tokens/{address}/performance | None | Four price-movement windows |
GET /api/tokens/{address}/performance-raw | None | Alias of performance, kept for backward compatibility |
GET /api/tokens/{address}/rankings | limit, page | Neighbouring tokens by rank |
GET /api/tokens/{address}/score | None | Trending-score breakdown. Recomputes and persists the score |
GET /api/tokens/{address}/trending-eligibility | None | Whether the token qualifies for the trending list |
GET /api/tokens/preview/{address} | interval | Lightweight preview for cards |
GET /api/tokens/preview/{address}/sparkline.svg | interval, background, height, width | An SVG image, not JSON |
{address} accepts a name
Every {address} path parameter accepts a ct_... sale address, a ct_... AEX-9 address or
the plain token name:
# Resolve by name
curl -s "https://api.superhero.com/api/tokens/SUPERHERO"
# The same token, by its sale address — take sale_address from the response above
curl -s "https://api.superhero.com/api/tokens/ct_YOUR_SALE_ADDRESS"TokenDto
| Field | Type | Meaning |
|---|---|---|
id | number | Internal row id. Not an on-chain identifier |
network_id | string | ae_mainnet or ae_uat |
factory_address | string | ct_... of the community factory that minted it |
sale_address | string | ct_... of the token sale (bonding curve) contract |
create_tx_hash | string | th_... of the creation transaction |
creator_address | string | ak_... that called create_community |
dao_address | string | ct_... of the token's DAO treasury |
owner_address | string | ak_... currently recognised as owner |
beneficiary_address | string | ak_... receiving the beneficiary fee share |
bonding_curve_address | string | ct_... of the curve contract used for pricing |
collection | string | Collection id, NAME-ak_deployer |
collection_info | CollectionInfoDto or null | Resolved collection metadata; null when unknown to the factory |
metaInfo | object | Free-form creator metadata map. The only camelCase field on the DTO |
unlisted | boolean | Hidden from curated listings |
last_sync_tx_count | number | Transactions seen at last sync |
tx_count | number | Total trades recorded against the token |
address | string | ct_... of the AEX-9 token contract |
name | string | Token name, e.g. SUPERHERO |
symbol | string | Ticker |
decimals | string | Decimal places. 18 for factory-minted tokens. Parse before use |
rank | number | Position in the market-cap ranking across the current factory. 1 is highest. 2147483647 means not yet ranked |
holders_count | number | Distinct holding addresses |
price | string | Current buy price per token, in AE |
price_data | PriceDto | The same buy price in all nine currencies |
sell_price | string | Current sell price per token, in AE |
sell_price_data | PriceDto | The same sell price in all nine currencies |
market_cap | string | Market capitalisation in aettos. total_supply * price |
market_cap_data | PriceDto | Market cap in all nine currencies, all on the aettos scale |
total_supply | string | The sale contract's total_supply(), in token base units |
circulating_supply | string or null | The middleware's AEX-9 eventSupply, in base units. Null when the middleware did not answer |
dao_balance | string | AE held by the token's DAO, in aettos |
trending_score | number | Score driving the trending list. A decimal in [0, 1], six decimal places |
trending_score_update_at | string | ISO 8601 timestamp of the last score recompute |
performance | TokenPerformanceDto or null | Inlined performance summary |
created_at | string | ISO 8601 creation timestamp |
List rows may also carry collection_rank, the token's position within its collection.
address versus sale_address
sale_addressis the bonding-curve sale contract you buy from and sell into. The rest of the API keys on it:token_addresson/api/transactions, the WebSocket channels, the portfolio PnL map and the DAO routes all mean the sale address.addressis the AEX-9 token contract that holds balances. It is what a wallet displays and what the middleware's/v3/aex9/{address}endpoint takes.
When in doubt, use sale_address.
PriceDto
Wherever a value has a price, the API returns all nine currencies at once:
{ "ae": 0.0421, "usd": 0.0013, "eur": 0.0011, "aud": 0.002,
"brl": 0.0071, "cad": 0.0018, "chf": 0.001, "gbp": 0.00097, "xau": 0.0000004 }Every key is on the same scale as ae: usd is ae * rate.usd, and likewise for the
rest. On market_cap_data every key is in aettos, so market_cap_data.usd / 1e18 is the USD
market cap. Rates refresh every ten minutes; when unavailable every key except ae is null.
CollectionInfoDto
| Field | Type | Meaning |
|---|---|---|
id | string | Full collection id, NAME-ak_deployer |
name | string | Human-readable badge label |
description | string or null | Optional |
allowed_name_length | string | Maximum token name length in this collection |
Units
| Field | Unit |
|---|---|
price | AE, the sale contract's price for one token |
sell_price | AE, the sale contract's sell return for one token |
total_supply | token base units |
market_cap | aettos (total_supply * price) |
dao_balance | aettos |
circulating_supply | token base units |
decimals | string |
holder balance | token base units |
A worked check:
total_supply = "1000000000000000000" -> 1000000000000000000 / 1e18 = 1 token
price = "0.0421" -> 0.0421 AE per token
market_cap = "42100000000000000" -> 42100000000000000 / 1e18 = 0.0421 AEHolder balances follow decimals rather than a hardcoded 18:
Decimal.from(holder.balance).div(10 ** (parseInt(token.decimals) || 18))GET /api/tokens
order_by | Sorts on |
|---|---|
name, price, created_at, holders_count, rank, trending_score | The column of that name |
market_cap | rank, with the direction flipped (see below) |
treasury | dao_balance, the DAO's AE balance in aettos |
order_direction is ASC or DESC. order_by=treasury&order_direction=DESC is "richest
treasuries first".
| Parameter | Notes |
|---|---|
collection | all (default) returns every collection. Otherwise a collection name such as WORDS or CHINESE, or a full collection id such as CHINESE-ak_... |
search | Substring match on name, case-insensitive. Rejected with 400 above 100 characters |
owner_address | Tokens with a non-zero holder row for this ak_... |
creator_address | Tokens created by this ak_... |
factory_address | Tokens from a specific factory deployment |
limit, page | limit defaults to 100 and is capped at 100. Outside 1–100 it is a 400 |
- An unknown
order_byfalls back tomarket_capand an unknownorder_directiontoDESC, without an error. order_by=market_capsorts onrank(refreshed every five minutes) with the direction reversed. Rank 1 is the highest market cap; unranked tokens carry2147483647and sort last.order_by=trending_scorereturns only tokens with at least 5 holders, 2 all-time posts mentioning the symbol and 3 all-time trades; if no token clears the gate the query is re-run without it. Zero-score tokens fall back to newest-first. This sort is cached for 15 minutes, every other sort for 60 seconds.- Tokens with
unlisted = trueare excluded.
# The ten highest-scoring trending tokens
curl -s "https://api.superhero.com/api/tokens?order_by=trending_score&order_direction=DESC&limit=10"Response is the standard items + meta envelope described in
Conventions.
GET /api/tokens/{address}/trending-eligibility
One token's standing against the gate:
{
"sale_address": "ct_...", "symbol": "SUPERHERO",
"holders_count": 42, "post_count": 9, "stored_post_count": 9,
"content_post_count": 7, "trade_count": 151,
"thresholds": { "min_holders": 5, "min_posts": 2, "min_trades": 3 },
"passes": { "holders": true, "posts": true, "trades": true, "eligible": true }
}GET /api/tokens/{address}/holders
Paginated holder rows, ordered by balance descending, filtered to balance > 0:
| Field | Type | Meaning |
|---|---|---|
id | string | Row id |
aex9_address | string | ct_... of the AEX-9 contract this balance belongs to |
address | string | Holder ak_... |
balance | string | Balance in token base units |
block_number | number | Height at which the balance was last synced |
last_tx_hash | string | th_... of the transfer that produced this balance |
created_at | string | ISO 8601, first seen holding |
A holder's share of supply is balance / total_supply (both in base units, so the scaling
cancels). Requesting holders for a token whose holder table is empty enqueues a background sync,
so a second request a few seconds later often returns more.
curl -s "https://api.superhero.com/api/tokens/SUPERHERO/holders?limit=20&page=1"GET /api/tokens/{address}/performance
Returns token_id, sale_address and four windows:
past_24h · past_7d · past_30d · all_timeEach window carries these eleven fields:
| Field | Type | Meaning |
|---|---|---|
current | PriceDto | Latest buy price inside the window, in AE |
current_date | string | Timestamp of current |
current_change | number or null | Latest minus first, in AE |
current_change_percent | number or null | The same as a percentage of the first price |
current_change_direction | string or null | up, down or neutral |
high / high_date | PriceDto / string | Window high and when |
low / low_date | PriceDto / string | Window low and when |
last_updated | string | ISO 8601, same instant as current_date |
volume | string or null | Window volume in whole tokens |
Prices are trade buy prices in AE, the same scale as TokenDto.price; volume is already in
whole tokens. The data is rebuilt every five minutes, so a brand-new trade is not reflected
immediately, and a token with no indexed transactions returns 404. The same structure is inlined
on TokenDto.performance.
curl -s "https://api.superhero.com/api/tokens/SUPERHERO/performance"GET /api/tokens/{address}/performance-raw returns the identical payload.
GET /api/tokens/{address}/history
OHLC candles for charting. Returns a bare JSON array, not an items envelope; you have
reached the end when a page comes back empty.
| Parameter | Default | Notes |
|---|---|---|
interval | 3600 | Candle width in seconds |
convertTo | ae | One of the nine currency codes |
limit, page | None | Standard pagination; limit=100 is typical |
Each element carries timeOpen, timeClose, timeHigh, timeLow and a quote:
{
"timeOpen": "2026-09-12T13:00:00.000Z",
"timeClose": "2026-09-12T13:59:59.999Z",
"timeHigh": "2026-09-12T13:41:02.000Z",
"timeLow": "2026-09-12T13:06:55.000Z",
"quote": {
"convertedTo": "ae",
"open": 0.0413, "close": 0.0421,
"high": 0.0433, "low": 0.0409,
"volume": 12.84,
"total_supply": 305.5,
"market_cap": 12.86,
"timestamp": "2026-09-12T13:59:59.999Z",
"symbol": "SUPERHERO"
}
}Candle units differ from TokenDto units. volume and total_supply are in whole
tokens, and market_cap is in AE, not aettos and not base units. open, high, low
and close are buy prices in the convertTo currency. open is set to the previous candle's
close so the series is continuous.
GET /api/tokens/{address}/transactions covers the same ground with start_date / end_date
bounds instead of paging. Defaults are interval=3600, mode=aggregated and start_date two
days ago, so an unparameterised call returns 48 hourly candles; mode=normal returns the
underlying rows. /history is cached for 5 seconds, /transactions for 60.
GET /api/tokens/{address}/rankings
The tokens adjacent to this one in the global ranking, as full token rows with performance
and collection_info in an items plus meta envelope. limit defaults to 5; the window
is centred on the target token, and an edge-of-board token still returns limit rows.
An unknown, unranked, other-factory or unlisted token returns an empty page, not a 404.
meta.totalItems is the number of neighbours returned and totalPages is always 1.
GET /api/tokens/preview/{address}
A compact payload for cards and link previews. interval takes a keyword rather than seconds:
1d, 7d, 30d, 90d, 180d or all-time.
GET /api/tokens/preview/{address}/sparkline.svg returns a rendered SVG with the same
interval plus background, height and width.
GET /api/tokens/{address}/score
Recomputes the trending score, persists trending_score and trending_score_update_at on the
token, and returns { metrics, token }. Use it to inspect a score, not in a polling loop.
{
"window_hours": 24,
"last_activity_at": "2026-09-14T09:12:44.000Z",
"last_trade_at": "2026-09-14T09:12:44.000Z",
"last_social_activity_at": "2026-09-14T07:55:01.000Z",
"age_hours_since_last_activity": 1.4213,
"decay_multiplier": 0.575394,
"trading_signals": {
"active_wallets": { "raw": 7, "cap": 25, "normalized": 0.637 },
"buy_count": { "raw": 12, "cap": 40, "normalized": 0.691 },
"sell_count": { "raw": 3, "cap": 40, "normalized": 0.374 },
"volume_ae": { "raw": 430.5, "cap": 5000, "normalized": 0.713 }
},
"social_signals": {
"mention_posts": { "raw": 4, "cap": 15, "normalized": 0.58 },
"mention_comments": { "raw": 11, "cap": 50, "normalized": 0.635 },
"unique_authors": { "raw": 6, "cap": 20, "normalized": 0.639 },
"tips_count": { "raw": 0, "cap": 15, "normalized": 0 },
"tips_amount_ae": { "raw": 0, "cap": 250, "normalized": 0 },
"reads": { "raw": 88, "cap": 200, "normalized": 0.845 }
},
"component_scores": { "trading": 0.661, "social": 0.588, "pre_decay": 0.614 },
"trending_score": {
"formula": "((trading_weight * trading_score) + (social_weight * social_score)) * freshness_decay",
"result": 0.353294,
"pre_decay": 0.614
}
}Values are illustrative. Caps, weights and decay constants are shared by every token, so
trending_score is comparable across tokens. The full formula is on
Trending & Topics.
Related
- API Conventions: pagination, the
limitcap and the full unit table - Transactions API: the trade records behind
tx_countand the price series - Accounts API: the same tokens from the holder's side, with portfolio value and PnL
- WebSocket API: push updates for
TokenDtoinstead of polling - Trending & Topics: the trending-score formula behind
trending_score - Bonding curve: why buy price and sell price differ