{"openapi":"3.0.0","info":{"title":"LSAS Platform Gateway API","version":"0.1.0","description":"Governed gateway boundaries with persisted decision evidence. Developer Evaluation scenarios use an in-process synthetic provider, not a live model."},"paths":{"/v1/chat/completions":{"post":{"summary":"Create chat completion via LSAS Platform gateway","tags":["chat"],"parameters":[{"name":"x-lsas-api-key","in":"header","schema":{"type":"string"},"required":false,"description":"LSAS Platform API key is required in production. Public demos use the configured strong demo key and server-side tenant/app binding; tenant/app headers are development-only."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string"},"messages":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string"},"content":{"type":"string"}},"required":["role","content"]}},"stream":{"type":"boolean"}},"required":["messages"]}}}},"responses":{"200":{"description":"Upstream response plus LSAS Platform envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"lsas":{"type":"object"}},"required":["data","lsas"]}}}}}}},"/v1/payload/sanitize":{"post":{"summary":"Evaluate and, when permitted, sanitize a JSON payload","description":"Uses the authenticated application's effective policy without contacting a model provider. Ordinary tenant keys require sanitize scope. Evaluation keys additionally require current server-owned evaluation authority and the exact selected policy, and share activation, expiry and decision budgets with evaluation scenarios. Evaluation requests are limited to 32768 UTF-8 bytes of normalized parsed JSON, 32 nesting levels and 4096 JSON nodes before recursive processing; the gateway's raw body parser retains its 1 MiB limit. Policy-required transformations are revalidated before return. Public fixture behavior requires the separately configured public-demo identity.","tags":["payload"],"parameters":[{"name":"x-lsas-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"Current LSAS API key with sanitize scope. Evaluation authority cannot be supplied through tenant/app headers."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["payload"],"properties":{"payload":{"description":"JSON value to inspect, including objects, arrays, strings, finite numbers, booleans or null. Use synthetic or non-sensitive test data for Developer Evaluation."}}}}}},"responses":{"200":{"description":"Authorized unchanged or revalidated transformed data with the actual enforcement envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadBoundaryResult"}}}},"400":{"description":"Invalid payload request, or committed BLOCKED evaluation result with data:null. Malformed parser input may return a generic request error."},"401":{"description":"Missing, invalid, revoked or expired key."},"403":{"description":"Identity scope or evaluation authority is unavailable."},"409":{"description":"HELD payload with data:null, or evaluation policy conflict. No automatic approval or resume."},"410":{"description":"Evaluation expired."},"413":{"description":"Request bytes, evaluation nesting or node budget exceeded."},"429":{"description":"Gateway rate limit or shared evaluation rate/cumulative budget exceeded."},"503":{"description":"Required runtime policy configuration is unavailable."}}}},"/v1/evaluation/scenarios":{"post":{"summary":"Exercise real ingress and egress enforcement with a recording synthetic provider","description":"Requires an active evaluation API key with sanitize scope and the scenario's exact server-selected policy version. Uses the same evaluation activation, expiry and cumulative/shared request budgets as payload sanitization. Does not grant ordinary chat, tools, external destinations, approval or resume. The complete JSON body is limited to 8192 UTF-8 bytes; custom input to 4096 UTF-8 bytes. Customized input is evaluated as supplied and may produce a different outcome from the default scenario.","tags":["evaluation"],"parameters":[{"name":"x-lsas-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"Current sanitize-scoped evaluation API key. Tenant/app headers and public-demo credentials are not accepted."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["scenarioId"],"properties":{"scenarioId":{"type":"string","enum":["safe-release","redact-input","block-input","hitl-input","warn-release","redact-output","block-output","hitl-output"]},"input":{"type":"string","maxLength":4096,"description":"Optional replacement request text, limited to 4096 UTF-8 bytes. The synthetic response, provider, model and policy cannot be overridden."}}}}}},"responses":{"200":{"description":"Committed allowed, warned or transformed response. This records authorization, not downstream application consumption.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluationScenarioResult"}}}},"400":{"description":"Invalid scenario request, or committed BLOCKED outcome with data:null and enforcement evidence. Malformed parser input may return a generic request error without an enforcement envelope."},"401":{"description":"Missing, invalid, expired or revoked API key; no provider call."},"403":{"description":"Evaluation unavailable or the identity lacks evaluation authority; no provider call."},"409":{"description":"Scenario-policy mismatch without execution, or a committed HELD outcome with data:null. No automatic approval or resume.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluationScenarioResult"}}}},"410":{"description":"Evaluation expired; no provider call."},"413":{"description":"Request or custom input exceeds the supported byte limit; no provider call."},"429":{"description":"Shared evaluation rate or cumulative decision budget exhausted; no provider call."},"503":{"description":"Required runtime policy authority or persistence is unavailable; no success is returned."}}}},"/v1/evaluation/actions":{"post":{"summary":"Exercise registered action and destination authority with a synthetic reader","description":"Requires an active sanitize-scoped evaluation key. The actual deterministic kernel authorizes one fixed in-process synthetic record reader or denies a fixed wrong destination/unregistered action before invocation. No external connector, network call, write, human approval or resume capability is granted. The currently selected exact policy evaluates content separately from action authority. Complete raw and normalized JSON request bodies are limited to 1024 UTF-8 bytes. Uses the shared evaluation activation, expiry and decision budgets. Only a case ID is accepted; arguments, destination, grants and policy cannot be supplied by the caller.","tags":["evaluation"],"parameters":[{"name":"x-lsas-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"Current evaluation API key; public-demo credentials and tenant/app headers do not grant authority."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["caseId"],"properties":{"caseId":{"type":"string","enum":["allowed-read","wrong-destination","unregistered-action"]}}}}}},"responses":{"200":{"description":"One actual synthetic-reader invocation; computed output separately validated and authorized for return. Does not establish downstream application delivery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluationActionResult"}}}},"400":{"description":"Committed kernel authorization denial: data:null, BLOCKED at ingress, zero invocations and no grant/receipt. Invalid/malformed requests may instead return a generic request error without decision evidence."},"401":{"description":"Missing, invalid, revoked or expired key. Admission denial prevents invocation; authority lost during processing prevents final publication."},"403":{"description":"Evaluation disabled or identity/environment lacks evaluation authority. Admission denial prevents invocation; authority lost during processing prevents final publication."},"409":{"description":"Current policy/authority, kernel execution or evidence publication cannot be confirmed. No successful output or automatic resume."},"410":{"description":"Evaluation expired. Admission denial prevents invocation; expiry during processing prevents final publication."},"413":{"description":"Request exceeds 1024 UTF-8 bytes; no invocation."},"429":{"description":"Shared evaluation rate or cumulative budget exhausted; no invocation."},"503":{"description":"Required policy, fixture eligibility or persistence is unavailable; no successful output."}}}},"/v1/sandbox/connectors/epic/patient-summary":{"post":{"summary":"Execute Epic sandbox connector flow with LSAS Platform mediation","tags":["connectors"],"parameters":[{"name":"x-lsas-api-key","in":"header","schema":{"type":"string"},"required":false},{"name":"x-correlation-id","in":"header","schema":{"type":"string"},"required":false}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string","enum":["PATIENT_READ","PATIENT_SEARCH"]},"scenarioId":{"type":"string"},"policyTier":{"type":"string"},"patientId":{"type":"string"},"search":{"type":"object","properties":{"fhirId":{"type":"string"},"family":{"type":"string"},"given":{"type":"string"},"birthDate":{"type":"string"},"identifier":{"type":"string"},"name":{"type":"string"}}}}}}}},"responses":{"200":{"description":"Connector contract with run metadata, decisions, payloads, and timeline","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"object","properties":{"timestamp":{"type":"string"},"operationClass":{"type":"string"},"baselineDecision":{"type":"string"},"executionStatus":{"type":"string"},"run":{"type":"object"},"scenario":{"type":"object"},"connector":{"type":"object"},"decisions":{"type":"object"},"payloads":{"type":"object"},"timeline":{"type":"array","items":{"type":"object"}},"explanation":{"type":"string"}}}},"required":["contract"]}}}},"400":{"description":"Invalid request or connector configuration"},"401":{"description":"Unauthorized"},"403":{"description":"Ingress or egress policy blocked execution"},"502":{"description":"Connector auth or upstream error"}}}},"/healthz":{"get":{"summary":"Gateway health check","responses":{"200":{"description":"Health information."}}}}},"components":{"schemas":{"PayloadBoundaryResult":{"type":"object","required":["data","lsas"],"properties":{"data":{"description":"Authorized JSON value, or null when blocked or held. A released JSON null is valid; inspect the enforcement envelope to distinguish it from withholding."},"lsas":{"type":"object","description":"Actual decision, policy provenance, request ID, enforcement outcome/stage and authorized artifact fingerprint."},"error":{"type":"string"}}},"EvaluationScenarioResult":{"type":"object","required":["data"],"properties":{"data":{"type":"object","nullable":true,"description":"Only the authorized synthetic chat response; null when blocked or held. Withheld output is never returned as diagnostics."},"error":{"type":"string"},"lsas":{"type":"object","description":"Final persisted decision and enforcement metadata. audit.requestId identifies its record."},"ingress":{"type":"object","description":"Actual initial request decision, independently recording ingress transformation or withholding."},"demo":{"type":"object","required":["scenarioId","mode","providerCalls","inputWasCustomized"],"properties":{"scenarioId":{"type":"string"},"mode":{"type":"string","enum":["synthetic-provider"]},"providerCalls":{"type":"integer","enum":[0,1]},"inputWasCustomized":{"type":"boolean"},"providerRequest":{"type":"object","description":"Exact normalized request captured only when the recording adapter was called. Sensitive input transformations are applied before this capture. Omitted for blocked or held ingress."}}}}},"EvaluationActionResult":{"type":"object","required":["data","lsas","action"],"properties":{"data":{"type":"object","nullable":true,"description":"Only the final authorized synthetic record, or null on action denial."},"lsas":{"type":"object","description":"Final persisted enforcement. A kernel action denial is distinct from a content-policy finding."},"error":{"type":"string"},"action":{"type":"object","required":["caseId","mode","authorization","reasonCodes","invocationCount","contentDecision","requestedSkillId","destination","manifest"],"properties":{"caseId":{"type":"string","enum":["allowed-read","wrong-destination","unregistered-action"]},"mode":{"type":"string","enum":["synthetic-reader"]},"authorization":{"type":"string","enum":["AUTHORIZED","DENIED"]},"reasonCodes":{"type":"array","items":{"type":"string","enum":["execution_authority_held","skill_unavailable"]},"maxItems":1},"invocationCount":{"type":"integer","enum":[0,1]},"contentDecision":{"type":"string","enum":["ALLOW","ALLOW_WITH_WARNINGS"],"description":"Actual initial content-policy decision. Allowed content does not grant an action or destination."},"requestedSkillId":{"type":"string"},"destination":{"type":"string","description":"A fixed logical synthetic destination, never a caller-controlled URL or external connection."},"manifest":{"type":"object","required":["id","version","digest"],"properties":{"id":{"type":"string"},"version":{"type":"string"},"digest":{"type":"string","pattern":"^[a-f0-9]{64}$"}}},"grant":{"type":"object","description":"Present only after actual kernel authorization. This metadata is not a reusable bearer token.","required":["grantId","inputDigest","actionDigest","authorityDigest","expiresAt"],"properties":{"grantId":{"type":"string","format":"uuid"},"inputDigest":{"type":"string"},"actionDigest":{"type":"string"},"authorityDigest":{"type":"string"},"expiresAt":{"type":"number","description":"Epoch milliseconds; expired grants cannot authorize final publication."}}},"executionReceipt":{"type":"object","required":["state","outputDigest"],"description":"Kernel computation receipt, separate from final LSAS release. Digest uses SHA-256 over core canonical sorted-key JSON; the final enforcement artifact hash uses the existing JSON.stringify contract.","properties":{"state":{"type":"string","enum":["computed-unreleased"]},"outputDigest":{"type":"string","pattern":"^[a-f0-9]{64}$"}}}}}}}}}}