apiton blog
Using the apiton API: list domains, usernames and numbers for sale with curl
Everything on apiton.org — the hubs, the item pages, the sitemaps — is built from the public
apiton API. You can call the same methods yourself. This guide uses only curl; every request is
a POST with a JSON body to https://app.apiton.org/<service>/<method>.
Keys and limits
Public methods work without a key: anonymous callers share the free plan per IP — 1 request
per second and 10,000 requests per month. To get your own quota, open
@apitonBot, send /get_api and pass the key as a header:
-H 'Authorization: Bearer <tg_id>:<secret>'
Paid plans (/upgrade in the bot) raise the limits to 10 or 100 requests per second. Every
response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset.
Domains for sale, cheapest first
v2.Catalog/List returns a filtered, sorted, paginated list:
curl -X POST https://app.apiton.org/v2.Catalog/List \
-H 'Content-Type: application/json' \
-d '{"kind":"domain","statuses":["sale"],"sort":"price_asc","limit":20}'
Each item has name (the label, without .ton), status, price and currency (empty means
TON), price_source (chain or fragment), owner_address, nft_address, expires_at and
changed_at. The same list is the domains for sale hub on apiton.org.
The request fields:
| Field | Values |
|---|---|
kind |
username, number or domain (required) |
statuses |
any of not_listed, sale, auction, expired; empty = all |
name_len |
exact length; 0 = any |
digits_only |
only names made of digits |
prefix |
name prefix (for domains: of the label, without .ton) |
expires_after, expires_before |
domains: expiry window (RFC 3339) |
sort |
name, price_asc, price_desc, expires_asc, changed |
offset, limit |
paging; limit up to 500, default 50 |
More recipes
Expired .ton domains (the expired domains hub):
curl -X POST https://app.apiton.org/v2.Catalog/List \
-H 'Content-Type: application/json' \
-d '{"kind":"domain","statuses":["expired"],"sort":"changed"}'
Domains that expire in the next 30 days, soonest first (adjust the dates):
curl -X POST https://app.apiton.org/v2.Catalog/List \
-H 'Content-Type: application/json' \
-d '{"kind":"domain","expires_after":"2026-09-26T00:00:00Z","expires_before":"2026-10-26T00:00:00Z","sort":"expires_asc"}'
Four-letter usernames on auction:
curl -X POST https://app.apiton.org/v2.Catalog/List \
-H 'Content-Type: application/json' \
-d '{"kind":"username","statuses":["auction"],"name_len":4}'
Paging and JSON quirks
totalis the number of all matches, ignoringoffsetandlimit. It is an int64, so under proto3 JSON it arrives as a string:"total":"1523".- Zero values are omitted. An empty result is
{}, not{"items":[],"total":"0"}— code for it. offsetgoes up to 100,000. For a full export by name usev2.Catalog/Sitemap, which pages withafter_nameinstead of an offset.
History and counts
The newest events of one item — listed, delisted, price changes, sales, bids, expiry and renewal:
curl -X POST https://app.apiton.org/v2.Catalog/Events \
-H 'Content-Type: application/json' \
-d '{"kind":"number","name":"+888 0000 1312"}'
Leave out name to get a feed, e.g. {"types":["sold"],"limit":50} for the latest sales across all
kinds. v2.Catalog/Summary with {} returns item counts per kind and status — the numbers on the
apiton.org home page.
Live state of one item
The catalog is refreshed in the background and cached. For the current on-chain state of a single
item, call the live methods — v2.Nft/Username, v2.Nft/Number or v2.Nft/Domain:
curl -X POST https://app.apiton.org/v2.Nft/Domain \
-H 'Content-Type: application/json' \
-d '{"domain":"foundation.ton"}'
They return the owner, the expiry for domains and the current sale or auction. See What the statuses mean for how fresh each source is.
Errors
Errors use the Connect JSON envelope, e.g. {"code":"invalid_argument","message":"…"}. An unknown
kind or sort is invalid_argument; out-of-range limit or offset is failed_precondition;
too many requests is resource_exhausted (HTTP 429) — slow down or use a key.
Prefer Telegram to curl? The same data, plus alerts, is in @apitonBot.