τTaosisTaoScale

Public API

Everything on this site is served by a JSON API you can call directly. No key, no sign-up, no quota to negotiate. It is the same API the site itself uses, so it cannot silently fall behind what you see here. It is read-only: every endpoint below is a GET, and there is no endpoint that builds, signs, relays or pays for a transaction. Listed here are the read endpoints behind the public pages; a few small helpers the pages call (subnet logos, the announcement banner, the site's own analytics beacon and the newsletter's sign-up, confirm and unsubscribe forms) are left out. Every yield comes as two fields, labelled on the site exactly as here: apr is the APR (simple) and apy the APY (compounded), computed from the apr with one shared rule (APR vs APY).

Two inputs do not come from the chain: the TAO/USD rate (CoinGecko), used only to convert τ figures to USD, and news content — the RSS and Atom feeds of subnet teams and of ecosystem outlets (blogs, newsletters, the press, Medium, Reddit, YouTube), Google News, the official X API, and GitHub release and commit feeds, which also give the development counts. Neither enters any τ price, pool, stake, emission or yield figure. Subnet logos are images Taosis's server downloads from the address in each subnet's on-chain identity. Here the rate is served by /markets/tao-usd and /markets/tao-usd/history, the news by the /news and /dev-activity endpoints, and the logos by /markets/logo/{netuid}; everything else is read from the chain or from Taosis's own index of it.

Base URL

https://taosis.com/api/backend

Example

curl https://taosis.com/api/backend/markets/subnets

Machine-readable contract

OpenAPI JSON — OpenAPI 3.1 contract, generated from the running API.

The one rule that matters

null means unknown, never zero. A figure Taosis could not verify comes back as null, and a probability it cannot support is absent rather than 0. Code that treats null as 0 will state something false — a subnet with no observed registrations is not a subnet with no deregistration risk. The full contract.

Markets

Subnet prices, reserves and market columns — one row per subnet, refreshed every few minutes.

GET/markets/subnets?spark=0

Every subnet: α price, its 1h/24h/7d/30d/90d moves (change_1h … change_90d), reserves, apr (APR (simple)) and apy (APY (compounded)), 24h volume with its sides (inflow_24h_tao / outflow_24h_tao) and the prior 24h (volume_prev_24h_tao, volume_change_24h), turnover_24h, buy_count_24h / sell_count_24h / unique_buyers_24h / unique_sellers_24h, the sell-off figures (selloff_value_tao, selloff_price_tao, selloff_discount), τ flows, emission and its per-day emission_split, tempo, swap fee, owner keys and the owner's own selling (owner_net_alpha_sold_7d/_30d, owner_net_tao_sold_7d/_30d, owner_net_alpha_transferred_7d/_30d, owner_alpha_held with its block and time, owner_sold_share_7d/_30d).

note spark=0 drops the 7-day price series, about an eighth of the body (479 KB → 419 KB uncompressed, measured on 28 Sep 2026) — use it when you only need to name and price a subnet. apr is null when no validator on the subnet is paid or the reading is more than 2 hours old; apy is null whenever apr or the tempo is. volume_24h_tao, inflow/outflow, the counts and buyers/sellers are 0 when Taosis's block index covers the window and nothing traded, and null when it cannot vouch for the window (a gap, the index more than 15 minutes behind, or the netuid registered again inside it). The owner_* windows stay null until the index covers them after block 9,138,689 (2026-09-24 16:20 UTC). emission_split is null on root, while the subnet is not emitting, or when the per-block α emission is unknown. Each change_* is null without a price sample near the start of its window from the current registration on; change_90d takes the nearest within 13 hours either side, since prices that old may be the archive's daily samples.

GET/markets/subnets/{netuid}

One subnet's full market row, including its τ flows and emission read from the chain's own counters.

