API Reference
Tokens

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 & pathQueryReturns
GET /api/tokensorder_by, order_direction, collection, limit, page, search, owner_address, creator_address, factory_addressPaginated TokenDto list
GET /api/tokens/{address}NoneOne TokenDto
GET /api/tokens/{address}/holderslimit, pagePaginated holder rows
GET /api/tokens/{address}/transactionsinterval, start_date, end_date, convertTo, modeAggregated trade series
GET /api/tokens/{address}/historyinterval, convertTo, limit, pageOHLC candles, as a bare array
GET /api/tokens/{address}/performanceNoneFour price-movement windows
GET /api/tokens/{address}/performance-rawNoneAlias of performance, kept for backward compatibility
GET /api/tokens/{address}/rankingslimit, pageNeighbouring tokens by rank
GET /api/tokens/{address}/scoreNoneTrending-score breakdown. Recomputes and persists the score
GET /api/tokens/{address}/trending-eligibilityNoneWhether the token qualifies for the trending list
GET /api/tokens/preview/{address}intervalLightweight preview for cards
GET /api/tokens/preview/{address}/sparkline.svginterval, background, height, widthAn 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

FieldTypeMeaning
idnumberInternal row id. Not an on-chain identifier
network_idstringae_mainnet or ae_uat
factory_addressstringct_... of the community factory that minted it
sale_addressstringct_... of the token sale (bonding curve) contract
create_tx_hashstringth_... of the creation transaction
creator_addressstringak_... that called create_community
dao_addressstringct_... of the token's DAO treasury
owner_addressstringak_... currently recognised as owner
beneficiary_addressstringak_... receiving the beneficiary fee share
bonding_curve_addressstringct_... of the curve contract used for pricing
collectionstringCollection id, NAME-ak_deployer
collection_infoCollectionInfoDto or nullResolved collection metadata; null when unknown to the factory
metaInfoobjectFree-form creator metadata map. The only camelCase field on the DTO
unlistedbooleanHidden from curated listings
last_sync_tx_countnumberTransactions seen at last sync
tx_countnumberTotal trades recorded against the token
addressstringct_... of the AEX-9 token contract
namestringToken name, e.g. SUPERHERO
symbolstringTicker
decimalsstringDecimal places. 18 for factory-minted tokens. Parse before use
ranknumberPosition in the market-cap ranking across the current factory. 1 is highest. 2147483647 means not yet ranked
holders_countnumberDistinct holding addresses
pricestringCurrent buy price per token, in AE
price_dataPriceDtoThe same buy price in all nine currencies
sell_pricestringCurrent sell price per token, in AE
sell_price_dataPriceDtoThe same sell price in all nine currencies
market_capstringMarket capitalisation in aettos. total_supply * price
market_cap_dataPriceDtoMarket cap in all nine currencies, all on the aettos scale
total_supplystringThe sale contract's total_supply(), in token base units
circulating_supplystring or nullThe middleware's AEX-9 eventSupply, in base units. Null when the middleware did not answer
dao_balancestringAE held by the token's DAO, in aettos
trending_scorenumberScore driving the trending list. A decimal in [0, 1], six decimal places
trending_score_update_atstringISO 8601 timestamp of the last score recompute
performanceTokenPerformanceDto or nullInlined performance summary
created_atstringISO 8601 creation timestamp

List rows may also carry collection_rank, the token's position within its collection.

address versus sale_address

  • sale_address is the bonding-curve sale contract you buy from and sell into. The rest of the API keys on it: token_address on /api/transactions, the WebSocket channels, the portfolio PnL map and the DAO routes all mean the sale address.
  • address is 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

FieldTypeMeaning
idstringFull collection id, NAME-ak_deployer
namestringHuman-readable badge label
descriptionstring or nullOptional
allowed_name_lengthstringMaximum token name length in this collection

Units

FieldUnit
priceAE, the sale contract's price for one token
sell_priceAE, the sale contract's sell return for one token
total_supplytoken base units
market_capaettos (total_supply * price)
dao_balanceaettos
circulating_supplytoken base units
decimalsstring
holder balancetoken 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 AE

Holder balances follow decimals rather than a hardcoded 18:

Decimal.from(holder.balance).div(10 ** (parseInt(token.decimals) || 18))

GET /api/tokens

order_bySorts on
name, price, created_at, holders_count, rank, trending_scoreThe column of that name
market_caprank, with the direction flipped (see below)
treasurydao_balance, the DAO's AE balance in aettos

order_direction is ASC or DESC. order_by=treasury&order_direction=DESC is "richest treasuries first".

ParameterNotes
collectionall (default) returns every collection. Otherwise a collection name such as WORDS or CHINESE, or a full collection id such as CHINESE-ak_...
searchSubstring match on name, case-insensitive. Rejected with 400 above 100 characters
owner_addressTokens with a non-zero holder row for this ak_...
creator_addressTokens created by this ak_...
factory_addressTokens from a specific factory deployment
limit, pagelimit defaults to 100 and is capped at 100. Outside 1–100 it is a 400
  • An unknown order_by falls back to market_cap and an unknown order_direction to DESC, without an error.
  • order_by=market_cap sorts on rank (refreshed every five minutes) with the direction reversed. Rank 1 is the highest market cap; unranked tokens carry 2147483647 and sort last.
  • order_by=trending_score returns 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 = true are 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:

FieldTypeMeaning
idstringRow id
aex9_addressstringct_... of the AEX-9 contract this balance belongs to
addressstringHolder ak_...
balancestringBalance in token base units
block_numbernumberHeight at which the balance was last synced
last_tx_hashstringth_... of the transfer that produced this balance
created_atstringISO 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_time

Each window carries these eleven fields:

FieldTypeMeaning
currentPriceDtoLatest buy price inside the window, in AE
current_datestringTimestamp of current
current_changenumber or nullLatest minus first, in AE
current_change_percentnumber or nullThe same as a percentage of the first price
current_change_directionstring or nullup, down or neutral
high / high_datePriceDto / stringWindow high and when
low / low_datePriceDto / stringWindow low and when
last_updatedstringISO 8601, same instant as current_date
volumestring or nullWindow 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.

ParameterDefaultNotes
interval3600Candle width in seconds
convertToaeOne of the nine currency codes
limit, pageNoneStandard 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