API Reference
Posts

Posts API

Superhero posts live on chain; this API is the indexed, queryable copy. Use it to read a feed, load a thread, search post content, or find everything one account has written.

All paths are relative to https://api.superhero.com. Reads need no authentication. Posting is a contract call, not a REST operation. See Posting.

Endpoints

Method & pathQueryReturns
GET /api/postsorder_by, order_direction, search, account_address, topics, limit, pagePaginated PostDto
GET /api/posts/popularpage, limit, eight ranking weights, debugPaginated PostDto, ranked
GET /api/posts/{id}NoneOne PostDto. {id} accepts a slug too
GET /api/posts/{id}/commentsorder_direction, limit, pagePaginated comment thread
GET /api/feedsort, cursor, limitCursor-paginated union of posts, token creations and trades
GET /api/topicsorder_by, order_direction, search, limit, pagePaginated topics
GET /api/topics/name/{name}NoneOne topic with its posts
GET /api/topics/popular/trendingNoneMost-used topics by post count
GET /api/tips/posts/{postId}/summaryNoneTotal tipped on a post
GET /api/tipsorder_by, order_direction, sender, receiver, type, post_id, limit, pagePaginated tips
GET /api/tips/accounts/{address}/summaryNoneTips sent and received by an account
GET /api/posts/analyticsstart_date, end_date, sender_addressDaily posting volume series
GET /api/posts/analytics/top-postersstart_date, end_date, limitLeaderboard of authors
GET /api/posts/analytics/top-topicsstart_date, end_date, limitLeaderboard of topics

PostDto

FieldTypeMeaning
idstringUnique post identifier
tx_hashstringth_... of the transaction that created the post
tx_argsarray of objectsRaw contract-call arguments as JSON
sender_addressstringAuthor ak_...
senderPostSenderDtoInlined author profile: address, public_name, bio, avatarurl
contract_addressstringct_... of the posting contract
typestringThe contract entrypoint that created the post on a single-post read; the literal post on list endpoints
contentstringThe post body
trend_mentionsarray of PostTrendMentionDtoHashtags in content resolved to tokens
mediaarray of stringsMedia URLs attached to the post
total_commentsnumberComment count
created_atstringISO 8601

A single-post read also carries slug, updated_at, post_id (the parent, null on a top-level post), is_hidden, token_mentions and version.

PostTrendMentionDto turns a #HASHTAG in the body into a renderable price chip:

FieldTypeMeaning
namestringThe trend name, without the #
sale_addressstring or nullToken sale address, when a token exists for that name
collection_infoCollectionInfoDto or nullCollection metadata for that token
performanceTrendPerformanceSummaryDto or nullpast_24h, past_7d, past_30d, all_time price movement

type

On a single post, type is the contract entrypoint that created it, or unknown. The posting contract is one deployment per network (ct_2Hyt9ZxzXra5NAzhePkRsDPDWppoatVD7CtHnUoHVbuehwR8Nb on mainnet). On the list endpoints type is always the literal post.

Whether a post is a comment, hidden, or generated by a token launch or trade is encoded in the transaction's second argument, a string array carrying comment:<parentId>, hidden, bcl: or bcl-tx:. A comment surfaces as a non-null post_id.

GET /api/posts

ParameterNotes
order_bytotal_comments or created_at
order_directionASC or DESC
searchFilters by content or topic
account_addressOnly posts by this ak_...
topicsComma-separated topic names, partial matching
limit, pageStandard pagination, limit capped at 100
# Newest 20 posts mentioning a topic
curl -s "https://api.superhero.com/api/posts?topics=superhero&order_by=created_at&order_direction=DESC&limit=20"

GET /api/posts/popular

Ranking is all-time with a freshness boost for new posts; window is accepted and ignored. Eight per-request weights tune it, each low, med (the default) or high:

ParameterSignal
commentsComment count
tipsAmountAETotal AE tipped
tipsCountNumber of tips
uniqueTippersDistinct tipping accounts
trendingBoostWhether the post mentions a trending topic
contentQualityServer-side content quality signal
readsRead count
interactionsPerHourEngagement velocity from comments, tips and unique tippers per hour

Defaults are page=1 and limit=50. debug=1 returns the ranking breakdown alongside the items. Note the casing: tipsAmountAE has a capital AE; the rest are lowerCamelCase.

# A feed that leans on tips rather than comments
curl -s "https://api.superhero.com/api/posts/popular?limit=20&tipsAmountAE=high&comments=low"