note Same fields and null rules as the list. net_flow_24h / net_flow_7d: users' net staking, Δ SubnetTaoFlow between the latest sample and the one nearest 24 h / 7 d earlier, never rescaled — the real span is flow_24h_window_blocks / flow_7d_window_blocks, from flow_*_anchor_at; it excludes emission, chain buys and root-basket trades. net_protocol_flow_24h: Δ SubnetProtocolFlow (emission + chain buys + basket buys − basket sells). emission_captured_24h: measured Σ (SubnetTaoInEmission + SubnetExcessTao) × blocks; net_basket_flow_24h = net protocol − captured, negative when basket trades took τ out. inject_tao_per_block / buys_tao_per_block and emission_pct all come from one block, flow_tick_block. emitting:false = the chain has not started emission there: it receives nothing, so emission_pct, buys_*, inject_tao_per_block and emission_tao are a verified 0 (null only while the network total is unread), and the 24 h protocol-flow split and emission_split are null. flow_reset_mode:true = the chain's flow EMA is live and clears both counters every block, so the flow deltas are null. balancer_reservoir_active:true = the injected τ is not this block's emission. owner_alpha_held is the chain's own reading at owner_alpha_held_block (null when older than 8 h or when the owner is outside the subnet's 100 largest holders); on a subnet with no α staked out at all it and holders are a verified 0 with no block.

GET/markets/subnets/{netuid}/ohlc?interval=15m|1h|4h|1d|1w

OHLC candles of the α price with the τ volume of indexed fills. Prices are read from the chain: Taosis's own samples every ~5 minutes since 24 Aug 2026, and before that samples read back from the archive node to dTAO's launch on 13 Feb 2025. Only the netuid's current registration: a row counts when its block is after the registration block, so a dissolved subnet's prices are never mixed in.

note Each interval carries its own lookback: 15m the last 7 days, 1h the last 90 days, 4h, 1d and 1w the whole history. A candle's open is the previous candle's close when that candle is the one just before (else its own first sample), and its high and low include the open. volume is 0 when nothing traded and null for a bucket that ended before the fill index starts (indexed_since on /markets/stats) — not indexed then, not zero. hours= is rejected with 400 — this endpoint buckets by interval, and silently ignoring an unknown parameter would be worse than refusing it.

GET/markets/subnets/{netuid}/chart?hours=

Price series for charting.

GET/markets/stats

Network totals, with indexed_since: the time of the oldest fill, movement or lock Taosis has indexed.

GET/markets/tao-usd

TAO/USD rate, with its 24h change and the time it was sampled.

note USD figures use an external TAO/USD rate (CoinGecko), never used in pool, stake or yield math. The 24h change is null unless a sample from 24 to 30 hours ago exists.

GET/markets/tao-usd/history?interval=15m|1h|4h|1d|1w

TAO/USD per candle bucket, for converting a price chart to USD: the same intervals, bucket grid and lookback as /markets/subnets/{netuid}/ohlc, so each candle converts at the rate of its own time, never today's.

note Source: CoinGecko, also named in the X-Data-Source response header. The series starts at the first rate Taosis stored — it is not read back like the α prices — so a USD chart can begin long after the τ one. A bucket with no sample is absent, not filled in. Any other interval is a 400.

GET/markets/trades?limit=

Recent indexed pool fills.

Network

TAO itself: issuance and halvings, the supply split, subnet registration, and network-wide market history. Every "now" figure carries the block and time it was read at; every projection says what it holds constant.

GET/network/tokenomics

Issued supply of the 21,000,000 τ maximum, the supply split (root / subnet pools / wallets), the block reward, measured issuance over 200 blocks, 24h and 7d (with what was recycled or burned), the next halving with two estimated dates, and the halving schedule H1–H12.

note The block reward is worked out from TotalIssuance with the runtime's halving rule; the chain's BlockEmission item is out of date and is not used. stale:true when the last sample is over 30 minutes old. Before the first sample every figure is null and the lists are empty.

GET/network/registration

The subnet registration cost now (the runtime's SubnetRegistrationRuntimeApi), its decay per block and per day, the floor and when it is reached, when the next registration is allowed, the price right after a registration, and projections at 1, 7, 14 and 30 days.

note formula_verified:false means Taosis's own formula did not reproduce the runtime's price at the same block — show the cost only, not the decay or the projections.

GET/network/registration/history?days=1..365

Registration cost over time, plus the registrations in the window with the τ each one locked.

note Hourly points up to a few days, daily beyond (bucket says which).

GET/network/registrations?limit=1..500&offset=

Every subnet registration Taosis has tracked, newest first: netuid, block, time, the τ locked, and whether that subnet is still the current one on its netuid.

note lock_tao is null where the chain holds 0 (subnets registered before dTAO). Subnets dissolved before tracked_since are not listed: the chain only holds the current subnet on each netuid.

GET/network/market-history?days=1..365|all

Network-wide daily history: the sum of α prices, τ in subnet pools vs τ on root, and daily α and root volume; plus the same figures now.

note days=all is every stored day, back to dTAO's launch on 13 Feb 2025; the default is 30. Days before 1 Sep 2026, and any later day the live sampling missed, have source archive: read back from the chain archive at one block of the day, with every pool that existed then (subnets dissolved since included), τ on root, and no volume. A day with volume_complete:false has null volumes — a gap, never 0. That includes every day up to 2026-09-01, before the per-leg trade index was complete. Today (partial:true) carries its volume so far.

GET/network/emission-history?days=1..365&top=1..30

Each subnet's share of the τ emitted per block, one point per day, for the top N subnets plus "other".

note A series is null on days before its subnet's current registration; the dissolved predecessor's share is inside other, so each day still sums to 1.

GET/network/subnets/{netuid}/history?days=1..365|all

One subnet's daily history: price, τ in pool, α in and out, emission share and root proportion.

note days=all reaches back to dTAO's launch on 13 Feb 2025, or to the registration when later; the default is 90. Only days from the registration that holds the netuid now (registered_block); an earlier subnet on the same netuid is never mixed in. A day with source archive was read back from the chain archive at its block: price and pool only (a few the price alone), α out, emission share and root proportion null.

GET/network/movers?limit=1..20&min_pool_tao=

Top gainers and losers over 24h, the most traded subnets, and the biggest net inflow and outflow.

note Only pools of at least min_pool_tao τ (default 1,000) are ranked on price. A subnet registered again in the last 24 h has no change and no volume. most_traded_24h is only meaningful while volume_complete is true.

GET/network/simulate-stake?netuid=&amount_tao= | ?netuid=&amount_alpha=&hotkey=

Staking return projection: what a stake of amount_tao (or α already held) on one subnet and validator becomes over 1, 3, 6 and 12 months at the validator's yield measured now — at APR (simple) and at APY (compounded) — with the entry through today's pool (fee and price impact) and the τ value at today's price or sold into today's pool.

note Exactly one of amount_tao and amount_alpha, else 400; a hotkey that is not a checksum-valid ss58 address, 400; unknown subnet 404. A projection with the yield and the α price held constant — not a forecast. When the pool is older than 30 minutes or predates the subnet's registration, or the hotkey is not a validator on that subnet, unavailable_reason says so and nothing is quoted. Root (netuid 0) is not simulated — its per-validator yields are on /validators/top?netuid=0. Read-only: it never builds or signs a transaction.

Risk

The questions no other Bittensor API answers — and the ones most likely to return null on purpose.

GET/markets/dereg

The deregistration prune queue: rank, immunity, live registration lock cost.

note subnets_registered and at_capacity come from the chain snapshot (network count against SubnetLimit); both are null when that snapshot is missing — a registration prunes a subnet only when at_capacity is true.

GET/markets/simulate/dereg/{netuid}

Modelled deregistration probability for one subnet.

note null when too few registrations have been observed to estimate one. null is NOT zero risk.

GET/markets/conviction/{netuid}

Locked α, matured conviction and progress toward the 18% ownership takeover threshold.

note top_lock_account / top_lock_conviction_alpha is the strongest challenger: the top-scoring hotkey that another coldkey than the owner's owns, the only kind the chain hands a subnet to — not the subnet's largest lock. takeover_progress is its conviction ÷ the threshold. owner_side_hotkey / owner_side_conviction_alpha is the owner's side: the top-scoring hotkey that cannot take the subnet, with the owner's own locks (OwnerLock, DecayingOwnerLock) counted on the owner hotkey. The runtime changes the owner only when the top-scoring hotkey of all clears the bar and belongs to another coldkey, so takeover_progress ≥ 1 is not eligibility while owner_side_conviction_alpha is larger, nor before the subnet is a year old. owner_side_* null = not measured (never 0); 0 = measured, no lock.

GET/markets/simulate/conviction/{netuid}?account= | ?locked_alpha=&perpetual=

Project a lock forward using the runtime's own decay function.

GET/markets/holders/{netuid}?limit=

Holders and concentration — HHI, Nakamoto coefficient, top-10 share, Gini — and the largest holders with their profit.

note reconciled:true when the holder balances add up to the chain's TotalAlphaStaked within 2% (drift = total_alpha ÷ target_alpha − 1, checked on every pass; checked_at says when). The concentration figures are null unless reconciled and coverage ≥ 0.98. as_of = when the balances last changed; basis / basis_at / seed_block = the last whole chain read (a full scan or a refresh). reregistered:true = the netuid was registered again after the balances were read: every figure is null and top is empty. Per holder: profit since 1 Sep 2026 03:25 UTC (block 8,969,695) in τ and USD, split trading / staking, with status full_history | since_t0 | unverified and flags; usd_now / total_tao_at_usd_now / usd_fx_effect separate the TAO/USD move from the τ result. pnl.usd_now is the rate of the last P&L computation and is null once that is stale. limit is clamped to 1–100.

GET/markets/holders/{netuid}/history?days=1..730

Concentration history: one point per UTC day with holders, total α against the chain's TotalAlphaStaked, reconciled, HHI, Nakamoto, top-10 share and Gini.

note Each point is the last published state of that day, the owner excluded. A missing day was not measured — never 0. Days before the netuid's current registration are dropped. available:false before the history table exists, which is not the same as "no data". days outside 1–730 is a 422.

GET/markets/attribution/{netuid}?hours=

Decompose a price move into trading versus emission — exact arithmetic, not a fitted model: the named parts plus the published residual equal the whole move.

note Publishes a residual and an explained flag; explained:false means the named causes cover under 90% of the move. share is a fraction of the net move and is unbounded when causes offset each other — use log_contribution for a bounded figure.

GET/markets/takeover?limit=

Every subnet ranked by how close its strongest challenger — the top-scoring hotkey another coldkey than the owner's owns — is to the 18% ownership threshold, with the remaining distance priced in τ and the owner's side it must also out-score.

note top_lock_* is that challenger, not the subnet's largest lock; owner_side_conviction_alpha is the owner's side (see /markets/conviction/{netuid}): the top-scoring hotkey that cannot take the subnet, the owner's own locks counted on the owner hotkey. takeover_progress ≥ 1 is not eligibility while owner_side_conviction_alpha is larger, nor while age_gate_open is not true; remaining_alpha is the distance to the bar only. owner_side_conviction_alpha null = not measured, never 0. Subnets whose α out cannot be read are counted in unknown_subnets (named in unknown_netuids) and excluded — never ranked at 0, which would read as safe; those whose eligible α reads 0 on chain are counted in no_eligible_subnets (no_eligible_netuids): nothing to take over. limit is clamped to 1–200. The chain opens a subnet to takeover only one year (age_gate_blocks, 2,629,800 blocks) after it registered: each row carries registered_block, age_gate_block, age_gate_open (null when the registration block or the head is unknown — never assumed open) and age_gate_opens_at, an estimate at 12 s a block while the gate is closed.

GET/markets/correlation?netuids=1,64,8

Pairwise return correlation between subnets — how much they actually move together.

note Pearson r of hourly log returns over the last 90 days of α prices — Taosis's own samples, and the chain archive's before they began — each subnet from its current registration. r is null under 48 common hours — not enough overlap is not zero correlation.

Validators

Yields computed from the chain — APR (simple) and APY (compounded), on each subnet and on root — and the track record behind them.

GET/validators?limit=1..500&offset=&q=

Every delegate, largest stake first: on-chain name, take, total stake split into root_stake_tao and alpha_stake_tao (α valued at each subnet's price), stake_weight_tao (α + root × TaoWeight), dominance, the 24h stake change, nominator_count, the main-subnet yield (best_apr / best_apy) and the root yield (root_apr / root_apy).

note The number of delegates matching q comes in the X-Total-Count response header; paging is stable (ties broken by hotkey). best_apr is the 24h median on the main subnet (largest α stake by τ value, ≥ 500 τ); null means no such subnet paid dividends in the window — not 0%. root_apr is the root stakers' return from the chain's BasketTwr series over root_yield_window_blocks (~7,200) to root_yield_block; 0.0 is a verified zero (nothing paid into the fund). When root_apr is null, root_yield_reason says why: no_root_series (a fresh read found no fund for this hotkey), collecting (no reading ~24 h back yet), series_restarted (the fund started or restarted inside the window) or stale (no reading under 3 h old). dominance is null on every row when any delegate's weight is unknown. The stake_change_24h_* fields compare with the reading 22–26 h earlier (stake_change_ref_at) and include α price moves; root_stake_change_24h_tao is exact. nominator_count is counted for the 256 largest delegates, a batch each hourly pass, oldest count first; nominators_at says when it was read, and it is null for every other delegate and when the count is over 24 h old — never sum it: one coldkey can stake on several. child_key_subnets is how many subnets the hotkey validates on through child keys (0 is a verified none); null when the child-key snapshot is over 1 h old. q matches the on-chain name case-insensitively, τ as t, with % and _ taken literally.

GET/validators/page?limit=1..500&offset=&q=

One page of the same directory with its total: {total, limit, offset, out_of_range, as_of, rows}.

note out_of_range is true when offset > 0 and offset ≥ total; rows is [] then. Use it to answer "page 99 of 36" with a 404 instead of an empty page. as_of is when the directory pass that wrote these rows read the chain; null when rows is empty.

GET/validators/count?q=

How many delegates the directory holds, or match q.

GET/validators/top?netuid=&limit=1..128&hotkey=…

Validators on one subnet — its permitted UIDs plus every hotkey the chain paid there, parent hotkeys paid through child keys included — safe default first, with apr (APR (simple)), apy (APY (compounded)) and yield_window_blocks. netuid=0 lists the delegates with root stake: stake in τ, apr/apy = the root yield.

note hotkey= is repeatable (at most 128, else 422) and returns only those hotkeys, with the same ranking; a hotkey that is not a checksum-valid ss58 address is a 400, and a valid one that is not a validator there is skipped. An unknown subnet is a 404. limit defaults to the number of hotkeys asked for, else 5. On a subnet apr is null for a validator the chain did not pay last epoch — not 0% — and stake is the α its nominators hold (TotalHotkeyAlpha). On root, validators with a known yield (0.0 included) rank first, then the others by stake, and yield_reason carries the same values as root_yield_reason; more than 128 root validators have a known yield, so ask for given hotkeys with hotkey=.

GET/validators/reliability/{netuid}/{hotkey}

Has this validator actually paid, consistently: paying ratio, median APR, spread, permit losses, stake trend — with apy_median, worst_apy and best_apy beside the APRs.

note Verdict is "insufficient" until the observed series is long enough (12 observations over 2 days). The series is Taosis's own epoch samples since it began recording — not back-filled — and observed_days says how long it is; on a netuid registered again since, it starts at the current subnet's registration, never the dissolved one's (series_start and registered_block say where). Not shown on any page: this endpoint is the only place to read it. Each APY is its APR compounded at the subnet's tempo.

Accounts & portfolio

Anything an address holds is public on-chain data — no key and no wallet connection.

GET/accounts/{ss58}

What an address is (coldkey or hotkey, classified from chain evidence) and what it holds: free τ balance, α positions with average buy price, validator name, earning status and APR (simple) / APY (compounded), delegated stake, recent fills, plain-language history.

note 404 on an invalid address; 503 when the address has never been read successfully. A snapshot read from the chain and kept up to 10 minutes; computed_at says when it was read, and free_tao is null — not 0 — when no read has succeeded. Prices older than 30 minutes are null (root is exactly 1 τ). history_error set = the fills were not read, which is not "no activity".

GET/portfolio/{ss58}/overview?method=wac|fifo&refresh=false

A wallet at one chain block: free, reserved and root τ, every α position priced, its value and what it would realize sold into its own pool now, the 24h price effect, per-subnet validators with APR (simple) / APY (compounded) and earning status, holder rank, cost basis, and staking earned since 1 Sep 2026.

note 400 for an invalid address, 503 when the chain read fails (or the last good read, flagged stale, for up to 15 minutes). Cached 30 s; refresh=true forces a new read once the cached one is 5 s old. earnings.status computing = poll again.

GET/portfolio/{ss58}/earnings

Staking earned and total P&L since 1 Sep 2026 03:25 UTC (block 8,969,695), per subnet and in total.

note Totals are null until every non-root subnet is verified; *_verified fields sum the verified ones. A wallet with nothing but root reads a verified 0. Netuids are reused: subnets holds the subnet on each netuid now, previous_subnets the one it replaced (with replaced_at_block) when this wallet traded or held it.

GET/portfolio/{ss58}/history?range=7d|30d|since_t0

The wallet's value, one point per UTC day, read from the archive node.

note status computing = points are being read; poll. A day that could not be read or priced is in missing_days — a gap, never an interpolated point.

GET/portfolio/{ss58}/activity?kind=all|trades|moves|locks|tao&cursor=&limit=1..200

The wallet's indexed activity, newest first: trades, stake moves and transfers, locks, burns and fees, and plain TAO transfers.

note Paged with next_cursor (null = the end). indexed_since and transfers_recorded_since bound what Taosis has seen: TAO transfers are recorded from the deploy of this feature onward.

GET/portfolio/{ss58}/activity.csv?kind=

The same activity as a CSV file, up to 200,000 rows.

note Line 1 is a # comment naming the coverage; line 2 is the header. Text cells that start with = + - @ are prefixed with a quote.

GET/portfolio/positions?address=

α positions for one address, with the block they were read at.

note 400 for an invalid address, 503 when the chain read fails. total_value_tao is 0.0 only for a wallet read and holding nothing; null when a price is missing or older than 30 minutes.

GET/portfolio/pnl?address=&method=wac|fifo

Cost basis and P&L with a coverage model.

note States coverage per position; below full coverage the figure is marked partial rather than guessed. USD figures are null when the TAO/USD rate at a fill is more than 3 hours old.

GET/markets/metagraph/{netuid}

A subnet's hyperparameters, its top neurons by reward (stake, consensus, axon included) and its child-key graph.

Blocks & search

The block explorer and the one search box. Old blocks come from the public archive on demand — one connection, cached hard — plus the movement and activity feeds built on the same index.

GET/explorer/search?q= (128 characters at most)

Resolves anything a visitor pastes: an address (checksum checked), a block number ("9143700", "#9,143,700", "block 9143700"), a block hash (0x + 64 hex), a subnet ("sn 64", a number, a name) or a validator name. Returns {query, kind, target, matches, detail}.

note target is the site path to open, or null when nothing matched or when more than one subnet or validator partly matches the text (matches then lists up to 10 subnets, then up to 10 validators, each validator with its hotkey, how many hotkeys share the name and the stake); an exact name, or a single partial match, opens directly. A bare number is the subnet when that netuid exists, with the block of the same number as an alternative. A hash is looked up in Taosis's index, then on the chain (the entrypoint first, the public archive only when the entrypoint does not know it); 503 with Retry-After when the chain cannot be asked right now. Extrinsic hashes are not resolved: when the entrypoint has no block with the hash and the archive is busy, the answer is no match with a detail saying so. Longer than 128 characters is a 422.

GET/explorer/blocks?limit=

Blocks Taosis has indexed, newest first, with the stake fills through a subnet pool in each (not the unstake/restake pair the chain writes around a move or transfer within one subnet).

note This is our index, not the chain's head — indexed_from/indexed_to bound what we have actually seen.

GET/explorer/block/{number}

One block: hash, parent, chain timestamp, every extrinsic (module, call, signer, result) and every event.

note 404 = the block has not been produced yet (or the number is past 2^32 − 1); the detail names the newest block Taosis has indexed. 503 with Retry-After and an X-Block-Read header (rate_limited, decode_failed, unreachable, pruned, busy, error) = it could not be read right now; the detail states that the block exists only for heights at or below Taosis's indexed head. An extrinsic whose result we could not determine returns success:null — that is not the same as false. fills:null means the block is outside our index; fills:0 means we scanned it and indexed none.

GET/explorer/movements?kind=all|transfer|move|swap&limit=

Stake movement legs from our own index: α transferred between coldkeys, moved between hotkeys, swapped across subnets — one row per leg, never paired into "A → B". This is what /transfers renders.

note An unknown kind is rejected with 400; limit is clamped to 1–200. indexed_since bounds what we have seen — it is not the chain's full history.

GET/explorer/active-wallets?days=&limit=

Activity leaderboard over indexed fills: volume in τ, buys, sells, last seen. What /accounts renders — an activity board, not a balance rich list.

note days is clamped to 1–30 and limit to 1–200; the response echoes the clamped window back in window_days. Counts pool fills only — not the unstake/restake pair the chain writes around a move or transfer within one subnet. Each window's board is computed once and kept 120 s, so a new fill can take up to two minutes to show.

News & on-chain events

Subnet news from each subnet's own sources, and events Taosis reads from the chain itself.

GET/news?netuid=&limit=1..100&offset=&types=&categories=

Indexed Bittensor and subnet news. Each item carries source_category (official, press, newsletter, community, video, onchain; null = unknown provenance) and kind (news | onchain).

note types is a comma list of rss, html, sitemap, manual, twitter, discord, github_releases, onchain; categories a comma list of category names. An unrecognised value is rejected with 400, not dropped — a silently unfiltered feed would look like a working filter. On-chain events are opt-in: they appear only when types or categories names onchain. With ?netuid=, only items published after the subnet's current on-chain registration are listed. An on-chain item's id is 100,000,000,000 + its event id, and its url is a site path (/block/N, /subnets/N).

GET/news/{id}

One news item — or, for ids from 100,000,000,000, one on-chain event in the same shape.

GET/news/ids

Ids and publication times of the published news items (what the sitemap lists). On-chain events are not in it.

GET/news/stats?days=&types=&categories=

Counts by source type and by category, the on-chain event count, and the most active subnets.

note onchain is null before on-chain events exist — never a fake 0.

GET/news/subnets?days=&types=&categories=

Every tracked subnet in netuid order with its name and item count over ?days= (default 7), scoped by ?types= and ?categories=.

GET/news/sources?netuid=

The sources Taosis polls for one subnet: type, category, name, URL, last check time and status.

GET/news/events?netuid=&kinds=&limit=1..100&offset=

On-chain events, newest first: subnet registered, re-registered or deregistered, owner changes, emissions off/on, deregistration risk, immunity ended, takeover locks, take raised, owner key swaps, child keys, runtime upgrades, halvings, identity and hyperparameter changes, miner burn, large trades — each with its block and a kind-specific data object.

note exact_block:false with since_block set = it happened in (since_block, block]; block null = detected from a metagraph read, time only. current_subnet:false = history of an earlier subnet on a reused netuid (no name or logo then). 503 before events exist.

GET/news/events/{event_id}

One on-chain event.

GET/news/feed?netuid=&types=&categories=&limit=1..100

The news (and, opted in, the on-chain events) as feed-ready JSON: title, subtitle, entries with a stable guid, permalink and categories — what /news/rss.xml is built from.

GET/newsletter/issues?letter=&limit=&offset=

Taosis Weekly and Taosis News, the issues sent so far, newest first: id, letter (weekly | news), the 7 days covered (week_start and week_end: Monday to Sunday UTC for the Weekly, Friday to Thursday UTC for News), subject and sent_at.

GET/newsletter/issues/{id}

One sent issue as archived: its letter, its structured content (the Weekly: the week in numbers, top movers, best yields and on-chain events, plus top news in content version 1 and usd_rate, the week's closing TAO/USD rate, from version 2; News — kind "news": a lead article and its groups) and its plain text, without any personal link.

note 404 for an issue that does not exist or has not been sent yet. The archive pages on /newsletter draw this content.

GET/dev-activity

GitHub development activity per subnet, from the repository named in its on-chain identity: commits over 7 and 30 days, the last commit, and a dormant flag.

note commits_7d_exact:false = at least that many (GitHub's feed lists the latest 20). Every count is null unless status is ok or empty; empty is a verified zero. status says why otherwise: no_repo, not_a_repo, not_found, pending, unavailable.

GET/dev-activity/{netuid}

The same for one subnet.

note 404 for a netuid Taosis does not track.

Status

GET/status

Freshness of the data sources behind the site, one row per subsystem, measured from the database clock. Where Taosis's fill index starts is indexed_since on /markets/stats (the oldest fill, movement or lock); where its block list starts is indexed_from on /explorer/blocks.

note clock_skew_seconds: how far the server clock runs behind chain time — a lower bound, rounded down to 0.1 s; null when there are no indexed blocks to measure against. clock_note is one sentence when the skew is over 2 s. No age is negative.

GET/health

Liveness.

Fair use

There is no key and no hard quota, but the origin is rate-limited per IP. If you need a heavy or sustained pull, cache on your side — most of this data only changes every few minutes, and the status page shows how fresh each source it tracks is, and names the ones it does not.

For LLM agents

Taosis also ships an MCP server exposing these reads as tools, with the null-is-not-zero contract stated in each tool description. It is deliberately read-only: it cannot sign, spend, place an order or cancel one. It is not published for download; its tools wrap the endpoints listed above one-for-one, so an agent can call them directly over HTTP — same JSON, same contract, no key. robots.txt opens /api/backend/ to assistants fetching for a person's question (ChatGPT-User, Claude-User, Perplexity-User, Meta-ExternalFetcher, MistralAI-User) and keeps crawlers off it.