Shark Tank Control API
OpenAPI 3.0 · raw JSON →
GET /api/health
Liveness probe
Returns module name and server time.
Responses
| Status | Description |
|---|---|
200 | Healthy — application/json HealthResponse |
GET /api/tank
List joinable tanks
Stable catalog of ocean-named tanks with live player counts and top score. One earlier path name still reaches this same handler.
Responses
| Status | Description |
|---|---|
200 | Tank list — application/json TankResponse |
GET /api/leaderboard
Global leaderboard
Top scores across all tanks, persisted by the control plane.
Responses
| Status | Description |
|---|---|
200 | Top scores — application/json LeaderboardResponse |
GET /api/profile
Read a player profile
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
id | query | no | string | Player id (default: local) |
Responses
| Status | Description |
|---|---|
200 | Profile — application/json ProfileResponse |
POST /api/profile
Upsert a player profile
Unauthenticated: the identity is a `wg_player` cookie the first GET mints, so the cookie cannot be the throttle key. Writes are bucketed per edge connection and, separately, under a global ceiling across every public caller at once — an overwrite of an existing row costs the same Durable Object write as a new one, so both branches are metered. Bodies over 16 KiB are refused, and the ceiling is enforced on the bytes that actually arrive rather than on a declared `Content-Length`. When the spend gate is closed this route is refused with 503 along with the game, because it is one of the writes the spend limit exists to stop.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
id | query | no | string | Player id (default: local) |
Request body (required)
application/json → Profile
Responses
| Status | Description |
|---|---|
200 | Saved profile — application/json ProfileResponse |
413 | Payload too large |
429 | Rate limited, per connection or across all public callers |
503 | Spend gate closed |
POST /api/audit
Record a public gameplay event
The only unauthenticated write into the 90-day service action log, and the reason that log carries two limits the trusted server-side callers do not. Accepts exactly two event types: `play` (which requires a `room` from the fixed tank list) and `customize` (whose `detail` must match `skin <id>` or is replaced with a fixed phrase). Bodies over 16 KiB are refused, and the ceiling is enforced on the bytes that actually arrive rather than on a declared `Content-Length`, so a chunked body cannot slip past it. Writes are bucketed per edge connection and, separately, under a global ceiling across every public caller at once; publicly written rows are then trimmed to their own floor before the whole-log trim runs, so a flood can only evict other public rows and never server-recorded evidence. The display name attached to the row is resolved on the server behind that rate limit, never taken from the request.
Responses
| Status | Description |
|---|---|
200 | Event recorded — application/json object |
400 | Unsupported public event type, or a play event without a valid tank |
413 | Payload too large |
429 | Rate limited, per connection or across all public callers |
503 | Spend gate closed |
POST /api/security-report
Report a security issue
Same-origin public white-hat intake. One request creates a linked report, a retained audit event, and an append-only SHA-256 control-history receipt, and raises the report to operations. It does not change service state: the game stays online, no incident is opened, and no tank is disconnected. Whether a report warrants downtime is a separate authenticated operator decision made at /admin/security-report. Accepted reports are throttled globally to one per minute. Returned metadata is limited to environment, deployment, colo, and country; it contains no secrets or IP data. A report is not confirmation of compromise.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
X-WG-Security-Report | header | yes | enum: white-hat |
Responses
| Status | Description |
|---|---|
200 | Security report receipt — application/json object |
403 | Same-origin report required |
429 | A security report was accepted moments ago |
502 | Report could not be persisted |
GET /room/{id}/ws
Realtime play (WebSocket upgrade)
Upgrades the connection (HTTP 101) into the tank's realtime Room. **Client → server** messages: `{t:'hello',name,skin,debugLanguage}`, `{t:'debug',language}` (selected TypeScript/PHP capture tag), `{t:'input',action}` (action = setHeading/setBoost/rocket/respawn), `{t:'ping',ts}`. **Server → client**: `welcome`, `state` (per-tick snapshot), `leaderboard`, `died`, `pong`.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
id | path | yes | string | Tank id (e.g. room-1) |
roomName | query | no | string | Display name for the tank |
Responses
| Status | Description |
|---|---|
101 | Switching Protocols — WebSocket established |
426 | Upgrade Required — request was not a WebSocket upgrade |
GET /docs/
API documentation (this page)
Renders this OpenAPI document as HTML. Raw document at /docs/openapi.json.
Responses
| Status | Description |
|---|---|
200 | HTML documentation — text/html string |
GET /docs/openapi.json
OpenAPI document
This document. Also served at `/openapi.json`, which is the path the conformance register's evidence index links to.
Responses
| Status | Description |
|---|---|
200 | OpenAPI 3.0 document — application/json object |
GET /trust/
Trust and operations overview
The entry point to the published evidence: availability, incidents, metered spend, conformance readiness, the last deployment and the receipt chain verdict. Every figure is computed from the same source the owning page uses and links to it; none is stored a second time.
Responses
| Status | Description |
|---|---|
200 | Trust overview — text/html string |
GET /roadmap/
Change record (moved)
Permanently redirects to `/status/#delivery`, where the change record now lives. `/roadmap.json` did not move and is unchanged.
Responses
| Status | Description |
|---|---|
301 | Moved to /status/#delivery |
GET /roadmap.json
Mission and feature-to-deployment map (JSON)
Responses
| Status | Description |
|---|---|
200 | Availability, delivery velocity, elapsed time, deployment batches, and feature updates — application/json object |
GET /status/
Operations dashboard
Operations. Server and tank availability, live tank occupancy with the computer-controlled agent count beside it, state copies and restore drills, the full incident record at `#incidents`, the append-only control receipt chain at `#control-history`, and the change record at `#delivery`. Spend is at `/spend/`; operator controls are behind authentication at `/admin/`.
Responses
| Status | Description |
|---|---|
200 | HTML dashboard — text/html string |
GET /status.json
Status (JSON)
Responses
| Status | Description |
|---|---|
200 | Independent server and tank availability, scheduled downtime, rooms, incidents, and control receipts — application/json StatusResponse |
GET /incidents/
Incident record (moved)
Permanently redirects to `/status/#incidents`. `/incidents.json` did not move and is unchanged.
Responses
| Status | Description |
|---|---|
301 | Moved to /status/#incidents |
GET /incidents.json
Public incident and control history (JSON)
Responses
| Status | Description |
|---|---|
200 | Availability summary, incident records, control entries, and SHA-256 chain head — application/json object |
GET /spend/
Cost and capacity meters
Links normal game and operations actions to measured Workers, Durable Objects, D1 and R2 usage, against each free-tier allowance and against the hard spend limit that closes the game rather than billing. Previously served at `/inquiry/`, which still redirects here.
Responses
| Status | Description |
|---|---|
200 | Cost and capacity meters — text/html string |
GET /spend.json
Cost and capacity meters (JSON)
Also served at `/inquiry.json`, the pre-rename name, which is unchanged.
Responses
| Status | Description |
|---|---|
200 | Proof-of-concept statement and reset-window billing summary — application/json object |
GET /inquiry/
Cost and capacity meters (moved)
Permanently redirects to `/spend/`.
Responses
| Status | Description |
|---|---|
301 | Moved to /spend/ |
GET /logs/
Public reason-coded logs
Searchable, filterable service evidence with 90-day retention plus the 40 newest reason-coded captures per ocean tank and sanitized TXT downloads.
Responses
| Status | Description |
|---|---|
200 | Public Shark Tank evidence — text/html string |
GET /logs.json
Public service and tank logs (JSON)
Every row includes a letter-plus-three-digit reason code. Tank records use the same timestamp, reasonCode, tick, action, language, name, and details fields as the live inspector and TXT export.
Responses
| Status | Description |
|---|---|
200 | Public service and tank event stream — application/json object |
GET /logs/game/{id}.txt
Download a sanitized Shark Tank log
Plain UTF-8 text with timestamp,reason_code,tick,action,language,name,details comma-separated fields and newline-separated records. Internal player ids are omitted.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
id | path | yes | string |
Responses
| Status | Description |
|---|---|
200 | Downloadable TXT log — text/plain string |
404 | Unknown tank |
GET /audit/
ISO/IEC 27001 and ISO/IEC 42001 conformance register
Public, unauthenticated readiness register: every clause of ISO/IEC 27001:2022 and ISO/IEC 42001:2023, all 93 Annex A controls, all 38 AI controls, the fourteen documented change-management processes, the Stage 1 documented-information list, and an index of every route that serves as evidence. Each row carries a status, the justification behind it, and links to the live routes that prove it. This is a readiness statement, not a certificate.
Responses
| Status | Description |
|---|---|
200 | Conformance register — text/html string |
GET /audit/manifest.json
Conformance register (JSON)
The same register as machine-readable data, for independent scoring or import into a compliance tool.
Responses
| Status | Description |
|---|---|
200 | Standards, status meanings, readiness summary, change processes, mandatory documents, control registers, and the evidence index — application/json object |
GET /policies/
Governance policy index
The index of the written record ISO/IEC 27001:2022 and ISO/IEC 42001:2023 ask for, published as pages rather than filed. Each document is its own route at `/policies/{document}/`, searchable from here, and every section within a document has its own anchor.
Responses
| Status | Description |
|---|---|
200 | Policy index — text/html string |
GET /policies/{document}/
One governance document
A single document — context and scope, the information security policy, roles and authorities, the risk assessment and treatment processes, the Statement of Applicability cover, the risk treatment plan, the security and AI objectives, the AI policy with its impact assessment, the AI system life cycle, and the rest. Each names the clauses it is the record for, and the conformance register links to it directly. The document identifier is the `id` field in `/policies.json`.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
document | path | yes | string | Document identifier, e.g. `risk-assessment` |
Responses
| Status | Description |
|---|---|
200 | Governance document — text/html string |
404 | No such document — text/html string |
GET /policies.json
Governance policy set (JSON)
The same documents as machine-readable data: reference, identifier, the route it is published at, title, purpose, the clauses each satisfies, its sections with their anchor ids, and what triggers its review.
Responses
| Status | Description |
|---|---|
200 | Governance documents with their clause coverage and review triggers — application/json object |
GET /admin/
Operations control panel
Protected HTML dashboard for action records, measured billing counters, billing reset, and maintenance mode. Formerly served at /audit/, which is now the public conformance register.
Responses
| Status | Description |
|---|---|
200 | Control panel — text/html string |
401 | Operations authentication required |
GET /admin/log.json
Action log (JSON array)
90-day user and service action record. Also served at the pre-move path /audit.json.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
limit | query | no | integer |
Responses
| Status | Description |
|---|---|
200 | Audit events — application/json object |
401 | Operations authentication required |
GET /admin/log.jsonl
Action log (newline-delimited JSON)
Also served at the pre-move path /audit.jsonl.
Responses
| Status | Description |
|---|---|
200 | Audit event stream — application/x-ndjson string |
401 | Operations authentication required |
GET /admin/game/{id}.jsonl
Authenticated replayable room action log
Seed plus the ordered action stream for one tank — the ISO/IEC 42001 A.6.2.8 event record. Also served at /audit/game/{id}.jsonl.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
id | path | yes | string |
Responses
| Status | Description |
|---|---|
200 | Room actions with internal replay identifiers — application/x-ndjson string |
401 | Operations authentication required |
GET /admin/replay/{id}
Reconstruct a room at a retained tick
Deterministic reconstruction of authoritative state, including every autonomous agent, at a chosen tick. Also served at /audit/replay/{id}.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
id | path | yes | string | |
tick | query | no | integer |
Responses
| Status | Description |
|---|---|
200 | Reconstructed authoritative state — application/json object |
401 | Operations authentication required |
410 | Complete replay history expired |
GET /admin/status.json
Private operational status and billing data
The unredacted operational record, including the running version identifier and instance residency. Also served at /audit/status.json.
Responses
| Status | Description |
|---|---|
200 | Full status, audit counters, and billing window — application/json object |
401 | Operations authentication required |
POST /admin/maintenance
Enable or disable maintenance mode
Same-origin Admin action. Enabling creates a separate operator-maintenance incident, closes active WebSockets, and returns the controlled 503 page for the game shell, game assets, and tank traffic while Roadmap, API, Docs, Status, Incidents, Inquiry, Logs, the conformance register, and Admin remain online. Disabling records the end of service impact but leaves independent security reports active until separately resolved. Every transition is persisted to the action log and the control-history receipt chain.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
X-WG-Ops-Action | header | yes | enum: maintenance |
Request body (required)
application/json → object
Responses
| Status | Description |
|---|---|
200 | Maintenance state — application/json object |
401 | Operations authentication required |
POST /admin/billing-reset
Reset the billing measurement window
Resets measured billing baselines without resetting service uptime or status history.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
X-WG-Ops-Action | header | yes | enum: billing-reset |
Responses
| Status | Description |
|---|---|
200 | Fresh billing window — application/json object |
401 | Operations authentication required |
POST /admin/security-resolve
Resolve owner-confirmed security exercises
Resolves open white-hat reports as owner-confirmed dry runs without changing the separate maintenance gate. Appends one immutable resolution receipt per report.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
X-WG-Ops-Action | header | yes | enum: security-resolve |
Request body (required)
application/json → object
Responses
| Status | Description |
|---|---|
200 | Owner-confirmed resolution receipts — application/json object |
400 | Owner confirmation and dry-run flag required |
401 | Operations authentication required |
POST /admin/security-report
File a security report and take the game down
Same-origin Admin action. Records the same report, audit event, and control-history receipt as the public intake, and additionally opens an active security incident, enables game maintenance, and disconnects active tanks pending operator review. Restoring game traffic records the end of service impact but does not resolve or close the security report; that is /admin/security-resolve. At most one security-report lockdown is open at a time — a repeat call while one is open returns the existing incident and creates no second incident or receipt. Roadmap, Status, Incidents, Inquiry, Logs, Docs, API, the conformance register, and authenticated Admin remain available throughout.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
X-WG-Ops-Action | header | yes | enum: security-report |
Responses
| Status | Description |
|---|---|
200 | Linked lockdown and report receipt — application/json object |
401 | Operations authentication required |
403 | Same-origin operation required |
502 | Report and lockdown could not be persisted |
POST /admin/test-alert
Send an authenticated test alert
Accepts exactly one ASCII letter followed by three digits, normalizes the letter uppercase, and records the acknowledgement in the action log.
Parameters
| Name | In | Req | Type | Description |
|---|---|---|---|---|
X-WG-Ops-Action | header | yes | enum: test-alert |
Request body (required)
application/json → object
Responses
| Status | Description |
|---|---|
200 | Test alert receipt — application/json object |
400 | Code does not match letter-digit-digit-digit |
401 | Operations authentication required |
Schemas
HealthResponse
| Field | Type |
|---|---|
ok | boolean |
module | string |
time | string (date-time) |
TankRoom
| Field | Type |
|---|---|
id | string |
name | string |
players | integer |
bots | integer |
capacity | integer |
topScore | integer |
topName | string |
TankResponse
| Field | Type |
|---|---|
ok | boolean |
rooms | array of TankRoom |
ScoreEntry
| Field | Type |
|---|---|
id | string |
name | string |
skin | string |
score | integer |
alive | boolean |
LeaderboardResponse
| Field | Type |
|---|---|
ok | boolean |
entries | array of ScoreEntry |
Profile
| Field | Type |
|---|---|
name | string |
skin | string |
best | integer |
settings | object |
ProfileResponse
| Field | Type |
|---|---|
ok | boolean |
profile | Profile |
AuditEvent
| Field | Type |
|---|---|
ts | integer |
type | enum: room-boot, join, leave, death, play, customize, skin, settings, nav, quit, maintenance-on, maintenance-off, billing-reset, billing-hard-stop, security-report, security-resolved, test-alert |
room | string |
subject | string |
detail | string |
ControlHistoryEntry
| Field | Type |
|---|---|
sequence | integer |
ts | integer |
code | string |
actor | string |
title | string |
summary | string |
reference | string |
detail | string |
previousHash | string |
hash | string |
Usage
| Field | Type |
|---|---|
startedAt | integer |
uptimeMs | integer |
presenceReports | integer |
durableObjects | object |
Availability
| Field | Type |
|---|---|
windowHours | integer |
uptimeMs | integer |
downtimeMs | integer |
scheduledDowntimeMs | integer |
unscheduledDowntimeMs | integer |
availabilityPercent | number |
scheduledDowntimePercent | number |
unscheduledDowntimePercent | number |
calculatedAt | string (date-time) |
StatusResponse
| Field | Type |
|---|---|
ok | boolean |
maintenance | object |
usage | Usage |
history | array of ControlHistoryEntry |
historyIntegrity | object |
rooms | array of TankRoom |
global | array of ScoreEntry |
portalAvailability | Availability |
tankAvailability | Availability |
ErrorResponse
| Field | Type |
|---|---|
ok | boolean |
error | string |