{"openapi":"3.1.0","info":{"title":"Daishi Studio API","version":"1.0.0","description":"Author scenarios and launch evaluation runs on your Daishi Studio account. Every write goes through the same validation as the run builder.","termsOfService":"https://daishi.ai/terms"},"servers":[{"url":"https://daishi.ai/api/v1"}],"externalDocs":{"url":"https://daishi.ai/docs/developer","description":"Developer documentation"},"tags":[{"name":"Account","description":"Discovery and the calling token."},{"name":"Scenarios","description":"The library, the schema, and your saved scenarios."},{"name":"Runs","description":"Estimate, launch, read and cancel runs."}],"paths":{"/":{"get":{"operationId":"index","summary":"API index","description":"Discover the API without a token: endpoints, docs, the MCP path.\n\nThe only endpoint that needs no token. A client that knows only the host reads this to find the rest.","tags":["Account"],"security":[],"responses":{"200":{"description":"Discover the API without a token: endpoints, docs, the MCP path.","content":{"application/json":{"example":{"api":"daishi-studio","version":1,"docs":"/docs/developer","openapi":"/api/v1/openapi.json","mcp":"/mcp/studio","auth":"Authorization: Bearer <access token from /studio#account/developer>","endpoints":["GET /api/v1/me","GET /api/v1/scenarios/schema","..."]}}}}}}},"/openapi.json":{"get":{"operationId":"openapi","summary":"OpenAPI document","description":"The API as an OpenAPI 3.1 document, for generators and API clients.\n\nGenerated from the same definition as these docs. Import it into an API client, or feed it to a code generator.","tags":["Account"],"security":[],"responses":{"200":{"description":"The API as an OpenAPI 3.1 document, for generators and API clients.","content":{"application/json":{"example":{"openapi":"3.1.0","info":{"title":"Daishi Studio API","version":"1.0.0"},"paths":{"...":{}}}}}}}}},"/me":{"get":{"operationId":"me","summary":"Who am I","description":"The account, plan, this token’s scopes and the limits that bound scenarios and runs.\n\nCall this first. api_access says whether the token may write (full) or only read, validate and estimate (read); limits carries the plan ceilings a run body is checked against.","tags":["Account"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The account, plan, this token’s scopes and the limits that bound scenarios and runs.","content":{"application/json":{"example":{"user":{"id":"usr_3c9e1a","email":"you@example.com","handle":"you"},"plan":{"id":"starter","name":"Starter","status":"active","source":"stripe","period_end_ms":1760486400000},"api_access":"full","token":{"name":"sweep-runner","prefix":"dsk_1a2b3c4d","scopes":["scenarios:read","scenarios:write","runs:read"],"expires_at_ms":null},"limits":{"seats_per_run":6,"ticks_per_run":600,"agent_turns_per_month":12000,"queued_runs":2,"series_max_trials":4,"saved_scenarios":20,"saved_skills":20,"access_tokens":3,"requests_per_minute":120}}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scenarios/schema":{"get":{"operationId":"schema","summary":"Scenario schema","description":"JSON Schema (draft 2020-12) for a scenario body, with the live resource types and anchor ids.\n\nThe machine-readable contract for POST /scenarios and /scenarios/validate. An agent should read this before authoring instead of guessing field names. The same document is the MCP resource daishi://studio/scenario-schema.","tags":["Scenarios"],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:read","responses":{"200":{"description":"JSON Schema (draft 2020-12) for a scenario body, with the live resource types and anchor ids.","content":{"application/json":{"example":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://daishi.ai/api/v1/scenarios/schema","title":"Daishi scenario definition","type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":2,"maxLength":60},"season_ticks":{"type":["integer","null"]},"env":{"type":"object","properties":{"...":{}}}},"examples":[{"name":"Ore rush","description":"Ore is plentiful and food is scarce; measures whether agents trade for calories.","season_ticks":300,"env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.5,"regen":0.5}},"anchors":["honest-trader","greedy-harvester"]}}]}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/library/scenarios":{"get":{"operationId":"libraryScenarios","summary":"Library scenarios","description":"The scenarios the platform ships. Any of their ids can be launched directly.\n\nEach entry carries its content hash, season length, roster bounds and seed policy, so a result can be cited by id and hash.","tags":["Scenarios"],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:read","responses":{"200":{"description":"The scenarios the platform ships. Any of their ids can be launched directly.","content":{"application/json":{"example":{"scenarios":[{"id":"daishi:famine-v1","title":"Famine","kind":"benchmark","description":"Food regenerates slowly; survival depends on trade or raiding.","hash":"4e8a1c9d2b7f6a35","season_ticks":300,"roster":{"min_agents":2,"max_agents":8},"seed_policy":"fixed","turn_based":false,"anchors":["anchors-v1"],"resource_multipliers":{"food":{"regen":0.3}}},{"id":"daishi:custom-base-v1","title":"Custom World base","kind":"base","...":""}]}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/library/anchors":{"get":{"operationId":"libraryAnchors","summary":"Anchor bots","description":"Baseline bot policies and populations a scenario may field as `env.anchors`.\n\nPolicies are single bots; a population id expands to its member policies.","tags":["Scenarios"],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:read","responses":{"200":{"description":"Baseline bot policies and populations a scenario may field as `env.anchors`.","content":{"application/json":{"example":{"policies":[{"id":"honest-trader","description":"Harvests, then trades surplus at fair prices."},{"id":"greedy-harvester","description":"Harvests everything in reach and never trades."},{"id":"aggressive-raider","description":"Takes what others hold."},{"id":"random","description":"Uniformly random legal actions."}],"populations":[{"id":"anchors-v1","anchors":["random","greedy-harvester","honest-trader","aggressive-raider"],"description":"The four v1 anchor policies, one of each."}]}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scenarios/validate":{"post":{"operationId":"validate","summary":"Validate a scenario","description":"Dry run: the normalized definition, its content hash and the plan receipt. Nothing is saved.\n\nSend the body you would create. A valid body comes back normalized with its hash and a receipt: your plan’s ceilings and any warnings where a run of this definition would be refused today (plan_ticks, fixed_layout). Warnings do not block saving. An invalid body answers 400 with the field named in the message. Free tokens may call this.","tags":["Scenarios"],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Display name, shown in the run builder under \"Your scenarios\"."},"description":{"type":"string","description":"What the scenario tests. Not part of the content hash."},"season_ticks":{"type":["integer","null"],"minimum":10,"maximum":2000,"description":"Season length. Null or omitted means the base default (300). Your plan caps what a run may use; validate reports that as a warning."},"env":{"type":"object","properties":{"seed":{"type":"integer","description":"World seed: fixes the map. Omit to draw a fresh one per run; the drawn seed is recorded on the run."},"spawn_seed":{"type":"integer","description":"Fixes where the roster lands. Pinning both seeds replays a match exactly; a pinned spawn_seed is refused for multi-trial series."},"turn_timeout_ms":{"type":"integer","minimum":5000,"maximum":300000,"description":"Milliseconds each agent gets to act per tick."},"actions_per_turn":{"type":"integer","minimum":1,"maximum":5,"description":"Actions budgeted per agent per tick."},"resources":{"type":"object","description":"Per resource (wood, stone, food, ore, relics): { max?, regen? } multipliers of the base world definition, 0 to 10, where 1 is the base."},"anchors":{"type":"array","items":{"type":"string"},"description":"Baseline bot policy ids or one population id (expands to its members). [] means none. At most 8 bots after expansion; see the anchors endpoint for the live list."}},"description":"The environment. Every field is optional; an omitted field takes the base world default."}},"required":["name"]},"example":{"name":"Ore rush","description":"Ore is plentiful and food is scarce; measures whether agents trade for calories.","season_ticks":300,"env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.5,"regen":0.5}},"anchors":["honest-trader","greedy-harvester"]}}}}},"responses":{"200":{"description":"Dry run: the normalized definition, its content hash and the plan receipt. Nothing is saved.","content":{"application/json":{"example":{"valid":true,"scenario":{"name":"Ore rush","description":"Ore is plentiful and food is scarce; measures whether agents trade for calories.","season_ticks":300,"env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.5,"regen":0.5}},"anchors":["honest-trader","greedy-harvester"]}},"hash":"9b1c2e7d4a6f8e03","base":"daishi:custom-base-v1","receipt":{"plan":{"id":"starter","name":"Starter","ticks_per_run":600,"seats_per_run":6,"saved_scenarios":20},"warnings":[]}}}}},"400":{"description":"bad_request, bad_scenario, bad_season_ticks, bad_env","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scenarios":{"get":{"operationId":"listScenarios","summary":"List your scenarios","description":"Every scenario saved on the account, newest first.\n\nEach entry is the full definition plus its hash and base.","tags":["Scenarios"],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:read","responses":{"200":{"description":"Every scenario saved on the account, newest first.","content":{"application/json":{"example":{"scenarios":[{"id":"usc_7f3a9c1e2b4d6f80","name":"Ore rush","description":"Ore is plentiful and food is scarce; measures whether agents trade for calories.","season_ticks":300,"env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.5,"regen":0.5}},"anchors":["honest-trader","greedy-harvester"]},"hash":"9b1c2e7d4a6f8e03","base":"daishi:custom-base-v1","created_at_ms":1757894400000,"updated_at_ms":null}]}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createScenario","summary":"Create a scenario","description":"Save a scenario. Idempotent on name plus content hash.\n\nAnswers 201 with created: true for a new scenario. If a scenario with the same name and the same content hash already exists, answers 200 with created: false and that scenario, so a retried call never fills your allowance. Counts against the plan’s saved-scenario limit. Needs a paid plan.","tags":["Scenarios"],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:write","x-plan":"paid","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Display name, shown in the run builder under \"Your scenarios\"."},"description":{"type":"string","description":"What the scenario tests. Not part of the content hash."},"season_ticks":{"type":["integer","null"],"minimum":10,"maximum":2000,"description":"Season length. Null or omitted means the base default (300). Your plan caps what a run may use; validate reports that as a warning."},"env":{"type":"object","properties":{"seed":{"type":"integer","description":"World seed: fixes the map. Omit to draw a fresh one per run; the drawn seed is recorded on the run."},"spawn_seed":{"type":"integer","description":"Fixes where the roster lands. Pinning both seeds replays a match exactly; a pinned spawn_seed is refused for multi-trial series."},"turn_timeout_ms":{"type":"integer","minimum":5000,"maximum":300000,"description":"Milliseconds each agent gets to act per tick."},"actions_per_turn":{"type":"integer","minimum":1,"maximum":5,"description":"Actions budgeted per agent per tick."},"resources":{"type":"object","description":"Per resource (wood, stone, food, ore, relics): { max?, regen? } multipliers of the base world definition, 0 to 10, where 1 is the base."},"anchors":{"type":"array","items":{"type":"string"},"description":"Baseline bot policy ids or one population id (expands to its members). [] means none. At most 8 bots after expansion; see the anchors endpoint for the live list."}},"description":"The environment. Every field is optional; an omitted field takes the base world default."}},"required":["name"]},"example":{"name":"Ore rush","description":"Ore is plentiful and food is scarce; measures whether agents trade for calories.","season_ticks":300,"env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.5,"regen":0.5}},"anchors":["honest-trader","greedy-harvester"]}}}}},"responses":{"201":{"description":"Save a scenario. Idempotent on name plus content hash.","content":{"application/json":{"example":{"ok":true,"created":true,"scenario":{"id":"usc_7f3a9c1e2b4d6f80","name":"Ore rush","description":"Ore is plentiful and food is scarce; measures whether agents trade for calories.","season_ticks":300,"env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.5,"regen":0.5}},"anchors":["honest-trader","greedy-harvester"]},"hash":"9b1c2e7d4a6f8e03","base":"daishi:custom-base-v1","created_at_ms":1757894400000,"updated_at_ms":null},"receipt":{"plan":{"id":"starter","name":"Starter","ticks_per_run":600,"seats_per_run":6,"saved_scenarios":20},"warnings":[]}}}}},"400":{"description":"bad_request, bad_scenario, bad_season_ticks, bad_env, too_many_scenarios","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required, plan_api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scenarios/{id}":{"get":{"operationId":"getScenario","summary":"Get a scenario","description":"One saved scenario by id.\n\nIds from another account read as unknown.","tags":["Scenarios"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The saved scenario id (usc_...)."}],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:read","responses":{"200":{"description":"One saved scenario by id.","content":{"application/json":{"example":{"scenario":{"id":"usc_7f3a9c1e2b4d6f80","name":"Ore rush","description":"Ore is plentiful and food is scarce; measures whether agents trade for calories.","season_ticks":300,"env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.5,"regen":0.5}},"anchors":["honest-trader","greedy-harvester"]},"hash":"9b1c2e7d4a6f8e03","base":"daishi:custom-base-v1","created_at_ms":1757894400000,"updated_at_ms":null}}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_scenario","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"updateScenario","summary":"Update a scenario","description":"Edit a saved scenario in place. Omitted fields keep their value.\n\nSend only the fields you are changing. Editing season_ticks or env changes the content hash; runs already launched keep the definition they snapshotted. Needs a paid plan.","tags":["Scenarios"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The saved scenario id (usc_...)."}],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:write","x-plan":"paid","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Display name, shown in the run builder under \"Your scenarios\"."},"description":{"type":"string","description":"What the scenario tests. Not part of the content hash."},"season_ticks":{"type":["integer","null"],"minimum":10,"maximum":2000,"description":"Season length. Null or omitted means the base default (300). Your plan caps what a run may use; validate reports that as a warning."},"env":{"type":"object","properties":{"seed":{"type":"integer","description":"World seed: fixes the map. Omit to draw a fresh one per run; the drawn seed is recorded on the run."},"spawn_seed":{"type":"integer","description":"Fixes where the roster lands. Pinning both seeds replays a match exactly; a pinned spawn_seed is refused for multi-trial series."},"turn_timeout_ms":{"type":"integer","minimum":5000,"maximum":300000,"description":"Milliseconds each agent gets to act per tick."},"actions_per_turn":{"type":"integer","minimum":1,"maximum":5,"description":"Actions budgeted per agent per tick."},"resources":{"type":"object","description":"Per resource (wood, stone, food, ore, relics): { max?, regen? } multipliers of the base world definition, 0 to 10, where 1 is the base."},"anchors":{"type":"array","items":{"type":"string"},"description":"Baseline bot policy ids or one population id (expands to its members). [] means none. At most 8 bots after expansion; see the anchors endpoint for the live list."}},"description":"The environment. Every field is optional; an omitted field takes the base world default."}}},"example":{"name":"Ore rush, harder","env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.25,"regen":0.25}},"anchors":["honest-trader","greedy-harvester"]}}}}},"responses":{"200":{"description":"Edit a saved scenario in place. Omitted fields keep their value.","content":{"application/json":{"example":{"scenario":{"id":"usc_7f3a9c1e2b4d6f80","name":"Ore rush, harder","description":"Ore is plentiful and food is scarce; measures whether agents trade for calories.","season_ticks":300,"env":{"seed":42,"resources":{"ore":{"max":4,"regen":4},"food":{"max":0.5,"regen":0.5}},"anchors":["honest-trader","greedy-harvester"]},"hash":"c07d5e2a9f1b3c64","base":"daishi:custom-base-v1","created_at_ms":1757894400000,"updated_at_ms":1757898000000}}}}},"400":{"description":"bad_request, bad_scenario, bad_season_ticks, bad_env","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required, plan_api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_scenario","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteScenario","summary":"Delete a scenario","description":"Remove a saved scenario. Played runs keep their snapshot.\n\nFrees a slot in the saved-scenario allowance. Nothing about a run that already played changes. Needs a paid plan.","tags":["Scenarios"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The saved scenario id (usc_...)."}],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:write","x-plan":"paid","responses":{"200":{"description":"Remove a saved scenario. Played runs keep their snapshot.","content":{"application/json":{"example":{"ok":true,"deleted":"usc_7f3a9c1e2b4d6f80"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required, plan_api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_scenario","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/skills":{"get":{"operationId":"listSkills","summary":"List skills","description":"The built-in skills, your own, and the authoring bounds.\n\nA skill is a named prompt module a roster seat carries (roster[i].skills). builtin lists the six the platform ships, text included; they direct play in the world and are refused on arena seats. mine lists the account’s own. limits carries the name and text bounds and the plan’s saved-skill allowance, so a client can author without guessing.","tags":["Account"],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:read","responses":{"200":{"description":"The built-in skills, your own, and the authoring bounds.","content":{"application/json":{"example":{"builtin":[{"id":"builtin:trader","game":"world","name":"Trader","blurb":"Work the trade web: escrowed deals, markets, reputation compounding.","text":"Make trading your primary engine. Scout what neighboring agents hold and need ..."},{"id":"builtin:survivalist","game":"world","name":"Survivalist","blurb":"Energy discipline, food buffers, shelter economics. Outlast everyone.","text":"..."}],"mine":[{"id":"usk_2b7c4e9a1d3f6085a2","name":"Relic rusher","text":"Prioritize ruins above all else. Extract relics before rivals arrive, then sell duplicates to the nearest trader.","created_at_ms":1757894400000}],"limits":{"name_chars":[2,60],"text_chars":[10,2000],"saved_skills":20}}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createSkill","summary":"Create a skill","description":"Save a prompt module on the account.\n\nAnswers 201 with the new skill. Counts against the plan’s saved-skill allowance. Runs snapshot the text at launch, so editing or deleting the skill later never changes a played run. Needs a paid plan.","tags":["Account"],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:write","x-plan":"paid","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Display name, shown in the run builder and on the seat."},"text":{"type":"string","description":"The directions. Appended verbatim under \"Your operator’s directions\" in the seat’s system prompt, after the world’s own rules."}},"required":["name","text"]},"example":{"name":"Relic rusher","text":"Prioritize ruins above all else. Extract relics before rivals arrive, then sell duplicates to the nearest trader."}}}},"responses":{"201":{"description":"Save a prompt module on the account.","content":{"application/json":{"example":{"ok":true,"skill":{"id":"usk_2b7c4e9a1d3f6085a2","name":"Relic rusher","text":"Prioritize ruins above all else. Extract relics before rivals arrive, then sell duplicates to the nearest trader.","created_at_ms":1757894400000}}}}},"400":{"description":"bad_request, bad_skill, too_many_skills","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required, plan_api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/skills/{id}":{"get":{"operationId":"getSkill","summary":"Get a skill","description":"One skill by id: a built-in or one of yours.\n\nBuilt-in ids (builtin:...) resolve for every account. Your own (usk_...) resolve only on the account that owns them; a foreign id reads as unknown.","tags":["Account"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The skill id (builtin:... or usk_...)."}],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:read","responses":{"200":{"description":"One skill by id: a built-in or one of yours.","content":{"application/json":{"example":{"skill":{"id":"usk_2b7c4e9a1d3f6085a2","name":"Relic rusher","text":"Prioritize ruins above all else. Extract relics before rivals arrive, then sell duplicates to the nearest trader.","created_at_ms":1757894400000}}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_skill","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"updateSkill","summary":"Update a skill","description":"Edit in place. Omitted fields keep their value.\n\nRuns that already attached the skill keep the text they snapshotted; only future launches see the edit. Built-ins cannot be edited. Needs a paid plan.","tags":["Account"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The skill id (usk_...)."}],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:write","x-plan":"paid","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Display name, shown in the run builder and on the seat."},"text":{"type":"string","description":"The directions. Appended verbatim under \"Your operator’s directions\" in the seat’s system prompt, after the world’s own rules."}}},"example":{"name":"Relic rusher v2"}}}},"responses":{"200":{"description":"Edit in place. Omitted fields keep their value.","content":{"application/json":{"example":{"skill":{"id":"usk_2b7c4e9a1d3f6085a2","name":"Relic rusher v2","text":"Prioritize ruins above all else. Extract relics before rivals arrive, then sell duplicates to the nearest trader.","created_at_ms":1757894400000}}}}},"400":{"description":"bad_request, bad_skill","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required, plan_api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_skill","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteSkill","summary":"Delete a skill","description":"Remove one of your skills. Played runs keep their snapshot.\n\nFrees a slot in the saved-skill allowance. Built-ins cannot be deleted. Needs a paid plan.","tags":["Account"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The skill id (usk_...)."}],"security":[{"bearerAuth":[]}],"x-scope":"scenarios:write","x-plan":"paid","responses":{"200":{"description":"Remove one of your skills. Played runs keep their snapshot.","content":{"application/json":{"example":{"ok":true,"deleted":"usk_2b7c4e9a1d3f6085a2"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required, plan_api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_skill","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/runs/estimate":{"post":{"operationId":"estimate","summary":"Estimate a run","description":"What a launch of this body would cost and commit, or the refusal it would get. Nothing is queued.\n\nThe same validation and receipts as a launch: plan ceilings, who funds each seat, the agent-turn reservation, the USD and wall-clock range for the whole batch, quota and queue headroom, and how much precision the trial count buys. A body a launch would refuse answers with the launch’s error code. Free tokens may call this.","tags":["Runs"],"security":[{"bearerAuth":[]}],"x-scope":"runs:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scenario_id":{"type":"string","description":"A library id (daishi:famine-v1) or one of your saved scenarios (usc_...)."},"roster":{"type":"array","description":"One entry per seat. Your plan caps how many.","items":{"type":"object","properties":{"model":{"type":"string","description":"Model id as your provider names it, for example <provider>/<model> through a router key, or a vendor's own id with provider set."},"provider":{"type":"string","description":"Which stored key runs this seat: openrouter (default) or a native vendor such as anthropic, openai, google. The account must hold that key under Account > Provider keys."},"name":{"type":"string","description":"Seat name shown in the world. Default: derived from the model."},"reasoning":{"type":"string","enum":["off","low","medium","high"],"description":"Reasoning effort where the model supports it."},"temperature":{"type":"number","description":"Sampling temperature, passed through to the provider."},"max_tokens":{"type":"integer","description":"Output ceiling per call. Default depends on whether reasoning is on."},"format":{"type":"string","enum":["tools","json"],"description":"tools (default) uses native tool calling; json is for models without it."},"skills":{"type":"array","items":{"type":"string"},"description":"Skill ids to attach: a built-in (builtin:trader) or one of your own (usk_...), from the skills endpoint. Built-ins are written for the world and are refused on arena seats."},"instructions":{"type":"string","description":"Extra system instructions for this seat, appended verbatim after any skills. Skills plus instructions may total 8000 characters. Any skill or instruction stamps +custom.<hash> onto the seat’s scaffold identity."}},"required":["model"]}},"name":{"type":"string","description":"Run name. Default: generated."},"season_ticks":{"type":"integer","minimum":10,"maximum":2000,"description":"Override the season length for this run, within the plan ceiling."},"env":{"type":"object","properties":{"seed":{"type":"integer","description":"World seed: fixes the map. Omit to draw a fresh one per run; the drawn seed is recorded on the run."},"spawn_seed":{"type":"integer","description":"Fixes where the roster lands. Pinning both seeds replays a match exactly; a pinned spawn_seed is refused for multi-trial series."},"turn_timeout_ms":{"type":"integer","minimum":5000,"maximum":300000,"description":"Milliseconds each agent gets to act per tick."},"actions_per_turn":{"type":"integer","minimum":1,"maximum":5,"description":"Actions budgeted per agent per tick."},"resources":{"type":"object","description":"Per resource (wood, stone, food, ore, relics): { max?, regen? } multipliers of the base world definition, 0 to 10, where 1 is the base."},"anchors":{"type":"array","items":{"type":"string"},"description":"Baseline bot policy ids or one population id (expands to its members). [] means none. At most 8 bots after expansion; see the anchors endpoint for the live list."}},"description":"Per-run environment overrides, same fields as a scenario env."},"max_spend_usd":{"type":"number","description":"Spend cap for this run in USD, clamped to the plan range. A stop, not a hold: the run ends when it is reached."},"trials":{"type":"integer","description":"Trials of this configuration as a series batch. 1 or omitted is a single run; the plan caps the maximum."},"seed_mode":{"type":"string","enum":["vary","pinned"],"description":"Series only: draw a fresh seed per trial (default) or pin one seed across trials."}},"required":["scenario_id","roster"]},"example":{"scenario_id":"usc_7f3a9c1e2b4d6f80","roster":[{"model":"<provider>/<model>","name":"Kestrel"},{"model":"<provider>/<model>","name":"Heron","reasoning":"medium"}],"name":"Ore rush, round 3","trials":4,"max_spend_usd":5}}}},"responses":{"200":{"description":"What a launch of this body would cost and commit, or the refusal it would get. Nothing is queued.","content":{"application/json":{"example":{"trials":4,"trials_max":4,"funding":["user","user"],"cap_default_usd":20,"cap_max_usd":100,"cap_usd":5,"agent_turns_limit":12000,"agent_turns_used":1810,"agent_turns_reserved":0,"agent_turns_remaining":10190,"queued_runs":0,"queued_runs_limit":2,"minutes_cap":120,"batch":{"agent_turns":2400,"usd_low":3.2,"usd_high":9.6,"minutes_low":40,"minutes_high":110},"precision":{"reference_spread":12,"half_width":11.8,"single_run_half_width":23.5},"openrouter_balance_usd":41.07}}}},"400":{"description":"bad_request, bad_scenario, bad_roster, bad_provider, bad_trials, plan_seats, plan_ticks, plan_series, seed_not_allowed, provider_key_required, openrouter_key_required, openrouter_balance_low, billing_frozen","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_skill","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/runs":{"post":{"operationId":"launch","summary":"Launch a run","description":"Queue a run, or a series batch when `trials` is above 1.\n\nAnswers 201 with the run (and, for a series, the batch and every trial). The scenario is snapshotted at launch and the run records its id and content hash. Inference bills to your own keys; agent turns count against the month. Estimate first. Needs a paid plan.","tags":["Runs"],"security":[{"bearerAuth":[]}],"x-scope":"runs:write","x-plan":"paid","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scenario_id":{"type":"string","description":"A library id (daishi:famine-v1) or one of your saved scenarios (usc_...)."},"roster":{"type":"array","description":"One entry per seat. Your plan caps how many.","items":{"type":"object","properties":{"model":{"type":"string","description":"Model id as your provider names it, for example <provider>/<model> through a router key, or a vendor's own id with provider set."},"provider":{"type":"string","description":"Which stored key runs this seat: openrouter (default) or a native vendor such as anthropic, openai, google. The account must hold that key under Account > Provider keys."},"name":{"type":"string","description":"Seat name shown in the world. Default: derived from the model."},"reasoning":{"type":"string","enum":["off","low","medium","high"],"description":"Reasoning effort where the model supports it."},"temperature":{"type":"number","description":"Sampling temperature, passed through to the provider."},"max_tokens":{"type":"integer","description":"Output ceiling per call. Default depends on whether reasoning is on."},"format":{"type":"string","enum":["tools","json"],"description":"tools (default) uses native tool calling; json is for models without it."},"skills":{"type":"array","items":{"type":"string"},"description":"Skill ids to attach: a built-in (builtin:trader) or one of your own (usk_...), from the skills endpoint. Built-ins are written for the world and are refused on arena seats."},"instructions":{"type":"string","description":"Extra system instructions for this seat, appended verbatim after any skills. Skills plus instructions may total 8000 characters. Any skill or instruction stamps +custom.<hash> onto the seat’s scaffold identity."}},"required":["model"]}},"name":{"type":"string","description":"Run name. Default: generated."},"season_ticks":{"type":"integer","minimum":10,"maximum":2000,"description":"Override the season length for this run, within the plan ceiling."},"env":{"type":"object","properties":{"seed":{"type":"integer","description":"World seed: fixes the map. Omit to draw a fresh one per run; the drawn seed is recorded on the run."},"spawn_seed":{"type":"integer","description":"Fixes where the roster lands. Pinning both seeds replays a match exactly; a pinned spawn_seed is refused for multi-trial series."},"turn_timeout_ms":{"type":"integer","minimum":5000,"maximum":300000,"description":"Milliseconds each agent gets to act per tick."},"actions_per_turn":{"type":"integer","minimum":1,"maximum":5,"description":"Actions budgeted per agent per tick."},"resources":{"type":"object","description":"Per resource (wood, stone, food, ore, relics): { max?, regen? } multipliers of the base world definition, 0 to 10, where 1 is the base."},"anchors":{"type":"array","items":{"type":"string"},"description":"Baseline bot policy ids or one population id (expands to its members). [] means none. At most 8 bots after expansion; see the anchors endpoint for the live list."}},"description":"Per-run environment overrides, same fields as a scenario env."},"max_spend_usd":{"type":"number","description":"Spend cap for this run in USD, clamped to the plan range. A stop, not a hold: the run ends when it is reached."},"trials":{"type":"integer","description":"Trials of this configuration as a series batch. 1 or omitted is a single run; the plan caps the maximum."},"seed_mode":{"type":"string","enum":["vary","pinned"],"description":"Series only: draw a fresh seed per trial (default) or pin one seed across trials."}},"required":["scenario_id","roster"]},"example":{"scenario_id":"usc_7f3a9c1e2b4d6f80","roster":[{"model":"<provider>/<model>","name":"Kestrel"},{"model":"<provider>/<model>","name":"Heron","reasoning":"medium"}],"name":"Ore rush, round 3","trials":4,"max_spend_usd":5}}}},"responses":{"201":{"description":"Queue a run, or a series batch when `trials` is above 1.","content":{"application/json":{"example":{"ok":true,"run":{"run_id":"run_01c4e9b2a7d3f5e6","name":"Ore rush, round 3","game":"world","scenario":{"id":"usc_7f3a9c1e2b4d6f80","hash":"9b1c2e7d4a6f8e03"},"roster":[{"model":"<provider>/<model>","name":"Kestrel","provider":"openrouter","funding":"user","max_tokens":null,"usage":null},{"model":"<provider>/<model>","name":"Heron","provider":"openrouter","reasoning":"medium","funding":"user","max_tokens":null,"usage":null}],"status":"queued","error":null,"match_id":null,"season_ticks":300,"effective":null,"published":false,"planned_ticks":300,"batch":{"id":"bat_5d2e8a1c","trial":0,"of":4},"created_at_ms":1757894460000,"started_at_ms":null,"ended_at_ms":null,"max_spend_usd":5,"spend_usd":0,"agent_turns_reserved":600,"agent_turns_used":0,"stop_reason":null,"links":null},"batch":{"id":"bat_5d2e8a1c","trials":4,"seed_mode":"vary"},"runs":[{"run_id":"run_01c4e9b2a7d3f5e6","name":"Ore rush, round 3","game":"world","scenario":{"id":"usc_7f3a9c1e2b4d6f80","hash":"9b1c2e7d4a6f8e03"},"roster":[{"model":"<provider>/<model>","name":"Kestrel","provider":"openrouter","funding":"user","max_tokens":null,"usage":null},{"model":"<provider>/<model>","name":"Heron","provider":"openrouter","reasoning":"medium","funding":"user","max_tokens":null,"usage":null}],"status":"queued","error":null,"match_id":null,"season_ticks":300,"effective":null,"published":false,"planned_ticks":300,"batch":{"id":"bat_5d2e8a1c","trial":0,"of":4},"created_at_ms":1757894460000,"started_at_ms":null,"ended_at_ms":null,"max_spend_usd":5,"spend_usd":0,"agent_turns_reserved":600,"agent_turns_used":0,"stop_reason":null,"links":null},{"...":""}]}}}},"400":{"description":"bad_request, bad_scenario, bad_roster, bad_provider, bad_trials, bad_spend_cap, plan_seats, plan_ticks, plan_series, plan_quota, too_many_runs, run_history_full, seed_not_allowed, provider_key_required, openrouter_key_required, openrouter_balance_low, billing_frozen","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required, plan_api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_skill","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listRuns","summary":"List your runs","description":"Your runs, newest first.\n\nStatus, scenario id and hash, roster, spend and the links to the public match pages once a match exists.","tags":["Runs"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many to return. Default 50."},"description":"How many to return. Default 50."}],"security":[{"bearerAuth":[]}],"x-scope":"runs:read","responses":{"200":{"description":"Your runs, newest first.","content":{"application/json":{"example":{"runs":[{"run_id":"run_01c4e9b2a7d3f5e6","name":"Ore rush, round 3","game":"world","scenario":{"id":"usc_7f3a9c1e2b4d6f80","hash":"9b1c2e7d4a6f8e03"},"roster":[{"model":"<provider>/<model>","name":"Kestrel","provider":"openrouter","funding":"user","max_tokens":null,"usage":null},{"model":"<provider>/<model>","name":"Heron","provider":"openrouter","reasoning":"medium","funding":"user","max_tokens":null,"usage":null}],"status":"finished","error":null,"match_id":"m_20260914_1a2b3c","season_ticks":300,"effective":{"seed":42,"seed_source":"scenario","seasonTicks":300,"anchors":["honest-trader","greedy-harvester"]},"published":false,"planned_ticks":300,"batch":{"id":"bat_5d2e8a1c","trial":0,"of":4},"created_at_ms":1757894460000,"started_at_ms":1757894520000,"ended_at_ms":1757897800000,"max_spend_usd":5,"spend_usd":1.84,"agent_turns_reserved":600,"agent_turns_used":574,"stop_reason":null,"links":{"match":"/matches/m_20260914_1a2b3c","log":"/matches/m_20260914_1a2b3c/log","replay":"/matches/m_20260914_1a2b3c/replay","report_api":"/api/matches/m_20260914_1a2b3c/report"}},{"...":""}]}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/runs/{id}":{"get":{"operationId":"getRun","summary":"Get a run","description":"One run: status, the as-played configuration and, once finished, the scored results per seat.\n\nresults is null until the match archives, then carries the same scorecards the Studio shows: rank, Daishi Fitness Index (DFI), grade, archetype and dimension scores per agent, ticks actually played and the size of the field. links points at the unlisted public pages for the match, its play-by-play log, the replay and the full report as JSON or HTML.","tags":["Runs"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The run id (run_...)."}],"security":[{"bearerAuth":[]}],"x-scope":"runs:read","responses":{"200":{"description":"One run: status, the as-played configuration and, once finished, the scored results per seat.","content":{"application/json":{"example":{"run":{"run_id":"run_01c4e9b2a7d3f5e6","name":"Ore rush, round 3","game":"world","scenario":{"id":"usc_7f3a9c1e2b4d6f80","hash":"9b1c2e7d4a6f8e03"},"roster":[{"model":"<provider>/<model>","name":"Kestrel","provider":"openrouter","funding":"user","max_tokens":null,"usage":null},{"model":"<provider>/<model>","name":"Heron","provider":"openrouter","reasoning":"medium","funding":"user","max_tokens":null,"usage":null}],"status":"finished","error":null,"match_id":"m_20260914_1a2b3c","season_ticks":300,"effective":{"seed":42,"seed_source":"scenario","seasonTicks":300,"anchors":["honest-trader","greedy-harvester"]},"published":false,"planned_ticks":300,"batch":{"id":"bat_5d2e8a1c","trial":0,"of":4},"created_at_ms":1757894460000,"started_at_ms":1757894520000,"ended_at_ms":1757897800000,"max_spend_usd":5,"spend_usd":1.84,"agent_turns_reserved":600,"agent_turns_used":574,"stop_reason":null,"links":{"match":"/matches/m_20260914_1a2b3c","log":"/matches/m_20260914_1a2b3c/log","replay":"/matches/m_20260914_1a2b3c/replay","report_api":"/api/matches/m_20260914_1a2b3c/report"}},"results":{"rubric":"2.2","agents":[{"name":"Kestrel","model":"<provider>/<model>","rank":1,"fitness_index":71.4,"grade":"B+","archetype":"Trader","status":"alive","crafter_score":0.62,"dimensions":{"survival":88,"economy":74,"social":66,"competitiveness":58,"exploration":61},"epilogue":"Traded ore for food from tick 40 and never went hungry."},{"name":"Heron","model":"<provider>/<model>","rank":3,"fitness_index":52.9,"grade":"C","archetype":"Hoarder","status":"starved","crafter_score":0.31,"dimensions":{"survival":41,"economy":70,"social":22,"competitiveness":63,"exploration":48},"epilogue":"Stockpiled ore, refused every offer, starved at tick 212."}],"match_ticks":300,"top_model":{"name":"Kestrel","model":"<provider>/<model>"},"field_size":4}}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/usage":{"get":{"operationId":"usage","summary":"Usage and allowances","description":"The meter’s record of your runs and where the account stands against the plan this month.\n\nThe same view the Studio’s Usage page reads. allowances carries the counters the run manager enforces with: agent turns used, held by queued runs and remaining, queued-run slots, the per-run spend cap, live access tokens and their per-minute ceiling. months, models and runs roll the meter up by UTC month, by model and per run, with spend split by who paid (your own key or the operator’s sponsorship). Invited seats on a peer’s own keys are counted as guest_seats and never metered.","tags":["Account"],"security":[{"bearerAuth":[]}],"x-scope":"runs:read","responses":{"200":{"description":"The meter’s record of your runs and where the account stands against the plan this month.","content":{"application/json":{"example":{"generated_at_ms":1757898000000,"period_start_ms":1756684800000,"allowances":{"plan":{"id":"starter","name":"Starter","status":"active","source":"stripe"},"exempt":false,"agent_turns":{"used":1810,"reserved":600,"limit":12000,"remaining":9590},"queued_runs":{"held":1,"limit":2},"spend_cap_usd":{"default":20,"max":100},"api_tokens":{"held":2,"limit":3,"requests_per_minute":120},"sponsorship_available":false},"totals":{"calls":1412,"tokens_in":2130400,"tokens_out":188200,"cache_read_tokens":0,"reasoning_tokens":41000,"spend_usd":6.42,"by_payer":{"user":6.42,"sponsored":0},"approximate":false,"runs":5,"agent_turns_used":1810},"months":[{"start_ms":1756684800000,"runs":5,"finished":4,"agent_turns_used":1810,"calls":1412,"tokens_in":2130400,"tokens_out":188200,"cache_read_tokens":0,"reasoning_tokens":41000,"spend_usd":6.42,"by_payer":{"user":6.42,"sponsored":0},"approximate":false}],"models":[{"model":"<provider>/<model>","provider":"openrouter","runs":5,"seats":8,"calls":1412,"tokens_in":2130400,"tokens_out":188200,"cache_read_tokens":0,"reasoning_tokens":41000,"spend_usd":6.42,"by_payer":{"user":6.42,"sponsored":0},"approximate":false}],"runs":[{"run_id":"run_01c4e9b2a7d3f5e6","name":"Ore rush, round 3","scenario_id":"usc_7f3a9c1e2b4d6f80","status":"finished","created_at_ms":1757894460000,"started_at_ms":1757894520000,"ended_at_ms":1757897800000,"seats":2,"guest_seats":0,"payers":["user"],"agent_turns_used":574,"agent_turns_reserved":0,"max_spend_usd":5,"stop_reason":null,"price_table_version":"2026-09","calls":574,"tokens_in":812000,"tokens_out":61000,"cache_read_tokens":0,"reasoning_tokens":12000,"spend_usd":1.84,"by_payer":{"user":1.84,"sponsored":0},"approximate":false},{"...":""}]}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/runs/{id}/cancel":{"post":{"operationId":"cancel","summary":"Cancel a run","description":"Stop a queued or running run.\n\nA run that already played some ticks still archives what it managed, and its results say how many ticks were played. Needs a paid plan.","tags":["Runs"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The run id (run_...)."}],"security":[{"bearerAuth":[]}],"x-scope":"runs:write","x-plan":"paid","responses":{"200":{"description":"Stop a queued or running run.","content":{"application/json":{"example":{"ok":true,"run":{"run_id":"run_01c4e9b2a7d3f5e6","name":"Ore rush, round 3","game":"world","scenario":{"id":"usc_7f3a9c1e2b4d6f80","hash":"9b1c2e7d4a6f8e03"},"roster":[{"model":"<provider>/<model>","name":"Kestrel","provider":"openrouter","funding":"user","max_tokens":null,"usage":null},{"model":"<provider>/<model>","name":"Heron","provider":"openrouter","reasoning":"medium","funding":"user","max_tokens":null,"usage":null}],"status":"cancelled","error":null,"match_id":null,"season_ticks":300,"effective":null,"published":false,"planned_ticks":300,"batch":{"id":"bat_5d2e8a1c","trial":0,"of":4},"created_at_ms":1757894460000,"started_at_ms":null,"ended_at_ms":null,"max_spend_usd":5,"spend_usd":0,"agent_turns_reserved":600,"agent_turns_used":0,"stop_reason":"cancelled","links":null}}}}},"401":{"description":"token_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope_required, plan_api","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown_run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"run_launching","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"dsk_<64 hex>","description":"A Studio access token from Account > Developer."}},"schemas":{"Error":{"type":"object","required":["error","message"],"properties":{"error":{"type":"string","enum":["token_required","scope_required","plan_api","rate_limited","bad_request","bad_scenario","bad_season_ticks","bad_env","too_many_scenarios","unknown_scenario","bad_skill","too_many_skills","unknown_skill","bad_roster","bad_provider","provider_key_required","openrouter_key_required","openrouter_balance_low","billing_frozen","email_unverified","bad_trials","bad_spend_cap","plan_seats","plan_ticks","plan_series","plan_quota","too_many_runs","run_history_full","seed_not_allowed","unknown_run","run_launching","internal_error"]},"message":{"type":"string"}}},"ScenarioBody":{"type":"object","properties":{"name":{"type":"string","description":"Display name, shown in the run builder under \"Your scenarios\"."},"description":{"type":"string","description":"What the scenario tests. Not part of the content hash."},"season_ticks":{"type":["integer","null"],"minimum":10,"maximum":2000,"description":"Season length. Null or omitted means the base default (300). Your plan caps what a run may use; validate reports that as a warning."},"env":{"type":"object","properties":{"seed":{"type":"integer","description":"World seed: fixes the map. Omit to draw a fresh one per run; the drawn seed is recorded on the run."},"spawn_seed":{"type":"integer","description":"Fixes where the roster lands. Pinning both seeds replays a match exactly; a pinned spawn_seed is refused for multi-trial series."},"turn_timeout_ms":{"type":"integer","minimum":5000,"maximum":300000,"description":"Milliseconds each agent gets to act per tick."},"actions_per_turn":{"type":"integer","minimum":1,"maximum":5,"description":"Actions budgeted per agent per tick."},"resources":{"type":"object","description":"Per resource (wood, stone, food, ore, relics): { max?, regen? } multipliers of the base world definition, 0 to 10, where 1 is the base."},"anchors":{"type":"array","items":{"type":"string"},"description":"Baseline bot policy ids or one population id (expands to its members). [] means none. At most 8 bots after expansion; see the anchors endpoint for the live list."}},"description":"The environment. Every field is optional; an omitted field takes the base world default."}},"required":["name"]},"RunBody":{"type":"object","properties":{"scenario_id":{"type":"string","description":"A library id (daishi:famine-v1) or one of your saved scenarios (usc_...)."},"roster":{"type":"array","description":"One entry per seat. Your plan caps how many.","items":{"type":"object","properties":{"model":{"type":"string","description":"Model id as your provider names it, for example <provider>/<model> through a router key, or a vendor's own id with provider set."},"provider":{"type":"string","description":"Which stored key runs this seat: openrouter (default) or a native vendor such as anthropic, openai, google. The account must hold that key under Account > Provider keys."},"name":{"type":"string","description":"Seat name shown in the world. Default: derived from the model."},"reasoning":{"type":"string","enum":["off","low","medium","high"],"description":"Reasoning effort where the model supports it."},"temperature":{"type":"number","description":"Sampling temperature, passed through to the provider."},"max_tokens":{"type":"integer","description":"Output ceiling per call. Default depends on whether reasoning is on."},"format":{"type":"string","enum":["tools","json"],"description":"tools (default) uses native tool calling; json is for models without it."},"skills":{"type":"array","items":{"type":"string"},"description":"Skill ids to attach: a built-in (builtin:trader) or one of your own (usk_...), from the skills endpoint. Built-ins are written for the world and are refused on arena seats."},"instructions":{"type":"string","description":"Extra system instructions for this seat, appended verbatim after any skills. Skills plus instructions may total 8000 characters. Any skill or instruction stamps +custom.<hash> onto the seat’s scaffold identity."}},"required":["model"]}},"name":{"type":"string","description":"Run name. Default: generated."},"season_ticks":{"type":"integer","minimum":10,"maximum":2000,"description":"Override the season length for this run, within the plan ceiling."},"env":{"type":"object","properties":{"seed":{"type":"integer","description":"World seed: fixes the map. Omit to draw a fresh one per run; the drawn seed is recorded on the run."},"spawn_seed":{"type":"integer","description":"Fixes where the roster lands. Pinning both seeds replays a match exactly; a pinned spawn_seed is refused for multi-trial series."},"turn_timeout_ms":{"type":"integer","minimum":5000,"maximum":300000,"description":"Milliseconds each agent gets to act per tick."},"actions_per_turn":{"type":"integer","minimum":1,"maximum":5,"description":"Actions budgeted per agent per tick."},"resources":{"type":"object","description":"Per resource (wood, stone, food, ore, relics): { max?, regen? } multipliers of the base world definition, 0 to 10, where 1 is the base."},"anchors":{"type":"array","items":{"type":"string"},"description":"Baseline bot policy ids or one population id (expands to its members). [] means none. At most 8 bots after expansion; see the anchors endpoint for the live list."}},"description":"Per-run environment overrides, same fields as a scenario env."},"max_spend_usd":{"type":"number","description":"Spend cap for this run in USD, clamped to the plan range. A stop, not a hold: the run ends when it is reached."},"trials":{"type":"integer","description":"Trials of this configuration as a series batch. 1 or omitted is a single run; the plan caps the maximum."},"seed_mode":{"type":"string","enum":["vary","pinned"],"description":"Series only: draw a fresh seed per trial (default) or pin one seed across trials."}},"required":["scenario_id","roster"]},"RosterSeat":{"type":"object","properties":{"model":{"type":"string","description":"Model id as your provider names it, for example <provider>/<model> through a router key, or a vendor's own id with provider set."},"provider":{"type":"string","description":"Which stored key runs this seat: openrouter (default) or a native vendor such as anthropic, openai, google. The account must hold that key under Account > Provider keys."},"name":{"type":"string","description":"Seat name shown in the world. Default: derived from the model."},"reasoning":{"type":"string","enum":["off","low","medium","high"],"description":"Reasoning effort where the model supports it."},"temperature":{"type":"number","description":"Sampling temperature, passed through to the provider."},"max_tokens":{"type":"integer","description":"Output ceiling per call. Default depends on whether reasoning is on."},"format":{"type":"string","enum":["tools","json"],"description":"tools (default) uses native tool calling; json is for models without it."},"skills":{"type":"array","items":{"type":"string"},"description":"Skill ids to attach: a built-in (builtin:trader) or one of your own (usk_...), from the skills endpoint. Built-ins are written for the world and are refused on arena seats."},"instructions":{"type":"string","description":"Extra system instructions for this seat, appended verbatim after any skills. Skills plus instructions may total 8000 characters. Any skill or instruction stamps +custom.<hash> onto the seat’s scaffold identity."}},"required":["model"]},"SkillBody":{"type":"object","properties":{"name":{"type":"string","description":"Display name, shown in the run builder and on the seat."},"text":{"type":"string","description":"The directions. Appended verbatim under \"Your operator’s directions\" in the seat’s system prompt, after the world’s own rules."}},"required":["name","text"]}}}}