{"openapi":"3.1.0","info":{"title":"Denpa Protocol API","version":"1.9.2","summary":"The public contract of the Denpa broadcast protocol — federation reads, the canonical signal write, market context, resolution, THE WIRE, SITUATIONS, AURA and MCP.","description":"Machine-readable form of `docs/API.md` (contract version 1.9 · 2026-09-18). The prose file remains the versioned contract; this document mirrors its endpoint tables and pins the response shapes the route handlers emit.\n\n**The router in four lines**\n\n1. **Reads** — public REST, CORS-open (`Access-Control-Allow-Origin: *`, GET/OPTIONS) on `/api/polymarket/ · /api/broadcast/ · /api/oracle/featured · /api/embed/ · /api/card/ · /api/c/ · /api/fashion/signals · /api/network/ · /api/situations`. Operations carry `x-denpa-cors-open: true` when a browser on any origin may call them.\n2. **Writes** — `dk_` operator key (or a first-party session) → `POST /api/predictions`. Not CORS-open: a fork calls it from its own server route.\n3. **Agents** — `dk_` bearer → `POST /api/mcp` (10 tools, streamable HTTP).\n4. **Keys** — `POST /api/dev/keys` needs a Privy login. You cannot mint a key with a key.\n\n**Graceful-empty rule** — every read endpoint returns a well-formed empty state rather than erroring (`/api/wire` answers 200 with an empty list on failure). Forks must do the same: render `NO SIGNAL`, never fabricate.\n\n**Hosts** — the hub (`https://denpa.ai`) serves every path unless the operation declares its own `servers`; the Hono API service (`https://api.denpa.ai`, alias `https://api-production-802f5.up.railway.app`) serves `/api/v1/*` and `/api/aura/*`.\n\n**Conventions** — prices tagged `bps` are integers 0–10000; `priceAtPrediction` is the price of the SIDE called (a NO call sends the NO price). Public endpoints identify operators by handle or the masked `op_<hmac16>` id; the one exception that still carries raw provider ids (the market signal ledger) is noted on the operation.","x-contract-version":"1.9","x-contract-date":"2026-09-18","contact":{"name":"Denpa","url":"https://denpa.ai/developer","email":"hi@dreambooth.io"},"termsOfService":"https://denpa.ai/terms"},"externalDocs":{"description":"REST API reference (docs.denpa.ai)","url":"https://docs.denpa.ai/rest-api/overview/"},"servers":[{"url":"https://denpa.ai","description":"Protocol hub (Next.js) — federation, writes, receipts, market context"}],"security":[{}],"tags":[{"name":"federation","description":"`/api/network/*` — the router surface every station consumes. CORS-open, no identity export."},{"name":"protocol-writes","description":"The canonical signal write, stream binding, overlay SIGNAL, keys, signal events, follows."},{"name":"market-context","description":"Featured tiles, universe search, single market, price history, resolved markets, market-page reads."},{"name":"resolution","description":"Layer 6 — the outcome record. One claim per market, with provenance."},{"name":"broadcast","description":"The channel clock, spotlight, bumpers and the director inbox."},{"name":"wire-situations","description":"THE WIRE (raw belief movement, server-side) and SITUATIONS (grouped stories, CORS-open) plus the categorised protocol feed."},{"name":"operator-live","description":"Overlay SIGNAL, live operators, receipts, clips."},{"name":"aura","description":"The attention oracle — Hono API service."},{"name":"signals-leaderboard","description":"Read one signal, its history, the global feed and the boards."},{"name":"mcp","description":"`POST /api/mcp` — streamable HTTP, stateless, `dk_` bearer, ten tools."},{"name":"admin","description":"Internal — `x-admin-secret` (or the cron secret where noted). Documented for completeness; not a fork surface."},{"name":"protocol","description":"Denpa Protocol V0 — Denpa ID, Sign in with Denpa, scoped app tokens, delegated signers, signed messages. Base path `/api/protocol/v1`, CORS-open (`*`: bearer only, never cookies). Spec: `docs/protocol/{README,AUTH,MESSAGES}.md`."}],"components":{"securitySchemes":{"siwdToken":{"type":"http","scheme":"bearer","bearerFormat":"dat_…","description":"Sign in with Denpa access token — scoped to what the user approved for the app. Accepted only under /api/protocol/*."},"operatorKey":{"type":"http","scheme":"bearer","description":"`Authorization: Bearer dk_…` — the operator key minted at denpa.ai/developer. `db_live_…` keys (minted by `/api/v1/agent/keys`) are the same family and are accepted everywhere `dk_` is. sha-256 hashed at rest, revocable, resolves to the same identity as a session. Every write acts as the key's owner; handles are resolved server-side, never from a body. Permissions: `read`, `signal`, `broadcast` (new keys carry all three) — enforced as scopes on `/api/protocol/v1` and MCP (403 `insufficient_scope`), recorded only on the legacy write routes. Hub rate limit: 60 requests/min per key → 429 `{error:\"rate_limited\", limit, retryAfterMs}` with `Retry-After` (contract 1.9)."},"sessionCookie":{"type":"apiKey","in":"cookie","name":"db_uid","description":"First-party session — `db_uid` plus the HMAC `db_sig` cookie set by `POST /api/auth/privy`. App surfaces only; forks use `operatorKey`."},"privyJwt":{"type":"http","scheme":"bearer","description":"A Privy access token (`Authorization: Bearer <jwt>`). Only key management (`/api/dev/keys`) verifies this — you cannot mint a key with a key."},"adminSecret":{"type":"apiKey","in":"header","name":"x-admin-secret","description":"Internal operator secret (`ADMIN_SECRET`). Admin and stats routes."},"cronSecret":{"type":"apiKey","in":"query","name":"secret","description":"`?secret=CRON_SECRET` — accepted on the cron-friendly aliases (`GET /api/admin/resolve-signals`, `POST /api/admin/daily-digest`)."}},"parameters":{"handle":{"name":"handle","in":"path","required":true,"schema":{"type":"string"},"description":"Operator handle (case-insensitive)."},"marketId":{"name":"marketId","in":"path","required":true,"schema":{"type":"string"},"description":"Protocol market id. Numeric → Polymarket (Gamma), `lmt-…` → Limitless, `kalshi-…` → Kalshi, `denpa-…` → Denpa-native."},"signalId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Signal id (`signal_predictions.id`)."},"lane":{"name":"lane","in":"query","schema":{"$ref":"#/components/schemas/DenpaLane"},"description":"Restrict to one content lane. Unknown values are ignored (no filter)."},"wireWindow":{"name":"window","in":"query","schema":{"$ref":"#/components/schemas/WireWindow"},"description":"Movement window. Default `24h`."}},"responses":{"Unauthorized":{"description":"Missing or invalid credential.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"BadRequest":{"description":"Validation error. `error` names the missing or malformed field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"DenpaPassport":{"type":"object","description":"Public, portable identity (docs/protocol/README.md).","properties":{"denpaId":{"type":"string","format":"uuid"},"uri":{"type":"string","example":"denpa://user/8c2f…"},"operatorId":{"type":"string","example":"op_1a2b…"},"username":{"type":["string","null"]},"displayName":{"type":["string","null"]},"avatar":{"type":["string","null"]},"bio":{"type":["string","null"]},"wallets":{"type":"array","items":{"type":"object","properties":{"chain":{"type":"string"},"address":{"type":"string"}}}},"identities":{"type":"array","items":{"type":"object","properties":{"station":{"type":"string"},"identity":{"type":"string"},"verifiedAt":{"type":"string"},"profileUrl":{"type":["string","null"]}}}},"operatorType":{"type":"string","enum":["human","ai_agent","system_bot"]},"isAi":{"type":"boolean"},"createdAt":{"type":"string"},"stats":{"type":"object","properties":{"stations":{"type":"integer"},"broadcasts":{"type":"integer"},"signals":{"type":"integer"},"predictions":{"type":"integer"},"won":{"type":"integer"},"score":{"type":"integer"},"followers":{"type":"integer"},"following":{"type":"integer"}}},"urls":{"type":"object","properties":{"profile":{"type":"string"}}}}},"SiwdTokenResponse":{"type":"object","properties":{"tokenType":{"type":"string","const":"Bearer"},"accessToken":{"type":"string","example":"dat_…"},"expiresIn":{"type":"integer","example":3600},"refreshToken":{"type":["string","null"],"example":"drt_…"},"scope":{"type":"string","example":"profile:read signal:create"},"denpaId":{"type":"string","format":"uuid"},"grantId":{"type":"string","format":"uuid"}}},"DenpaSignedMessage":{"type":"object","required":["version","type","denpaId","appId","timestamp","nonce","payload","signer","signature"],"properties":{"version":{"type":"integer","const":1},"type":{"type":"string","enum":["profile.update","station.create","station.update","broadcast.create","broadcast.goLive","signal.create","prediction.create","market.create","resolution.create"]},"denpaId":{"type":"string"},"appId":{"type":["string","null"]},"timestamp":{"type":"integer"},"nonce":{"type":"string","minLength":16},"payload":{"type":"object"},"signer":{"type":"object","properties":{"kind":{"type":"string","const":"ed25519"},"publicKey":{"type":"string"}}},"signature":{"type":"string"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Stable machine-readable code (snake_case) or a short reason."},"message":{"type":"string"}},"additionalProperties":true},"Ok":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","const":true}}},"Direction":{"type":"string","enum":["YES","NO"]},"SignalStatus":{"type":"string","enum":["pending","won","lost","void"]},"SignalSource":{"type":"string","enum":["web","mobile","farcaster","embed"],"description":"Client that filed the signal. Unknown values are stored as `web`."},"Bps":{"type":"integer","minimum":0,"maximum":10000,"description":"Probability in basis points (0–10000)."},"DenpaLane":{"type":"string","enum":["POLITICS","CRYPTO","SPORT","CULTURE","MUSIC","TECH","ECONOMY","SCIENCE","WORLD","ENTERTAINMENT","OTHER"],"description":"Content lane (`@denpa/core` `DenpaLane`). `OTHER` is the unclassified fallback and is not a filter chip."},"WireWindow":{"type":"string","enum":["15m","1h","6h","24h"]},"ProviderId":{"type":"string","enum":["polymarket","kalshi","limitless","manifold","manual"]},"MarketStatus":{"type":"string","enum":["open","closed","resolved","unknown"]},"SignalWrite":{"type":"object","required":["marketId","direction","priceAtPrediction"],"properties":{"marketId":{"type":"string"},"direction":{"$ref":"#/components/schemas/Direction"},"priceAtPrediction":{"$ref":"#/components/schemas/Bps","description":"Price of the SIDE called, in bps. A NO call sends the NO price. The server normalises a NO call that arrived as the YES price when the YES snapshot is known."},"marketTitle":{"type":"string"},"channelId":{"type":["string","null"]},"confidence":{"type":["integer","null"],"minimum":1,"maximum":100,"description":"Operator self-assessed confidence."},"crowdYesAtSignal":{"type":["integer","null"],"description":"Market YES probability (bps) at signal time. Captured server-side at write time when omitted."},"timeToResolution":{"type":["integer","null"],"description":"Seconds from signal to expected resolution. Captured server-side when omitted."},"source":{"$ref":"#/components/schemas/SignalSource"},"mediaAssetId":{"type":["string","null"]},"textTake":{"type":["string","null"]},"reach":{"type":["integer","null"],"description":"Client-reported audience size for the take (untrusted; capped). The server coalesces it with its own live-viewer count for `clobTokenId`."},"clobTokenId":{"type":["string","null"],"description":"The market's public CLOB token id — lets the server snapshot concurrent viewers as `reach`."},"crowdLeanBps":{"type":["integer","null"],"description":"Crowd YES lean (bps) shown to the user at signal time. Audit payload only — never written to the signal."}}},"SignalWriteResult":{"type":"object","required":["ok","id"],"properties":{"ok":{"type":"boolean","const":true},"id":{"type":"string","format":"uuid","description":"The signal id. Receipt at `https://denpa.ai/receipts/<id>`."}}},"Signal":{"type":"object","description":"One canonical signal as `GET /api/signals/{id}` returns it. `privyId` is the masked `op_<hmac16>` operator id (field name kept for client compatibility).","required":["id","privyId","marketId","marketTitle","direction","priceAtPrediction","status","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"privyId":{"type":"string","description":"Masked operator id, `op_<hmac16>`.","examples":["op_3f9c1a2b7d4e5f60"]},"callsign":{"type":["string","null"]},"marketId":{"type":"string"},"marketTitle":{"type":"string"},"direction":{"$ref":"#/components/schemas/Direction"},"priceAtPrediction":{"$ref":"#/components/schemas/Bps"},"crowdYesAtSignal":{"type":["integer","null"]},"confidence":{"type":["integer","null"]},"textTake":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/SignalStatus"},"score":{"type":["integer","null"],"description":"Points after resolution; null while pending."},"createdAt":{"type":"string","format":"date-time"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"timeToResolution":{"type":["integer","null"],"description":"Seconds, captured at write time."},"source":{"type":["string","null"]},"outcome":{"type":["string","null"],"enum":["YES","NO",null]},"closePrice":{"type":["integer","null"],"description":"Market YES bps at close (the closing line)."},"clvBps":{"type":["integer","null"],"description":"Closing-line value in bps."}}},"SignalFeedItem":{"type":"object","required":["operatorPublicId","marketId","marketTitle","direction","priceAtPrediction","status","createdAt"],"properties":{"operatorPublicId":{"type":"string","description":"`op_<hmac16>` — never a raw provider id."},"marketId":{"type":"string"},"marketTitle":{"type":"string"},"direction":{"$ref":"#/components/schemas/Direction"},"priceAtPrediction":{"$ref":"#/components/schemas/Bps"},"crowdYesAtSignal":{"type":["integer","null"]},"score":{"type":["integer","null"]},"status":{"$ref":"#/components/schemas/SignalStatus"},"createdAt":{"type":"string"},"resolvedAt":{"type":["string","null"]},"textTake":{"type":["string","null"]},"handle":{"type":["string","null"]},"liveYesBps":{"type":["integer","null"],"description":"Current market YES bps — only on `?type=open`, null when the market cannot be priced."},"moveBps":{"type":["integer","null"],"description":"Live mark of the call against the current price — only on `?type=open`."}}},"SignalFeed":{"type":"object","required":["type","count","signals"],"properties":{"type":{"type":"string","enum":["recent","beat_crowd","open"]},"count":{"type":"integer"},"signals":{"type":"array","items":{"$ref":"#/components/schemas/SignalFeedItem"}}}},"SignalEventType":{"type":"string","enum":["take","reaffirm","confidence","note","share","resolved"]},"SignalEvent":{"type":"object","required":["id","type","payload","actor","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/SignalEventType"},"payload":{"type":"object","additionalProperties":true},"actor":{"type":["string","null"],"description":"`owner` for operator events; the resolver source for `resolved`."},"createdAt":{"type":"string","format":"date-time"}}},"SignalEvents":{"type":"object","required":["signalId","events"],"properties":{"signalId":{"type":"string"},"events":{"type":"array","items":{"$ref":"#/components/schemas/SignalEvent"},"description":"Oldest first."}}},"SignalEventWrite":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["take","reaffirm","confidence","note","share"],"description":"`resolved` is resolver-only and rejected here."},"payload":{"type":"object","description":"Shape depends on `type`: `take` → `{ mediaAssetId? (≤200), url? (http(s), ≤500), text? (≤500) }` (at least one) · `confidence` → `{ confidence: 1–100 }` · `note` → `{ text (≤500) }` · `share` → `{ channel? (≤40) }` · `reaffirm` → none.","properties":{"mediaAssetId":{"type":"string","maxLength":200},"url":{"type":"string","format":"uri","maxLength":500},"text":{"type":"string","maxLength":500},"confidence":{"type":"integer","minimum":1,"maximum":100},"channel":{"type":"string","maxLength":40}},"additionalProperties":true}}},"MarketLedgerSignal":{"type":"object","description":"A signal on the market ledger (`GET /api/m/{marketId}/signals`). Note: this surface still carries the raw `privyId`.","properties":{"id":{"type":"string","format":"uuid"},"privyId":{"type":"string","description":"Raw provider id (not masked on this route)."},"direction":{"$ref":"#/components/schemas/Direction"},"priceAtPrediction":{"$ref":"#/components/schemas/Bps"},"crowdYesAtSignal":{"type":["integer","null"]},"confidence":{"type":["integer","null"]},"textTake":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/SignalStatus"},"score":{"type":["integer","null"]},"createdAt":{"type":"string","format":"date-time"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"callsign":{"type":["string","null"]}}},"MarketLedger":{"type":"object","required":["marketId","count","signals"],"properties":{"marketId":{"type":"string"},"count":{"type":"integer"},"yes":{"type":"integer","description":"Absent when `count` is 0."},"no":{"type":"integer","description":"Absent when `count` is 0."},"signals":{"type":"array","items":{"$ref":"#/components/schemas/MarketLedgerSignal"}}}},"CrowdRead":{"type":"object","description":"MARKET vs CROWD vs YOU. Only `operator_type IN ('human','ai_agent')` counts as crowd; seeded system bots are excluded.","required":["marketId","yesCount","noCount","totalSignals","yesPercent","noPercent","topForecasters","currentUserSignal","updatedAt"],"properties":{"marketId":{"type":"string"},"yesCount":{"type":"integer"},"noCount":{"type":"integer"},"totalSignals":{"type":"integer"},"yesPercent":{"type":["integer","null"],"description":"null when no signals."},"noPercent":{"type":["integer","null"]},"topForecasters":{"type":["object","null"],"description":"Consensus of the top quartile of eligible operators (≥10 resolved); null below 3 qualifying signals.","properties":{"yesPercent":{"type":"integer"},"sampleSize":{"type":"integer"}}},"currentUserSignal":{"type":["object","null"],"description":"The caller's own first call on this market (session only); null when anonymous or none.","properties":{"id":{"type":"string"},"direction":{"$ref":"#/components/schemas/Direction"},"priceAtPrediction":{"$ref":"#/components/schemas/Bps"},"createdAt":{"type":"string","format":"date-time"},"status":{"$ref":"#/components/schemas/SignalStatus"}}},"updatedAt":{"type":"string","format":"date-time"}}},"StreamBinding":{"type":"object","required":["handle","url","label","updatedAt"],"properties":{"handle":{"type":"string"},"url":{"type":"string","description":"HLS playback URL."},"label":{"type":"string"},"updatedAt":{"type":"string"}}},"StreamerSignal":{"type":"object","description":"The active overlay SIGNAL an operator routed to their live page and OBS overlay.","required":["marketId","name","yesPct","streamerId","slug","updatedAt"],"properties":{"marketId":{"type":"string"},"name":{"type":"string"},"yesPct":{"type":"number"},"streamerId":{"type":"string","description":"The operator handle, resolved server-side."},"slug":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"annotation":{"type":"string","maxLength":180},"closesAt":{"type":"string","description":"Market resolution time (ISO)."}}},"StreamerSignalWrite":{"type":"object","required":["marketId","name"],"properties":{"marketId":{"type":"string"},"name":{"type":"string"},"yesPct":{"type":"number"},"slug":{"type":"string"},"annotation":{"type":"string","maxLength":180},"closesAt":{"type":"string"}}},"ApiKeyMint":{"type":"object","required":["key","id","label","tier","permissions"],"properties":{"key":{"type":"string","description":"The plaintext `dk_…` key. Shown ONCE; only its sha-256 is stored."},"id":{"type":"string","format":"uuid"},"label":{"type":"string"},"tier":{"type":"string","enum":["free","builder","pro","enterprise"]},"permissions":{"type":"array","items":{"type":"string","enum":["read","signal","broadcast"]}}}},"ApiKeyListItem":{"type":"object","required":["id","label","tier","active","lastUsedAt","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"label":{"type":"string"},"tier":{"type":"string","enum":["free","builder","pro","enterprise"]},"active":{"type":"boolean"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"FollowCounts":{"type":"object","required":["followers","following","isFollowing"],"properties":{"followers":{"type":"integer"},"following":{"type":"integer","description":"The caller's following count (0 when anonymous)."},"isFollowing":{"type":"boolean"}}},"NetworkOrigin":{"type":"string","enum":["denpa","basetv"]},"NetworkTape":{"type":"object","required":["id","origin","originUrl","handle","url","marketId","href","durationS","views","stance","createdAt","boosted"],"properties":{"id":{"type":"string"},"origin":{"$ref":"#/components/schemas/NetworkOrigin"},"originUrl":{"type":"string","format":"uri"},"handle":{"type":"string"},"url":{"type":"string","description":"HLS playback URL (Cloudflare Stream or Mux — consumers sniff the host)."},"marketId":{"type":"string"},"href":{"type":"string","format":"uri","description":"Absolute link to the operator on the origin site."},"durationS":{"type":["integer","null"]},"views":{"type":"integer"},"stance":{"type":["string","null"]},"createdAt":{"type":"string"},"boosted":{"type":"boolean"}}},"NetworkOperator":{"type":"object","required":["origin","originUrl","handle","displayName","avatarUrl","score","accuracy","total","won","lost","pending","followers","href"],"properties":{"origin":{"$ref":"#/components/schemas/NetworkOrigin"},"originUrl":{"type":"string","format":"uri"},"handle":{"type":"string"},"displayName":{"type":"string"},"avatarUrl":{"type":["string","null"]},"score":{"type":"integer"},"accuracy":{"type":"integer","minimum":0,"maximum":100},"total":{"type":"integer"},"won":{"type":"integer"},"lost":{"type":"integer"},"pending":{"type":"integer"},"followers":{"type":"integer"},"href":{"type":"string","format":"uri","description":"Absolute link to the operator's field record on the origin site."}}},"FieldRecord":{"type":"object","description":"Layer 8 — the operator's public field record. Rank is computed among human operators with the leaderboard ordering (score DESC, correct DESC, total DESC); a bot or zero-signal operator is unranked (`rank: null`).","required":["handle","origin","rank","operators","score","calls","resolved","correct","pending","accuracy","streak","avgClvBps","recent","profileUrl"],"properties":{"handle":{"type":"string"},"origin":{"type":"string","const":"denpa"},"rank":{"type":["integer","null"]},"operators":{"type":["integer","null"],"description":"Size of the ranked human board."},"score":{"type":"integer"},"calls":{"type":"integer"},"resolved":{"type":"integer"},"correct":{"type":"integer"},"pending":{"type":"integer"},"accuracy":{"type":"integer","minimum":0,"maximum":100},"streak":{"type":"integer","description":"Current consecutive wins across the most recent resolved calls."},"avgClvBps":{"type":["integer","null"]},"recent":{"type":"array","maxItems":5,"items":{"type":"object","required":["marketId","marketTitle","direction","status","createdAt","receiptUrl"],"properties":{"marketId":{"type":"string"},"marketTitle":{"type":"string"},"direction":{"$ref":"#/components/schemas/Direction"},"status":{"$ref":"#/components/schemas/SignalStatus"},"createdAt":{"type":"string"},"receiptUrl":{"type":"string","format":"uri","description":"Hub-anchored receipt — provenance resolves through the protocol."}}}},"profileUrl":{"type":"string","format":"uri"}}},"NetworkIdentity":{"type":"object","required":["handle","origin","identities"],"properties":{"handle":{"type":"string"},"origin":{"type":"string","const":"denpa"},"identities":{"type":"array","items":{"type":"object","required":["station","identity","verifiedAt","profileUrl"],"properties":{"station":{"type":"string","examples":["basetv"]},"identity":{"type":"string","examples":["base:0xabc…"]},"verifiedAt":{"type":"string","format":"date-time"},"profileUrl":{"type":["string","null"],"format":"uri"}}}}}},"NetworkPayout":{"oneOf":[{"type":"object","required":["eligible"],"properties":{"eligible":{"type":"boolean","const":false}}},{"type":"object","required":["eligible","handle","origin","payoutAddress","chainId","chainLabel","usdcAddress","tipUrl"],"properties":{"eligible":{"type":"boolean","const":true},"handle":{"type":"string"},"origin":{"type":"string","const":"denpa"},"payoutAddress":{"type":"string"},"chainId":{"type":"integer"},"chainLabel":{"type":"string"},"usdcAddress":{"type":"string"},"tipUrl":{"type":"string","format":"uri"}}}]},"ResolutionOutcome":{"type":"object","description":"The canonical Layer-6 record (`market_resolution_claims`): outcome, who resolved it, from what, proof, and dispute state.","required":["outcome","resolver","source","proofUrl","resolvedAt","disputed","disputeReason","disputedAt"],"properties":{"outcome":{"$ref":"#/components/schemas/Direction"},"resolver":{"type":"string","description":"`provider` · `admin` · `oracle` · `manual`."},"source":{"type":["string","null"],"examples":["polymarket","kalshi","admin:lukas","oracle:football-data"]},"proofUrl":{"type":["string","null"]},"resolvedAt":{"type":"string","format":"date-time"},"disputed":{"type":"boolean"},"disputeReason":{"type":["string","null"]},"disputedAt":{"type":["string","null"],"format":"date-time"}}},"NetworkMarket":{"type":"object","description":"One normalised market shape for any protocol market id — prices as 0–1 decimals. `resolution` is the hub's own Layer-6 record and is null until Denpa has scored the market; the venue's `status`/`outcome` can be ahead of it.","required":["id","provider","title","yesPrice","noPrice","volume","status","outcome","endDate","url","updatedAt","resolution"],"properties":{"id":{"type":"string"},"provider":{"type":"string","enum":["polymarket","limitless","kalshi"]},"title":{"type":"string"},"yesPrice":{"type":["number","null"],"minimum":0,"maximum":1},"noPrice":{"type":["number","null"],"minimum":0,"maximum":1},"volume":{"type":["number","null"]},"status":{"$ref":"#/components/schemas/MarketStatus"},"outcome":{"type":["string","null"],"enum":["YES","NO",null]},"endDate":{"type":["string","null"]},"url":{"type":"string","format":"uri","description":"The hub market page."},"updatedAt":{"type":"string","format":"date-time"},"resolution":{"oneOf":[{"$ref":"#/components/schemas/ResolutionOutcome"},{"type":"null"}]}}},"PulseWeek":{"type":"object","required":["ws","independent","house","automated","activeIndependent"],"properties":{"ws":{"type":"string","description":"ISO week start (UTC Monday), `YYYY-MM-DD`."},"independent":{"type":"integer","description":"Signals filed by people who are not Denpa. The traction number."},"house":{"type":"integer","description":"Signals from accounts Denpa operates (founder, brand, persona wallets)."},"automated":{"type":"integer","description":"Signals from bots, AI operators and seeded profiles."},"activeIndependent":{"type":"integer"}}},"NetworkPulse":{"type":"object","description":"The protocol's traction series. Three tiers: `independent` (the only traction number), `house`, `automated`. `last7`, `prev7` and `northStar` are independent-only; `northStar` reads the latest COMPLETE week even when it is zero.","required":["weeks","totals","northStar","lastIndependentWeek","hub","generatedAt"],"properties":{"weeks":{"type":"array","items":{"$ref":"#/components/schemas/PulseWeek"},"description":"Last 16 ISO weeks ascending, zero-filled; the last is the week to date."},"totals":{"type":"object","properties":{"signals":{"type":"integer"},"independentSignals":{"type":"integer"},"houseSignals":{"type":"integer"},"automatedSignals":{"type":"integer"},"last7":{"type":"integer"},"prev7":{"type":"integer"},"independentOperators":{"type":"integer"},"independentActive28":{"type":"integer"},"houseOperators":{"type":"integer"},"registered":{"type":"integer"},"markets":{"type":"integer"},"resolved":{"type":"integer"},"won":{"type":"integer"},"lost":{"type":"integer"},"open":{"type":"integer"},"clvCount":{"type":"integer"},"beatLine":{"type":"integer"}}},"northStar":{"type":["object","null"],"properties":{"weekStart":{"type":"string"},"scoredSignals":{"type":"integer"},"activeOperators":{"type":"integer"},"wssAo":{"type":"number"}}},"lastIndependentWeek":{"type":["string","null"]},"hub":{"type":"object","properties":{"resolutions28":{"type":"integer"}}},"generatedAt":{"type":"string","format":"date-time"}}},"ProgramSpec":{"type":"object","description":"FilterSpec forwarded to the clock. Empty object = the persisted global rundown.","properties":{"providers":{"type":"array","items":{"type":"string","enum":["polymarket","kalshi"]}},"categories":{"type":"array","items":{"type":"string"}},"maxResolveHours":{"type":"number"},"minVolume":{"type":"number"},"topPerCategory":{"type":"integer"}}},"ProgramSegment":{"type":"object","description":"One block of the rundown (program-clock `PublicSegment`). Prices are 0–100.","required":["id","marketId","title","category","lane","kind","score","yesPrice","noPrice","volume","startsAt","endsAt","endsInMs","durationSec","status","locked","bumper","snapshot","preempted","preemptReason","curationReason"],"properties":{"id":{"type":"string"},"marketId":{"type":"string"},"title":{"type":"string"},"category":{"type":"string"},"lane":{"type":"string"},"kind":{"type":"string","enum":["bumper","content"]},"score":{"type":"number"},"yesPrice":{"type":"number","minimum":0,"maximum":100},"noPrice":{"type":"number","minimum":0,"maximum":100},"volume":{"type":"number"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"endsInMs":{"type":"integer"},"durationSec":{"type":"integer"},"status":{"type":"string","enum":["live","next","upcoming"]},"locked":{"type":"boolean"},"bumper":{"type":["object","null"],"description":"Planned bumper (`status: \"planned\"`) — never rendered automatically.","properties":{"assetId":{"type":["string","null"]},"seed":{"type":["integer","null"]},"durationSec":{"type":"integer"},"status":{"type":"string"}}},"snapshot":{"type":["object","null"],"description":"Move-step snapshot, present once the block has gone on air (content only). Deltas are for consumers to compute.","properties":{"airedAt":{"type":"string","format":"date-time"},"yesAirBps":{"type":["integer","null"]},"yesEndBps":{"type":["integer","null"]},"yesPostBps":{"type":["integer","null"]},"volumeAir":{"type":["number","null"]},"volumeEnd":{"type":["number","null"]},"volumePost":{"type":["number","null"]}}},"preempted":{"type":"boolean"},"preemptReason":{"type":["string","null"]},"curationReason":{"type":["string","null"]}}},"ProgramLane":{"type":"object","required":["key","label","segments"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"segments":{"type":"array","items":{"$ref":"#/components/schemas/ProgramSegment"}}}},"ProgramResponse":{"type":"object","description":"The broadcast clock as a service. `{ enabled: false, generatedAt: null, total: 0, lanes: [], segments: [] }` when the hub has no clock wired.","required":["enabled","generatedAt","total","lanes","segments"],"properties":{"enabled":{"type":"boolean"},"generatedAt":{"type":["string","null"],"format":"date-time"},"total":{"type":"integer","description":"Length of the whole rundown, even when `limit` truncates `segments`."},"lanes":{"type":"array","items":{"$ref":"#/components/schemas/ProgramLane"},"description":"`[]` when `lanes=0` — the grouping repeats every segment."},"segments":{"type":"array","items":{"$ref":"#/components/schemas/ProgramSegment"}},"preset":{"type":"string"},"spec":{"$ref":"#/components/schemas/ProgramSpec"}}},"FeaturedTile":{"type":"object","required":["id","label","tagline","route","totalVol24h","topMarket","topYesPct"],"properties":{"id":{"type":"string","description":"Market id, or `live:<handle>` for a pinned live operator tile."},"label":{"type":"string"},"tagline":{"type":"string"},"route":{"type":"string","description":"Hub-relative route (`/m/<id>` or `/live/<handle>`)."},"totalVol24h":{"type":"number"},"topMarket":{"type":["string","null"]},"topYesPct":{"type":["number","null"],"minimum":0,"maximum":100},"isLive":{"type":"boolean"}}},"FeaturedResponse":{"type":"object","required":["source","tiles","updatedAt"],"properties":{"source":{"type":"string","enum":["signal-router","empty"]},"tiles":{"type":"array","items":{"$ref":"#/components/schemas/FeaturedTile"}},"updatedAt":{"type":"string","format":"date-time"}}},"SignalMarket":{"type":"object","required":["id","name","yesPct","volume","volume24h","closed","slug","clobTokenIds"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"yesPct":{"type":"number","minimum":0,"maximum":100},"volume":{"type":"number"},"volume24h":{"type":"number"},"closed":{"type":"boolean"},"slug":{"type":"string"},"clobTokenIds":{"type":"array","items":{"type":"string"}},"closesAt":{"type":"string","description":"Market resolution time (ISO)."}}},"PricePoint":{"type":"object","required":["t","p"],"properties":{"t":{"type":"integer","description":"Unix seconds."},"p":{"type":"number","description":"YES price, 0–1."}}},"ResolvedMarket":{"type":"object","required":["id","question","outcomePrices","outcomes","endDate"],"properties":{"id":{"type":"string"},"question":{"type":"string"},"outcomePrices":{"type":"string","description":"JSON-encoded array string (Gamma quirk), e.g. `[\"1\",\"0\"]`."},"outcomes":{"type":"string","description":"JSON-encoded array string, e.g. `[\"Yes\",\"No\"]`."},"endDate":{"type":"string"},"slug":{"type":"string"}}},"MarketSummary":{"type":"object","required":["question","description","endDate","resolved","resolutionValue","clobTokenId","volume","liquidity"],"properties":{"question":{"type":"string"},"description":{"type":["string","null"]},"endDate":{"type":["string","null"]},"resolved":{"type":"boolean"},"resolutionValue":{"type":["string","null"]},"clobTokenId":{"type":["string","null"],"description":"`clobTokenIds[0]` — pass as `tokenId` to price history."},"volume":{"type":["number","null"]},"liquidity":{"type":["number","null"]}}},"RelatedMarket":{"type":"object","required":["id","question","yesPct","noPct","volume","endDate","clobTokenId","clobTokenIds"],"properties":{"id":{"type":"string"},"question":{"type":"string"},"yesPct":{"type":["number","null"],"description":"null when the venue has no price (Denpa-native markets). Render `--`, never 50."},"noPct":{"type":["number","null"]},"volume":{"type":"number"},"endDate":{"type":["string","null"]},"clobTokenId":{"type":["string","null"]},"clobTokenIds":{"type":["array","null"],"items":{"type":"string"}},"resolved":{"type":"boolean"},"resolutionValue":{"type":["string","null"]}}},"RelatedResponse":{"type":"object","required":["active","related","crossVertical","recommended","resolution"],"properties":{"active":{"$ref":"#/components/schemas/RelatedMarket"},"related":{"type":"array","items":{"$ref":"#/components/schemas/RelatedMarket"}},"crossVertical":{"type":"array","items":{"type":"object","properties":{"markets":{"type":"array","items":{"$ref":"#/components/schemas/RelatedMarket"}}},"additionalProperties":true}},"recommended":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"markets":{"type":"array","items":{"$ref":"#/components/schemas/RelatedMarket"}}},"additionalProperties":true}},"resolution":{"oneOf":[{"$ref":"#/components/schemas/ResolutionOutcome"},{"type":"null"}]}}},"Sentiment":{"type":"object","required":["flow","comments","news"],"properties":{"flow":{"type":["object","null"],"description":"Trade flow from the Polymarket data-api; null when unavailable.","properties":{"yesPct":{"type":"integer"},"trades":{"type":"integer"},"notionalUsd":{"type":"integer"},"tape":{"type":"array","items":{"type":"object","properties":{"side":{"type":"string","enum":["BUY","SELL"]},"outcome":{"type":"string"},"size":{"type":"number"},"price":{"type":"number"},"timestamp":{"type":"integer"},"yesLean":{"type":"boolean"}}}}}},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"body":{"type":"string"},"createdAt":{"type":"string"}}}},"news":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"link":{"type":"string"},"source":{"type":"string"},"pubDate":{"type":"string"}}}}}},"ClipEntry":{"type":"object","required":["id","handle","url","status","durationS","views","archived","stance","mine","createdAt"],"properties":{"id":{"type":"string"},"handle":{"type":"string"},"url":{"type":"string","description":"HLS manifest."},"status":{"type":"string"},"durationS":{"type":["integer","null"]},"views":{"type":"integer"},"archived":{"type":"boolean"},"stance":{"type":["string","null"]},"mine":{"type":"boolean","description":"true when the caller (session or key) owns the take."},"createdAt":{"type":"string"}}},"DenpaMarket":{"type":"object","description":"A Denpa-native (off-money, manually resolved) cultural market. Ids are namespaced `denpa-…`.","required":["id","question","category","status","source","marketType","resolutionMode","isOffMoney","cutoffAt","createdBy","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"question":{"type":"string"},"category":{"type":"string"},"status":{"type":"string","enum":["open","resolved","invalid"]},"source":{"type":"string"},"marketType":{"type":"string"},"resolutionMode":{"type":"string"},"isOffMoney":{"type":"boolean"},"cutoffAt":{"type":["string","null"],"format":"date-time"},"createdBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ResolutionVerdict":{"type":"object","required":["id","marketId","verdict","status","reason","finalizedBy","finalizedAt","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"marketId":{"type":"string"},"verdict":{"type":["string","null"],"enum":["YES","NO","INVALID",null]},"status":{"type":"string","enum":["draft","final","invalid"]},"reason":{"type":["string","null"]},"finalizedBy":{"type":["string","null"]},"finalizedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"MarketResolutionClaim":{"type":"object","required":["marketId","outcome","claimedAt","watchersNotifiedAt","resolver","source","proofUrl","disputed","disputeReason","disputedAt"],"properties":{"marketId":{"type":"string"},"outcome":{"$ref":"#/components/schemas/Direction"},"claimedAt":{"type":"string","format":"date-time"},"watchersNotifiedAt":{"type":["string","null"],"format":"date-time"},"resolver":{"type":"string"},"source":{"type":["string","null"]},"proofUrl":{"type":["string","null"]},"disputed":{"type":"boolean"},"disputeReason":{"type":["string","null"]},"disputedAt":{"type":["string","null"],"format":"date-time"}}},"BroadcastSegment":{"type":"object","description":"A block of the broadcast guide. Prices are 0–100.","required":["id","title","yesPrice","noPrice","volume","endDate","endsInMs","bucket","signals","tapes","status","eventKey"],"properties":{"id":{"type":"string","description":"Market id (links to `/m/<id>`)."},"title":{"type":"string"},"yesPrice":{"type":"number"},"noPrice":{"type":"number"},"volume":{"type":"number"},"endDate":{"type":"string"},"endsInMs":{"type":"integer"},"bucket":{"type":"string","enum":["ON AIR","TODAY","TOMORROW","THIS WEEK","THIS MONTH","LATER"]},"signals":{"type":"integer"},"tapes":{"type":"integer","description":"takes + bound streams."},"takes":{"type":"integer"},"streams":{"type":"integer"},"status":{"type":"string","enum":["live","resolving","resolved"]},"eventKey":{"type":"string"},"startsAt":{"type":"string"},"kind":{"type":"string","enum":["bumper","content"]},"category":{"type":"string"},"spotlight":{"type":"boolean"},"marketId":{"type":"string"},"segmentId":{"type":"string"},"preempted":{"type":"boolean"},"preemptReason":{"type":"string"},"snapshot":{"type":"object","properties":{"airedAt":{"type":"string"},"yesAirBps":{"type":["integer","null"]},"yesEndBps":{"type":["integer","null"]},"yesPostBps":{"type":["integer","null"]}}},"overflowCount":{"type":"integer"},"overflow":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"BroadcastProgram":{"type":"object","required":["enabled","lanes"],"properties":{"enabled":{"type":"boolean"},"lanes":{"type":"array","items":{"type":"object","required":["key","label","segs"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"segs":{"type":"array","items":{"$ref":"#/components/schemas/BroadcastSegment"}}}}}}},"FeedClip":{"type":"object","properties":{"id":{"type":"string"},"handle":{"type":"string"},"url":{"type":"string"},"stance":{"type":["string","null"]},"views":{"type":"integer"},"durationS":{"type":["integer","null"]},"createdAt":{"type":"string"}}},"FeedGroup":{"type":"object","properties":{"marketId":{"type":"string"},"title":{"type":"string"},"yesPrice":{"type":["number","null"]},"endDate":{"type":["string","null"]},"endsInMs":{"type":"integer"},"resolved":{"type":"boolean"},"signals":{"type":"integer"},"clips":{"type":"array","items":{"$ref":"#/components/schemas/FeedClip"}}}},"WireEvent":{"type":"object","description":"One market's belief movement over the window (`@denpa/core` `WireEvent`). Probabilities are 0–1; `delta` is signed, in absolute probability points on the primary outcome.","required":["id","marketId","provider","title","lane","outcome","fromProbability","toProbability","delta","windowSeconds","detectedAt","wireScore","deltaSource"],"properties":{"id":{"type":"string"},"marketId":{"type":"string"},"eventId":{"type":"string"},"providerEventId":{"type":"string"},"provider":{"$ref":"#/components/schemas/ProviderId"},"title":{"type":"string"},"lane":{"$ref":"#/components/schemas/DenpaLane"},"outcome":{"type":"string","description":"Label of the primary outcome the movement refers to."},"fromProbability":{"type":"number"},"toProbability":{"type":"number"},"delta":{"type":"number"},"windowSeconds":{"type":"integer"},"velocity":{"type":"number","description":"Probability points per hour."},"volume":{"type":"number"},"liquidity":{"type":"number"},"crowdProbability":{"type":"number"},"crowdDelta":{"type":"number"},"detectedAt":{"type":"string","format":"date-time"},"wireScore":{"type":"number"},"deltaSource":{"type":"string","enum":["provider","denpa"],"description":"`provider` while ranking on the venue's 24h delta; `denpa` once Denpa's own observation history backs the movement."},"url":{"type":"string"}}},"WireCoverage":{"type":"object","required":["providerMarketsFetched","eligibleMarkets","wireCandidates","returned","coverageStatus","denpaEvents","providerEvents"],"properties":{"providerMarketsFetched":{"type":"integer"},"eligibleMarkets":{"type":"integer"},"wireCandidates":{"type":"integer"},"returned":{"type":"integer"},"coverageStatus":{"type":"string","enum":["complete","partial"]},"denpaEvents":{"type":"integer"},"providerEvents":{"type":"integer"}}},"WireResponse":{"type":"object","required":["events","updatedAt","window","windowSeconds","coverage"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/WireEvent"}},"updatedAt":{"type":"string","format":"date-time"},"window":{"$ref":"#/components/schemas/WireWindow"},"windowSeconds":{"type":"integer"},"coverage":{"$ref":"#/components/schemas/WireCoverage"}}},"SituationMarket":{"type":"object","required":["marketId","title","outcome","fromProbability","toProbability","delta","wireScore"],"properties":{"marketId":{"type":"string"},"title":{"type":"string"},"outcome":{"type":"string"},"fromProbability":{"type":"number"},"toProbability":{"type":"number"},"delta":{"type":"number"},"volume":{"type":"number"},"wireScore":{"type":"number"},"url":{"type":"string"}}},"DenpaSituation":{"type":"object","description":"Every moving market in one provider event collapsed into a single story. Read `peakDelta` and `markets[]`; never sum the deltas — mutually exclusive buckets cancel to zero. `id` is stable across polls.","required":["id","eventKey","provider","headline","lane","markets","marketCount","leadMarketId","peakDelta","volume","situationScore","criticality","windowSeconds","detectedAt"],"properties":{"id":{"type":"string"},"eventKey":{"type":"string","description":"`event:<id>` / `slug:<s>` / `market:<id>`."},"provider":{"$ref":"#/components/schemas/ProviderId"},"headline":{"type":"string"},"lane":{"$ref":"#/components/schemas/DenpaLane"},"markets":{"type":"array","items":{"$ref":"#/components/schemas/SituationMarket"},"description":"Sorted by |delta| descending."},"marketCount":{"type":"integer"},"leadMarketId":{"type":"string"},"peakDelta":{"type":"number","description":"Signed delta of the lead market."},"volume":{"type":"number","description":"Summed 24h volume across the cluster."},"situationScore":{"type":"number"},"criticality":{"type":"string","enum":["Routine","Elevated","Critical"]},"windowSeconds":{"type":"integer"},"detectedAt":{"type":"string","format":"date-time"},"url":{"type":"string"}}},"SituationCoverage":{"type":"object","required":["providerMarketsFetched","eligibleMarkets","wireEvents","situations","returned","coverageStatus"],"properties":{"providerMarketsFetched":{"type":"integer"},"eligibleMarkets":{"type":"integer"},"wireEvents":{"type":"integer"},"situations":{"type":"integer"},"returned":{"type":"integer"},"coverageStatus":{"type":"string","enum":["complete","partial"]}}},"SituationsResponse":{"type":"object","required":["situations","updatedAt","window","windowSeconds","coverage"],"properties":{"situations":{"type":"array","items":{"$ref":"#/components/schemas/DenpaSituation"}},"updatedAt":{"type":"string","format":"date-time"},"window":{"$ref":"#/components/schemas/WireWindow"},"windowSeconds":{"type":"integer"},"coverage":{"$ref":"#/components/schemas/SituationCoverage"}}},"ObserveStatus":{"type":"object","required":["rawRows","markets","newestObservedAt","hourlyRows"],"properties":{"rawRows":{"type":"integer"},"markets":{"type":"integer"},"newestObservedAt":{"type":["string","null"]},"hourlyRows":{"type":"integer"}}},"ExternalSignal":{"type":"object","description":"One market of the categorised protocol feed (`@denpa/types` `ExternalSignal`).","required":["id","source","marketId","title","category","status","yesProbabilityBps","noProbabilityBps","volumeUsd","liquidityUsd","signalScoreBps","marketUrl","endTime","updatedAt"],"properties":{"id":{"type":"string","examples":["polymarket:1234567"]},"source":{"type":"string","enum":["polymarket","kalshi"]},"marketId":{"type":"string"},"title":{"type":"string"},"category":{"type":"string","description":"`sports` · `politics` · `fashion` · `music_culture`."},"status":{"type":"string","enum":["active","inactive"]},"yesProbabilityBps":{"$ref":"#/components/schemas/Bps"},"noProbabilityBps":{"$ref":"#/components/schemas/Bps"},"volumeUsd":{"type":"number"},"liquidityUsd":{"type":["number","null"]},"signalScoreBps":{"type":"integer"},"freshnessScoreBps":{"type":"integer"},"sourceReliabilityBps":{"type":"integer"},"stale":{"type":"boolean"},"staleReason":{"type":"string"},"marketUrl":{"type":["string","null"]},"endTime":{"type":["string","null"]},"updatedAt":{"type":"string"},"bestBid":{"type":["number","null"]},"bestAsk":{"type":["number","null"]},"spread":{"type":["number","null"]},"volume24hUsd":{"type":["number","null"]},"volume1wUsd":{"type":["number","null"]},"lastTradePrice":{"type":["number","null"]},"oneDayPriceChange":{"type":["number","null"]},"imageUrl":{"type":["string","null"]},"description":{"type":["string","null"]},"conditionId":{"type":["string","null"]},"clobTokenIds":{"type":["array","null"],"items":{"type":"string"}},"slug":{"type":["string","null"]}}},"ExternalSignalsResponse":{"type":"object","required":["source","mode","stale","failedSources","top"],"properties":{"source":{"type":"string","description":"The exchange(s) the rows actually came from — `polymarket`, `kalshi`, `kalshi+polymarket`, `none`, or `postgres_snapshot` on a DB fallback."},"mode":{"type":"string","enum":["live_external","db_snapshot"]},"stale":{"type":"boolean"},"failedSources":{"type":"array","items":{"type":"string","enum":["polymarket","kalshi"]}},"top":{"type":"array","items":{"$ref":"#/components/schemas/ExternalSignal"}}}},"LiveStreamer":{"type":"object","required":["handle","hlsUrl","viewers","startedAt","signal"],"properties":{"handle":{"type":"string"},"hlsUrl":{"type":"string"},"viewers":{"type":"integer"},"startedAt":{"type":["string","null"],"format":"date-time"},"signal":{"type":["object","null"],"properties":{"marketId":{"type":"string"},"name":{"type":"string"}}}}},"RecentStreamer":{"type":"object","required":["handle","endedAt","durationSecs","peakViewers","vodPlaybackId","clipHlsUrl"],"properties":{"handle":{"type":"string"},"endedAt":{"type":"string"},"durationSecs":{"type":["integer","null"]},"peakViewers":{"type":"integer"},"vodPlaybackId":{"type":["string","null"],"description":"Mux VOD of the session, when recorded."},"clipHlsUrl":{"type":["string","null"],"description":"HLS of the latest clip/take, when that is the content."}}},"StreamReceipt":{"type":"object","properties":{"id":{"type":"string"},"handle":{"type":"string"},"muxStreamId":{"type":["string","null"]},"startedAt":{"type":"string"},"endedAt":{"type":["string","null"]},"durationSecs":{"type":["integer","null"]},"peakViewers":{"type":"integer"},"marketsActive":{"type":"array","items":{"type":"object","properties":{"marketId":{"type":"string"},"marketTitle":{"type":"string"},"hlsUrl":{"type":"string"}}}},"reconstructed":{"type":"boolean"},"vodPlaybackId":{"type":["string","null"]},"createdAt":{"type":"string"},"recap":{"type":["object","null"],"additionalProperties":true,"description":"END CARD recap, when published."},"recapPublishedAt":{"type":["string","null"]}}},"OperatorBoardRow":{"type":"object","description":"Broadcast-score board row: call accuracy is the backbone; airtime and reach are bounded, log-scaled enhancers (max ≈ 125).","required":["handle","totalCalls","resolvedCalls","correctCalls","accuracy","bestOddsBps","airtimeSecs","peakViewers","sessions","verified","broadcastScore","rank"],"properties":{"handle":{"type":"string"},"totalCalls":{"type":"integer"},"resolvedCalls":{"type":"integer"},"correctCalls":{"type":"integer"},"accuracy":{"type":"integer","minimum":0,"maximum":100},"bestOddsBps":{"type":["integer","null"],"description":"Lowest entry odds of a correct call (most surprising)."},"airtimeSecs":{"type":"integer"},"peakViewers":{"type":"integer"},"sessions":{"type":"integer"},"verified":{"type":"boolean"},"broadcastScore":{"type":"number"},"rank":{"type":"string","enum":["OPERATOR","FIELD OPERATOR","SIGNAL COMMANDER","TRANSMISSION ARCHITECT"]}}},"SignalCall":{"type":"object","description":"An on-stream market call (`signal_calls`).","properties":{"id":{"type":"string","format":"uuid"},"handle":{"type":"string"},"marketId":{"type":"string"},"marketQuestion":{"type":["string","null"]},"position":{"$ref":"#/components/schemas/Direction"},"oddsBps":{"type":"integer"},"usdcStaked":{"type":["string","null"]},"marketVolume":{"type":["string","null"]},"concurrentViewers":{"type":["integer","null"]},"eventName":{"type":["string","null"]},"streamId":{"type":["string","null"]},"conviction":{"type":"boolean"},"resolvedOutcome":{"type":["string","null"]},"isCorrect":{"type":["boolean","null"]},"callTs":{"type":"string","format":"date-time"},"resolvedTs":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"OperatorAtom":{"type":"object","required":["handle","rank","manifesto","stats","liveSignal","recentCalls","moments","_meta"],"properties":{"handle":{"type":"string"},"rank":{"type":"string","enum":["OPERATOR","FIELD OPERATOR","SIGNAL COMMANDER","TRANSMISSION ARCHITECT"]},"manifesto":{"type":["string","null"]},"stats":{"type":"object","properties":{"totalCalls":{"type":"integer"},"resolvedCalls":{"type":"integer"},"correctCalls":{"type":"integer"},"accuracy":{"type":["integer","null"]},"bestCall":{"type":["object","null"],"properties":{"marketQuestion":{"type":["string","null"]},"oddsBps":{"type":"integer"}}}}},"liveSignal":{"oneOf":[{"$ref":"#/components/schemas/StreamerSignal"},{"type":"null"}]},"recentCalls":{"type":"array","items":{"$ref":"#/components/schemas/SignalCall"},"maxItems":20},"moments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"callId":{"type":"string"},"tier":{"type":"string","enum":["COMMON","SIGNAL","RARE","LEGENDARY"]},"rarityScore":{"type":["string","null"]},"txHash":{"type":["string","null"]},"mintedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"marketQuestion":{"type":["string","null"]},"position":{"$ref":"#/components/schemas/Direction"},"oddsBps":{"type":"integer"},"eventName":{"type":["string","null"]}}}},"_meta":{"type":"object","properties":{"atomVersion":{"type":"string"},"embedUrl":{"type":"string"},"atomUrl":{"type":"string"}}}}},"OperatorLeaderRow":{"type":"object","description":"Hono signal leaderboard row. Operators are identified by the masked `op_<hmac16>` id (same value as the hub emits); the field is still named `privyId` for client compatibility.","required":["rank","privyId","operatorPublicId","callsign","displayName","score","totalBroadcastValue","total","won","lost","pending","accuracy"],"properties":{"rank":{"type":"integer"},"privyId":{"type":"string","description":"The masked `op_<hmac16>` id (since 2026-09-19; the name is kept for compatibility). Accepted wherever an operator id is."},"operatorPublicId":{"type":"string","description":"`op_<hmac16>` — the same value as `privyId`."},"callsign":{"type":["string","null"],"description":"Display name — kept for web compatibility."},"displayName":{"type":["string","null"]},"score":{"type":"integer"},"totalBroadcastValue":{"type":"integer"},"total":{"type":"integer"},"won":{"type":"integer"},"lost":{"type":"integer"},"pending":{"type":"integer"},"accuracy":{"type":"integer","minimum":0,"maximum":100}}},"SignalCategory":{"type":"string","enum":["culture","news","sports","film","fashion","music"],"description":"AURA category (`@denpa/types` `SignalCategory`)."},"CategoryWeights":{"type":"object","required":["viewers","chat_accel","market_vol","convergence","rarity","authority"],"properties":{"viewers":{"type":"number"},"chat_accel":{"type":"number"},"market_vol":{"type":"number"},"convergence":{"type":"number"},"rarity":{"type":"number"},"authority":{"type":"number"}}},"AuraCategoryResult":{"type":"object","required":["category","score","ema","label","tier","weights","computedAt"],"properties":{"category":{"$ref":"#/components/schemas/SignalCategory"},"score":{"type":"number","minimum":0,"maximum":100,"description":"The raw reading."},"ema":{"type":"number","minimum":0,"maximum":100,"description":"EMA-damped — the number surfaces show (no thrash)."},"label":{"type":"string","description":"Benjamin label: KULTWERT · AUSSTELLUNG · ÜBERTRAGUNG · REPRODUKTION."},"tier":{"type":"string","enum":["PRIME","OVERLAY","QUEUE","TRACK","NOISE"]},"weights":{"$ref":"#/components/schemas/CategoryWeights"},"computedAt":{"type":"string","format":"date-time"}}},"MarketPressure":{"type":"object","required":["tokenId","lastMid","velocityCentsPerMin","pressure","subscribers","lastTickAt","ticker"],"properties":{"tokenId":{"type":"string"},"lastMid":{"type":["number","null"]},"velocityCentsPerMin":{"type":"number"},"pressure":{"type":"number","minimum":0,"maximum":1,"description":"Normalised on the same 5000 cents/min cap AURA pressure uses."},"subscribers":{"type":"integer"},"lastTickAt":{"type":["string","null"],"format":"date-time"},"ticker":{"type":"object","properties":{"upstreamConnected":{"type":"boolean"},"tokens":{"type":"integer"},"viewerSockets":{"type":"integer"}}}}},"JsonRpcRequest":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"type":["string","integer","null"],"description":"Omit for a notification (answered `202`)."},"method":{"type":"string","enum":["initialize","ping","tools/list","tools/call","notifications/initialized"]},"params":{"type":"object","additionalProperties":true}}},"JsonRpcResponse":{"type":"object","required":["jsonrpc","id"],"properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"type":["string","integer","null"]},"result":{"type":"object","additionalProperties":true},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}}}}}},"paths":{"/api/protocol/v1/apps":{"get":{"tags":["protocol"],"summary":"My apps","description":"`?mine=1` — the caller's registered apps (owner view). First-party session or dk_ only; an app token gets 403.","operationId":"protocolListMyApps","security":[{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"name":"mine","in":"query","required":false,"description":"1","schema":{"type":"string"}}],"responses":{"200":{"description":"Apps"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["protocol"],"summary":"Register an app (self-serve)","description":"denpa.ai/developer → YOUR APPS. Public (PKCE) unless `confidential`. Ten apps per developer; financial scopes refused; same-origin.","operationId":"protocolRegisterApp","security":[{"operatorKey":[]},{"sessionCookie":[]}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["slug","name","redirectUris"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"redirectUris":{"type":"array","items":{"type":"string"}},"allowedOrigins":{"type":"array","items":{"type":"string"}},"allowedScopes":{"type":"array","items":{"type":"string"}},"confidential":{"type":"boolean"}}}}}},"responses":{"201":{"description":"App + clientSecret (once, null for public clients)"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"slug taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"too_many_apps","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/apps/{id}/secret":{"post":{"tags":["protocol"],"summary":"Mint / rotate my app's client secret","description":"Owner only. Shown once.","operationId":"protocolRotateAppSecret","security":[{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"app ref","schema":{"type":"string"}}],"responses":{"200":{"description":"App + clientSecret (once)"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/users/me/username":{"post":{"tags":["protocol"],"summary":"Claim the network-wide username","description":"Lowercase a-z 0-9 -, 3–32 chars, unique. Mirrors into the streamer handle. Scope profile:write.","operationId":"protocolClaimUsername","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["username"],"properties":{"username":{"type":"string","example":"lukas"}}}}}},"responses":{"200":{"description":"Claimed"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"username_taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/users/{id}/signers":{"get":{"tags":["protocol"],"summary":"Public verification keys","description":"Root key + active delegated signer public keys of an identity — what a node needs to verify its messages.","operationId":"protocolUserSigners","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"Denpa ID · denpa://user/… · op_…","schema":{"type":"string"}}],"responses":{"200":{"description":"Keys"},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/users/me/root-key":{"get":{"tags":["protocol"],"summary":"My root key","description":"First-party session only.","operationId":"protocolGetRootKey","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Root key"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["protocol"],"summary":"Register / rotate my root key","description":"Raw 32-byte Ed25519 public key (base64url). The key that owns the Denpa ID: signs signer.add / signer.remove and logs in at /unlock/root-key. Session + same-origin only.","operationId":"protocolSetRootKey","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["publicKey"],"properties":{"publicKey":{"type":"string"}}}}}},"responses":{"200":{"description":"Root key"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["protocol"],"summary":"Remove my root key","description":"Session + same-origin only.","operationId":"protocolRemoveRootKey","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"ok"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/follows":{"get":{"tags":["protocol"],"summary":"Follow graph","description":"`?user=` public following + followers by Denpa ID; `?mine=1` needs follow:read.","operationId":"protocolFollows","security":[],"parameters":[{"name":"user","in":"query","required":false,"description":"Denpa ID · op_","schema":{"type":"string"}},{"name":"mine","in":"query","required":false,"description":"1","schema":{"type":"string"}}],"responses":{"200":{"description":"Graph"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["protocol"],"summary":"Follow","description":"{ denpaId }. Scope follow:create. Also recorded as a follow.create message.","operationId":"protocolFollow","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["denpaId"],"properties":{"denpaId":{"type":"string"}}}}}},"responses":{"200":{"description":"Already following"},"201":{"description":"Created"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/follows/{denpaId}":{"delete":{"tags":["protocol"],"summary":"Unfollow","description":"Scope follow:create.","operationId":"protocolUnfollow","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"name":"denpaId","in":"path","required":true,"description":"Denpa ID","schema":{"type":"string"}}],"responses":{"200":{"description":"ok"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/auth/device":{"post":{"tags":["protocol"],"summary":"Device authorization (RFC 8628)","description":"{ client_id, scope } → { device_code, user_code, verification_uri, verification_uri_complete, expires_in, interval }. The user approves at /activate; poll /auth/token with grant_type=urn:ietf:params:oauth:grant-type:device_code.","operationId":"siwdDevice","security":[],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["client_id","scope"],"properties":{"client_id":{"type":"string"},"scope":{"type":"string"}}}}}},"responses":{"201":{"description":"Device challenge"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"origin not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/root-key/challenge":{"post":{"tags":["protocol"],"summary":"Root-key login — step 1","description":"{ denpaId | username } → { denpaId, nonce, expiresAt } (5 min, single use).","operationId":"rootKeyLoginChallenge","security":[],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"denpaId":{"type":"string"},"username":{"type":"string"}}}}}},"responses":{"200":{"description":"Nonce"},"400":{"description":"no_root_key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/root-key":{"post":{"tags":["protocol"],"summary":"Root-key login — step 2","description":"{ denpaId, nonce, signature } — Ed25519 over `denpa-login-v1\\n<nonce>\\n<denpaId>` by the root key. Sets the ordinary db_auth / db_uid / db_sig session cookies.","operationId":"rootKeyLogin","security":[],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["denpaId","nonce","signature"],"properties":{"denpaId":{"type":"string"},"nonce":{"type":"string"},"signature":{"type":"string"}}}}}},"responses":{"200":{"description":"Session cookies set"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"bad_signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/admin/protocol/apps/{id}":{"patch":{"tags":["admin","protocol"],"summary":"Edit any app / hand it to a developer","description":"x-admin-secret. Any registration field, plus `developerUserId` to make a seeded station self-serve for that identity.","operationId":"adminPatchProtocolApp","security":[{"adminSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"app ref","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string"},"description":{"type":"string"},"redirectUris":{"type":"array","items":{"type":"string"}},"allowedOrigins":{"type":"array","items":{"type":"string"}},"allowedScopes":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","suspended"]},"developerUserId":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"App"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1":{"get":{"tags":["protocol"],"summary":"Discovery document","description":"Issuer, endpoints, supported scopes and message types — what an SDK needs to bootstrap. CORS-open.","operationId":"protocolDiscovery","security":[],"responses":{"200":{"description":"Discovery","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/protocol/v1/users/{id}":{"get":{"tags":["protocol"],"summary":"Passport by Denpa ID","description":"Public Passport. `id` is a Denpa ID (uuid), a `denpa://user/…` uri, or a legacy `op_…` operator id — never a raw internal id.","operationId":"protocolGetUser","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"Denpa ID · denpa://user/… · op_…","schema":{"type":"string"}}],"responses":{"200":{"description":"Passport","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DenpaPassport"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/users/by-username/{username}":{"get":{"tags":["protocol"],"summary":"Passport by username","description":"Claimed handle first, then callsign / display name.","operationId":"protocolGetUserByUsername","security":[],"parameters":[{"name":"username","in":"path","required":true,"description":"handle","schema":{"type":"string"}}],"responses":{"200":{"description":"Passport","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DenpaPassport"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/users/me":{"get":{"tags":["protocol"],"summary":"The caller's Passport","description":"Passport plus `auth: { kind, app, scopes, grantId }` — exactly what the presented credential may do. Scope `profile:read`.","operationId":"protocolMe","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"responses":{"200":{"description":"Passport + auth","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DenpaPassport"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/auth/challenge":{"post":{"tags":["protocol"],"summary":"Sign in with Denpa — step 1: challenge","description":"Creates an authorization request (10 min). Public clients must send PKCE S256. Financial scopes (`wallet:*`) are refused. Returns the `authorizeUrl` the user must visit. 30/min per IP.","operationId":"siwdChallenge","security":[],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["client_id","redirect_uri","scope"],"properties":{"client_id":{"type":"string","example":"dapp_basetv"},"redirect_uri":{"type":"string","example":"https://basetv.tv/auth/denpa/callback"},"scope":{"type":"string","example":"profile:read signal:create"},"state":{"type":"string"},"code_challenge":{"type":"string"},"code_challenge_method":{"type":"string","enum":["S256"]}}}}}},"responses":{"201":{"description":"Challenge","content":{"application/json":{"schema":{"type":"object","properties":{"challengeId":{"type":"string"},"authorizeUrl":{"type":"string","example":"https://denpa.ai/authorize?challenge=…"},"expiresAt":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"origin not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/auth/authorize":{"get":{"tags":["protocol"],"summary":"Approval page data","description":"What `/authorize?challenge=` renders. First-party session cookie only.","operationId":"siwdAuthorizeInfo","security":[{"sessionCookie":[]}],"parameters":[{"name":"challenge","in":"query","required":false,"description":"challenge id","schema":{"type":"string"}}],"responses":{"200":{"description":"App + scopes"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["protocol"],"summary":"Sign in with Denpa — step 3: the user's decision","description":"Approve or deny. First-party session cookie **and** same-origin only — an app can never approve itself. Returns the redirect URL (`?code=…&state=…` or `?error=access_denied`).","operationId":"siwdAuthorize","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["challengeId","decision"],"properties":{"challengeId":{"type":"string"},"decision":{"type":"string","enum":["approve","deny"]}}}}}},"responses":{"200":{"description":"Redirect","content":{"application/json":{"schema":{"type":"object","properties":{"redirectUrl":{"type":"string"}}}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"cross-origin refused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/auth/token":{"post":{"tags":["protocol"],"summary":"Sign in with Denpa — step 5: token","description":"`grant_type=authorization_code` (code + `code_verifier`, or `client_secret` / HTTP Basic) or `grant_type=refresh_token` (rotating). JSON or form-urlencoded. Codes: 5 min, single use — reuse revokes the family. Access 1h, refresh 30d. 60/min per IP.","operationId":"siwdToken","security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token","urn:ietf:params:oauth:grant-type:device_code"]},"code":{"type":"string"},"code_verifier":{"type":"string"},"redirect_uri":{"type":"string"},"client_id":{"type":"string"},"client_secret":{"type":"string"},"refresh_token":{"type":"string"}}}},"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiwdTokenResponse"}}}},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"invalid_client","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/auth/revoke":{"post":{"tags":["protocol"],"summary":"Revoke a token","description":"Access (`dat_`) or refresh (`drt_`). Possession is the credential. Always 200 (RFC 7009).","operationId":"siwdRevoke","security":[],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"}}}}}},"responses":{"200":{"description":"ok"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/auth/grants":{"get":{"tags":["protocol"],"summary":"Connected apps","description":"The session user's grants. First-party only.","operationId":"siwdListGrants","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Grants"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/auth/grants/{id}":{"delete":{"tags":["protocol"],"summary":"Revoke an app","description":"Revokes the grant, every token under it, and every signer the app registered. First-party session + same-origin.","operationId":"siwdRevokeGrant","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"grant id","schema":{"type":"string"}}],"responses":{"200":{"description":"ok"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"cross-origin refused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/apps/{id}":{"patch":{"tags":["protocol"],"summary":"Edit my app","description":"Owner only, same-origin: name, description, redirectUris, allowedOrigins, allowedScopes, status.","operationId":"protocolPatchApp","security":[{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"app ref","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string"},"description":{"type":"string"},"redirectUris":{"type":"array","items":{"type":"string"}},"allowedOrigins":{"type":"array","items":{"type":"string"}},"allowedScopes":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","suspended"]}}}}}},"responses":{"200":{"description":"App"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["protocol"],"summary":"Suspend my app","description":"Owner only. Grants and tokens stop resolving; history is kept.","operationId":"protocolSuspendApp","security":[{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"app ref","schema":{"type":"string"}}],"responses":{"200":{"description":"ok"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["protocol"],"summary":"Public app record","description":"By uuid, `dapp_…` client id, slug, or `denpa://app/…`. Never exposes the secret.","operationId":"protocolGetApp","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"app ref","schema":{"type":"string"}}],"responses":{"200":{"description":"App"},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/stations":{"get":{"tags":["protocol"],"summary":"Stations","description":"Public list (Station Protocol). `?mine=1` = the caller's own — scope `station:read`.","operationId":"protocolListStations","security":[],"parameters":[{"name":"mine","in":"query","required":false,"description":"1 = caller's stations","schema":{"type":"string"}}],"responses":{"200":{"description":"Stations"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/stations/{id}":{"get":{"tags":["protocol"],"summary":"Station manifest","description":"Public.","operationId":"protocolGetStation","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"station slug","schema":{"type":"string"}}],"responses":{"200":{"description":"Manifest"},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/events":{"get":{"tags":["protocol"],"summary":"Events","description":"Developing stories — provider events grouping moving markets (SITUATIONS), with `denpa://event/…` and per-market `denpa://market/…` uris. Public.","operationId":"protocolListEvents","security":[],"parameters":[{"name":"lane","in":"query","required":false,"description":"DENPA lane","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"max 100","schema":{"type":"integer"}}],"responses":{"200":{"description":"Events"}}}},"/api/protocol/v1/events/{id}":{"get":{"tags":["protocol"],"summary":"Event","description":"Public.","operationId":"protocolGetEvent","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"event id","schema":{"type":"string"}}],"responses":{"200":{"description":"Event"},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/signals":{"get":{"tags":["protocol"],"summary":"List signals","description":"`?user=` (Denpa ID / op_) or `?market=` public; `?mine=1` needs `signal:read`. In V0 a Prediction is the same record as a Signal (`signal_predictions`).","operationId":"protocolListSignals","security":[],"parameters":[{"name":"user","in":"query","required":false,"description":"Denpa ID · op_","schema":{"type":"string"}},{"name":"market","in":"query","required":false,"description":"market id","schema":{"type":"string"}},{"name":"mine","in":"query","required":false,"description":"1 = caller's","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"max 200","schema":{"type":"integer"}}],"responses":{"200":{"description":"signals"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["protocol"],"summary":"Create a signal","description":"Scope `signal:create`. Same canonical write as POST /api/predictions (first-call-lock, snapshot, `source: \"api\"`); also recorded as a hub-attested `signal.create` message.","operationId":"protocolCreateSignal","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"requestBody":{"required":true,"description":"`eventId` / `signal` are accepted as aliases of `marketId` / `position`.","content":{"application/json":{"schema":{"type":"object","required":["marketId","position"],"properties":{"marketId":{"type":"string","example":"540818"},"position":{"type":"string","enum":["YES","NO"]},"priceBps":{"type":"integer"},"confidence":{"type":"integer"},"take":{"type":"string"},"marketTitle":{"type":"string"}}}}}},"responses":{"200":{"description":"Filed — same result as POST /api/predictions, plus `uri`"},"201":{"description":"Filed"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`market_closed` / first-call-lock","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/predictions":{"get":{"tags":["protocol"],"summary":"List predictions","description":"`?user=` (Denpa ID / op_) or `?market=` public; `?mine=1` needs `prediction:read`. In V0 a Prediction is the same record as a Signal (`signal_predictions`).","operationId":"protocolListPredictions","security":[],"parameters":[{"name":"user","in":"query","required":false,"description":"Denpa ID · op_","schema":{"type":"string"}},{"name":"market","in":"query","required":false,"description":"market id","schema":{"type":"string"}},{"name":"mine","in":"query","required":false,"description":"1 = caller's","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"max 200","schema":{"type":"integer"}}],"responses":{"200":{"description":"predictions"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["protocol"],"summary":"Create a prediction","description":"Scope `prediction:create`. Same canonical write as POST /api/predictions (first-call-lock, snapshot, `source: \"api\"`); also recorded as a hub-attested `prediction.create` message.","operationId":"protocolCreatePrediction","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"requestBody":{"required":true,"description":"`eventId` / `signal` are accepted as aliases of `marketId` / `position`.","content":{"application/json":{"schema":{"type":"object","required":["marketId","position"],"properties":{"marketId":{"type":"string","example":"540818"},"position":{"type":"string","enum":["YES","NO"]},"priceBps":{"type":"integer"},"confidence":{"type":"integer"},"take":{"type":"string"},"marketTitle":{"type":"string"}}}}}},"responses":{"200":{"description":"Filed — same result as POST /api/predictions, plus `uri`"},"201":{"description":"Filed"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`market_closed` / first-call-lock","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/signals/{id}":{"get":{"tags":["protocol"],"summary":"Signal","description":"Public.","operationId":"protocolGetSignal","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"signal uuid","schema":{"type":"string"}}],"responses":{"200":{"description":"Signal"},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/markets":{"get":{"tags":["protocol"],"summary":"Markets","description":"Canonical markets (same source as /api/markets) with `denpa://market/…` uris. Public.","operationId":"protocolListMarkets","security":[],"parameters":[{"name":"lane","in":"query","required":false,"description":"DENPA lane","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"max 300","schema":{"type":"integer"}}],"responses":{"200":{"description":"Markets"}}}},"/api/protocol/v1/markets/{id}":{"get":{"tags":["protocol"],"summary":"Market","description":"Normalized market context for any protocol market id. Public.","operationId":"protocolGetMarket","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"market id","schema":{"type":"string"}}],"responses":{"200":{"description":"Market"},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/markets/{id}/resolution":{"get":{"tags":["protocol"],"summary":"Resolution","description":"The Layer-6 resolution record (resolver, source, proof, disputed) or `PENDING`. Public.","operationId":"protocolGetResolution","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"market id","schema":{"type":"string"}}],"responses":{"200":{"description":"Resolution"}}}},"/api/protocol/v1/messages":{"get":{"tags":["protocol"],"summary":"The protocol log","description":"`?since=<cursor>&limit=&type=&user=` — oldest first, ms-exact keyset cursor, signatures included. What a node replicates.","operationId":"protocolMessageFeed","security":[],"parameters":[{"name":"since","in":"query","required":false,"description":"cursor from `next`","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"max 500","schema":{"type":"integer"}},{"name":"type","in":"query","required":false,"description":"message type","schema":{"type":"string"}},{"name":"user","in":"query","required":false,"description":"Denpa ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Messages + next"}}},"post":{"tags":["protocol"],"summary":"Submit a signed Denpa message","description":"No bearer: the Ed25519 signature is the credential. Verified for shape, freshness (±5 min), signature, active signer, app grant + scope, nonce uniqueness; recorded; executed when the type is executable (`signal.create`, `prediction.create`, `profile.update`). docs/protocol/MESSAGES.md.","operationId":"protocolSubmitMessage","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DenpaSignedMessage"}}}},"responses":{"201":{"description":"Receipt","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"uri":{"type":"string"},"type":{"type":"string"},"executed":{"type":"boolean"},"resultRef":{"type":"string"},"result":{}}}}}},"400":{"description":"`invalid_message` (error_description names the check)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`unknown_signer` / `grant_revoked` / `insufficient_scope`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`replay`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/signers":{"get":{"tags":["protocol"],"summary":"Signers","description":"The caller's delegated signers (an app token sees only its own). Scope `signer:manage`.","operationId":"protocolListSigners","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"responses":{"200":{"description":"Signers"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["protocol"],"summary":"Register a signer","description":"Raw 32-byte Ed25519 public key (base64url), bound to the presenting app. Scope `signer:manage`.","operationId":"protocolRegisterSigner","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["publicKey"],"properties":{"publicKey":{"type":"string"},"label":{"type":"string"},"expiresAt":{"type":"string"}}}}}},"responses":{"201":{"description":"Signer"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"public key already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/protocol/v1/signers/{id}":{"delete":{"tags":["protocol"],"summary":"Revoke a signer","description":"An app may only revoke its own. Scope `signer:manage`.","operationId":"protocolRevokeSigner","security":[{"siwdToken":[]},{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"signer id","schema":{"type":"string"}}],"responses":{"200":{"description":"ok"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`insufficient_scope` / forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/admin/protocol/apps":{"get":{"tags":["admin","protocol"],"summary":"List first-party apps","description":"x-admin-secret.","operationId":"adminListProtocolApps","security":[{"adminSecret":[]}],"responses":{"200":{"description":"Apps"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["admin","protocol"],"summary":"Register an app (V0)","description":"Admin-only registration. `confidential: true` mints a client secret shown once (stored hashed). Financial scopes cannot be registered.","operationId":"adminRegisterProtocolApp","security":[{"adminSecret":[]}],"requestBody":{"required":true,"description":"","content":{"application/json":{"schema":{"type":"object","required":["slug","name","redirectUris"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"redirectUris":{"type":"array","items":{"type":"string"}},"allowedOrigins":{"type":"array","items":{"type":"string"}},"allowedScopes":{"type":"array","items":{"type":"string"}},"confidential":{"type":"boolean"},"developerUserId":{"type":"string"}}}}}},"responses":{"201":{"description":"App + clientSecret (once)"},"400":{"description":"`invalid_request` / `invalid_scope` / `invalid_grant`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"slug taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/admin/protocol/apps/{id}/secret":{"post":{"tags":["admin","protocol"],"summary":"Mint / rotate a client secret","description":"Turns a public client confidential. Shown once. x-admin-secret.","operationId":"adminRotateProtocolAppSecret","security":[{"adminSecret":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"app ref","schema":{"type":"string"}}],"responses":{"200":{"description":"App + clientSecret (once)"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/network/tapes":{"get":{"tags":["federation"],"summary":"Network tape reel","description":"Ready clips from every station (denpa + basetv), origin-labelled, merged newest-first. Dead manifests are probed and dropped. CDN-cached 60 s (SWR 300 s).","operationId":"getNetworkTapes","x-denpa-cors-open":true,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":48,"default":24}},{"name":"exclude","in":"query","schema":{"type":"string"},"description":"Comma-separated origins to drop (a station drops its own items: `exclude=basetv`)."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["tapes","fetchedAt"],"properties":{"tapes":{"type":"array","items":{"$ref":"#/components/schemas/NetworkTape"}},"fetchedAt":{"type":"string","format":"date-time"}}}}}}}}},"/api/network/operators":{"get":{"tags":["federation"],"summary":"Network operator board","description":"Human operators from every station, origin-labelled, merged by score. No internal ids. CDN-cached 60 s.","operationId":"getNetworkOperators","x-denpa-cors-open":true,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":40,"default":20},"description":"Per origin; the merged list is at most 2× this."},{"name":"exclude","in":"query","schema":{"type":"string"},"description":"Comma-separated origins to drop."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["operators","fetchedAt"],"properties":{"operators":{"type":"array","items":{"$ref":"#/components/schemas/NetworkOperator"}},"fetchedAt":{"type":"string","format":"date-time"}}}}}}}}},"/api/network/field-record/{handle}":{"get":{"tags":["federation"],"summary":"Public field record","description":"Layer 8 as a protocol service: the operator's judgment history, served by the hub so forks render it instead of computing their own. `handle=me` with an operator key resolves the caller's own record (`Cache-Control: no-store`) — the fork \"who am I\".","operationId":"getFieldRecord","x-denpa-cors-open":true,"security":[{},{"operatorKey":[]}],"parameters":[{"name":"handle","in":"path","required":true,"schema":{"type":"string"},"description":"Operator handle, or `me` (requires `operatorKey`)."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldRecord"}}}},"401":{"description":"`operator_key_required` — `me` without a key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`unknown_operator`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/network/identity/{handle}":{"get":{"tags":["federation"],"summary":"Identity bridge","description":"Which sister-station identities this operator has claimed (opt-in via `POST /api/identity/claim`). Only claimed links are exposed — never derived wallet linkage.","operationId":"getNetworkIdentity","x-denpa-cors-open":true,"parameters":[{"$ref":"#/components/parameters/handle"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkIdentity"}}}},"404":{"description":"`unknown_operator`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/network/payout/{handle}":{"get":{"tags":["federation"],"summary":"Payout registry","description":"The protocol-canonical tip destination for an operator handle — only what a client needs to build the direct USDC transfer. `{ eligible: false }` whenever tips are disabled or the operator has no payout profile.","operationId":"getNetworkPayout","x-denpa-cors-open":true,"parameters":[{"$ref":"#/components/parameters/handle"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkPayout"}}}}}}},"/api/network/market/{marketId}":{"get":{"tags":["federation","market-context"],"summary":"Market context","description":"One normalised market shape for any protocol market id, provider quirks handled once at the hub. Answers for closed and resolved markets. Includes the Layer-6 record as `market.resolution`. Cached 60 s.","operationId":"getNetworkMarket","x-denpa-cors-open":true,"parameters":[{"$ref":"#/components/parameters/marketId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["market"],"properties":{"market":{"$ref":"#/components/schemas/NetworkMarket"}}}}}},"400":{"description":"`unsupported_id` — not a numeric, `lmt-` or `kalshi-` id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`unknown_market`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/network/pulse":{"get":{"tags":["federation"],"summary":"Network pulse","description":"The protocol's traction series — weekly signal volume by tier, WSS/AO for the latest complete week, resolution and movement, hub throughput. Aggregate counts only, no identities. CDN-cached 300 s. Drawn on `/network`.","operationId":"getNetworkPulse","x-denpa-cors-open":true,"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkPulse"}}}},"503":{"description":"`pulse_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/network/program":{"get":{"tags":["federation","broadcast"],"summary":"Broadcast clock as a service","description":"The same rundown denpa.ai airs, scoped to a station's venues and lanes. No params = the persisted global rundown; `preset` overrides the filters. 30 s SWR. SDK: `client.getProgram()`.","operationId":"getNetworkProgram","x-denpa-cors-open":true,"parameters":[{"name":"preset","in":"query","schema":{"type":"string","enum":["hot","resolving","close"]},"description":"A named lineup (overrides the filters)."},{"name":"providers","in":"query","schema":{"type":"string"},"description":"Comma-separated venues: `polymarket`, `kalshi`. Default polymarket."},{"name":"categories","in":"query","schema":{"type":"string"},"description":"Comma-separated lanes to air (explicit = allowed)."},{"name":"maxResolveHours","in":"query","schema":{"type":"number","minimum":1,"maximum":2160}},{"name":"minVolume","in":"query","schema":{"type":"number","minimum":0}},{"name":"topPerCategory","in":"query","schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":400,"default":200},"description":"Caps `segments`; `total` still reports the whole rundown."},{"name":"lanes","in":"query","schema":{"type":"string","enum":["0"]},"description":"`lanes=0` returns `lanes: []` — halves the payload."}],"responses":{"200":{"description":"OK (also `{ enabled: false }` when the hub has no clock).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgramResponse"}}}}}}},"/api/identity/claim":{"get":{"tags":["federation"],"summary":"Own station identity claims","operationId":"listIdentityClaims","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"identities":{"type":"array","items":{"type":"object","properties":{"station":{"type":"string"},"identity":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["federation"],"summary":"Claim a sister-station identity","description":"Cross-station identity bridge (Layer 1). v1: `basetv`, where identity IS the wallet (`base:<address>`); ownership is proven by the address being a Privy-linked wallet on this account. Explicit opt-in — never auto-derived. First-party, not CORS.","operationId":"claimIdentity","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address"],"properties":{"station":{"type":"string","enum":["basetv"],"default":"basetv"},"address":{"type":"string","description":"EVM address, must be a linked wallet."}}}}}},"responses":{"200":{"description":"Claimed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"station":{"type":"string"},"identity":{"type":"string"}}}}}},"400":{"description":"`unknown_station` · `invalid_address`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"`wallet_not_linked`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`identity_already_claimed`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["federation"],"summary":"Unlink a station identity","operationId":"deleteIdentityClaim","security":[{"sessionCookie":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"station":{"type":"string","default":"basetv"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/predictions":{"post":{"tags":["protocol-writes"],"summary":"File a signal (the canonical write)","description":"THE canonical signal write. One scored signal per user per market, first-call-locked — later additions go through `POST /api/signals/{id}/events`, never a rewrite. The Layer-4 snapshot (`crowdYesAtSignal`, `timeToResolution`) is captured at write time when the client omits it. Identity comes from the session or the operator key; the handle is never read from the body. Not CORS-open — a fork calls this from its own server route (`DENPA_BASE_URL`, default `https://denpa.ai`). Receipt at `https://denpa.ai/receipts/<id>`.","operationId":"createSignal","security":[{"operatorKey":[]},{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalWrite"}}}},"responses":{"200":{"description":"Filed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalWriteResult"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"description":"`unauthenticated`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`market_closed` — the market is settled or provisional · `already_predicted` — the caller's signal on this market is locked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`signal_service_unavailable` · `db_unavailable`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/signals/{id}":{"get":{"tags":["signals-leaderboard"],"summary":"One signal","description":"Public. The operator id is the masked `op_…` form (field `privyId` kept for client compatibility).","operationId":"getSignal","parameters":[{"$ref":"#/components/parameters/signalId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signal"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/signals/{id}/events":{"get":{"tags":["signals-leaderboard"],"summary":"Signal history","description":"The signal's append-only history, oldest first: operator events (take, reaffirm, confidence, note, share) and the resolution. Empty list when the signal has none — 404 only when the signal itself does not exist.","operationId":"listSignalEvents","parameters":[{"$ref":"#/components/parameters/signalId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalEvents"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["protocol-writes"],"summary":"Append a signal event","description":"Owner only (session or operator key). Appends an event; never edits the canonical signal (first-call lock) and never accepts `resolved` — only the resolver writes that.","operationId":"createSignalEvent","security":[{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"$ref":"#/components/parameters/signalId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalEventWrite"}}}},"responses":{"201":{"description":"Appended","content":{"application/json":{"schema":{"type":"object","required":["ok","event"],"properties":{"ok":{"type":"boolean"},"event":{"oneOf":[{"$ref":"#/components/schemas/SignalEvent"},{"type":"null"}]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"description":"`auth_required`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`not_your_signal`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/signals/feed":{"get":{"tags":["signals-leaderboard"],"summary":"Global signal feed","description":"Operators are identified by `operatorPublicId` (`op_<hmac16>`) and handle — never a raw provider id.","operationId":"getSignalFeed","parameters":[{"name":"type","in":"query","schema":{"type":"string","enum":["beat_crowd","open"]},"description":"`beat_crowd` — contrarian wins only (crowd >65 % against at signal time). `open` — pending signals marked to the current price (`liveYesBps`, `moveBps`). Omit for the most recent."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}}],"responses":{"200":{"description":"OK (empty list on error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalFeed"}}}}}}},"/api/m/{marketId}/streams":{"get":{"tags":["market-context"],"summary":"Streams bound to a market","operationId":"listMarketStreams","parameters":[{"$ref":"#/components/parameters/marketId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["streams"],"properties":{"streams":{"type":"array","items":{"$ref":"#/components/schemas/StreamBinding"}}}}}}}}},"post":{"tags":["protocol-writes"],"summary":"Bind a stream to a market","description":"One operator, one active market at a time: prior bindings under the caller's handle are cleared before (re)binding. The handle is resolved server-side from the verified identity, never from the body.","operationId":"bindMarketStream","security":[{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"$ref":"#/components/parameters/marketId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"HLS URL — must contain `.m3u8` or `stream.mux.com`."},"label":{"type":"string","description":"Defaults to the upper-cased handle."}}}}}},"responses":{"200":{"description":"Bound","content":{"application/json":{"schema":{"type":"object","required":["ok","streams"],"properties":{"ok":{"type":"boolean"},"streams":{"type":"array","items":{"$ref":"#/components/schemas/StreamBinding"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["protocol-writes"],"summary":"Unbind the caller's stream","operationId":"unbindMarketStream","security":[{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"$ref":"#/components/parameters/marketId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/streamer/signal":{"get":{"tags":["operator-live"],"summary":"Active overlay SIGNAL","description":"Public with `?handle=`. Without a handle the route is an admin-only dump of every active signal keyed by handle.","operationId":"getStreamerSignal","security":[{},{"adminSecret":[]}],"parameters":[{"name":"handle","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"The signal, or `{ marketId: null }` when none is routed.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/StreamerSignal"},{"type":"object","required":["marketId"],"properties":{"marketId":{"type":"null"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["protocol-writes","operator-live"],"summary":"Route a SIGNAL to the overlay","description":"Pushes the OBS overlay / live-page SIGNAL for the caller's own channel (`streamerId` is the verified handle, never body input).","operationId":"setStreamerSignal","security":[{"operatorKey":[]},{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StreamerSignalWrite"}}}},"responses":{"200":{"description":"Routed","content":{"application/json":{"schema":{"type":"object","required":["ok","signal"],"properties":{"ok":{"type":"boolean"},"signal":{"$ref":"#/components/schemas/StreamerSignal"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["protocol-writes","operator-live"],"summary":"Clear the caller's overlay SIGNAL","operationId":"clearStreamerSignal","security":[{"operatorKey":[]},{"sessionCookie":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/dev/keys":{"post":{"tags":["protocol-writes"],"summary":"Mint a dk_ key","description":"Needs a Privy login (JWT) — you cannot mint a key with a key. The plaintext key is returned once; new keys carry `permissions: [\"read\",\"signal\",\"broadcast\"]` (or the subset passed) and tier `free`. Every keyed hub request counts against 60/min per key — tolerate `429`.","operationId":"createDevKey","security":[{"privyJwt":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["label"],"properties":{"label":{"type":"string","maxLength":100},"permissions":{"type":"array","items":{"type":"string","enum":["read","signal","broadcast"]},"description":"Optional subset to mint a narrower key; default all three."}}}}}},"responses":{"200":{"description":"Minted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyMint"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"description":"`auth_required`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["protocol-writes"],"summary":"List own keys","operationId":"listDevKeys","security":[{"privyJwt":[]}],"responses":{"200":{"description":"OK (no raw keys).","content":{"application/json":{"schema":{"type":"object","required":["keys"],"properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyListItem"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["protocol-writes"],"summary":"Revoke a key","operationId":"revokeDevKey","security":[{"privyJwt":[]}],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/user/follow":{"get":{"tags":["protocol-writes"],"summary":"Follow counts for a handle","operationId":"getFollow","security":[{},{"sessionCookie":[]}],"parameters":[{"name":"handle","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowCounts"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}},"post":{"tags":["protocol-writes"],"summary":"Follow an operator","description":"\"I trust this operator's judgment.\" The route takes a handle, writes the handle-keyed `follows` table and bridges to the id-keyed `user_follows` graph best-effort; the protocol rule is user-to-user by id.","operationId":"follow","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["handle"],"properties":{"handle":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"followers":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["protocol-writes"],"summary":"Unfollow an operator","operationId":"unfollow","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["handle"],"properties":{"handle":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"followers":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/live/{handle}/clip":{"post":{"tags":["operator-live","protocol-writes"],"summary":"MARK ▸ 30 s","description":"Clips the last window of the caller's live Mux broadcast into a take (cooldown 120 s, 10/day). Session-authenticated; the clip lands on the operator's tape as `processing`.","operationId":"markLiveClip","security":[{"sessionCookie":[]},{"operatorKey":[]}],"parameters":[{"$ref":"#/components/parameters/handle"}],"responses":{"200":{"description":"Clip requested","content":{"application/json":{"schema":{"type":"object","properties":{"clipId":{"type":"string"},"assetId":{"type":"string"},"marketId":{"type":["string","null"]},"status":{"type":"string","const":"processing"}}}}}},"400":{"description":"`invalid_window`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"`auth_required`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_live` · `too_early`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Cooldown or daily cap.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"`upstream_unreachable` · `clip_failed`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/polymarket/featured":{"get":{"tags":["market-context"],"summary":"Heatmap tiles","description":"The home heatmap. Default: culture-first tiles from the protocol feed (Polymarket only, numeric ids). Live operator tiles (`live:<handle>`, `isLive: true`) pin to the front. Crypto price markets are excluded from the resolving board.","operationId":"getFeatured","x-denpa-cors-open":true,"parameters":[{"name":"mode","in":"query","schema":{"type":"string","enum":["resolving24h","soccer"]},"description":"`resolving24h` — next-24h board, volume-ranked. `soccer` — Polymarket Soccer tag."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeaturedResponse"}}}}}}},"/api/polymarket/markets":{"get":{"tags":["market-context"],"summary":"Universe search","description":"All active Polymarket markets ranked by 24h volume (paginated upstream to ~500, crypto stripped), filtered client-side by `q` — Gamma's own `q=` is unreliable.","operationId":"searchMarkets","x-denpa-cors-open":true,"parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Substring match on name or slug."},{"name":"set","in":"query","schema":{"type":"string","enum":["cannes"]},"description":"Preserved Cannes-only payload."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["markets","fetchedAt"],"properties":{"markets":{"type":"array","items":{"$ref":"#/components/schemas/SignalMarket"}},"fetchedAt":{"type":"string","format":"date-time"}}}}}},"502":{"description":"Upstream failure — same shape with `markets: []`.","content":{"application/json":{"schema":{"type":"object","properties":{"markets":{"type":"array","items":{}},"fetchedAt":{"type":"string"}}}}}}}}},"/api/polymarket/market":{"get":{"tags":["market-context"],"summary":"Single market (raw Gamma)","description":"Proxy of `gamma-api.polymarket.com/markets/{id}` — the upstream object is returned unchanged.","operationId":"getMarketRaw","x-denpa-cors-open":true,"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The Gamma market object.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"`missing_id`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"`upstream_error` · `fetch_failed`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/polymarket/market-history":{"get":{"tags":["market-context"],"summary":"Price history","description":"CLOB-backed YES price series (`clobTokenIds[0]`). `lmt-` ids resolve through Limitless. Returns `{ history: [] }` rather than erroring.","operationId":"getMarketHistory","x-denpa-cors-open":true,"parameters":[{"name":"marketId","in":"query","schema":{"type":"string"},"description":"Resolved to the YES token when `tokenId` is omitted."},{"name":"tokenId","in":"query","schema":{"type":"string"},"description":"CLOB token id (preferred)."},{"name":"interval","in":"query","schema":{"type":"string","enum":["1H","24H","7D","ALL"],"default":"24H"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["history"],"properties":{"history":{"type":"array","items":{"$ref":"#/components/schemas/PricePoint"}}}}}}},"400":{"description":"Neither `tokenId` nor a resolvable `marketId` — `{ history: [] }`.","content":{"application/json":{"schema":{"type":"object","properties":{"history":{"type":"array","items":{}}}}}}}}}},"/api/polymarket/resolved":{"get":{"tags":["market-context"],"summary":"Recently resolved markets","description":"Closed markets from the last 7 days (crypto stripped, max 20) — the transmissions source.","operationId":"getResolvedMarkets","x-denpa-cors-open":true,"parameters":[{"name":"channel","in":"query","schema":{"type":"string","enum":["news","cannes","music","eurovision","science","worldcup"]},"description":"Keyword bucket; omit for all."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["markets"],"properties":{"markets":{"type":"array","items":{"$ref":"#/components/schemas/ResolvedMarket"}}}}}}}}}},"/api/m/{marketId}":{"get":{"tags":["market-context"],"summary":"Market summary (same-origin)","description":"Key fields of a Gamma market. Same-origin / server-side — not CORS-open; forks use `/api/network/market/{marketId}`.","operationId":"getMarketSummary","parameters":[{"$ref":"#/components/parameters/marketId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketSummary"}}}},"404":{"description":"`market_not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"`gamma_upstream_error` · `fetch_failed`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/m/{marketId}/related":{"get":{"tags":["market-context"],"summary":"Related markets (same-origin)","operationId":"getRelatedMarkets","parameters":[{"$ref":"#/components/parameters/marketId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelatedResponse"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/m/{marketId}/signals":{"get":{"tags":["market-context","signals-leaderboard"],"summary":"Market ledger (same-origin)","description":"The most recent 50 operator signals on a market with callsign and score. Note: this surface still carries the raw `privyId`.","operationId":"getMarketLedger","parameters":[{"$ref":"#/components/parameters/marketId"},{"name":"direction","in":"query","schema":{"$ref":"#/components/schemas/Direction"}},{"name":"excludePrivyId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketLedger"}}}}}}},"/api/m/{marketId}/crowd":{"get":{"tags":["market-context"],"summary":"MARKET vs CROWD vs YOU (same-origin)","description":"The Crowd Signal Layer read. CROWD is Denpa signals (bots excluded); YOU is the caller's own first call (session only). MARKET (the venue probability) is not served here.","operationId":"getMarketCrowd","security":[{},{"sessionCookie":[]}],"parameters":[{"$ref":"#/components/parameters/marketId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrowdRead"}}}}}}},"/api/m/{marketId}/sentiment":{"get":{"tags":["market-context"],"summary":"Sentiment bundle (same-origin)","description":"Trade flow (Polymarket data-api), trader comments (Gamma) and Google News headlines. Each section degrades to empty on failure.","operationId":"getMarketSentiment","parameters":[{"$ref":"#/components/parameters/marketId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sentiment"}}}}}}},"/api/m/{marketId}/clips":{"get":{"tags":["market-context"],"summary":"Market tape (same-origin)","description":"Ready takes on the market (7-day retention; the top 5 by views stay archived). Optional identity flags the caller's own takes `mine`. The REACT LIVE write path (POST/PATCH/DELETE) is first-party and not part of the fork contract.","operationId":"getMarketClips","security":[{},{"operatorKey":[]},{"sessionCookie":[]}],"parameters":[{"$ref":"#/components/parameters/marketId"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["clips"],"properties":{"clips":{"type":"array","items":{"$ref":"#/components/schemas/ClipEntry"}}}}}}}}}},"/api/markets/airable":{"get":{"tags":["market-context"],"summary":"Airable subset","description":"Which of the given markets a surface may still put on air: open at the provider AND not past `endDate` (`closed=false` alone is not enough). Non-numeric ids pass through unchecked; a provider blip returns every id.","operationId":"getAirableMarkets","parameters":[{"name":"ids","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated market ids (max 100)."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["airable"],"properties":{"airable":{"type":"array","items":{"type":"string"}}}}}}}}}},"/api/resolution/outcome":{"get":{"tags":["resolution"],"summary":"Resolution outcome","description":"The canonical Layer-6 record for a resolved market. `{ outcome: null }` when unresolved (graceful empty). The same object rides on `/api/network/market/{id}` as `market.resolution`.","operationId":"getResolutionOutcome","parameters":[{"name":"market","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["marketId","outcome"],"properties":{"marketId":{"type":"string"},"outcome":{"oneOf":[{"$ref":"#/components/schemas/ResolutionOutcome"},{"type":"null"}]}}}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/api/resolution/markets":{"get":{"tags":["resolution"],"summary":"Denpa-native markets","description":"`due=1` = open markets whose cutoff has passed and nobody has resolved yet — the Monday list.","operationId":"listDenpaMarkets","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["open","resolved","invalid"]}},{"name":"due","in":"query","schema":{"type":"string","enum":["1"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["markets"],"properties":{"markets":{"type":"array","items":{"$ref":"#/components/schemas/DenpaMarket"}},"due":{"type":"boolean","const":true}}}}}}}},"post":{"tags":["resolution","admin"],"summary":"Mint a Denpa-native market","description":"Ids are namespaced `denpa-…` (generated from the question when omitted). Idempotent on id.","operationId":"createDenpaMarket","security":[{"adminSecret":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["question"],"properties":{"id":{"type":"string"},"question":{"type":"string"},"category":{"type":"string","default":"culture"},"cutoffAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}}}}},"responses":{"200":{"description":"Created (or already existed).","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"market":{"$ref":"#/components/schemas/DenpaMarket"},"existed":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/resolution/finalize":{"post":{"tags":["resolution","admin"],"summary":"Finalize a Denpa-native market","description":"Commits the verdict and scores through the one choke point (claims the outcome once, with provenance). YES/NO scores every open signal; INVALID voids them. Polymarket numeric ids are rejected — those resolve through the venue scan.","operationId":"finalizeResolution","security":[{"adminSecret":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["marketId","verdict"],"properties":{"marketId":{"type":"string","description":"`denpa-…` only."},"verdict":{"type":"string","enum":["YES","NO","INVALID"]},"reason":{"type":"string"},"finalizedBy":{"type":"string"},"resolver":{"type":"string","enum":["admin","oracle","manual"]},"source":{"type":"string"},"proofUrl":{"type":"string"}}}}}},"responses":{"200":{"description":"Finalized","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"verdict":{"$ref":"#/components/schemas/ResolutionVerdict"},"scored":{"type":"integer"},"voided":{"type":"integer"}}}}}},"400":{"description":"Validation, or `polymarket_id_not_allowed`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/resolution/dispute":{"post":{"tags":["resolution","admin"],"summary":"Flag or clear a dispute","description":"A disputed market scores nothing further until cleared; existing scores stand (re-resolution is a separate human decision).","operationId":"disputeResolution","security":[{"adminSecret":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["marketId"],"properties":{"marketId":{"type":"string"},"disputed":{"type":"boolean","default":true},"reason":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"claim":{"$ref":"#/components/schemas/MarketResolutionClaim"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"No resolution claim for this market yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/admin/resolve-signals":{"post":{"tags":["resolution","admin"],"summary":"Venue auto-scan or force-resolve","description":"No body = scan up to 50 pending markets against the venue settlement. `{ marketId, outcome }` = force-resolve, recorded as `resolver: \"admin\"`.","operationId":"resolveSignals","security":[{"adminSecret":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"marketId":{"type":"string"},"outcome":{"$ref":"#/components/schemas/Direction"}}}}}},"responses":{"200":{"description":"Scan or manual result.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"manual"},"marketId":{"type":"string"},"outcome":{"$ref":"#/components/schemas/Direction"},"scored":{"type":"integer"}}},{"type":"object","properties":{"mode":{"type":"string","const":"scan"},"scanned":{"type":"integer"},"resolved":{"type":"integer"},"totalScored":{"type":"integer"},"results":{"type":"array","items":{"type":"object","properties":{"marketId":{"type":"string"},"outcome":{"type":["string","null"]},"scored":{"type":"integer"},"error":{"type":"string"}}}}}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}},"get":{"tags":["resolution","admin"],"summary":"Auto-scan (cron alias)","operationId":"resolveSignalsCron","security":[{"cronSecret":[]},{"adminSecret":[]}],"responses":{"200":{"description":"Scan result (see POST).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/admin/daily-digest":{"post":{"tags":["admin"],"summary":"Morning headlines (data for DENPA MORNING)","description":"Four Google News buckets — thesis / people / regulation / platforms — from the last 48h, as data. Sends nothing. This is what DENPA MORNING (`scripts/denpa_brew.py`) reads each morning. The operator digest this route used to build and mail was deleted on 2026-09-26 (contract 1.9.2); `?dry=1` is still accepted and ignored.","operationId":"dailyDigest","security":[{"adminSecret":[]}],"parameters":[{"name":"dry","in":"query","schema":{"type":"string","enum":["1"]},"description":"Accepted and ignored; the route only ever returns data."}],"responses":{"200":{"description":"The headlines.","content":{"application/json":{"schema":{"type":"object","properties":{"payload":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"},"news":{"type":"object","properties":{"thesis":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"url":{"type":"string","format":"uri"},"source":{"type":"string"},"seenAt":{"type":["string","null"],"format":"date-time"}}}},"people":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"url":{"type":"string","format":"uri"},"source":{"type":"string"},"seenAt":{"type":["string","null"],"format":"date-time"}}}},"regulation":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"url":{"type":"string","format":"uri"},"source":{"type":"string"},"seenAt":{"type":["string","null"],"format":"date-time"}}}},"platforms":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"url":{"type":"string","format":"uri"},"source":{"type":"string"},"seenAt":{"type":["string","null"],"format":"date-time"}}}},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/broadcast/program":{"get":{"tags":["broadcast"],"summary":"Canonical clock (guide lanes)","description":"Proxy of the program-clock timeline adapted into the lane shape the broadcast guide renders (SPORTS / MUSIC / CRYPTO / POLITICS …), with `lmt-` markets folded in and per-market signal/take/stream counts. `{ enabled: false, lanes: [] }` when the clock is unwired. For the raw rundown scoped to a station use `/api/network/program`.","operationId":"getBroadcastProgram","x-denpa-cors-open":true,"parameters":[{"name":"preset","in":"query","schema":{"type":"string","enum":["hot","resolving","close"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BroadcastProgram"}}}}}}},"/api/broadcast/schedule":{"get":{"tags":["broadcast"],"summary":"Direct schedule scan (legacy-but-live)","description":"Client-side fallback schedule built directly from the venue. Returns `{ total, buckets, programs[] }` of `BroadcastSegment`-shaped programs collapsed by event.","operationId":"getBroadcastSchedule","x-denpa-cors-open":true,"parameters":[{"name":"cat","in":"query","schema":{"type":"string"},"description":"Category filter."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["total","buckets","programs"],"properties":{"total":{"type":"integer"},"buckets":{"type":"object","additionalProperties":true},"programs":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}}}},"/api/broadcast/spotlight":{"get":{"tags":["broadcast"],"summary":"SPOTLIGHT lane","description":"Boosted user takes currently placed in the SPOTLIGHT lane (`boost_until` in the future).","operationId":"getBroadcastSpotlight","x-denpa-cors-open":true,"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["segments"],"properties":{"segments":{"type":"array","items":{"type":"object","additionalProperties":true,"description":"`BroadcastSegment`-shaped, `spotlight: true`."}}}}}}}}}},"/api/broadcast/feed":{"get":{"tags":["broadcast"],"summary":"Clip feed by market","operationId":"getBroadcastFeed","x-denpa-cors-open":true,"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["groups"],"properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/FeedGroup"}}}}}}}}}},"/api/broadcast/bumpers":{"get":{"tags":["broadcast"],"summary":"Bound bumpers","description":"Map of marketId → ready bumper clip. Bumpers are bound at admin time and planned by the clock; no AI video is produced as a side effect of any call.","operationId":"getBroadcastBumpers","x-denpa-cors-open":true,"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["bumpers"],"properties":{"bumpers":{"type":"object","additionalProperties":{"type":"object","properties":{"uid":{"type":"string"},"hlsUrl":{"type":"string"}}}}}}}}}}}},"/api/broadcast/influence":{"get":{"tags":["broadcast"],"summary":"Influence (clock proxy)","description":"Pass-through of the program-clock influence read; `{ enabled: false }` when unwired.","operationId":"getBroadcastInfluence","x-denpa-cors-open":true,"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}},"additionalProperties":true}}}}}}},"/api/broadcast/preempt":{"get":{"tags":["broadcast"],"summary":"Director inbox","description":"Momentum preemption proposals (CAUSAL_LOOP.md). `{ enabled: false, proposals: [] }` when unwired.","operationId":"getPreemptProposals","x-denpa-cors-open":true,"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["enabled","proposals"],"properties":{"enabled":{"type":"boolean"},"proposals":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true}}}}}},"post":{"tags":["broadcast","admin"],"summary":"Decide a proposal","operationId":"decidePreempt","security":[{"adminSecret":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}},"additionalProperties":true}}}},"responses":{"200":{"description":"Upstream decision.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"502":{"description":"`decide failed`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Program clock unwired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/wire":{"get":{"tags":["wire-situations"],"summary":"THE WIRE","description":"Markets ranked by how much their belief moved over the window. Movement is Denpa-derived from the observation history where it reaches back far enough (`deltaSource: \"denpa\"`), falling back to the provider's 24h delta until history matures. Always 200 — empty `events` with `coverageStatus: \"partial\"` on error. Not CORS-open: forks call it server-side. SDK `client.getWire()`.","operationId":"getWire","parameters":[{"$ref":"#/components/parameters/lane"},{"$ref":"#/components/parameters/wireWindow"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WireResponse"}}}}}}},"/api/wire/observe":{"get":{"tags":["wire-situations"],"summary":"Observation status","description":"Row counts so accrual can be verified with numbers, not a 200.","operationId":"getWireObserveStatus","responses":{"200":{"description":"OK (on error: `{ error, tablesReady: false }`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObserveStatus"}}}}}},"post":{"tags":["wire-situations","admin"],"summary":"Backstop observation write","description":"Writes one observation run for zero-traffic periods (the poller pings this each tick). Recency-gated so it never double-writes against organic `/api/wire` traffic.","operationId":"postWireObserve","security":[{"adminSecret":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"written":{"type":"integer"},"crowdWritten":{"type":"integer"},"markets":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/situations":{"get":{"tags":["wire-situations"],"summary":"SITUATIONS","description":"The developing stories THE WIRE is monitoring: every moving market in one provider event collapsed into a single ranked story. Read `peakDelta` and `markets[]`; never sum the deltas. Always 200, empty on error. CORS-open — a fork may fetch it from the browser. SDK `client.getSituations()`.","operationId":"getSituations","x-denpa-cors-open":true,"parameters":[{"$ref":"#/components/parameters/lane"},{"$ref":"#/components/parameters/wireWindow"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":30}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SituationsResponse"}}}}}}},"/api/v1/signals/external":{"servers":[{"url":"https://api.denpa.ai","description":"Hono API service"},{"url":"https://api-production-802f5.up.railway.app","description":"Same service, Railway hostname"}],"get":{"tags":["wire-situations","market-context"],"summary":"The categorised protocol feed","description":"Two exchanges: Polymarket carries `sports` and `politics`; Kalshi carries the whole `music_culture` bucket (~80 % of the feed). `category` is an exact match on the four buckets — `music`, `culture`, `entertainment` and `sport` are accepted aliases; anything else returns an empty feed rather than an error. `source=polymarket` is the only pin (denpa.ai's own heatmap uses it). Falls back to the Postgres snapshot (`stale: true`) when a live fetch fails. CORS `*` on the API service.","operationId":"getExternalSignals","x-denpa-cors-open":true,"parameters":[{"name":"category","in":"query","schema":{"type":"string","enum":["sports","politics","fashion","music_culture","music","culture","entertainment","sport"]}},{"name":"source","in":"query","schema":{"type":"string","enum":["polymarket"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":10}},{"name":"fresh","in":"query","schema":{"type":"string","enum":["1","true"]},"description":"Bypass the 30 s cache."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalSignalsResponse"}}}},"502":{"description":"`external_signals_unavailable` — live fetch failed and no snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/streamers/live":{"get":{"tags":["operator-live"],"summary":"Live and recent operators","description":"Powers the channel rail. `live` = an open Mux session (staleness-guarded at 12 h); `recent` = each operator's latest content in the last 30 days (ended broadcast or ready take), excluding anyone live.","operationId":"getLiveStreamers","responses":{"200":{"description":"OK (empty lists on error).","content":{"application/json":{"schema":{"type":"object","required":["live","recent"],"properties":{"live":{"type":"array","items":{"$ref":"#/components/schemas/LiveStreamer"}},"recent":{"type":"array","items":{"$ref":"#/components/schemas/RecentStreamer"}}}}}}}}}},"/api/streamer/receipts":{"get":{"tags":["operator-live"],"summary":"Session receipts","description":"Broadcast session receipts for a handle, including the END CARD recap when published. Empty without `handle`.","operationId":"getStreamerReceipts","parameters":[{"name":"handle","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["receipts"],"properties":{"receipts":{"type":"array","items":{"$ref":"#/components/schemas/StreamReceipt"}}}}}}}}}},"/api/operator/leaderboard":{"get":{"tags":["signals-leaderboard"],"summary":"Broadcast-score board","description":"Operators with ≥3 resolved on-stream calls, ranked by composite BROADCAST score (accuracy + bounded airtime/reach bonuses), top 50. The response is a bare array.","operationId":"getOperatorLeaderboard","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OperatorBoardRow"}}}}}}}},"/api/operator/{handle}":{"get":{"tags":["signals-leaderboard","operator-live"],"summary":"Operator atom","description":"Unified, embeddable operator record: identity, rank, stats, manifesto, live SIGNAL, recent on-stream calls and moments.","operationId":"getOperatorAtom","parameters":[{"$ref":"#/components/parameters/handle"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperatorAtom"}}}},"404":{"description":"`operator_not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/signals/leaderboard":{"servers":[{"url":"https://api.denpa.ai","description":"Hono API service"},{"url":"https://api-production-802f5.up.railway.app","description":"Same service, Railway hostname"}],"get":{"tags":["signals-leaderboard"],"summary":"Signal leaderboard","description":"All operators ranked by total score (tiebreak: won). `operators=human` (default) keeps AI operators off the public board; `all` includes everyone; `ai` returns only AI operators. Rows carry the masked `op_` id in `privyId` and `operatorPublicId`. CORS `*` on the API service.","operationId":"getSignalLeaderboard","x-denpa-cors-open":true,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"operators","in":"query","schema":{"type":"string","enum":["human","all","ai"],"default":"human"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["count","operators","leaderboard"],"properties":{"count":{"type":"integer"},"operators":{"type":"string"},"leaderboard":{"type":"array","items":{"$ref":"#/components/schemas/OperatorLeaderRow"}}}}}}},"503":{"description":"`DB_UNAVAILABLE`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/aura/scores":{"servers":[{"url":"https://api.denpa.ai","description":"Hono API service"},{"url":"https://api-production-802f5.up.railway.app","description":"Same service, Railway hostname"}],"get":{"tags":["aura"],"summary":"All category scores","description":"Every category from the signal-router cache (refreshed every 15 s).","operationId":"getAuraScores","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["scores","categories","cachedAt"],"properties":{"scores":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/AuraCategoryResult"}},"categories":{"type":"array","items":{"type":"string"}},"cachedAt":{"type":"string","format":"date-time"}}}}}}}}},"/api/aura/score":{"servers":[{"url":"https://api.denpa.ai","description":"Hono API service"},{"url":"https://api-production-802f5.up.railway.app","description":"Same service, Railway hostname"}],"get":{"tags":["aura"],"summary":"One category score","description":"Category-aware AURA with EMA damping — `ema` is the number surfaces show. aura = liveness × (0.35·pressure + 0.25·density + 0.40·prime).","operationId":"getAuraScore","parameters":[{"name":"category","in":"query","schema":{"$ref":"#/components/schemas/SignalCategory"},"description":"Default `culture`."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuraCategoryResult"}}}},"400":{"description":"Invalid category (`valid` lists the options).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/aura/market-pressure/{tokenId}":{"servers":[{"url":"https://api.denpa.ai","description":"Hono API service"},{"url":"https://api-production-802f5.up.railway.app","description":"Same service, Railway hostname"}],"get":{"tags":["aura"],"summary":"Market pressure","description":"Market-side pressure from the live ticker: price velocity (cents/min over a rolling 5-min window) normalised on the same 5000 cents/min cap as the AURA pressure component.","operationId":"getMarketPressure","parameters":[{"name":"tokenId","in":"path","required":true,"schema":{"type":"string"},"description":"CLOB token id."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketPressure"}}}},"400":{"description":"`invalid_token_id`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/mcp":{"post":{"tags":["mcp"],"summary":"MCP server (streamable HTTP)","description":"Stateless JSON-RPC 2.0 over plain JSON, own CORS. Protocol subset: `initialize`, `ping`, `tools/list`, `tools/call`; notifications get `202`; batches accepted. Versions `2025-06-18` / `2025-03-26` / `2024-11-05`. Tools: `denpa_whoami · denpa_featured_markets · denpa_market · denpa_push_signal · denpa_get_signal · denpa_clear_signal · denpa_bind_stream · denpa_unbind_stream · denpa_go_live · denpa_my_broadcasts`. `initialize` and `tools/list` are open; authenticated tools act as the key's owner and forward the caller's `Authorization` to the operator REST routes, so validation and ownership rules stay in one place. Connect: `claude mcp add --transport http denpa https://denpa.ai/api/mcp --header \"Authorization: Bearer dk_…\"`.","operationId":"mcp","x-denpa-cors-open":true,"security":[{},{"operatorKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/JsonRpcRequest"},{"type":"array","items":{"$ref":"#/components/schemas/JsonRpcRequest"}}]}}}},"responses":{"200":{"description":"JSON-RPC response (or a batch of them).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/JsonRpcResponse"},{"type":"array","items":{"$ref":"#/components/schemas/JsonRpcResponse"}}]}}}},"202":{"description":"Notification accepted (no body)."},"400":{"description":"Parse error (`-32700`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}}}},"get":{"tags":["mcp"],"summary":"No SSE stream to resume","description":"The server is stateless; GET answers `405` with a pointer to the docs.","operationId":"mcpGet","responses":{"405":{"description":"Method not allowed.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","const":"denpa"},"transport":{"type":"string","const":"streamable-http"},"hint":{"type":"string"}}}}}}}}}}}