GET /api/posts/{id}

One post, by either its id or its slug:

curl -s "https://api.superhero.com/api/posts/hello-world-2f8a91c4"

A hidden post is a 404. The path segment must start with a letter or digit and may then contain letters, digits and . _ ~ : -, up to 128 characters; anything else is a 400.

A slug is the first 60 characters of the content, lowercased, with everything that is not a letter, digit, ., _, ~ or - collapsed to a single -, then the first underscore-delimited segment of the post id. Slugs are not guaranteed unique; prefer the id.

GET /api/posts/{id}/comments

Paginated thread under a post. Takes order_direction (ASC or DESC), limit and page; there is no order_by; comments are ordered by time. Comments are posts, so items follow the PostDto shape.

GET /api/feed

The combined home feed, and the only cursor-paginated endpoint in the API.

ParameterNotes
sortlatest or hot. Anything else is a 400
cursorOpaque cursor from the previous response's next_cursor
limitDefaults to 20, clamped to 1–50

sort=latest is a keyset-paginated union of posts, token creations and trades. sort=hot returns posts only, ranked by the same algorithm as /api/posts/popular. Responses are cached for 15 seconds.

{
  "items": [
    { "type": "post", "created_at": "2026-09-13T09:14:02.000Z", "data": {} }
  ],
  "next_cursor": "..."
}

Each item is a discriminated union:

typedata is
postA post row, the same shape as a /api/posts item
token_createdA token row, as on /api/tokens
tradeA transaction row, as on /api/transactions

next_cursor is null on the last page; pass it straight back as cursor and do not parse it. A cursor minted under one sort is ignored by the other, so switching sort restarts from the top.

Topics

A topic is a hashtag with a post count. GET /api/topics/name/{name} returns the topic with its posts array and post_count. GET /api/topics takes order_by of name, post_count or created_at, plus order_direction, search, limit and page. GET /api/topics/{id} accepts either a UUID or a name.

curl -s "https://api.superhero.com/api/topics/popular/trending"

See Trending & Topics for the topic row and how a tag maps to a token.

Tips

GET /api/tips/posts/{postId}/summary returns totalTips, an AE total as a decimal string. Parse it rather than comparing it. It 404s for an unknown post id.

curl -s "https://api.superhero.com/api/tips/posts/123/summary"

GET /api/tips lists individual tips, ordered by amount, type or created_at, with filters for sender, receiver, type and post_id. Combine post_id and receiver to list who tipped a post:

curl -s "https://api.superhero.com/api/tips?post_id=123&receiver=ak_YOUR_ADDRESS&order_by=created_at&order_direction=DESC&limit=100"
FieldTypeMeaning
tx_hashstringth_... of the tipping transaction, the primary key
typestringprofile (the default) or post
sender_addressstringThe tipper. The row also carries a joined sender account object
receiver_addressstringThe recipient, with a joined receiver account object
post_idstring or nullThe tipped post, null for a profile tip
amountstringTip size in AE, so no 1e18 division
created_atstringISO 8601

order_by=amount sorts numerically, not lexically.

GET /api/tips/accounts/{address}/summary returns two AE totals as decimal strings, both excluding self-tips:

{ "totalTipsSent": "12.5", "totalTipsReceived": "3.25" }

Posting analytics

Three endpoints under /api/posts/analytics, all taking start_date and end_date as YYYY-MM-DD. Defaults are the last 10 days. A start after the end, or an unparseable date, is a 400.

GET /api/posts/analytics

A bare array, one element per day, computed live:

FieldTypeMeaning
datestringYYYY-MM-DD
total_postsnumberTop-level posts that day (post_id IS NULL)
total_commentsnumberComments that day
total_allnumberBoth together
total_unique_postersnumberDistinct authors that day
cumulative_total_postsnumberRunning total up to and including that day
avg_comments_per_postnumber

Hidden posts are excluded throughout. sender_address scopes every figure to one author. GET /api/posts/analytics/past-24-hours returns the same object for a rolling 24-hour window.

GET /api/posts/analytics/top-posters

limit defaults to 10 and is clamped to 1–100. Each item:

sender_address · total_posts · total_comments · total_all · public_name

Ordered by total_all descending. public_name falls back to the address when no profile exists, so it is never null.

GET /api/posts/analytics/top-topics

Each item is topic_id, topic_name and post_count for the range, ordered by post_count descending. Same limit handling.

GET /api/posts/analytics/preview is a server-rendered HTML dashboard, not JSON.

Related