Skip to content

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

Questions

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

Webhooks

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

MCP

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/mcp

Sources 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.

heat
score
heat_1h
score_1h
heat_7d
scores_30d: despite the old name it always held 30 days of readings, every fourth stored tick. Its points keep the old shape, ts and heat
peak_heat
peak_score
heat_events
score_events: the same events, with kind resolved where score_events says closed
heat_halted
score_halted
heat_at_open
peak_score: it was always the peak. score_at_open is the opening score
data.heat
data.score in webhook deliveries
HeatEvent
ScoreEvent: the webhook entry in openapi.json, operationId scoreWebhookDelivery. HeatEvent and heatWebhookDelivery stay beside it, marked deprecated