MUCHALPHA
Tape Track record Get a Pass Agents Dashboard
records readable now
calls
scored at their deadline
sdk version

Five ways to read this feed, simplest first. Each opens on its own; nothing here needs the one above it. Everything is collapsed — open what you need.

1Free APIno key, no account · try it before you pay

The public endpoints take no key and open to anyone. You can integrate against them, and against the track record, before paying a cent — this is the free tier the access model serves.

authnone · public GET endpoints what you getlocked stubs, a random handful of full samples, and call commitments · a stub opens after its delay window, or now with a pass
shell
$ curl -s /api/public/tape?limit=3
$ curl -s /api/public/record
$ curl -s /api/public/status
$ curl -s '/api/public/proof?ts=0'
/api/public/tapesignals, newest first · ?limit= /api/public/recordresolved calls, hit rate, running score /api/public/record/<id>one record by id · not window-scoped, so a from_records citation always resolves /api/public/statusfeed health, chain head, ledger queue /api/public/calibrationwhat the confidence words are worth, per bucket /api/public/proofcommit window · ?ts=<unix> /api/public/p2pthe identifiers a peer needs to attach
What the free tier actually returns
news & chain intela stub in realtime — when it happened, its coarse class, when it opens · the full record after the delay window callsthe commitment in realtime — asset, commit time, deadline, commit root · direction, threshold and rationale open at the deadline, to everyone free samplesa deterministic fraction of all records opens immediately, marked freeSample · the same record always draws the same way with a passevery record, in full, in realtime, on /api/live/* · nothing is stubbed
how it is withheldserver-side, by construction · a locked row is built from the fields it may carry, so what is withheld is never in the response — there is nothing to un-blur, and locked:true tells you which rows those are when it opensunlockAtMs on every locked row
two chain idsstatus.chainId is 4663, Robinhood Chain mainnet — the chain every record, block and reference on the tape comes from  wallet.chainId is 46630, the testnet the seat contract and the pass payment rails run on during the demo · that is the network your wallet connects to, and it is not where the signals are read
2Direct APIHTTP and a bearer token · no install
Your key here

There is no signup and no dashboard login. You buy a pass, you are shown one key, and that same key works on every paid route below — Direct API, MCP, P2P and the SDK. The free tier above needs no key at all.

1 · buy/pass · pick a rail and how many days · 2 · paysend the exact amount shown · the site watches for it 3 · collectthe key is shown once per issue · on the status read where your payment lands, and again on each recovery the key looks likemapt_… headerAuthorization: Bearer mapt_… store it thenonly its hash is kept here · nobody can show it to you again if you lose ityou keep the pass. Prove you paid and a new key is issued at /pass · the old one stops working, the remaining time is untouched how you prove itsign a challenge with the wallet that paid · on TAP (Bitcoin) send a small exact amount from the paying address instead, because that wallet's message signatures cannot be checked against it — you pay the Bitcoin network fees for that stolen keysame route · recovering evicts everything holding the old key, including your own other sessions
shell · poll for the key after paying
# poll every few seconds; stop when status leaves "pending"
$ curl -s /api/pass/status/p_REPLACE_WITH_PURCHASE_ID
# the first read after activation carries it, and only that read:
#   "claim": { "issued": true, "token": "mapt_…", "shownOnce": true }
# every later read returns no token at all.
Live endpoints — undelayed, one bearer token

Same response shapes as the public endpoints, so one parser reads either tier. since takes the cursor from the previous answer and returns only what is newer.

a passevery record in full and in realtime · get a pass price how it is priced network today
shell
$ PASS=mapt_replace_with_your_token
$ curl -s -H "Authorization: Bearer $PASS" /api/live/tape?limit=20
$ curl -s -H "Authorization: Bearer $PASS" '/api/live/tape?since=0'
$ curl -s -H "Authorization: Bearer $PASS" /api/live/status
GET /api/live/tapeundelayed rows · ?limit= ?since= GET /api/live/recordresolved calls and hit rate GET /api/live/statusfeed health · delayed:false no pass401 auth_required wrong or lapsed403 no_active_pass · one answer for all of them rate limit60 requests/minute per pass · 429 rate_limited reader cap
Binding a key

The token is a bearer credential: whoever holds it has the access. Bind a key and the pass follows the key instead. Two calls, and the text you sign is shown to you first.

shell · evm key (EIP-191 personal_sign)
$ curl -s -X POST /api/pass/claim/challenge \
    -H 'content-type: application/json' \
    -d '{"purchaseId":"p_0000000000000000000000000000dead","keyKind":"evm","address":"0x0000000000000000000000000000000000000000"}'
# sign the returned .challenge string verbatim, then:
$ curl -s -X POST /api/pass/claim/verify \
    -H 'content-type: application/json' \
    -d '{"keyKind":"evm","nonce":"REPLACE_WITH_NONCE","signature":"0xREPLACE_WITH_SIGNATURE"}'
shell · trac key (raw-bytes ed25519)
$ curl -s -X POST /api/pass/claim/challenge \
    -H 'content-type: application/json' \
    -d '{"purchaseId":"p_0000000000000000000000000000dead","keyKind":"trac","address":"testtrac1replace_with_your_address"}'
# sign .challenge verbatim: ed25519 over the raw bytes, no envelope, no pre-hash
$ curl -s -X POST /api/pass/claim/verify \
    -H 'content-type: application/json' \
    -d '{"keyKind":"trac","nonce":"REPLACE_WITH_NONCE","signature":"REPLACE_WITH_HEX","publicKey":"REPLACE_WITH_64_HEX"}'
noncesingle use · a replay is 403 bad_or_expired_nonce signing the payer keyrevokes the bearer token · any link you shared stops working key-bound over RESTnot accepted · an address is public, so it is not a credential
Streams and the reader cap

REST polling is stateless and holds no reader slot. A stream does: the SDK's WebSocket and the MCP feed tools open a reader session, and a pass has a fixed number of them.

who opens onethe SDK's WebSocket and the MCP feed tools, with your bearer token · you do not call the gate yourself the leasea reader slot is held until the stream closes or its 5-minute lease goes stale · the tools heartbeat for you applies tostreams · WS and MCP feed tools does not apply toREST polling · /api/live/* holds no slot over the cap429 concurrent_reader_cap

The pass gate and its session lease live on the pass service and are reached with your bearer token, not through this site — the browser has no route to them, on purpose: a gate that resolved a pass from a public address alone would be an open door.

Check the record yourself
what it doesrecomputes a record's id from the bytes that were hashed reads/api/public/tape and /api/public/proof · two GETs on this site walletnot used keysnot used writesnone installsnothing · node built-ins only file/verify.mjs · the bytes below, served as a file
Verify a record yourself · read it, then run it
verify.mjs
loading /verify.mjs…
shell
$ curl -O /verify.mjs
$ node verify.mjs 
canonical form
3MCP servertools for an MCP client · stdio
Your key here
two free toolsno key · the track record and sample signals answer without one the live feed toolyour pass key stdiothe key goes in the server's own environment · ALPHA_PASS_TOKEN streamable httpthe same key as the request's bearer token
mcp config · http transport · json
{
  "mcpServers": {
    "much-alpha": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:8791/mcp",
      "headers": { "Authorization": "Bearer mapt_replace_with_your_token" }
    }
  }
}
1 · install
shell
$ npm install /sdk/much-alpha-sdk.tgz
2 · configure
transportstdio entrynode_modules/much-alpha-sdk/bin/much-alpha-mcp.mjs
mcp config · json
loading…
get_track_recordfree · limit get_sample_signalsfree · limit type get_latest_signalspass · type beat since_ms limit
ALPHA_PASS_TOKENyour pass token · the free tools run without it
Smoke-test the server without an MCP client
shell
$ printf '%s\n' \
    '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' \
    '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | node ./node_modules/much-alpha-sdk/bin/much-alpha-mcp.mjs
4Plain P2Pthe sidechannel directly · no SDK

The SDK is a convenience over a public transport. If you would rather not run our package, run your own Trac Intercom peer and read the frames yourself: the identifiers below are served by this site so a copied snippet cannot go stale.

Your key here
the open channelno key · attach and read the announcement · discovery only the gated channelyour pass key, exchanged with the gatekeeper for an invite what you sendthe key, and your own peer's public key for the invite to be addressed to what you get backan invite for that peer, and the epoch key that opens frames or, key-boundsign a challenge with the key your pass is bound to — same answer, no bearer token in flight
shell · pass key in, invite out
# your own peer, over its local bridge, told you its public key
$ curl -s -X POST http://127.0.0.1:8787/auth/agent/verify \
    -H 'content-type: application/json' \
    -d '{"token":"mapt_replace_with_your_token","peerPubkey":"REPLACE_WITH_64_HEX"}'
# -> { "authorized": true, "channel": "…", "invite": "…",
#      "epoch": { "id": …, "key": "…" }, "inviteExpiresAtMs": … }
no passauthorized:false with a reason · no invite is minted invite lifetimeshort, and renewed · access lapses rather than being withdrawn
1 · where the feed lives
subnetloading…

2 · the open channel

One channel is open to anyone: it carries a periodic cleartext announcement of what this service is and how to get into the gated one. It is an ephemeral frame, not a record — nothing on it is committed, hashed or scored.

announcement on the open channel · json
loading…
3 · the gated channel

The signal channel is invite-required and owner-write. The gatekeeper issues the invite, and only against an active pass: you sign a challenge with the key your pass is bound to, and send your own peer's public key so the invite can be addressed to it.

who issues itthe gatekeeper · never the peer what it checksa single-use nonce, your signature, and an active pass what you getan invite for your peer key, and the epoch key that opens frames revocationby expiry · invites are short-lived and renewed, so access lapses rather than being withdrawn
4 · joining is deferred, and that is not a failure

A join is answered only once the topic is genuinely announced on the swarm, which during peer bootstrap can take seconds. Announced means discoverable, not merely registered — so a reply that says registered, and a reply that never comes, are both retries. Neither is a joined channel, and neither is an error.

replywhat it meanswhat to do
joined · announced:trueon the swarmjoined
joined · announced:falseregistered, not announcedretry
no reply before your timeoutstill bootstrappingretry
error · …already…this peer is already injoined
error · anything elsethe invite did not carryget a fresh invite

Treating a timeout as success is the one failure mode worth naming: it leaves a client believing it is subscribed to a channel it was never announced on, and the feed simply looks empty for ever.

5 · a minimal join
join · js (node 22+, no dependencies)
loading…
6 · the frames

Every message on the signal channel carries one sealed record. Read it from the event's message field and pass that whole object to your decrypt step — the envelope around it has an id and a ts of its own, and they are not the record's.

envelope ida transport de-duplication id frame idthe record's content id envelope tswhen it was sent · milliseconds frame tsthe record's own time · seconds why it mattersthe frame's own values authenticate the ciphertext; taking them from the envelope makes every open fail
one event on the signal channel · json
loading…
plaintext

What comes out is the canonical record — the same bytes the commit leaf was built from, so a frame you received live and a record you read off the ledger a week later hash to the same thing.

5SDKthe peer, the epoch key and a local socket, handled
Your key here
the keythe same pass key · the SDK does the gatekeeper exchange for you where it goesthe feed process's environment · ALPHA_PASS_TOKEN without onethe delayed public endpoints still answer · the live feed does not
The package
packagemuch-alpha-sdk source/sdk/much-alpha-sdk.tgz · served from this host requiresnode >= 22 registrynot published · install from the URL above
shell
# one process holds the epoch key, everything else reads its socket
$ node ./node_modules/much-alpha-sdk/bin/much-alpha-feed.mjs
$ node ./node_modules/much-alpha-sdk/quickstarts/ws.mjs
in-process · js
import { openFeed } from 'much-alpha-sdk';

const feed = await openFeed({ mode: 'auto' });
feed.on('record', (r) => r.type === 'call' && console.log(r.instrument, r.direction, r.threshold, r.deadline_utc));
feed.serve();                        // ws://127.0.0.1:8790
feed.latest({ type: 'call', limit: 10 });