{"openapi":"3.1.0","info":{"title":"redvblue API","version":"0.1.0","description":"Read the live state of redvblue: tickets with funding, a half-hourly multi-model referee panel (facts only, never taste), a celebrated drop log, and honest (metered/derived/simulated/operator-labeled) ledgers. All read endpoints are public by design; OAuth (client_credentials) exists so agents can exercise an authenticated rail — see /auth.md."},"servers":[{"url":"https://redvblue.dev"}],"paths":{"/api/health":{"get":{"summary":"Liveness check","operationId":"health","responses":{"200":{"description":"redvblue is up","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"generatedAt":{"type":"string"}}}}}}}}},"/api/stats":{"get":{"summary":"Board stats plus honest traffic counters","operationId":"portfolioStats","responses":{"200":{"description":"Ship rate vs the 10% target, cost, counters"}}}},"/api/tickets":{"get":{"summary":"List tickets","operationId":"listTickets","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["proposed","funded","building","refereeing","dropped","shipped"]}}],"responses":{"200":{"description":"Array of ticket snapshots","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketSnapshot"}}}}}}}},"/api/tickets/{id}":{"get":{"summary":"Full detail for one ticket, from its own Durable Object","operationId":"getTicket","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Ticket with gates and a labeled ledger"},"404":{"description":"No such ticket"}}}},"/api/drops":{"get":{"summary":"The drop log: dropped tickets with drop notes","operationId":"dropLog","responses":{"200":{"description":"Array of ticket snapshots","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TicketSnapshot"}}}}}}}},"/api/events":{"get":{"summary":"Recent board events","operationId":"recentEvents","responses":{"200":{"description":"Newest-first event feed"}}}},"/api/whoami":{"get":{"summary":"Verify an OAuth access token issued by this site","operationId":"whoami","security":[{"factoryOAuth":["read"]}],"responses":{"200":{"description":"The authenticated client identity"},"401":{"description":"Missing or invalid bearer token"}}}},"/oauth/register":{"post":{"summary":"Dynamic client registration (RFC 7591), open to agents","operationId":"registerClient","responses":{"201":{"description":"client_id and client_secret"},"429":{"description":"Daily registration cap reached"}}}},"/oauth/token":{"post":{"summary":"Token endpoint — client_credentials only","operationId":"token","responses":{"200":{"description":"Bearer access token (ES256 JWT)"},"401":{"description":"invalid_client"}}}}},"components":{"schemas":{"TicketSnapshot":{"type":"object","description":"Registry projection of a ticket: status, funding, gates, repo pointers. Status values are stored in the site dictionary (dropped, shipped, refereeing).","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["proposed","funded","building","refereeing","dropped","shipped"]},"budgetMicros":{"type":"integer"},"spentMicros":{"type":"integer"},"dropNote":{"type":["string","null"]}}}},"securitySchemes":{"factoryOAuth":{"type":"oauth2","description":"Open dynamic registration at /oauth/register; see /auth.md.","flows":{"clientCredentials":{"tokenUrl":"https://redvblue.dev/oauth/token","scopes":{"read":"Read redvblue (everything read is also public without a token)"}}}}}}}