{"openapi":"3.1.0","info":{"title":"ScryMaster Stories API","version":"1.83.0","description":"Authoring + marketplace surface for deterministic D&D 5e narrative adventures. Author with the closed action vocabulary at /api/v1/actions; validate + simulate before publishing. AUTH (P15): every /api/v1/adventures draft endpoint accepts EITHER an authenticated owner session (Supabase cookie — the Studio) OR a creator PAT via `Authorization: Bearer scry_…` (mint one in Studio → ⚙ Settings → API tokens — the MCP/assistant path); ownership is enforced server-side either way. Concurrency: reads return a draftHash; send it back as baseHash on save/publish — a stale write is rejected 409, never clobbered. Monsters (deps.statBlocks[].actions): author STRUCTURED attack fields — toHit (number), damageRoll (dice expr, e.g. \"2d4+2\"), damageType, saveAbility+saveDc, and abilities (on-hit rider element ids) — with `detail` reserved for rider notes/flavor. Prose-only actions the engine cannot parse are display-only (skipped in solo combat) and surface as STATBLOCK_PROSE_ONLY_ATTACK / STATBLOCK_NO_ENGINE_ATTACK lint warnings in the validation report."},"servers":[{"url":"https://scrymaster.com"}],"paths":{"/api/v1/actions":{"get":{"summary":"The closed authoring vocabulary (ACTION_TYPES + conditions + triggers). Public grounding surface.","responses":{"200":{"description":"Vocabulary"}}}},"/api/v1/adventures":{"get":{"summary":"List the caller’s draft adventures (owner-scoped).","responses":{"200":{"description":"Drafts"},"401":{"description":"Unauthorized"}}},"post":{"summary":"Create a draft from a full AdventureDoc.","responses":{"200":{"description":"Created"},"400":{"description":"Invalid doc"},"401":{"description":"Unauthorized"}}}},"/api/v1/adventures/{id}":{"get":{"summary":"Read a draft (doc + meta + listing).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Adventure"},"404":{"description":"Not found"}}},"patch":{"summary":"Update the draft: {doc} | {node} | {rule} | {listing}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Updated"},"400":{"description":"Invalid"}}},"delete":{"summary":"Delete the draft.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"}}}},"/api/v1/adventures/{id}/validate":{"post":{"summary":"The authoritative ValidationReport (schema + reachability + closed-verb check).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"ValidationReport"}}}},"/api/v1/adventures/{id}/simulate":{"post":{"summary":"Run N headless playthroughs → a coverage/lethality report.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"SimReport"}}}},"/api/v1/adventures/{id}/publish":{"post":{"summary":"Validate + IP-denylist + snapshot an immutable version; classify compatible vs breaking. Body {dry:true} → the FULL verdict with no write; {confirmDataLoss:true} → explicit sign-off when the publish would discard content players have.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Published (or the dry verdict)"},"409":{"description":"Stale baseHash"},"422":{"description":"Blocked (validation/denylist/data-loss)"}}}},"/api/v1/adventures/{id}/versions":{"get":{"summary":"The immutable published-version history (newest first).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Versions"}}}},"/api/v1/adventures/{id}/restore":{"post":{"summary":"Restore an immutable snapshot INTO the draft: {version:N}. Recorded in the provenance ledger.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Restored (new draftHash)"},"404":{"description":"Version not found"}}}},"/api/v1/adventures/{id}/activity":{"get":{"summary":"The story’s authorship/provenance ledger (who changed what, via Studio or MCP). Owner-only.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Events"}}}},"/api/v1/app-settings":{"get":{"summary":"Public runtime feature toggles (allowlisted): {storyWindowing}.","responses":{"200":{"description":"Settings"}}}},"/api/v1/adventures/published/{id}":{"get":{"summary":"A playable adventure’s published doc by doc_id. ?version=N pins to an immutable version (save-versioning).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Doc + version + latest"},"404":{"description":"No published version"}}}},"/api/v1/store":{"get":{"summary":"Browse published + listed adventures (community + official).","responses":{"200":{"description":"Store cards"}}}},"/api/v1/store/{docId}":{"get":{"summary":"A store listing’s detail: gallery, settings, version cadence, creator, metrics.","parameters":[{"name":"docId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Listing"},"404":{"description":"Not found"}}}},"/api/v1/creator-profile":{"get":{"summary":"The caller’s creator store profile.","responses":{"200":{"description":"Profile or null"},"401":{"description":"Unauthorized"}}},"put":{"summary":"Create/update the caller’s creator profile.","responses":{"200":{"description":"Profile"}}}}}}