{"openapi":"3.1.0","info":{"title":"Sensory Experience API","version":"1.0.0","description":"Role-enforced event API. Payment processing is deferred. Read /docs/agent-manual.md before writing."},"security":[{"agentBearer":[]},{"staffSession":[]}],"components":{"securitySchemes":{"agentBearer":{"type":"http","scheme":"bearer"},"staffSession":{"type":"apiKey","in":"cookie","name":"__Host-sensory_session"},"participantToken":{"type":"apiKey","in":"header","name":"X-Participant-Token"}},"schemas":{"Answer":{"type":"object","properties":{"liking":{"type":"integer","minimum":1,"maximum":7},"intensity":{"type":"integer","minimum":1,"maximum":7},"descriptors":{"type":"array","maxItems":3,"items":{"type":"string","maxLength":80}},"measure":{"type":"string","maxLength":80},"notes":{"type":"string","maxLength":1000},"skip":{"type":"boolean"}}},"StudioAction":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["newEvent","saveEvent","ready","check","panel","screen","end","savePanel","removePanel","stock","entry","reconcileEntry","usage","paperJoin","paperAnswer","correctAnswer","document","simulate"]},"eventId":{"type":"string"},"name":{"type":"string"},"data":{"type":"object","description":"Complete event details from GET /api/studio, with intended edits."},"index":{"type":"integer","minimum":0},"command":{"type":"string","enum":["open","close","reopen","reveal"]},"closePrevious":{"type":"boolean"},"screen":{"type":"object","required":["kind","panel","metric","message","timer"],"properties":{"kind":{"enum":["welcome","panel","reveal","results"]},"panel":{"type":"integer"},"metric":{"type":"string"},"message":{"type":"string","maxLength":1000},"timer":{"type":"number","description":"Unix milliseconds; zero clears the timer."}}},"panel":{"type":"object","description":"Complete panel object from the studio; stable item IDs required when editing an opened panel."},"template":{"type":"boolean"},"stock":{"type":"object","description":"Complete inventory record. Omitting photos preserves the existing gallery; use an empty array to detach all photos.","properties":{"photos":{"type":"array","maxItems":20,"uniqueItems":true,"items":{"type":"string"},"description":"Accepted image keys only; PDFs are not package photos."},"photoLabels":{"type":"object","additionalProperties":{"type":"string","maxLength":80},"description":"Optional side labels keyed by an attached photo key."}}},"entry":{"type":"object","required":["eventId","kind","amount","description"],"properties":{"eventId":{"type":"string"},"kind":{"enum":["income","expense","refund","credit"]},"amount":{"type":"number","exclusiveMinimum":0},"description":{"type":"string"},"date":{"type":"string"},"category":{"type":"string"},"receipt":{"type":"string"},"reconciled":{"type":"boolean"}}},"participantId":{"type":"string"},"itemId":{"type":"string"},"answer":{"type":"object","properties":{"liking":{"type":"integer","minimum":1,"maximum":7},"intensity":{"type":"integer","minimum":1,"maximum":7},"descriptors":{"type":"array","maxItems":3,"items":{"type":"string","maxLength":80}},"measure":{"type":"string","maxLength":80},"notes":{"type":"string","maxLength":1000},"skip":{"type":"boolean"}}},"reason":{"type":"string"},"requestedBy":{"type":"string","description":"Authorized human host ID for agent corrections."},"count":{"type":"integer","minimum":1,"maximum":100},"approvalId":{"type":"string"},"key":{"type":"string"},"value":{"type":"boolean"},"id":{"type":"string"},"usage":{"type":"object"},"adjustCount":{"type":"boolean"}}}}},"paths":{"/api/auth/status":{"get":{"summary":"Current identity, role, environment and integration availability","security":[],"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/studio":{"get":{"summary":"Read your authorized studio records","responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}},"post":{"summary":"Apply an event, inventory, template or manual accounting action","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":120},"description":"Required for agents; reuse only for an exact retry."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["newEvent","saveEvent","ready","check","panel","screen","end","savePanel","removePanel","stock","entry","reconcileEntry","usage","paperJoin","paperAnswer","correctAnswer","document","simulate"]},"eventId":{"type":"string"},"name":{"type":"string"},"data":{"type":"object","description":"Complete event details from GET /api/studio, with intended edits."},"index":{"type":"integer","minimum":0},"command":{"type":"string","enum":["open","close","reopen","reveal"]},"closePrevious":{"type":"boolean"},"screen":{"type":"object","required":["kind","panel","metric","message","timer"],"properties":{"kind":{"enum":["welcome","panel","reveal","results"]},"panel":{"type":"integer"},"metric":{"type":"string"},"message":{"type":"string","maxLength":1000},"timer":{"type":"number","description":"Unix milliseconds; zero clears the timer."}}},"panel":{"type":"object","description":"Complete panel object from the studio; stable item IDs required when editing an opened panel."},"template":{"type":"boolean"},"stock":{"type":"object","description":"Complete inventory record. Omitting photos preserves the existing gallery; use an empty array to detach all photos.","properties":{"photos":{"type":"array","maxItems":20,"uniqueItems":true,"items":{"type":"string"},"description":"Accepted image keys only; PDFs are not package photos."},"photoLabels":{"type":"object","additionalProperties":{"type":"string","maxLength":80},"description":"Optional side labels keyed by an attached photo key."}}},"entry":{"type":"object","required":["eventId","kind","amount","description"],"properties":{"eventId":{"type":"string"},"kind":{"enum":["income","expense","refund","credit"]},"amount":{"type":"number","exclusiveMinimum":0},"description":{"type":"string"},"date":{"type":"string"},"category":{"type":"string"},"receipt":{"type":"string"},"reconciled":{"type":"boolean"}}},"participantId":{"type":"string"},"itemId":{"type":"string"},"answer":{"type":"object","properties":{"liking":{"type":"integer","minimum":1,"maximum":7},"intensity":{"type":"integer","minimum":1,"maximum":7},"descriptors":{"type":"array","maxItems":3,"items":{"type":"string","maxLength":80}},"measure":{"type":"string","maxLength":80},"notes":{"type":"string","maxLength":1000},"skip":{"type":"boolean"}}},"reason":{"type":"string"},"requestedBy":{"type":"string","description":"Authorized human host ID for agent corrections."},"count":{"type":"integer","minimum":1,"maximum":100},"approvalId":{"type":"string"},"key":{"type":"string"},"value":{"type":"boolean"},"id":{"type":"string"},"usage":{"type":"object"},"adjustCount":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/event":{"get":{"summary":"Public event and your personal workbook when authenticated","security":[{},{"participantToken":[]},{"agentBearer":[]}],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}},"post":{"summary":"Join, answer, save Flavorprint or request your review link","security":[{"participantToken":[]},{"agentBearer":[]},{}],"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action","eventId"],"properties":{"action":{"enum":["join","answer","flavorprint","requestReviewLink"]},"eventId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"itemId":{"type":"string"},"answer":{"type":"object","properties":{"liking":{"type":"integer","minimum":1,"maximum":7},"intensity":{"type":"integer","minimum":1,"maximum":7},"descriptors":{"type":"array","maxItems":3,"items":{"type":"string","maxLength":80}},"measure":{"type":"string","maxLength":80},"notes":{"type":"string","maxLength":1000},"skip":{"type":"boolean"}}},"values":{"type":"object"}}}}}},"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/staff":{"get":{"summary":"Administrator: list staff and agent assignments","responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}},"post":{"summary":"Human administrator: save/revoke access or issue a link/credential","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"enum":["save","revoke","link","credential"]},"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"kind":{"enum":["human","agent"]},"roles":{"type":"array","items":{"enum":["administrator","host","participant"]}},"events":{"type":"array","items":{"type":"string"}},"participantId":{"type":"string"},"sendEmail":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/audit":{"get":{"summary":"Read latest 100 authorized audit entries and pending approvals","parameters":[{"name":"eventId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}},"post":{"summary":"Human administrator: approve or reject an exact pending request","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","action"],"properties":{"id":{"type":"string"},"action":{"enum":["approve","reject"]}}}}}},"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/upload":{"post":{"summary":"Stage image bytes for review, save a PDF, or accept/discard a staged image","parameters":[{"name":"eventId","in":"query","schema":{"type":"string"}},{"name":"X-File-Name","in":"header","schema":{"type":"string"},"description":"URL-encoded filename for raw uploads."}],"requestBody":{"required":true,"content":{"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object","required":["action","key"],"properties":{"action":{"enum":["accept","discard"]},"key":{"type":"string"}}}}}},"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/file":{"get":{"summary":"Read an authorized attachment or event package photo","parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string"}},{"name":"event","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/templates":{"get":{"summary":"Administrator: export content without photos or operational records","responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}},"post":{"summary":"Human administrator: deliberately import reusable template content","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["format","version","panels"],"properties":{"format":{"const":"sensory-templates"},"version":{"const":1},"panels":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/review-links":{"post":{"summary":"Host: send personal links to participants with supplied emails","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["eventId"],"properties":{"eventId":{"type":"string"}}}}}},"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}},"/api/mcp":{"post":{"summary":"Stateless Streamable HTTP MCP endpoint; bearer authentication required","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"const":"2.0"},"id":{},"method":{"type":"string"},"params":{"type":"object"}}}}}},"responses":{"200":{"description":"Successful response"},"202":{"description":"Human approval required; no business change applied"},"400":{"description":"Validation failed"},"401":{"description":"Authentication required"},"403":{"description":"Role or event assignment denied"},"409":{"description":"Conflicting update or idempotency-key reuse"},"429":{"description":"Rate limited"}}}}}}