The Activity score API
Everything on the Terminal is available as JSON.
Use Tickerz inside your assistant
https://tickerz.com/mcp
Eight read-only tools and one that answers the referee's questions, no key. The REST API below is the same record, for code.
No key, no signup, CORS open. Base URL https://tickerz.com. Responses are cached at the edge for 60 to 300 seconds. Machine-readable OpenAPI 3.1 at /openapi.json. If you publish these numbers, attribute them as "Tickerz Activity score" with a link. Rate limit: 120 requests per minute per IP, shared across board, asset, base-rate, receipts, receipts/dataset, receipts/proof, indices/proof, status and changelog. Past that, a call returns 429 with a Retry-After header. Normal use never meets it.
GET /api/board
The full Terminal: every displayed asset with latest price, 24h move and current activity score, sorted by activity score, highest first. Assets without a score follow, by market cap. HTTP 503 when halted.
curl https://tickerz.com/api/board
updated_at- ISO timestamp of the latest snapshot
halted- true when the Terminal cannot serve live scores (for example database not connected); UI shows HALTED
assets[]- symbol, name, class (crypto | equity), mcap_rank, price, move_24h, score (the activity score, 0-100, null until a 14-day baseline exists), score_1h (the score one hour earlier), vol_mult (24h volume over the asset's 30-day baseline mean, measured, one decimal, null until a 14-day baseline exists), ts, stale (true when ts is not current: crypto more than 2 hours behind, equities more than 2 hours behind the newest equity tick, or older than 4 days)
assets[].heat, assets[].heat_1h- deprecated aliases of score and score_1h, same values, until at least 2026-12-31
breadth- unusual, scored, share, band: how many scored, current coins are at 70 or more right now, the share, and its band (lone under 3%, mid, crowd at 30% or more). Null when halted
GET /api/asset/{symbol}
One asset in depth: latest snapshot, 30 days of activity score readings, any open event, past events with receipts, a 24h spark and market context when present.
curl https://tickerz.com/api/asset/btc
asset- symbol, name, class, mcap_rank and listing metadata
latest- price, move_24h, vol_24h, mcap, ts
vol_mult- measured volume multiple of the latest snapshot, one decimal, null under a 14-day baseline
scores_30d[]- ts, score: activity score readings for the last 30 days, every fourth stored reading (hourly for crypto, every 40 minutes in market hours for stocks), oldest first; the last point is the latest score
heat_7d[]- ts, heat: deprecated alias of scores_30d, the same readings in the old shape, until at least 2026-12-31. Each heat equals the score at the same ts
open_event- the active event with score_at_open and peak_score, or null
past_events[]- the latest 10 closed events with score_at_open, peak_score and 24h / 7d / 30d receipts. peak_heat is the deprecated alias of peak_score
spark_24h[]- recent price points for the 24h spark line
context- derivatives context when present (funding, open interest); may be sparse
venues[]- where it trades: venue, name, kind (spot | perp | futures | options | prediction), venue_symbol, url, verified_at, trades_as (the venue's ticker when it differs, such as kPEPE or 1000PEPE), multiplier, us_available (false where the venue does not serve US users: Hyperliquid, Polymarket). Checked nightly against each venue's own product list: Binance.US, Coinbase, Kraken and Robinhood spot, Coinbase futures, Hyperliquid perpetuals, Kalshi and Polymarket. Plain links, not paid
venues_checked_at- the oldest of the latest complete reads of every venue list for the asset's class. Null when any of them is more than 7 days old, when the asset was added after it, or when a venue could not confirm the asset either way. An empty venues[] means not listed only when this is set
asset.active, asset.display- both true when the asset is on the Terminal. Otherwise (pegged, left out, or sharing a stock's ticker) the last reading stays readable, the nightly venue check skips the asset and venues_checked_at is null
GET /api/base-rate/{symbol}
What historically happened after a move like this asset's current one: the median, spread and share that beat the benchmark at 1, 7 and 30 days, next to an ordinary day. Only on days with an activity score of 70 or more, and only for groups that hold. Otherwise base_rate is null with a reason. Stocks are measured against SPY. Same as the MCP base_rate tool. HTTP 404 not_listed for an unknown symbol, 503 when halted.
curl https://tickerz.com/api/base-rate/sol
(the rate)- symbol, move_24h, bucket, breadth, coin_in_study, n, n_dates, top_date_share, horizons (1d, 7d, 30d), ordinary, edge_7d_pts, edge_7d_ci, plain, caveat, source; benchmark on stock rates only
base_rate, reason- when there is no rate the body is symbol, base_rate null and reason: a score below 70, a withheld group, a reading that is not current, or the stock study
GET /api/receipts?limit=30
The public record: closed events (cooling or resolved), newest first, each with receipts at 24h, 7d and 30d. A receipt not yet due has ret_pct and resolved_at null.
curl "https://tickerz.com/api/receipts?limit=50"
events[]- id, opened_at, closed_at, open_price, assets (symbol, name), score_at_open (the activity score that opened the event), peak_score (the highest while open), trigger_z_vol, trigger_z_move, open_vol_mult (volume multiple measured at open), driver_tag, driver_confidence, driver_source_headline, driver_source_url (the stated cause and its source; unclassified reads Driver: not identified), receipts. peak_heat is the deprecated alias of peak_score
receipts[]- horizon (24h | 7d | 30d), due_at, ret_pct and resolved_at (null until it resolves; resolved_at is the next Terminal tick at or after due_at), benchmark (BTC for crypto, SPY for stocks) and benchmark_ret_pct, its return over the same window (null until filled)
proofs[]- OpenTimestamps rows: event_id, horizon (open | 24h | 7d | 30d), digest_sha256, bitcoin_height, stamped_at. open is the event as called. New events are stamped within about an hour of open. Events already on the record when open stamping shipped on September 22 2026 were stamped later, some after their outcome: compare stamped_at with opened_at. A receipt card says Called before the outcome only for an open record stamped within 2 hours of open and confirmed in Bitcoin
limit- 1 to 100, default 30
GET /api/card/{symbol}
PNG share card for the asset, rendered with Satori. Cached at the edge. HTTP 404 for a ticker Tickerz does not track; an asset that is not on the Terminal gets a card that says so.
curl -OJ https://tickerz.com/api/card/btc
Content-Type- image/png
symbol- ticker, case-insensitive
GET /api/status
Public Terminal health: ok, degraded, or halted. Degraded when the newest snapshot is older than 45 minutes, a receipt is overdue, or a proof has no Bitcoin height after 24 hours. HTTP 503 when halted. HTML twin at /status.
curl https://tickerz.com/api/status
state- ok | degraded | halted
checked_at- ISO timestamp of this check
board- halted, updated_at, age_minutes, asset_count, scored_count
receipts- halted, recent_count, resolved_7d (receipts resolved in the last 7 days)
proofs- pending, stuck, oldest_hours
receipt_lag- overdue, oldest_overdue_min, late, resolved_checked
checks[]- id, ok, detail
GET /api/changelog
Curated Terminal ship notes plus recent open and closed events. No token required.
curl https://tickerz.com/api/changelog
generated_at- ISO timestamp
ships[]- date, pr, title, summary
score_events[]- id, kind (open | closed; a closed event's receipts may still be pending), symbol, name, opened_at, score_at_open (the activity score that opened the event), peak_score (the highest while open)
score_halted- true when the activity score feed is unavailable
heat_events[], heat_halted- deprecated aliases of score_events and score_halted, until at least 2026-12-31. heat_events keeps the old kind value resolved where score_events says closed. Each event also carries peak_heat, equal to peak_score
GET /api/receipts/dataset
Open dataset of closed events (cooling or resolved), one flat row per event. Returns stay null until each receipt resolves. Includes hidden assets with display=false. Omits trigger z-scores. Paginate with limit and offset (max 5000 per page). First export window starts 2026-08-27. Free for personal and non-commercial use with attribution; see /terms section 04.
curl "https://tickerz.com/api/receipts/dataset?since=2026-08-27&format=csv&limit=1000"
since- YYYY-MM-DD, clamped to a minimum of 2026-08-27
format- json (default) or csv
limit- 1 to 5000, default 1000
offset- pagination offset, default 0
rows[]- event_id, opened_at, symbol, name, class, display, heat_at_open, reference_price, ret_24h, resolved_24h, ret_7d, resolved_7d, ret_30d, resolved_30d, score_at_open, peak_score, benchmark, benchmark_ret_24h, benchmark_ret_7d, benchmark_ret_30d
benchmark- BTC for crypto, SPY for stocks. benchmark_ret_24h, _7d and _30d are its returns over the same windows as ret_24h, ret_7d and ret_30d, null until filled
score_at_open- activity score of the tick that opened the event
peak_score- highest activity score while the event was open
heat_at_open- deprecated: despite the name it is the peak, equal to peak_score. Use score_at_open for the opening score. Remains until at least 2026-12-31
next_offset- next page offset, or null when done
halted- true when the database is not connected
GET /api/receipts/proof?event_id=&horizon=
OpenTimestamps proof for one event record. horizon=open is the event as called. New events are stamped within about an hour of open. Events already on the record when open stamping shipped on September 22 2026 were stamped later, some after their outcome, so compare stamped_at with opened_at. 24h, 7d and 30d are the resolved receipts. Add format=ots to download the .ots file. Verify at opentimestamps.org or with the ots CLI.
curl "https://tickerz.com/api/receipts/proof?event_id=EVENT_ID&horizon=24h"
digest_sha256- SHA-256 of canonical_json
canonical_json- the exact bytes that were hashed: compact JSON with keys in the order below
canonical- receipts: event_id, symbol, opened_at, open_price, horizon, resolved_at, ret_pct. open: event_id, symbol, opened_at, open_price, horizon, score_at_open, trigger_z_vol, trigger_z_move
stamped_at- when the digest was sent to the OpenTimestamps calendars
bitcoin_height- Bitcoin block height once the stamp upgrades, else null
ots_url- same endpoint with format=ots
GET /api/indices/proof?day=
OpenTimestamps proof for one daily seal of the Tickerz Index: every complete period written or revised since the seal before, hashed and stamped in Bitcoin. The newest seal when day is omitted. Add format=ots to download tickerz-seal-DAY.ots and verify it with the OpenTimestamps client or at opentimestamps.org.
curl "https://tickerz.com/api/indices/proof?day=2026-09-23"
day- the seal day, UTC
digest_sha256- SHA-256 of canonical_json
canonical_json- the exact bytes that were hashed
stamped_at- when the digest was sent to the OpenTimestamps calendars
bitcoin_height- Bitcoin block height once the stamp upgrades, else null
ots_proof_base64- the .ots file, base64
The referee
One sealed attention question per crypto event: $SYM reads 40 or more at the event's open plus 24 hours, UTC. Answers are at_or_above or below. It resolves from the first Activity score Tickerz stores at or after that minute, and is void when none lands within 3 hours. Three nulls are frozen when it opens: the base rate, persistence and always below. Tickerz answers with the base rate and is graded too. No login, one answer per caller per question and at most 3 per address, answers close 4 hours after the question opens, and the crowd split stays hidden until then. No ranking, no prizes. The page for people is /questions.
GET /api/questions?state=open&symbol=&limit=
Every question, newest first, with calibration over every resolved question. state is open (still waiting on its reading), resolved (resolved or void) or all.
curl "https://tickerz.com/api/questions?state=open"
questions[]- id, event_id, symbol, statement, threshold, answers (key to label), state (open | closed | resolved | void), accepting_answers, event_opened_at, opens_at, closes_at, resolves_at, at_open (score, vol_mult)
nulls- base_rate (answer, hits, n, share), persistence (answer, score, ts), always (answer). Frozen when the question opened
tickerz- answer and rule (base_rate). Tickerz answers 40 or more when the base rate is at least half
answers_count- answers from outside Tickerz so far, agents left out
crowd- at_or_above, below, n, majority (null on a tie), mean_probability. Null until answers close. Agents never count in it
agents_count, agents- answers from agents, counted apart from the crowd; agents is n and labeled[] (label, answer, probability), null until answers close
outcome, grades- the reading it resolved on, and who was right: crowd (null without a majority), tickerz (null when the question was not sealed before answers closed), base_rate, persistence, always
seal, answer_batches[]- OpenTimestamps state (pending | stamped | confirmed), sealed_before_close, digest_sha256, stamped_at, bitcoin_height, bitcoin_block_time
calibration- resolved, void, and hits and n for crowd, tickerz, base_rate, persistence and always, over every resolved question
GET /api/questions/{id}
One question with proofs[]. The question's canonical_json and .ots proof are served at once. Each hourly answer batch's proof waits until answers close, so a batch cannot show the split early. sha256(canonical_json) equals digest_sha256.
curl https://tickerz.com/api/questions/QUESTION_ID
proofs[]- id, kind (question | answers), digest_sha256, canonical_json, n_answers, bitcoin_height, stamped_at, ots_base64
question canonical- compact JSON, keys in this order: kind, question_id, event_id, symbol, statement, threshold, event_opened_at, opens_at, closes_at, resolves_at, score_at_open, vol_mult_at_open, base_rate_hits, base_rate_n, persistence_score, persistence_ts, null_base_rate, null_persistence, null_always, tickerz_answer
answers canonical- kind, batch_id, question_id, sealed_at, answers[] (id, answer, probability, answered_at), sorted by answered_at then id. No caller is in it
POST /api/questions/{id}/answer
Answer an open question. No key, no login. One answer per caller per question: a repeat returns 200 with already_answered true and does not echo the first answer. At most 3 answers per question from one address, whatever the user agent (409 address_cap past that). 410 once answers close. 20 answers per minute per address, shared with the MCP tool submit_forecast. The body must be JSON. Unlike the reads, this route sends no CORS headers, so another site's page cannot answer from its visitors' browsers; curl, servers and agents are unaffected.
curl -X POST https://tickerz.com/api/questions/QUESTION_ID/answer \
-H 'content-type: application/json' \
-d '{"answer":"below","probability":0.35}'answer- at_or_above (it reads 40 or more) or below
probability- optional, 0 to 1: the chance it reads 40 or more. Must agree with the answer; 0.5 fits either
agent- optional: the name of an agent answering for someone, 1 to 32 letters, digits, spaces, dots, hyphens or underscores (400 bad_agent otherwise). The answer is stored as an agent's, never counts in the crowd split, and is shown by name beside the crowd once answers close. The one-answer rule still applies
returns- 201: answer_id, question_id, answer, probability, answered_at, closes_at, already_answered false, split_shown_at. Keep answer_id: it is in the sealed batch. 200 on a repeat: question_id, closes_at, already_answered true
caller- a keyed hash of the question, the address and the user agent for the one-answer rule, and a keyed hash of the question and the address (IPv6 by its /64) for the per-address cap. Neither is published
Push on open and resolve
Push within the hour after an event opens or a receipt resolves. One HTTPS URL per email. No API key. On subscribe Tickerz GETs your URL with ?challenge=; echo the token as plain text or {"challenge":"<token>"}. Deliveries are signed with HMAC-SHA256 of the raw body (X-Tickerz-Signature: sha256=...). Three attempts with backoff. Any endpoint that can answer the challenge works: your own script, a serverless function, or a Make scenario with a webhook response. Discord webhook URLs and Zapier catch hooks cannot answer it and need a relay.
POST /api/webhooks/subscribe
Register one URL per email. Confirms via GET challenge on the URL. A new email gets the signing secret once; an email already on file is left as it is and gets the same ok answer. Same-site JSON only: 403 cross_site, 415 not_json, 429 after five signups from one address in ten minutes.
curl -X POST https://tickerz.com/api/webhooks/subscribe \
-H 'content-type: application/json' \
-d '{"email":"you@example.com","url":"https://hooks.example.com/tickerz"}'email- contact address; unique; one URL
url- HTTPS endpoint that echoes ?challenge=
secret- HMAC key; shown once on confirm
POST (your URL)
Inbound delivery for event_opened and receipt_resolved. Verify the signature before acting.
{
"id": "delivery-id",
"type": "event_opened",
"created_at": "2026-09-12T01:00:00.000Z",
"data": {
"symbol": "GME",
"score": 85,
"heat": 85,
"event_id": "uuid",
"horizon": null,
"text": "$GME Activity score 85/100. Event opened. Volume is 2.6 times normal. Price +6.6% in 24h. Attention, not merit."
}
}type- event_opened | receipt_resolved
data.symbol- ticker
data.score- activity score, 0-100 or null. On receipt_resolved, the score that opened the event
data.heat- deprecated alias of data.score, same value, until at least 2026-12-31
data.event_id- event uuid
data.horizon- 24h | 7d | 30d on receipts; else null
headers- X-Tickerz-Signature, X-Tickerz-Delivery, X-Tickerz-Event
Eight tools, one that writes
Model Context Protocol server at https://tickerz.com/mcp (Streamable HTTP). Read-only tools, each marked readOnlyHint: board, asset, base_rate, receipts, methodology, open_questions, get_question. One tool writes: submit_forecast, an answer to an open question, on the same rules as the answer endpoint above. Same data as the JSON API above. No key. Free. Rate-limited like the public API.
# Cursor (mcp.json, Streamable HTTP)
{
"mcpServers": {
"tickerz": {
"url": "https://tickerz.com/mcp"
}
}
}
# Desktop config files and other stdio-only clients via mcp-remote
npx -y mcp-remote https://tickerz.com/mcpSources and terms
Scores are produced by the model documented on the methodology page. Machine-readable site summary at /llms.txt. OpenAPI 3.1 at /openapi.json. Crypto market data via CoinGecko. US equity data via Alpaca (IEX). Nothing served by this API is financial advice; see the Terms of Use.
Key names · September 22 2026
The API says score. Each old heat key stays as a deprecated alias with the same value, next to its new name, until at least 2026-12-31. Read the new key. The scores and the record are unchanged.
heatscoreheat_1hscore_1hheat_7dscores_30d: despite the old name it always held 30 days of readings, every fourth stored tick. Its points keep the old shape, ts and heatpeak_heatpeak_scoreheat_eventsscore_events: the same events, with kind resolved where score_events says closedheat_haltedscore_haltedheat_at_openpeak_score: it was always the peak. score_at_open is the opening scoredata.heatdata.scorein webhook deliveriesHeatEventScoreEvent: the webhook entry in openapi.json, operationId scoreWebhookDelivery. HeatEvent and heatWebhookDelivery stay beside it, marked deprecated