{"openapi":"3.1.0","info":{"title":"PRAMPTA","version":"1.0.0"},"paths":{"/v1/subjects/register":{"post":{"tags":["subjects"],"summary":"Register Subject","description":"Register one subject. Acting as an organization (X-Org-Context), the\nORGANIZATION holds it — owner_org_id, no personal owner — exactly as its\nbulk import does. This used to ignore the header and always file the\nsubject under the person (founder report, 2026-09-22): it then belonged\nto the wrong account and never showed in the organization's dashboard.","operationId":"register_subject_v1_subjects_register_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectRegisterRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/similar":{"get":{"tags":["subjects"],"summary":"Similar Subjects","description":"Existing subjects that look like potential duplicates of this one (F9).\n\nVisible to the subject's controller and to operators. This is where a\ncross-claim shows up — two people who each registered a near-identical name\n— so the people who can act on it are the ones who can see it.","operationId":"similar_subjects_v1_subjects__subject_id__similar_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/evidence-guidance":{"get":{"tags":["subjects"],"summary":"Evidence Guidance","description":"What evidence would back THIS subject's type (A8, F8).\n\nThe point of modelling the type: the system can ask for the right thing. A\npassport for a person, a trademark for a brand — surfaced from one map so\nthe prompt and the review criteria cannot drift apart.","operationId":"evidence_guidance_v1_subjects__subject_id__evidence_guidance_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/type":{"post":{"tags":["subjects"],"summary":"Set Subject Type","description":"Declare or correct a subject's type — the honest path for the legacy\nsubjects that backfilled to `unspecified`.","operationId":"set_subject_type_v1_subjects__subject_id__type_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectTypeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/risk-flags":{"post":{"tags":["subjects"],"summary":"Set Risk Flags","description":"Add or remove high-risk flags (16.9).\n\nThe asymmetry is the whole point: the subject's controller may ADD a flag\n(protecting the subject), but only an operator may REMOVE one. Otherwise an\nowner could mark a child as low-risk to unlock auto-approval and commercial\nlicensing — the exact move the protection exists to stop.","operationId":"set_risk_flags_v1_subjects__subject_id__risk_flags_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskFlagRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/custody":{"post":{"tags":["subjects"],"summary":"Set Custody","description":"Rotate a subject to a fresh managed key, or migrate a legacy\nself-custody subject onto one. Only the subject's owner may do this.\n\n2026-08: self-custody is retired (see register_subject) — mode=\"self\" is\nrejected here too, so a self-custody subject can only ever move TOWARD\nmanaged, never stay or re-enter self-custody. A legacy self-custody\nsubject's old public key keeps verifying whatever it already signed\n(a licence keeps its own stored signing key — see finalize_license_\nsignatures), it just can't sign anything NEW once this runs.","operationId":"set_custody_v1_subjects__subject_id__custody_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustodyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/reserved":{"post":{"tags":["subjects"],"summary":"Add Reserved Name","description":"Add a reserved / high-profile name (operator only). Matching registrations\nthen go to manual review.","operationId":"add_reserved_name_v1_subjects_reserved_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservedNameRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/subjects/index":{"get":{"tags":["subjects"],"summary":"Subject Index","description":"Machine-readable subject detection index.\n\nProviders poll this to know WHICH subjects to look for in prompts before\ncalling /verify (see docs/licensing-integration.md). Includes every\nregistration regardless of status — withdrawn/disputed subjects must\nstill be detected (they produce hard refusals), and private subjects\nmust be detected so the provider knows a license is required.\n\nNormal records expose only what detection needs: canonical id + aliases +\nstatus. Public operator-curated references additionally expose their\ndescriptions and PRAMPTA-hosted reference media. These records have no\nowner or retained signing key and always fail closed in /verify.\nETag/If-None-Match supported so a cached index costs one cheap 304.","operationId":"subject_index_v1_subjects_index_get","parameters":[{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectIndexResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}":{"get":{"tags":["subjects"],"summary":"Get Subject","operationId":"get_subject_v1_subjects__subject_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["subjects"],"summary":"Update Subject","description":"Edit a subject's settings. Only a controller of the subject may do this.\nIdentity (subject_id, public key) is immutable; everything here is policy\n/ presentation that the rights holder can tune anytime.","operationId":"update_subject_v1_subjects__subject_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["subjects"],"summary":"Delete Subject","description":"Hard-delete a subject the caller owns — but ONLY if it was never licensed.\n\nA subject with issued licenses is part of the permanent, verifiable record:\ndeleting it would break the signed licenses people hold. That case is refused\n(409) — the owner should PAUSE it (stop new generation, reversible) or\nwithdraw it (terminal) instead. Deletion is for cleaning up mistakes and\nnever-used registrations.","operationId":"delete_subject_v1_subjects__subject_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/epoch":{"get":{"tags":["subjects"],"summary":"Get Subject Epoch","description":"The subject's current revocation_epoch (§7 freshness controls).\n\nPublic and unauthenticated on purpose: a provider holding a cached decision\nneeds to check this cheaply and often, and it carries nothing sensitive —\njust an integer that moves when something happened. Comparing it against\nthe epoch a decision was issued with (SignedDecision.revocation_epoch) is\nthe cheap alternative to a full /verify re-check.","operationId":"get_subject_epoch_v1_subjects__subject_id__epoch_get","parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/banner":{"get":{"tags":["subjects"],"summary":"Get Subject Banner","operationId":"get_subject_banner_v1_subjects__subject_id__banner_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}},{"name":"if-none-match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["subjects"],"summary":"Set Subject Banner","description":"Set or clear a subject's preview banner. Only a controller of the subject\n(operator admin, the personal owner, or an admin of the owning org) may.","operationId":"set_subject_banner_v1_subjects__subject_id__banner_put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectBannerRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/gallery/{index}":{"get":{"tags":["subjects"],"summary":"Get Subject Gallery Image","operationId":"get_subject_gallery_image_v1_subjects__subject_id__gallery__index__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}},{"name":"index","in":"path","required":true,"schema":{"type":"integer","title":"Index"}},{"name":"if-none-match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/stats":{"get":{"tags":["subjects"],"summary":"Subject Stats","description":"Usage analytics for a subject the caller controls: how many times it was\nchecked for generation, how many were allowed vs refused, and a recent\ntimeline of who tried, when, and the outcome. Built from the tamper-evident\naudit log (verify_allowed / verify_refused events).","operationId":"subject_stats_v1_subjects__subject_id__stats_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/":{"get":{"tags":["subjects"],"summary":"List Subjects","description":"List active subjects. Private subjects are always redacted unless the\nrequester controls them — there is no public bypass.\n\nWith ``owned=true`` the result is scoped to subjects the caller actually\nOWNS or co-manages (their personal subjects + subjects of orgs where they\nare owner/admin). This deliberately ignores the operator (global admin)\noverride so the profile's \"My subjects\" shows a user's own registrations\nonly — an operator does not see everyone's subjects there. The Library\n(owned=false) is unchanged.\n\n``owner_username`` / ``owner_org_id`` back the public storefront pages\n(/id/@username, /org/@orgname) — same unauthenticated query anyone\nbrowsing the Library already runs, just pre-filtered to one owner. No new\nexposure: a public subject already appears in the plain Library listing,\nand a private one already redacts the same fields it would there. An\nunknown username/org id is not an error — it resolves to zero rows, same\nas the Library returning nothing for a query that matches nothing.","operationId":"list_subjects_v1_subjects__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"owned","in":"query","required":false,"schema":{"type":"boolean","description":"only subjects the caller owns/manages","default":false,"title":"Owned"},"description":"only subjects the caller owns/manages"},{"name":"owner_username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"public storefront: only this user's subjects","title":"Owner Username"},"description":"public storefront: only this user's subjects"},{"name":"owner_org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"public storefront: only this org's subjects","title":"Owner Org Id"},"description":"public storefront: only this org's subjects"},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"person | character | brand","title":"Kind"},"description":"person | character | brand"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/gallery":{"put":{"tags":["subjects"],"summary":"Set Subject Gallery","description":"Replace a subject's gallery (up to 5 images). Only a controller may.","operationId":"set_subject_gallery_v1_subjects__subject_id__gallery_put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectGalleryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/status":{"patch":{"tags":["subjects"],"summary":"Transition Subject Status","description":"Transition subject status with authority proof.\n\nAllowed transitions:\n- active → disputed (admin/third-party dispute)\n- active → withdrawn (subject self-withdrawal, requires signature)\n- disputed → active (dispute resolved, requires admin)\n- disputed → withdrawn (dispute led to removal)\n- pending → active (registration approved)","operationId":"transition_subject_status_v1_subjects__subject_id__status_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectStatusTransition"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/dispute":{"post":{"tags":["subjects"],"summary":"File Dispute","description":"File a dispute against a subject (marks as disputed, blocks generation).\n\nOnly admins or the subject owner can file disputes directly.\nThird-party disputes should go through a separate review process.","operationId":"file_dispute_v1_subjects__subject_id__dispute_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}},{"name":"reason","in":"query","required":false,"schema":{"type":"string","default":"","title":"Reason"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","default":{},"title":"Authority Proof"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/rotate-key":{"post":{"tags":["subjects"],"summary":"Rotate Subject Key","description":"Rotate a subject's Ed25519 public key.\n\nRequires dual proof-of-possession: the rotation message must be signed\nby BOTH the old key (proves current ownership) and the new key (proves\nthe caller holds the new private key). This prevents key replacement\nattacks where an attacker who compromises the account but not the\nsigning key tries to swap it.","operationId":"rotate_subject_key_v1_subjects__subject_id__rotate_key_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/provider-veto":{"put":{"tags":["subjects"],"summary":"Set Provider Veto","description":"Set which providers may generate this subject.\n\nEnforced in /verify ahead of any licence and NOT behind a feature flag:\na licence says what may be done, this says with whom, and this wins.\nExisting licences are deliberately NOT revoked — the veto stops future\ngeneration without rewriting a signed agreement, and revocation stays a\nseparate, explicit act.","operationId":"set_provider_veto_v1_subjects__subject_id__provider_veto_put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderVetoRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["subjects"],"summary":"Get Provider Veto","description":"Read the veto. Owner-only: who a rights holder has refused is their\nbusiness, and publishing it would tell a blocked provider it was singled\nout.","operationId":"get_provider_veto_v1_subjects__subject_id__provider_veto_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/certificate":{"get":{"tags":["subjects"],"summary":"Get Subject Certificate","operationId":"get_subject_certificate_v1_subjects__subject_id__certificate_get","parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/issue":{"post":{"tags":["licenses"],"summary":"Issue License","description":"DEPRECATED: use /licenses/issue-presigned. That path supports the full\npolicy (channels/territories/rules_text), records an audit event, and returns\npolicy-lint warnings. This endpoint is kept for backward compatibility.\n\nPre-v1.0.0 audit (P0) found this endpoint minted licenses that could never\npass /verify: the client signed `body_model_dump_for_signature(body)`,\nwhose `LicenseBody` schema has no `rules_text` field, while /verify always\nreconstructs the signed body via `license_model_dump_for_signature`, which\nunconditionally includes `\"rules_text\": \"\"`. Two different byte strings —\nevery license from this endpoint verified fine at MINT time (client and\nserver briefly agreed with each other) and then failed EVERY runtime check\nwith PG_INVALID_SIGNATURE forever after. A caller saw \"200 issued\" and had\na license nobody could ever use; nothing here caught it because mint-time\nverification never checked against what /verify would later reconstruct.\n\nFixed by routing through the same pipeline issue-presigned already uses:\nthe license row is built first, the subject's own rules checklist is\nmerged into it (the same additive/immutable treatment as every other mint\npath — see core/subject_rules.py), and the signed body is\nlicense_model_dump_for_signature(license) — the EXACT reconstruction\n/verify performs. A client whose signature doesn't anticipate the merge,\nor was computed the old (broken) way, now fails HERE with a clear 400\ninvalid-signature error instead of minting a license that looks issued\nbut is silently dead.","operationId":"issue_license_v1_licenses_issue_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseIssueRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"deprecated":true,"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/licenses/{license_id}":{"delete":{"tags":["licenses"],"summary":"Revoke License","operationId":"revoke_license_v1_licenses__license_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["licenses"],"summary":"Get License","operationId":"get_license_v1_licenses__license_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/{license_id}/breach":{"post":{"tags":["licenses"],"summary":"Report Breach","description":"Report that a generation went outside this licence, and choose what\nhappens next.\n\nTHE POINT, stated plainly because it is easy to mistake this for\nenforcement: /verify checks a DECLARED INTENTION before generation, never\nthe output. A determined caller can declare an allowed use and then prompt\nfor something else, and PRAMPTA will never see what came out. Prevention\nwas never the promise — the Terms say so too.\n\nWhat the licence actually gives the rights holder is a measuring stick. It\nrecords, signed and hash-chained, exactly what this licensee was permitted\nto do. So when they find something outside it, the breach is not an\nargument about intent; it is a comparison against a document the licensee\naccepted. This endpoint is where that comparison turns into a consequence.\n\nThree of them, because a registry whose only verb is \"ban\" is one nobody\ndares use on a customer they might want to keep:\n\n  notice  the licence keeps working; the holder is told what breached and\n          asked to correct it. This is the negotiation rung.\n  pause   generation stops while it is discussed. Reversible — PATCH the\n          status back to active.\n  revoke  terminated, through the same signed revocation record every\n          other withdrawal uses.\n\nWhatever the action, the report itself is recorded and audited, so a later\nrevocation can point at why rather than at a free-text field. That record\nis the evidence; the status change is only its effect.","operationId":"report_breach_v1_licenses__license_id__breach_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreachReport"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/{license_id}/status":{"patch":{"tags":["licenses"],"summary":"Set License Status","description":"Pause or revoke: subject side, operator, or licensee org admin.\nResume: subject side or operator only. Pauses have no stored source yet,\nso a licensee must not be able to clear a rights-holder's restriction.\n'paused' is reversible; 'revoked' is terminal.","operationId":"set_license_status_v1_licenses__license_id__status_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseStatusRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/{license_id}/revocations":{"post":{"tags":["licenses"],"summary":"Create Revocation","description":"Withdraw a licence, in whole or in part.\n\nA partial revocation (\"no longer provider ACME\", \"no longer commercial\")\nleaves the rest of the licence in force and is applied as an overlay at\nverify time — the signed body is never touched, because it cannot be. A\nfull revocation additionally retires the licence.","operationId":"create_revocation_v1_licenses__license_id__revocations_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevocationRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["licenses"],"summary":"List Revocations","description":"The licence's revocation timeline, oldest first. Rescinded entries are\nkept — 'withdrawn, then restored' is exactly the history F7 asked to keep.","operationId":"list_revocations_v1_licenses__license_id__revocations_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/{license_id}/revocations/{revocation_id}/rescind":{"post":{"tags":["licenses"],"summary":"Rescind Revocation","description":"Lift a PARTIAL revocation that was filed in error.\n\nA full revocation is terminal and cannot be rescinded — the licence is gone,\nmatching the existing 'revoked is terminal' rule. This does not delete the\nrecord: the original withdrawal genuinely happened, and its signature still\nproves it. The rescission is its own recorded act.","operationId":"rescind_revocation_v1_licenses__license_id__revocations__revocation_id__rescind_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}},{"name":"revocation_id","in":"path","required":true,"schema":{"type":"string","title":"Revocation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__licenses__RescindRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/":{"get":{"tags":["licenses"],"summary":"List Licenses","description":"List active licenses, scoped to what the caller may see. Operators see all;\nothers see licenses for subjects they control or held by their licensee ids.","operationId":"list_licenses_v1_licenses__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"query","required":false,"schema":{"type":"string","title":"Subject Id"}},{"name":"licensee_id","in":"query","required":false,"schema":{"type":"string","title":"Licensee Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/held":{"get":{"tags":["licenses"],"summary":"Held Licenses","description":"Licenses granted TO the current workspace (licensee side).\n\nWorking as an organization: the licences the organization holds. Working\npersonally: the person's own licensee identities. Plus any groups those\nidentities belong to — with usage/remaining for volume-capped licenses and\nexpiry. (It used to merge the personal account with every organization\nthe person belongs to, so each workspace showed the other's licences —\nthe workspace audit of 2026-09-25.)","operationId":"held_licenses_v1_licenses_held_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/{license_id}/proof":{"get":{"tags":["licenses"],"summary":"Get License Proof","description":"Public proof of one license — no login. This is what a THIRD PARTY\nresolves: a lawyer, a platform, a stranger checking a citation, none of\nwhom are a party to the deal and so could never pass get_license's\n`allowed` check above. Deliberately narrow (founder call, 2026-08-20):\nclass + subject + status + validity window is what proves the license is\nreal and what it covers — not who holds it or what they're using it for.\nEverything else (`_license_detail`'s licensee_id/product_name/purpose/\nproject_name/...) stays behind the authed endpoint above.\n\n2026-09-10: scope and the two denial lists joined that list. They describe\nthe PERMISSION, not the party — which is precisely what a third party\nresolving this citation is trying to establish, and the subject's own\npublic certificate already publishes the owner's denials anyway. Without\nthem the proof page can say a licence is active but not what it lets\nanyone do, which makes its own disclaimer (\"covers the uses recorded\nabove and nothing else\") point at nothing.","operationId":"get_license_proof_v1_licenses__license_id__proof_get","parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/{license_id}/receipts":{"get":{"tags":["licenses"],"summary":"License Receipts","description":"Generation history for a licence (Phase 3 §9 My Licenses).\n\nSame visibility rule as get_license — a holder needs to see what was\nactually generated against their purchase, and a rights holder needs to\nsee what was generated against their subject.","operationId":"license_receipts_v1_licenses__license_id__receipts_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/issue-presigned":{"post":{"tags":["licenses"],"summary":"Issue Presigned","description":"Issue a license using a client-side pre-computed Ed25519 signature.\n\nFlow:\n1. Client generates canonical JSON of license body\n2. Client signs with subject's Ed25519 private key (WebCrypto)\n3. Client submits body + signature_hex here\n4. Server verifies signature against registered public key\n5. Server countersigns and stores license","operationId":"issue_presigned_v1_licenses_issue_presigned_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuePresignedRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/licenses/lint":{"post":{"tags":["licenses"],"summary":"Lint License Policy","description":"Pre-issuance check: warn about rules_text terms that won't be enforced at\nruntime because they're not in the structured policy. Advisory only.","operationId":"lint_license_policy_v1_licenses_lint_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LintRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/licenses/sign-and-issue":{"post":{"tags":["licenses"],"summary":"Sign And Issue","description":"DEPRECATED: Use /licenses/issue-presigned instead.\nThis endpoint accepts raw private keys and is only available in development.","operationId":"sign_and_issue_v1_licenses_sign_and_issue_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignAndIssueRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"deprecated":true,"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/licenses/{license_id}/exceptions":{"post":{"tags":["license-exceptions"],"summary":"Create Exception","description":"Add an exception to a license (requires subject signature).","operationId":"create_exception_v1_licenses__license_id__exceptions_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExceptionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["license-exceptions"],"summary":"List Exceptions","description":"List all active exceptions for a license.\n\nSame visibility rule as GET /licenses/{id}: the operator, the subject side\n(owner / org-admin), or the holding licensee side. Exceptions are contract\nstate — not a public listing.","operationId":"list_exceptions_v1_licenses__license_id__exceptions_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ExceptionResponse"},"title":"Response List Exceptions V1 Licenses  License Id  Exceptions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/licenses/{license_id}/exceptions/{exception_id}":{"delete":{"tags":["license-exceptions"],"summary":"Revoke Exception","description":"Revoke an exception.\n\nOnly the granting side may take it back: the subject's owner (who signed\nthe exception into existence) or an operator. A licensee cannot revoke —\nand, before this check existed, neither should any random logged-in user.","operationId":"revoke_exception_v1_licenses__license_id__exceptions__exception_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"license_id","in":"path","required":true,"schema":{"type":"string","title":"License Id"}},{"name":"exception_id","in":"path","required":true,"schema":{"type":"string","title":"Exception Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-requests/":{"post":{"tags":["license-requests"],"summary":"Create License Request","description":"Create a license request to a subject.","operationId":"create_license_request_v1_license_requests__post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLicenseRequestBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["license-requests"],"summary":"List License Requests","description":"List license requests visible to current user.\n\nOnly shows requests where user is the requester OR owns the subject.","operationId":"list_license_requests_v1_license_requests__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LicenseRequestResponse"},"title":"Response List License Requests V1 License Requests  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-requests/{request_id}":{"get":{"tags":["license-requests"],"summary":"Get License Request","operationId":"get_license_request_v1_license_requests__request_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["license-requests"],"summary":"Resolve License Request","description":"Approve or reject a license request (subject owner action).\n\nOnly the user who owns the subject can approve/reject requests.","operationId":"resolve_license_request_v1_license_requests__request_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveLicenseRequestBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-requests/{request_id}/issue-presigned":{"post":{"tags":["license-requests"],"summary":"Issue License For Request","description":"Approve a license request and issue the signed license for it.\n\nThe subject or delegated org private key still signs client-side. This\nendpoint verifies that signature, stores the license, marks the request as\nlicensed, and returns a Movie-safe redirect URL only after verify can pass.","operationId":"issue_license_for_request_v1_license_requests__request_id__issue_presigned_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueLicenseRequestBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueLicenseRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-requests/{request_id}/approve":{"post":{"tags":["license-requests"],"summary":"Approve License Request","description":"Approve a (direct, non-connected) license request and mint its signed\nlicense — to the requester's personal licensee, with terms from the requested\nuse case. Managed subjects sign server-side (one tap); self-custody subjects\nmust include subject_signature_hex. Owner-only.","operationId":"approve_license_request_v1_license_requests__request_id__approve_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveRequestBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-requests/{request_id}/counter":{"post":{"tags":["license-requests"],"summary":"Counter License Request","description":"Propose a different price on a request under negotiation.\n\nWhoever did NOT make the CURRENT proposal may counter. The opening offer\n(at creation) counts as proposal #1 — up to 3 total; once the 3rd has\nbeen made, this 409s and the request can only be accepted or declined\n(see respond_to_negotiation), never countered again.","operationId":"counter_license_request_v1_license_requests__request_id__counter_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CounterOfferBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-requests/{request_id}/respond":{"post":{"tags":["license-requests"],"summary":"Respond To Negotiation","description":"Accept or decline the CURRENT proposed price on a negotiation.\n\nWhoever did NOT make the current proposal may respond. Accepting opens a\npayable Quote at that price — same downstream pipeline as an ordinary\nrequest_then_buy approval (api/priced_offers.py::_build_quote) — via a\none-off PricedOffer scoped to exactly this negotiated deal, since there\nis no owner-published tier price to quote against.","operationId":"respond_to_negotiation_v1_license_requests__request_id__respond_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NegotiationResponseBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/verify/":{"post":{"tags":["verify"],"summary":"Verify","operationId":"verify_v1_verify__post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":false,"schema":{"type":"string","maxLength":255,"default":"","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Prampta-Expected-Schema-Version","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Prampta-Expected-Schema-Version"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedDecision"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/verify/check-nonce":{"post":{"tags":["verify"],"summary":"Check Nonce","description":"Check if a decision nonce was consumed (issued by this server).\n\nRequires valid pair auth to prevent unauthenticated enumeration.\nReturns consumed=True if the nonce was legitimately issued.","operationId":"check_nonce_v1_verify_check_nonce_post","parameters":[{"name":"nonce","in":"query","required":true,"schema":{"type":"string","title":"Nonce"}},{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pairs/establish":{"post":{"tags":["pairs"],"summary":"Establish Pair","description":"Initiate or immediately establish a pair between provider and licensee orgs.\n\nIf both orgs exist and the user is a member of one:\n- If user belongs to BOTH orgs → pair activated immediately (self-pair)\n- If user belongs to ONE org → pair created as pending, counterparty must confirm\n\nLegacy behavior: if orgs don't exist yet, creates pair directly (for backward compat).\nThis will be removed once org migration is complete.","operationId":"establish_pair_v1_pairs_establish_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PairInitiateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/pairs/{pair_id}/confirm":{"patch":{"tags":["pairs"],"summary":"Confirm Pair","description":"Confirm a pending pair request. Must be a member of the counterparty org.\n\nReturns the pair access token upon successful confirmation.","operationId":"confirm_pair_v1_pairs__pair_id__confirm_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"pair_id","in":"path","required":true,"schema":{"type":"string","title":"Pair Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pairs/{pair_id}/reject":{"patch":{"tags":["pairs"],"summary":"Reject Pair","description":"Reject a pending pair request.","operationId":"reject_pair_v1_pairs__pair_id__reject_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"pair_id","in":"path","required":true,"schema":{"type":"string","title":"Pair Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pairs/{pair_id}/rotate-token":{"patch":{"tags":["pairs"],"summary":"Rotate Pair Token","description":"Rotate an active pair token.\n\nPair tokens are only shown once and only their SHA-256 hash is stored. This\nendpoint invalidates the previous token and returns the new token once.","operationId":"rotate_pair_token_v1_pairs__pair_id__rotate_token_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"pair_id","in":"path","required":true,"schema":{"type":"string","title":"Pair Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pairs/{pair_id}":{"delete":{"tags":["pairs"],"summary":"Revoke Pair","description":"Revoke an active pair. Must be a member of either org.","operationId":"revoke_pair_v1_pairs__pair_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"pair_id","in":"path","required":true,"schema":{"type":"string","title":"Pair Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pairs/":{"get":{"tags":["pairs"],"summary":"List Pairs","description":"List pairs visible to the current user (must be member of at least one org).","operationId":"list_pairs_v1_pairs__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pairs/pending":{"get":{"tags":["pairs"],"summary":"List Pending Pairs","description":"List pending pair requests that the current user can confirm.","operationId":"list_pending_pairs_v1_pairs_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/opt-outs/register":{"post":{"tags":["opt-outs"],"summary":"Register Opt Out","operationId":"register_opt_out_v1_opt_outs_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptOutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/opt-outs/{subject_id}":{"delete":{"tags":["opt-outs"],"summary":"Rescind Opt Out","description":"Rescind an active opt-out. Requires the subject owner/operator OR a valid\nsubject signature — an opt-out is consent and cannot be lifted by anyone.","operationId":"rescind_opt_out_v1_opt_outs__subject_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/app__api__opt_outs__RescindRequest"},{"type":"null"}],"title":"Req"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/opt-outs/register-presigned":{"post":{"tags":["opt-outs"],"summary":"Register Presigned Opt Out","description":"Register opt-out using a client-side pre-computed signature.","operationId":"register_presigned_opt_out_v1_opt_outs_register_presigned_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterPresignedOptOutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/opt-outs/sign-and-register":{"post":{"tags":["opt-outs"],"summary":"Sign And Register Opt Out","description":"DEPRECATED: Use /opt-outs/register-presigned instead.\nThis endpoint accepts raw private keys and is only available in development.","operationId":"sign_and_register_opt_out_v1_opt_outs_sign_and_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignAndRegisterOptOutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"deprecated":true,"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/crypto/generate-keypair":{"post":{"tags":["crypto"],"summary":"Generate Keypair","description":"DEPRECATED: Development-only endpoint. Hands out a real Ed25519\nprivate key to anyone who calls it, unauthenticated — allow-listed to\nENVIRONMENT == \"development\" specifically (not merely \"not production\"),\nsame convention as the other raw-private-key dev endpoint\n(api/licenses.py::sign_and_issue). The old check only blocked\nENVIRONMENT == \"production\" — a staging or any other non-dev/non-prod\nenvironment would have left this live (security-audit finding,\n2026-08-23).","operationId":"generate_keypair_v1_crypto_generate_keypair_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"deprecated":true}},"/v1/stats/":{"get":{"tags":["stats"],"summary":"Get Stats","operationId":"get_stats_v1_stats__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}}}}},"/v1/audit/mine":{"get":{"tags":["audit"],"summary":"Get My Audit","description":"Account-scoped activity log — only events tied to the current user.","operationId":"get_my_audit_v1_audit_mine_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/audit/":{"get":{"tags":["audit"],"summary":"Get Audit","operationId":"get_audit_v1_audit__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"action","in":"query","required":false,"schema":{"type":"string","title":"Action"}},{"name":"entity_type","in":"query","required":false,"schema":{"type":"string","title":"Entity Type"}},{"name":"entity_id","in":"query","required":false,"schema":{"type":"string","title":"Entity Id"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/audit/verify-chain":{"get":{"tags":["audit"],"summary":"Verify Chain","description":"Verify the tamper-evident hash chain and operator signatures.\n\nBounded to the most recent `limit` events (not the unbounded full chain) so it\ncan't be used as a DoS lever; operators can page further with `limit`.","operationId":"verify_chain_v1_audit_verify_chain_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20000,"minimum":1,"default":5000,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/audit/bundle":{"get":{"tags":["audit"],"summary":"Audit Bundle","description":"Export a self-contained, operator-signed audit bundle for a subject so a\nthird party can independently verify: license signatures, the hash-chained\naudit slice, generation receipts, and the operator key history needed to\ncheck every signature. See docs/trust-layer-gaps-plan.md (gap 4).","operationId":"audit_bundle_v1_audit_bundle_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"query","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/audit/anchor":{"post":{"tags":["audit"],"summary":"Create Anchor","description":"Compute and sign a new Merkle root over every audit event so far.\n\nThe ROOT commits to every event ever recorded (unchanged) — but STORAGE\nis incremental: this anchor's own `leaf_event_ids` holds only events\nnever claimed by an earlier anchor (`merkle_anchor_id IS NULL`), chained\nto the previous anchor via `previous_anchor_id`, so total storage across\nall anchors stays O(N) instead of O(N²) as both N and the number of\nanchors taken over time grow. See MerkleAnchor's docstring.\n\n\"At a defined interval\" (§10) is an operations decision, not a protocol\none — this is the mechanism a scheduled job (or an operator, ad hoc)\ncalls on that cadence; nothing here enforces a cadence itself, and\nnothing here guards against two overlapping calls (anchoring is an\ninfrequent admin/cron action, not a concurrent hot path).\n\nGap, stated plainly rather than silently: §10 also requires the signed\nroot be \"published to an external location not controlled solely by the\nregistry operator\" (a public log, a second party, a blockchain — anything\nthat isn't just this database). No such publication exists yet —\n`published_at`/`published_location` stay null until it does. Signing and\nstoring the root is real and load-bearing (it's what an inclusion proof\nverifies against); the missing piece is making that root reach somewhere\nan operator alone cannot quietly edit.","operationId":"create_anchor_v1_audit_anchor_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/audit/merkle-root":{"get":{"tags":["audit"],"summary":"Get Merkle Root","description":"The most recently anchored root — public and unauthenticated, same as\nthe operator's key at /version: a root is only useful as a check if\nanyone can fetch it without asking the registry's permission first.","operationId":"get_merkle_root_v1_audit_merkle_root_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/audit/inclusion-proof/{event_id}":{"get":{"tags":["audit"],"summary":"Get Inclusion Proof","description":"Proof that `event_id` is one of the leaves committed to by a published\nroot, without the caller downloading the rest of the log. Also public —\nan inclusion proof is worthless as independent evidence if only the\nregistry can produce or check it.","operationId":"get_inclusion_proof_v1_audit_inclusion_proof__event_id__get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/audit/evidence/{decision_id}":{"get":{"tags":["audit"],"summary":"Get Decision Evidence","description":"A self-contained, signed archive for ONE decision — litigation/\ncompliance review (§10), scoped narrower than /bundle's per-subject\nexport. Contains the decision itself, the license it resolved against (if\nany), every audit event tied to it, an inclusion proof when one exists,\nand the operator key material needed to check every signature offline.","operationId":"get_decision_evidence_v1_audit_evidence__decision_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"decision_id","in":"path","required":true,"schema":{"type":"string","title":"Decision Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/register":{"post":{"tags":["auth"],"summary":"Register","operationId":"register_v1_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/login":{"post":{"tags":["auth"],"summary":"Login","operationId":"login_v1_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/login/2fa":{"post":{"tags":["auth"],"summary":"Login 2Fa","description":"Completes a login that /auth/login paused for 2FA.\n\nThe mfa_token is burned here unconditionally, on the FIRST attempt,\nwhether the code turns out right or wrong — deliberately one shot, not\n\"keep guessing until the 5-minute TTL expires\". A wrong code means\nstarting over from /auth/login (a fresh password check). This costs a\nlegitimate user a re-entered password on a typo, in exchange for a\nstolen/intercepted mfa_token being worth exactly one guess. It stacks\nwith, not instead of, the account-level lockout below — that one still\nlimits how many *separate* login attempts (each with its own token) an\naccount gets per window.","operationId":"login_2fa_v1_auth_login_2fa_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Login2FARequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/me":{"get":{"tags":["auth"],"summary":"Me","operationId":"me_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/auth/me/avatar":{"put":{"tags":["auth"],"summary":"Update Avatar","description":"Set the current user's profile picture (data URL) or clear it (empty string).","operationId":"update_avatar_v1_auth_me_avatar_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/auth/me/preferences":{"put":{"tags":["auth"],"summary":"Update Preferences","description":"Toggle whether the consequential subset of notifications also emails\nthe user (core/notify.py::CONSEQUENTIAL_EMAIL_TYPES). In-app notifications\nare unaffected either way.","operationId":"update_preferences_v1_auth_me_preferences_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/auth/me/username":{"put":{"tags":["auth"],"summary":"Update Username","description":"Change the current user's @username. Auth is by user id, so the existing\nsession token keeps working.","operationId":"update_username_v1_auth_me_username_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsernameUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/auth/google":{"post":{"tags":["auth"],"summary":"Google Auth","description":"Authenticate via Google OAuth2. Creates account if first login.","operationId":"google_auth_v1_auth_google_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleAuthRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/github":{"post":{"tags":["auth"],"summary":"Github Auth","description":"Authenticate via GitHub OAuth. Creates account if first login.\n\nUnlike Google, GitHub has no client-side token-popup SDK — a GitHub\nOAuth App is a confidential client (it has a secret), so the only\ncorrect flow is: browser redirects to GitHub's authorize screen,\nGitHub redirects back to OUR callback with a one-time `code`, and only\nTHIS endpoint (server-side, holding GITHUB_CLIENT_SECRET) exchanges it\nfor a token. There is no access_token-direct variant the way Google's\nendpoint has, because GitHub never hands a token to the browser at all.","operationId":"github_auth_v1_auth_github_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubAuthRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/refresh":{"post":{"tags":["auth"],"summary":"Refresh","description":"Rotate a refresh token: consumes the old one, returns new access+refresh.\n\nReuse of an already-consumed token revokes all of the user's sessions.","operationId":"refresh_v1_auth_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","description":"Revoke a refresh token. Idempotent — unknown tokens still return ok.","operationId":"logout_v1_auth_logout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/change-password":{"post":{"tags":["auth"],"summary":"Change Password","description":"Change the password while signed in (Settings → Security). Asks for the\ncurrent one — a session left open on someone else's screen must not be\nenough to lock its owner out. Every other session ends.","operationId":"change_password_v1_auth_change_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/auth/logout-everywhere":{"post":{"tags":["auth"],"summary":"Logout Everywhere","description":"Sign out every other device at once (Settings → Security) — the answer\nto \"I signed in on a friend's laptop\" or a lost phone.","operationId":"logout_everywhere_v1_auth_logout_everywhere_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/auth/request-email-verification":{"post":{"tags":["auth"],"summary":"Request Email Verification","description":"(Re)send the email verification link for the logged-in user.","operationId":"request_email_verification_v1_auth_request_email_verification_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/auth/verify-email":{"post":{"tags":["auth"],"summary":"Verify Email","operationId":"verify_email_v1_auth_verify_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/request-password-reset":{"post":{"tags":["auth"],"summary":"Request Password Reset","description":"Send a password reset link. Always returns ok — no account enumeration.","operationId":"request_password_reset_v1_auth_request_password_reset_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/reset-password":{"post":{"tags":["auth"],"summary":"Reset Password","operationId":"reset_password_v1_auth_reset_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirm"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/account":{"delete":{"tags":["auth"],"summary":"Delete Account","description":"Step 1 of 3: request deletion. Sends an email; changes nothing else.\n\n2026-08(b) redesign — a stolen session token used to be enough on its own\nto instantly and irreversibly erase an account, since the confirm phrase\nis visible right there in the UI, not a secret. This endpoint no longer\ndeletes anything: it emails a confirmation link, which is the part an\nattacker holding only a session typically can't also produce. See\ncore/account_deletion.py for the full three-step design (request ->\nconfirm -> the actual, still-cancellable-for-30-days grace period ->\nfinalize) and exactly what survives finalization.\n\nNote this is NOT gated on require_2fa: erasure is a right, and making\npeople first enable TOTP to exercise it would be a dark pattern. 2FA IS\nrequired as part of the phrase+code check below when the account\nalready has it on — that account already opted into the higher bar.","operationId":"delete_account_v1_auth_account_delete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/auth/account/confirm-deletion":{"post":{"tags":["auth"],"summary":"Confirm Deletion Endpoint","description":"Step 2 of 3: the email link lands here. Public (token-gated, like\n/verify-email and /reset-password) — proving mailbox access IS the\nauthentication for this step, a session isn't required or checked.","operationId":"confirm_deletion_endpoint_v1_auth_account_confirm_deletion_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmDeletionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/account/cancel-deletion":{"post":{"tags":["auth"],"summary":"Cancel Deletion Endpoint","description":"Step out of the grace period: logging back in (this needs a fresh\nsession, since confirm_deletion revokes every refresh token) and calling\nthis restores exactly what confirm_deletion paused.","operationId":"cancel_deletion_endpoint_v1_auth_account_cancel_deletion_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/webhooks/":{"post":{"tags":["webhooks"],"summary":"Create Webhook","description":"Register a webhook URL for a pair. Returns signing secret (shown once).","operationId":"create_webhook_v1_webhooks__post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["webhooks"],"summary":"List Webhooks","description":"List webhooks for a pair (only those owned by the current user).","operationId":"list_webhooks_v1_webhooks__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"pair_id","in":"query","required":true,"schema":{"type":"string","title":"Pair Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookListItem"},"title":"Response List Webhooks V1 Webhooks  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/webhooks/{webhook_id}":{"delete":{"tags":["webhooks"],"summary":"Delete Webhook","description":"Delete a webhook. Only the owner can delete it.","operationId":"delete_webhook_v1_webhooks__webhook_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","title":"Webhook Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/linked-accounts/known-providers":{"get":{"tags":["linked-accounts"],"summary":"List Known Providers","description":"Public, unauthenticated — the small operator-curated allowlist a\nConnect AI redirect's self-reported `connect_provider` id can be checked\nagainst.\n\n2026-08(h): exists for /redirected (the AI-provider-redirect landing\npage a logged-out user lands on) to show \"recognized integration\" only\nfor a provider PRAMPTA's own team put on this list — never for the\narbitrary `connect_provider_name`/`connect_provider_domain` query\nparams a redirect can set to literally anything (see _provider_\ndisplay_name/_provider_domain above, which trust the caller-supplied\nname when one is given). Without this distinction, a nicer-looking\nlanding page would make an unverified redirect look MORE credible, not\nless — the opposite of what it's for. Nothing sensitive in this\nresponse; it's the same dict already defined above, just readable by\nthe frontend instead of drifting into a second hardcoded copy there.","operationId":"list_known_providers_v1_linked_accounts_known_providers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/linked-accounts/":{"get":{"tags":["linked-accounts"],"summary":"List Linked Accounts","operationId":"list_linked_accounts_v1_linked_accounts__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["linked-accounts"],"summary":"Link Account","operationId":"link_account_v1_linked_accounts__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/linked-accounts/{account_id}":{"delete":{"tags":["linked-accounts"],"summary":"Unlink Account","operationId":"unlink_account_v1_linked_accounts__account_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/connect-ai/exchange-code":{"post":{"tags":["connect-ai"],"summary":"Exchange Connect Code","description":"Exchange a browser callback code for the user's service pair token.","operationId":"exchange_connect_code_v1_connect_ai_exchange_code_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Provider-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Provider-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeCodeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/connect-ai/providers":{"get":{"tags":["connect-ai"],"summary":"List Directory Providers","description":"Public directory.\n\n`environment=production` (default) returns only providers people can\nactually connect: listed, verified, and on Connect Step 2\n(core/provider_trust.py — founder, 2026-09-25; a suspended provider is no\nlonger shown, and its users see the connection ended). `environment=sandbox`\nreturns the separately-labelled sandbox integrations. Unlisted providers\nare never returned by either — that is what \"unlisted\" means.","operationId":"list_directory_providers_v1_connect_ai_providers_get","parameters":[{"name":"environment","in":"query","required":false,"schema":{"type":"string","default":"production","title":"Environment"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/connect-ai/providers/{provider_id}":{"get":{"tags":["connect-ai"],"summary":"Get Directory Provider","operationId":"get_directory_provider_v1_connect_ai_providers__provider_id__get","parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/connect-ai/providers/{provider_id}/capabilities":{"get":{"tags":["connect-ai"],"summary":"Get Directory Provider Capabilities","operationId":"get_directory_provider_capabilities_v1_connect_ai_providers__provider_id__capabilities_get","parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/connect-ai/admin/directory/{provider_id}":{"patch":{"tags":["connect-ai"],"summary":"Update Directory Listing","description":"Operator: list/unlist and edit PRESENTATION only.\n\nTrust-bearing fields (verified_badge, trust_tier) are intentionally NOT\neditable here — they are synced from the granting application, so the badge\na user sees cannot be hand-forged. This endpoint moves an approved provider\nbetween listed/unlisted/sandbox and edits its tagline, logo and capability\nlabels.","operationId":"update_directory_listing_v1_connect_ai_admin_directory__provider_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectoryListingUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/":{"post":{"tags":["organizations"],"summary":"Create Organization","description":"Create a new organization. Creator becomes owner.\n\nRequires 2FA (require_2fa): an org can act as a provider/licensee, sign\nlicenses with a delegated key, and add other members — an account with\nthat much reach shouldn't rest on a password alone.","operationId":"create_organization_v1_organizations__post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrgRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["organizations"],"summary":"List Organizations","description":"List active organizations.","operationId":"list_organizations_v1_organizations__get","parameters":[{"name":"org_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/my/contexts":{"get":{"tags":["organizations"],"summary":"My Contexts","description":"Contexts the user can act as: personal + real (standard) orgs they belong to.\n\nAuto-provisioned identities (personal-licensee, Connect-AI service providers)\nare excluded — they are infrastructure, not selectable contexts.","operationId":"my_contexts_v1_organizations_my_contexts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/organizations/my/acting":{"get":{"tags":["organizations"],"summary":"My Acting Context","description":"Echo the validated acting context for the current X-Org-Context header.\n\nReturns the personal context when no (or empty) header is sent; 400/403 if\nthe header references an invalid org or one the user doesn't belong to.","operationId":"my_acting_context_v1_organizations_my_acting_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/my/verified":{"get":{"tags":["organizations"],"summary":"My Verified Org","description":"Capability check: 200 only when acting as a domain-verified org.\n\nThe frontend uses this to gate verified-org-only features. Returns 403 when\nacting personally or as an unverified org.","operationId":"my_verified_org_v1_organizations_my_verified_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/my/invitations":{"get":{"tags":["organizations"],"summary":"My Invitations","description":"Invitations waiting for this person's answer.","operationId":"my_invitations_v1_organizations_my_invitations_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/organizations/invitations/{invitation_id}/accept":{"post":{"tags":["organizations"],"summary":"Accept Invitation","operationId":"accept_invitation_v1_organizations_invitations__invitation_id__accept_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"invitation_id","in":"path","required":true,"schema":{"type":"string","title":"Invitation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/invitations/{invitation_id}/decline":{"post":{"tags":["organizations"],"summary":"Decline Invitation","operationId":"decline_invitation_v1_organizations_invitations__invitation_id__decline_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"invitation_id","in":"path","required":true,"schema":{"type":"string","title":"Invitation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/my/memberships":{"get":{"tags":["organizations"],"summary":"My Organizations","description":"List organizations the current user belongs to.","operationId":"my_organizations_v1_organizations_my_memberships_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/organizations/{org_id}":{"get":{"tags":["organizations"],"summary":"Get Organization","description":"Get organization details. Unauthenticated — this is what the public\norg storefront page (/org/@orgname) reads, same as the Library reading\nan unauthenticated subject listing.\n\n404s for `kind != \"standard\"` (personal auto-licensee identities, Connect\nAI's auto-created service orgs) exactly as if they didn't exist: those\naren't real, user-managed entities and were never meant to be a browsable\nidentity — the only existing caller (OrgSettings.tsx) only ever fetches\nan org the user actually manages, which is always `standard`, so this\ncan't break it.","operationId":"get_organization_v1_organizations__org_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["organizations"],"summary":"Update Organization","description":"Update editable org fields (admin+). Used to set the domain before\nverification. A verified domain cannot be changed.","operationId":"update_organization_v1_organizations__org_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrgRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/avatar":{"put":{"tags":["organizations"],"summary":"Update Organization Avatar","description":"Set (data URL) or clear (\"\") the organization's picture. Admin+.","operationId":"update_organization_avatar_v1_organizations__org_id__avatar_put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgAvatarRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/signing-key":{"post":{"tags":["organizations"],"summary":"Set Signing Key","description":"Retired (2026-08): an org-held delegated signing key let every subject\nbulk-registered under it sign new licences with zero PRAMPTA involvement\n— the same disintermediation risk per-subject self-custody carried, at\norg scale instead of one subject at a time. See register_subject's\ndocstring in app/api/subjects/registration.py for the full reasoning.\nbulk_register_subjects below no longer needs this — it mints each\nsubject its own managed key, same as ordinary registration.","operationId":"set_signing_key_v1_organizations__org_id__signing_key_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigningKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/signing-key/rotate":{"post":{"tags":["organizations"],"summary":"Rotate Signing Key","description":"Retired along with set_signing_key (2026-08) — see its docstring.\nKept reachable only for whatever legacy org already has a key set (there\nis no way to acquire one going forward), same test-only exception.\n\nProves possession of the NEW key only — you can't prove a lost/compromised\nold key, and requiring it would block rotation exactly when it's needed.\nSubjects bound to the old org key are repointed to the new key so FUTURE\nlicenses sign with it; already-issued licenses keep verifying against their\nsnapshotted key, so nothing in circulation breaks.","operationId":"rotate_signing_key_v1_organizations__org_id__signing_key_rotate_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateSigningKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/trusted-issuer":{"patch":{"tags":["organizations"],"summary":"Set Trusted Issuer","description":"Mark an organization as a trusted issuer (KYB / contracted partner).\n\nOperator-only — this is the out-of-band KYB decision made when a partner\n(e.g. a talent agency) signs a contract. A trusted issuer's bulk\nregistrations auto-activate (reserved / high-profile names still reviewed).","operationId":"set_trusted_issuer_v1_organizations__org_id__trusted_issuer_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustedIssuerRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/subjects/bulk":{"post":{"tags":["organizations"],"summary":"Bulk Register Subjects","description":"Register many subjects at once. Each one gets its own PRAMPTA-managed\nkey, exactly like an ordinary registration — the bulk value is doing it\nfor many subjects in one call, not a shared org key (that delegated-key\ndesign is retired, see set_signing_key's docstring: it let every subject\nunder it sign new licences with zero PRAMPTA involvement).\n\nRequires: admin role, a domain-verified org.","operationId":"bulk_register_subjects_v1_organizations__org_id__subjects_bulk_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkRegisterRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/portfolio":{"get":{"tags":["organizations"],"summary":"Agency Portfolio","description":"The agency's talent in one list (P2): every subject the org holds or\nrepresents, who owns it now, the mandate and whether the talent's signed\nconsent checks out, live licences and requests still waiting.\nAdmins of the org only.","operationId":"agency_portfolio_v1_organizations__org_id__portfolio_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/members":{"get":{"tags":["organizations"],"summary":"List Members","description":"List organization members. Must be a member to see.","operationId":"list_members_v1_organizations__org_id__members_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["organizations"],"summary":"Invite Member","description":"Invite someone to the organization (admin+). They join when they\naccept (founder, 2026-09-25) — nobody is put into a team unasked.","operationId":"invite_member_v1_organizations__org_id__members_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__organizations__InviteMemberRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/invitations/{invitation_id}":{"delete":{"tags":["organizations"],"summary":"Cancel Invitation","operationId":"cancel_invitation_v1_organizations__org_id__invitations__invitation_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}},{"name":"invitation_id","in":"path","required":true,"schema":{"type":"string","title":"Invitation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/members/{username}":{"delete":{"tags":["organizations"],"summary":"Remove Member","description":"Remove a member from the organization. Requires admin+ role.","operationId":"remove_member_v1_organizations__org_id__members__username__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}},{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["organizations"],"summary":"Change Member Role","description":"Change a member's role. Admin+; the owner's role only changes by\nhanding the organization over (transfer-ownership).","operationId":"change_member_role_v1_organizations__org_id__members__username__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}},{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberRoleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/transfer-ownership":{"post":{"tags":["organizations"],"summary":"Transfer Ownership","description":"The owner hands the organization to one of its admins and stays on as\nan admin. Only to an existing admin, so the admin count never grows.","operationId":"transfer_ownership_v1_organizations__org_id__transfer_ownership_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferOwnershipRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/verify-domain/initiate":{"post":{"tags":["organizations"],"summary":"Initiate Domain Verification","description":"Initiate DNS TXT domain verification.\n\nReturns a token that must be set as a DNS TXT record:\n  _prampta-verify.example.com  TXT  \"prampta-verify=<token>\"\n\nChallenge expires after 72 hours.","operationId":"initiate_domain_verification_v1_organizations__org_id__verify_domain_initiate_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/verify-domain/confirm":{"post":{"tags":["organizations"],"summary":"Confirm Domain Verification","description":"Confirm domain verification by checking DNS TXT record.\n\nLooks up the _prampta-verify TXT record and compares to the pending challenge.","operationId":"confirm_domain_verification_v1_organizations__org_id__verify_domain_confirm_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/":{"get":{"tags":["groups"],"summary":"List Groups","description":"List groups owned by the current user.","operationId":"list_groups_v1_groups__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["groups"],"summary":"Create Group","description":"Create a license group. Its id is used as the licensee_id of the\nsubject-signed group license.","operationId":"create_group_v1_groups__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGroupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/groups/my-memberships":{"get":{"tags":["groups"],"summary":"My Memberships","description":"Groups the current user has joined (as a member, not owner) — so an\ninvitee who accepted sees the groups they belong to.","operationId":"my_memberships_v1_groups_my_memberships_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/groups/{group_id}/members":{"get":{"tags":["groups"],"summary":"List Members","description":"List active and pending-invite members of a group (owner only).","operationId":"list_members_v1_groups__group_id__members_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["groups"],"summary":"Add Member","description":"Add a licensee identity to the group (owner only).","operationId":"add_member_v1_groups__group_id__members_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddMemberRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}/invite":{"post":{"tags":["groups"],"summary":"Invite Member","description":"Invite a PRAMPTA user to the group by @username. They get a notification\nand only join once they accept — the owner never adds someone silently.","operationId":"invite_member_v1_groups__group_id__invite_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__groups__InviteMemberRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/invitations/{membership_id}/respond":{"post":{"tags":["groups"],"summary":"Respond To Invite","description":"The invited user accepts or declines a group invitation. Only the invitee\n(the licensee identity the invite was addressed to) may respond.","operationId":"respond_to_invite_v1_groups_invitations__membership_id__respond_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"membership_id","in":"path","required":true,"schema":{"type":"string","title":"Membership Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RespondInviteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}/members/{member_licensee_id}":{"delete":{"tags":["groups"],"summary":"Revoke Member","description":"Revoke a member's access (owner only). Takes effect immediately at verify.","operationId":"revoke_member_v1_groups__group_id__members__member_licensee_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"member_licensee_id","in":"path","required":true,"schema":{"type":"string","title":"Member Licensee Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}/overrides":{"post":{"tags":["groups"],"summary":"Set Member Override","description":"Set a RESTRICT-ONLY narrowing override for a member (owner only).\n\nOverrides can only tighten the group license (drop modalities, add denied\ncategories, earlier expiry). They cannot grant anything new.","operationId":"set_member_override_v1_groups__group_id__overrides_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberOverrideRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["groups"],"summary":"List Overrides","description":"List active per-member overrides for a group (owner only).","operationId":"list_overrides_v1_groups__group_id__overrides_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}/overrides/{member_licensee_id}":{"delete":{"tags":["groups"],"summary":"Remove Override","description":"Remove a member's override (owner only) — restores full group license.","operationId":"remove_override_v1_groups__group_id__overrides__member_licensee_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"member_licensee_id","in":"path","required":true,"schema":{"type":"string","title":"Member Licensee Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-offers/":{"get":{"tags":["license-offers"],"summary":"List Offers","description":"List offers created by the current user.","operationId":"list_offers_v1_license_offers__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["license-offers"],"summary":"Create Offer","description":"Create a shareable offer for a group. Returns the share token ONCE.","operationId":"create_offer_v1_license_offers__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOfferRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/license-offers/claim/{token}":{"post":{"tags":["license-offers"],"summary":"Claim Offer","description":"Request access via a share link. Creates a pending claim (or auto-approves\nfor a trusted domain). Never grants access silently without owner consent.","operationId":"claim_offer_v1_license_offers_claim__token__post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-offers/claims/{claim_id}":{"patch":{"tags":["license-offers"],"summary":"Resolve Claim","description":"Approve or reject a pending claim. Only the offer owner can resolve it.","operationId":"resolve_claim_v1_license_offers_claims__claim_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveClaimRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-offers/{offer_id}/claims":{"get":{"tags":["license-offers"],"summary":"List Claims","description":"List claims on an offer (owner only).","operationId":"list_claims_v1_license_offers__offer_id__claims_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"offer_id","in":"path","required":true,"schema":{"type":"string","title":"Offer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/license-offers/{offer_id}":{"patch":{"tags":["license-offers"],"summary":"Manage Offer","description":"Pause, resume, or revoke an offer (owner only). Revoking stops new claims;\nexisting members are not affected (revoke them via the group).","operationId":"manage_offer_v1_license_offers__offer_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"offer_id","in":"path","required":true,"schema":{"type":"string","title":"Offer Id"}},{"name":"action","in":"query","required":true,"schema":{"type":"string","title":"Action"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/notifications/":{"get":{"tags":["notifications"],"summary":"List Notifications","description":"Open actions for the current user, then their history, newest first.\n\nScoped to the workspace being worked as (X-Org-Context), like the\ndashboard (founder, 2026-09-25 — a personal account and an organization\nshowed each other's notifications): an organization sees what is about\nthe subjects it holds or represents; the personal account sees the rest.\n\n2026-09-24 overhaul (founder: \"find an event from long ago\"): the history\nis the whole durable feed, searched and paged on the server — it used to\nbe every unread item plus only the last 20 read ones. `view`: all |\nactions (open decisions only) | unread. Open actions ride on page 1.","operationId":"list_notifications_v1_notifications__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":100,"default":"","title":"Q"}},{"name":"view","in":"query","required":false,"schema":{"type":"string","pattern":"^(all|actions|unread)$","default":"all","title":"View"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":30,"title":"Page Size"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/notifications/{notification_id}/read":{"patch":{"tags":["notifications"],"summary":"Mark Notification Read","description":"Dismiss one durable notification. Only applies to the persisted event\nkind (models/notification.py) — a computed pending-action item has no\n'read' state of its own; it disappears when the underlying thing it's\nabout is resolved, which happens elsewhere (approve/reject, payment,\netc.), not here.","operationId":"mark_notification_read_v1_notifications__notification_id__read_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"string","title":"Notification Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/notifications/read-all":{"post":{"tags":["notifications"],"summary":"Mark All Notifications Read","description":"Dismiss every unread durable notification in the workspace being\nworked as — reading the organization's feed doesn't clear the personal one.","operationId":"mark_all_notifications_read_v1_notifications_read_all_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/":{"post":{"tags":["receipts"],"summary":"Submit Receipt","description":"Record a provider's generation receipt, bound to an authorized decision.\n\nAuth goes through the same runtime check as /verify (see _verify_pair ->\nauthenticate_runtime): a ProviderCredential exchange_secret in\nproduction/strict mode, with the legacy pair token accepted only as a\npilot/dev fallback — not \"pair token\" unconditionally, despite how this\nread before. The receipt must reference a real `verify_allowed` decision\nfor this provider/licensee with the same prompt_hash.","operationId":"submit_receipt_v1_receipts__post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceiptRequest"}}}},"responses":{"200":{"description":"`recorded`, or `already_recorded` for the identical receipt sent again","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceiptAck"}}}},"400":{"description":"No authorized decision for this decision_id (unknown, or not an allow); prompt_hash differs from the decision's; output_hash missing; unsupported or conflicting schema version; provider signature missing or not verifying","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"401":{"description":"Invalid provider credentials for this provider/licensee pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"403":{"description":"The decision was not issued to this provider/licensee pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"409":{"description":"`receipt_conflict`: a different receipt for this decision exists; or the decision was released as not used","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/{decision_id}/events":{"post":{"tags":["receipts"],"summary":"Record Receipt Event","description":"Record a later moment in the life of an already-receipted output —\ntypically `output_delivered` or `output_published`.\n\nThe receipt is still one per decision: it is the proof that a generation\nhappened. But `usage_events` is keyed by (decision_id, event_type) so that\none generation can move through stages, and until this endpoint the only\nwriter was the receipt itself — the second stage was refused with 409 and\ncould never be recorded (journey map D7).\n\nIdempotent: repeating the same event returns `already_recorded`. The same\nevent with a different output_hash is a 409 — a retry must not quietly\nchange what was reported.","operationId":"record_receipt_event_v1_receipts__decision_id__events_post","parameters":[{"name":"decision_id","in":"path","required":true,"schema":{"type":"string","title":"Decision Id"}},{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceiptEventRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/{decision_id}/release":{"post":{"tags":["receipts"],"summary":"Release Decision","description":"Give back the use an `allow` reserved, when nothing was generated under it.\n\nOn a licence with `max_uses`, every allow counts, receipt or not (founder,\n2026-10-04). A provider whose generation failed or was cancelled says so\nhere instead: allowed only before a receipt and while the 24-hour\nreservation is open. The statement goes into the signed audit log, so a\nfalse \"not used\" is a recorded claim, not a silent one.","operationId":"release_decision_v1_receipts__decision_id__release_post","parameters":[{"name":"decision_id","in":"path","required":true,"schema":{"type":"string","title":"Decision Id"}},{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseAck"}}}},"401":{"description":"Invalid provider credentials for this provider/licensee pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"403":{"description":"The decision was not issued to this provider/licensee pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"404":{"description":"No authorized decision for this decision_id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"409":{"description":"`already_receipted`, `nothing_to_release` (no usage limit), or `too_late` (after 24 hours)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/lookup/{output_hash}":{"get":{"tags":["receipts"],"summary":"Lookup By Output Hash","description":"Public, unauthenticated proof for one piece of generated output — model\nplan Phase 1.2 (L2 provenance): \"given this output, whose subject is it and\nwho licensed it\". Same audience as GET /licenses/{id}/proof — a platform, a\nmoderator, a journalist holding a file, not a party to any deal — except\nthe key here is the thing they actually have in hand: a hash of the output\nitself, not a code copied off a receipt nobody outside the transaction ever\nsees.\n\noutput_hash is NOT unique in generation_receipts (two decisions can\nlegitimately produce byte-identical output — same prompt, same seed, same\nmodel, run twice), so this returns every match rather than silently\npicking one; usually that list has exactly one entry.\n\nDeliberately narrow, same discipline as the license proof endpoint: model,\ncompliance/watermark status, the subject and license behind it — not\nlicensee_id (who generated it) or provider_signature (crypto material).","operationId":"lookup_by_output_hash_v1_receipts_lookup__output_hash__get","parameters":[{"name":"output_hash","in":"path","required":true,"schema":{"type":"string","title":"Output Hash"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/receipts/compliance":{"get":{"tags":["receipts"],"summary":"Receipt Compliance","description":"Per-provider compliance for the orgs the user administers: how many\nauthorized decisions were followed by a receipt (enforcement evidence).","operationId":"receipt_compliance_v1_receipts_compliance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/authority/grants":{"get":{"tags":["authority"],"summary":"List Grants","description":"Authority grants visible to the caller.\n\nOperator sees all. Others see grants their org holds, or grants over\nsubjects they own / their org owns.","operationId":"list_grants_v1_authority_grants_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"subject_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority/grants/{grant_id}":{"patch":{"tags":["authority"],"summary":"Resolve Grant","description":"Verify (operator) or revoke (operator / subject controller / grantee org\nadmin) an authority grant.","operationId":"resolve_grant_v1_authority_grants__grant_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"grant_id","in":"path","required":true,"schema":{"type":"string","title":"Grant Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantActionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority/review":{"get":{"tags":["authority"],"summary":"Review Queue","description":"Operator post-audit queue: agency-asserted grants, pending talent\nclaims, and subjects awaiting a lifecycle-verification decision.","operationId":"review_queue_v1_authority_review_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/authority/subjects/{subject_id}/claim":{"post":{"tags":["authority"],"summary":"Claim Subject","description":"A rights holder claims a subject an agency manages — to confirm the\ndelegation (consent) or take direct ownership (transfer).","operationId":"claim_subject_v1_authority_subjects__subject_id__claim_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority/claims":{"get":{"tags":["authority"],"summary":"List Claims","description":"Claims visible to the caller: operator sees all; an org admin sees claims\non subjects their org manages; a user sees their own claims.","operationId":"list_claims_v1_authority_claims_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority/claims/{claim_id}":{"patch":{"tags":["authority"],"summary":"Resolve Claim","description":"Resolve a talent claim. The managing agency's admin or an operator may\nresolve it (the agency vets its own client).","operationId":"resolve_claim_v1_authority_claims__claim_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"claim_id","in":"path","required":true,"schema":{"type":"string","title":"Claim Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResolveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/workspaces":{"get":{"tags":["dashboard"],"summary":"Workspaces","description":"Every workspace this person can switch into. The switcher is a change\nof server scope, not a change of heading, so the list comes from\nmembership rather than from anything the client remembers.","operationId":"workspaces_v1_dashboard_workspaces_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/dashboard/overview":{"get":{"tags":["dashboard"],"summary":"Overview","description":"Short by construction: at most five tasks, five events, four figures.\nA thousand subjects must not make this page longer — they make the\nregister longer, which is a different screen.\n\nCounting happens in the database. The one thing that cannot: whether a\nsubject is offered to anyone at all is decided by `resolve_tier` over\nthe `tier_policy` JSON, so that pass reads a NARROW projection (five\ncolumns, no ORM objects) and computes each subject's summary ONCE —\nthe first version built full rows and re-derived five tiers per subject\nthree times over.","operationId":"overview_v1_dashboard_overview_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/subjects":{"get":{"tags":["dashboard"],"summary":"Subjects","description":"The roster, filtered and paged ON THE SERVER — a thousand talents must\nnot be shipped to a browser so it can filter them itself.\n\nOne exception, stated rather than hidden: \"closed to everyone\" is\nderived from the tier_policy JSON by `resolve_tier`, which SQL cannot\nexpress. That filter therefore scans this workspace's subjects (narrow\ncolumns) to find the matching ids, then pages those ids in SQL like any\nother filter. Denormalising a `licensable` column would remove the scan;\nit is not worth a migration until a roster is large enough to notice.","operationId":"subjects_v1_dashboard_subjects_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","description":"lifecycle status, or 'closed' for closed-to-everyone","default":"","title":"Status"},"description":"lifecycle status, or 'closed' for closed-to-everyone"},{"name":"representation","in":"query","required":false,"schema":{"type":"string","description":"mine | represented | held","default":"","title":"Representation"},"description":"mine | represented | held"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^(subject|newest|oldest)$","default":"subject","title":"Sort"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/requests":{"get":{"tags":["dashboard"],"summary":"Requests","description":"The decision queue. Everything needed to decide is on the row — who is\nasking, for what, for how long, on what terms, and whose sign-off it still\nneeds — because a decision made from a truncated row is a guess.","operationId":"requests_v1_dashboard_requests_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"state","in":"query","required":false,"schema":{"type":"string","pattern":"^(needs_action|waiting|resolved)$","default":"needs_action","title":"State"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/licenses":{"get":{"tags":["dashboard"],"summary":"Licenses","description":"Licences issued on this workspace's subjects, with the effective status\n— the term, not just the column.","operationId":"licenses_v1_dashboard_licenses_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"state","in":"query","required":false,"schema":{"type":"string","pattern":"^(live|expired|all)$","default":"live","title":"State"}},{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/generations":{"get":{"tags":["dashboard"],"summary":"Generations","description":"All generations, newest first, filterable by class, AI service,\nsubject and date. `source` says how PRAMPTA knows: a receipt for a\npermission it granted (Step 2) or a provider's report (Step 1).","operationId":"generations_v1_dashboard_generations_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"cls","in":"query","required":false,"schema":{"type":"string","pattern":"^(|PRM|RND|STD)$","default":"","title":"Cls"}},{"name":"provider","in":"query","required":false,"schema":{"type":"string","default":"","title":"Provider"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","default":"","title":"Subject"}},{"name":"since","in":"query","required":false,"schema":{"type":"string","default":"","title":"Since"}},{"name":"until","in":"query","required":false,"schema":{"type":"string","default":"","title":"Until"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/generations/{source}/{ref}":{"get":{"tags":["dashboard"],"summary":"Generation Detail","description":"One generation in full, and how to reach the AI app that made it\n(founder, 2026-09-26). A report is the provider's signed observation; a\nreceipt is the decision PRAMPTA issued and what the provider filed after.","operationId":"generation_detail_v1_dashboard_generations__source___ref__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"source","in":"path","required":true,"schema":{"type":"string","title":"Source"}},{"name":"ref","in":"path","required":true,"schema":{"type":"string","title":"Ref"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/generations/series":{"get":{"tags":["dashboard"],"summary":"Generations Series","description":"Generations per day, month or year, split by class.","operationId":"generations_series_v1_dashboard_generations_series_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(day|month|year)$","default":"month","title":"Period"}},{"name":"provider","in":"query","required":false,"schema":{"type":"string","default":"","title":"Provider"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","default":"","title":"Subject"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/earnings":{"get":{"tags":["dashboard"],"summary":"Earnings","description":"Money, with the sale it came from. Per currency, never summed across.\nThe summary is always the whole workspace; the filters narrow the list.","operationId":"earnings_v1_dashboard_earnings_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"cls","in":"query","required":false,"schema":{"type":"string","pattern":"^(|PRM|RND)$","default":"","title":"Cls"}},{"name":"provider","in":"query","required":false,"schema":{"type":"string","default":"","title":"Provider"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","default":"","title":"Subject"}},{"name":"since","in":"query","required":false,"schema":{"type":"string","default":"","title":"Since"}},{"name":"until","in":"query","required":false,"schema":{"type":"string","default":"","title":"Until"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/earnings/series":{"get":{"tags":["dashboard"],"summary":"Earnings Series","description":"What this workspace earned per day, month or year — the same shares\n`_money` totals (holder share + mandate commission), dated by when the\nbuyer paid. One series per currency, never summed across.","operationId":"earnings_series_v1_dashboard_earnings_series_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(day|month|year)$","default":"month","title":"Period"}},{"name":"provider","in":"query","required":false,"schema":{"type":"string","default":"","title":"Provider"}},{"name":"subject","in":"query","required":false,"schema":{"type":"string","default":"","title":"Subject"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/observations":{"post":{"tags":["observations"],"summary":"Report Observation","operationId":"report_observation_v1_observations_post","parameters":[{"name":"x-provider-id","in":"header","required":true,"schema":{"type":"string","maxLength":100,"title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","maxLength":4096,"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObservationRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/observations":{"get":{"tags":["observations"],"summary":"List Observations","operationId":"list_observations_v1_dashboard_observations_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"environment","in":"query","required":false,"schema":{"enum":["production","sandbox"],"type":"string","default":"production","title":"Environment"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/observations/{observation_id}/case":{"post":{"tags":["usage-cases"],"summary":"Open Case","operationId":"open_case_v1_observations__observation_id__case_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"observation_id","in":"path","required":true,"schema":{"type":"string","title":"Observation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__usage_cases__OpenIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/usage-cases":{"get":{"tags":["usage-cases"],"summary":"List Cases","operationId":"list_cases_v1_usage_cases_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"side","in":"query","required":false,"schema":{"enum":["holder","provider"],"type":"string","default":"holder","title":"Side"}},{"name":"status","in":"query","required":false,"schema":{"enum":["open","closed","all"],"type":"string","default":"open","title":"Status"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/usage-cases/{case_id}":{"get":{"tags":["usage-cases"],"summary":"Get Case","operationId":"get_case_v1_usage_cases__case_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"case_id","in":"path","required":true,"schema":{"type":"string","title":"Case Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/usage-cases/{case_id}/messages":{"post":{"tags":["usage-cases"],"summary":"Add Message","operationId":"add_message_v1_usage_cases__case_id__messages_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"case_id","in":"path","required":true,"schema":{"type":"string","title":"Case Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/usage-cases/{case_id}/files/{file_id}":{"get":{"tags":["usage-cases"],"summary":"Read File","description":"Both sides read the case's files — they are about a generated output,\nand the provider cannot answer what it cannot see. Every read is logged.","operationId":"read_file_v1_usage_cases__case_id__files__file_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"case_id","in":"path","required":true,"schema":{"type":"string","title":"Case Id"}},{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/usage-cases/{case_id}/close":{"post":{"tags":["usage-cases"],"summary":"Close Case","operationId":"close_case_v1_usage_cases__case_id__close_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"case_id","in":"path","required":true,"schema":{"type":"string","title":"Case Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloseIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider/usage-cases":{"get":{"tags":["usage-cases"],"summary":"Provider List Cases","operationId":"provider_list_cases_v1_provider_usage_cases_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"enum":["open","closed","all"],"type":"string","default":"open","title":"Status"}},{"name":"x-provider-id","in":"header","required":true,"schema":{"type":"string","maxLength":100,"title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","maxLength":4096,"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider/usage-cases/{case_id}/messages":{"post":{"tags":["usage-cases"],"summary":"Provider Add Message","operationId":"provider_add_message_v1_provider_usage_cases__case_id__messages_post","parameters":[{"name":"case_id","in":"path","required":true,"schema":{"type":"string","title":"Case Id"}},{"name":"x-provider-id","in":"header","required":true,"schema":{"type":"string","maxLength":100,"title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","maxLength":4096,"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/lookalikes":{"get":{"tags":["lookalikes"],"summary":"Holder Lookalikes","description":"The rights holder's queue: look-alikes providers reported for this\nworkspace's subjects only.","operationId":"holder_lookalikes_v1_dashboard_lookalikes_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"enum":["pending","confirmed","dismissed","all"],"type":"string","default":"pending","title":"Status"}},{"name":"environment","in":"query","required":false,"schema":{"enum":["production","sandbox"],"type":"string","default":"production","title":"Environment"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Page Size"}},{"name":"X-Org-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Org-Context"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dashboard/lookalikes/{observation_id}/dismiss":{"post":{"tags":["lookalikes"],"summary":"Dismiss Lookalike","description":"\"Not them.\" Takes the candidate out of the queue; tells nobody.","operationId":"dismiss_lookalike_v1_dashboard_lookalikes__observation_id__dismiss_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"observation_id","in":"path","required":true,"schema":{"type":"string","title":"Observation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DismissIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider/lookalikes":{"get":{"tags":["lookalikes"],"summary":"Provider Lookalikes","description":"A provider's own look-alike candidates and what the rights holder said.\nSame exchange-secret auth as reporting; never another provider's rows.","operationId":"provider_lookalikes_v1_provider_lookalikes_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"enum":["pending","confirmed","dismissed","all"],"type":"string","default":"all","title":"Status"}},{"name":"x-provider-id","in":"header","required":true,"schema":{"type":"string","maxLength":100,"title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","maxLength":4096,"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/users":{"get":{"tags":["admin"],"summary":"Search Users","description":"Find users by username, email, or id and include recent activity.","operationId":"search_users_v1_admin_users_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","description":"match username / email / id","default":"","title":"Q"},"description":"match username / email / id"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":25,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"activity_limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":0,"default":5,"title":"Activity Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/users/{user_id}":{"get":{"tags":["admin"],"summary":"Get User Detail","description":"Full operator view of a user: their profile, the subjects they own, the\nlicenses they hold (as a licensee, via their orgs + personal licensee), and\nthe license requests they've made.","operationId":"get_user_detail_v1_admin_users__user_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/users/{user_id}/ban":{"post":{"tags":["admin"],"summary":"Set User Ban","description":"Ban (deactivate) or unban a user. A banned user can no longer\nauthenticate. Operators cannot ban themselves or other operators.","operationId":"set_user_ban_v1_admin_users__user_id__ban_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BanRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/users/{user_id}/staff-role":{"patch":{"tags":["admin"],"summary":"Set Staff Role","description":"Assign a staff role (admin / support / reviewer / billing_staff /\ndeveloper) or demote back to an ordinary 'operator' account (A10 RBAC).\n\nAdmin-only: granting elevated access is itself a privileged action, so it\nis not exposed via the general permission system — only the full admin\nrole may perform it.","operationId":"set_staff_role_v1_admin_users__user_id__staff_role_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffRoleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/licenses":{"get":{"tags":["admin"],"summary":"Search Licenses","description":"Find licenses by license_id, subject_id, or licensee_id (substring).","operationId":"search_licenses_v1_admin_licenses_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","description":"match license id / subject / licensee","default":"","title":"Q"},"description":"match license id / subject / licensee"},{"name":"status","in":"query","required":false,"schema":{"type":"string","description":"optional status filter","default":"","title":"Status"},"description":"optional status filter"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/held-reviews":{"get":{"tags":["admin"],"summary":"List Held Reviews","description":"Commercial generations held for a human because the subject is\nhigh-risk (a child, a deceased person, a vulnerable adult) — see\napi/verify.py's PG_HELD_FOR_REVIEW branch and core/high_risk.py.\n\nA REVIEW is neither an allow nor a deny: /verify pauses the request and\nsigns a decision saying so. Without this list nobody could find those\ndecisions, which turns a deliberate \"a person should look at this\" into a\nsilent refusal — so the gate and this view ship together (2026-08-20).\n\nRead from the audit log rather than a separate queue table: the audit\nevent IS the durable record (verify.py writes `verify_review` on the same\ncommit as the decision), and a second store would be a copy that can\ndisagree with it.","operationId":"list_held_reviews_v1_admin_held_reviews_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"subject_id","in":"query","required":false,"schema":{"type":"string","description":"optional: only this subject","default":"","title":"Subject Id"},"description":"optional: only this subject"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/rnd-arbitrage-flags":{"get":{"tags":["admin"],"summary":"List Rnd Arbitrage Flags","description":"RND-arbitrage watchlist (2026-08(h) founder call): a licensee taking\nseveral separate RND grants on the SAME subject is the shape a quiet\noff-platform commercial deal would leave behind (see\ncore/tiers.py::RND_MAX_DURATION_DAYS's comment on the same risk) — one\ngrant is ordinary research/editorial use, several in a row on one\nsubject is worth a human looking at.\n\nFlags, does not act: nothing here pauses or revokes a license. It is a\nlive query over `licenses`, not a stored score — same reasoning as\nlist_provider_risk above, an operator should never read a stale verdict.","operationId":"list_rnd_arbitrage_flags_v1_admin_rnd_arbitrage_flags_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"min_count","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":2,"description":"RND licenses on one subject, same licensee, to flag","default":3,"title":"Min Count"},"description":"RND licenses on one subject, same licensee, to flag"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/groups":{"get":{"tags":["admin"],"summary":"Search Groups","description":"Find license groups by id, display name, or owner id (substring).","operationId":"search_groups_v1_admin_groups_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","description":"match group id / name / owner","default":"","title":"Q"},"description":"match group id / name / owner"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/groups/{group_id}":{"get":{"tags":["admin"],"summary":"Admin Group Detail","description":"Operator view of a group: settings, owner, and all members.","operationId":"admin_group_detail_v1_admin_groups__group_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Admin Update Group","description":"Rename a group and/or change its status (active ⇄ archived). An archived\ngroup's licenses stop applying because add_member rejects archived groups and\nverify only resolves active membership.","operationId":"admin_update_group_v1_admin_groups__group_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Admin Delete Group","description":"Delete a group and all of its memberships and overrides. Any license that\nwas signed to this group id stops resolving (no active members remain).","operationId":"admin_delete_group_v1_admin_groups__group_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/groups/{group_id}/members/{member_licensee_id}":{"delete":{"tags":["admin"],"summary":"Admin Revoke Group Member","description":"Revoke a member's access to a group. Takes effect immediately at verify.","operationId":"admin_revoke_group_member_v1_admin_groups__group_id__members__member_licensee_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"member_licensee_id","in":"path","required":true,"schema":{"type":"string","title":"Member Licensee Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/metrics":{"get":{"tags":["admin"],"summary":"Admin Metrics","description":"Operations dashboard: verify volume + allow/deny over time, top refusal\nreasons, platform totals, and the operator signing-key fingerprint/history.\n\nNote: per-request latency (p50/p95) is not stored server-side — measure it\nwith scripts/loadtest_verify*.py. This panel reports volume and outcomes.","operationId":"admin_metrics_v1_admin_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/admin/coverage-metrics":{"get":{"tags":["admin"],"summary":"Admin Coverage Metrics","description":"Model plan Phase 1.3: \"watermark_embedded и compliant — вывести в\nметрику покрытия: сколько авторизованных генераций реально несут метку.\nЭто цифра, с которой идут к платформе.\" A single whole-registry number —\ndistinct from GET /v1/receipts/compliance (scoped to the orgs the caller\nadministers) and GET /v1/admin/provider-risk (itemized per provider).\n\n`receipt_rate` is the more fundamental gap: it is entirely possible for a\nprovider to take an authorization and never report back at all, which\nthis catches and the label-coverage rates below cannot (they can only\ndescribe receipts that exist).\n\n`assertion_rate` counts real `PgAssertion` rows (api/assertions.py,\nthe existing PRE-GEN v1.1 §11 provenance bridge — POST /v1/assertions/\nissues a signed `pg.assertion.v1` a provider embeds in its own C2PA\nmanifest), not a self-reported flag: a provider that never bothered to\nrequest an assertion produces no row here, which is a stronger signal\nthan asking them to type \"yes I embedded it\" the way watermark_embedded\nhas to (PRAMPTA never sees the file either way, but AT LEAST issuing the\nassertion is an action PRAMPTA itself witnessed).","operationId":"admin_coverage_metrics_v1_admin_coverage_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/admin/pending-counts":{"get":{"tags":["admin"],"summary":"Admin Pending Counts","description":"How much unhandled work is sitting in each operator queue.\n\nOne request rather than the panel fetching six lists just to count them:\nthe admin panel polls this to put a dot on the sections that need an\noperator, the same way the Profile nav button carries one for the user's\nown notifications. Only counts queues an operator can actually clear —\nUsers/Licenses/Metrics have no \"pending\" state, so they never get a dot.","operationId":"admin_pending_counts_v1_admin_pending_counts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/admin/overview":{"get":{"tags":["admin"],"summary":"Admin Overview","description":"The operator's first screen (2026-09-24 overhaul): the registry in\ntotals, every queue that waits on an operator, and growth over time —\nsignups, subjects, generations by class, sales by class. Same buckets and\ngeneration counting as the rights holder's dashboard, over the whole\nregistry. Money is USD: every price on PRAMPTA is.","operationId":"admin_overview_v1_admin_overview_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(day|month|year)$","default":"month","title":"Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/providers":{"get":{"tags":["admin"],"summary":"List Provider Credentials","operationId":"list_provider_credentials_v1_admin_providers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["admin"],"summary":"Create Provider Credential","description":"Register an AI provider and mint its exchange secret (shown ONCE).\n\nThe credential — not a self-declared header — is what establishes this\nprovider's identity at Connect AI exchange time.","operationId":"create_provider_credential_v1_admin_providers_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderCredentialCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/admin/providers/{provider_id}/rotate":{"post":{"tags":["admin"],"summary":"Rotate Provider Credential","description":"Rotate a provider's exchange secret (old secret stops working immediately).","operationId":"rotate_provider_credential_v1_admin_providers__provider_id__rotate_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/providers/{provider_id}":{"patch":{"tags":["admin"],"summary":"Update Provider Credential","operationId":"update_provider_credential_v1_admin_providers__provider_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderCredentialUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/reports":{"get":{"tags":["admin"],"summary":"List Reports","description":"The operator takedown queue. Defaults to open reports, newest first.","operationId":"list_reports_v1_admin_reports_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"open","title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/reports/{report_id}":{"patch":{"tags":["admin"],"summary":"Resolve Report","description":"Triage a report. Optionally withdraw the offending subject in one step.\n\nWithdrawing a subject is a moderation takedown — recorded in the audit log.\nIt does not delete data; it flips the subject to 'withdrawn' so it stops\nappearing publicly and stops authorizing in /verify.","operationId":"resolve_report_v1_admin_reports__report_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"string","title":"Report Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportResolve"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/provider-risk":{"get":{"tags":["admin"],"summary":"List Provider Risk","description":"Risk view across all providers, worst first.\n\nScores are computed live rather than read from the row, so an operator is\nnever shown a stale judgement — the counters are the stored truth, the\nscore is a function of them.","operationId":"list_provider_risk_v1_admin_provider_risk_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/admin/provider-risk/{provider_id}/evaluate":{"post":{"tags":["admin"],"summary":"Evaluate Provider Risk","description":"Rescore one provider now, auto-suspending it if it crosses the bar.\n\nExposed so an operator can act on a report immediately instead of waiting\nfor the next scheduled pass.","operationId":"evaluate_provider_risk_v1_admin_provider_risk__provider_id__evaluate_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/provider-risk/{provider_id}/reset-window":{"post":{"tags":["admin"],"summary":"Reset Provider Risk Window","description":"Zero the counters and restart the window.\n\nWithout this the score only ever climbs and the signal dies: a provider\nthat fixed its integration would stay condemned by its worst month\nforever, and operators would learn to ignore the number.","operationId":"reset_provider_risk_window_v1_admin_provider_risk__provider_id__reset_window_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskWindowReset"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/evidence/purge":{"post":{"tags":["admin"],"summary":"Purge Evidence","description":"Delete authority evidence whose retention period has elapsed (A4).\n\nExplicit rather than a background timer. Deleting people's identity\ndocuments should be an act an operator performs and sees the result of —\na silent job is one nobody notices has stopped running, and \"we thought it\nwas deleting\" is not a defence.\n\nThe rows survive; only the bytes go. A decided review still shows what it\nrested on, and the SHA-256 still proves which document that was.","operationId":"purge_evidence_v1_admin_evidence_purge_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/admin/account-deletions/finalize":{"post":{"tags":["admin"],"summary":"Finalize Account Deletions","description":"Finalize every account whose 30-day cancellation window has elapsed\n(2026-08(b) — see core/account_deletion.py for the full request -> confirm\n-> grace-period -> finalize design).\n\nSame reasoning as evidence purge above: explicit, operator-triggered, not\na silent background timer — the account owner has already had 30 days to\nlog back in and cancel, so this step withdraws their subjects for good\nand scrubs their PII into a tombstone. Nothing here is a surprise to the\nperson it happens to; they were emailed at request time and again would\nhave seen the pending banner on every login during the window.","operationId":"finalize_account_deletions_v1_admin_account_deletions_finalize_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/admin/csam/incidents":{"get":{"tags":["admin"],"summary":"List Incidents","operationId":"list_incidents_v1_admin_csam_incidents_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["admin"],"summary":"Open Incident","operationId":"open_incident_v1_admin_csam_incidents_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__csam__OpenIn"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/admin/csam/incidents/{incident_id}/reported":{"post":{"tags":["admin"],"summary":"Mark Reported","operationId":"mark_reported_v1_admin_csam_incidents__incident_id__reported_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"incident_id","in":"path","required":true,"schema":{"type":"string","title":"Incident Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportedIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/csam/incidents/{incident_id}/evidence/{n}":{"get":{"tags":["admin"],"summary":"Download Evidence","description":"One preserved file, to attach to the CyberTipline report. Audited.","operationId":"download_evidence_v1_admin_csam_incidents__incident_id__evidence__n__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"incident_id","in":"path","required":true,"schema":{"type":"string","title":"Incident Id"}},{"name":"n","in":"path","required":true,"schema":{"type":"integer","title":"N"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reports/":{"post":{"tags":["reports"],"summary":"Create Report","operationId":"create_report_v1_reports__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/enterprise/inquiries":{"post":{"tags":["enterprise"],"summary":"Submit Inquiry","description":"Submit an agency inquiry. Open to anyone (incl. logged-out visitors on the\nlanding page); rate-limited to deter spam.","operationId":"submit_inquiry_v1_enterprise_inquiries_post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InquiryRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["enterprise"],"summary":"List Inquiries","description":"List enterprise inquiries with status counts (operator only).","operationId":"list_inquiries_v1_enterprise_inquiries_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/enterprise/inquiries/{lead_id}":{"patch":{"tags":["enterprise"],"summary":"Update Inquiry","description":"Update an inquiry's status (operator only).","operationId":"update_inquiry_v1_enterprise_inquiries__lead_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInquiryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/health/report":{"post":{"tags":["health"],"summary":"Submit Report","description":"File an error/bug report. Open to anyone; rate-limited to deter floods.","operationId":"submit_report_v1_health_report_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/health/reports":{"get":{"tags":["health"],"summary":"List Reports","description":"List error/bug reports with status counts (operator only).","operationId":"list_reports_v1_health_reports_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/health/reports/{report_id}":{"patch":{"tags":["health"],"summary":"Update Report","operationId":"update_report_v1_health_reports__report_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"string","title":"Report Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReportRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider/identity-assertions":{"post":{"tags":["identity-v2"],"summary":"Submit Identity Assertion","description":"Provider posts a signed identity assertion.\n\nTrust chain:\n  1. X-Provider-ID + Bearer secret ⇒ authenticated provider_id\n     (rejects unknown providers even if the body looks well-formed).\n  2. Body.provider_id MUST equal the authenticated provider_id — a\n     credential holder cannot forge assertions under a different provider.\n  3. Ed25519 signature over canonical_json(body) MUST verify against the\n     provider Organization's signing_public_key_hex — same primitive as\n     receipts/decisions. Missing signing key ⇒ 409 (setup required).\n  4. audience MUST match PRAMPTA_ASSERTION_AUDIENCE (prevents an\n     assertion aimed at a different system from being replayed here).\n  5. timestamp within ±_MAX_CLOCK_SKEW.\n  6. UNIQUE(provider_id, nonce) blocks replay at the DB layer — a raced\n     second submission returns 409.","operationId":"submit_identity_assertion_v1_provider_identity_assertions_post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssertionIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssertionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/identity/bind":{"post":{"tags":["identity-v2"],"summary":"Bind Identity","description":"Redeem a verified assertion as a link owned by the current PRAMPTA user.\n\nInvariants:\n  * The assertion must exist, be signature-verified, and unconsumed.\n  * (provider_id, external_subject_hash) can be claimed by AT MOST ONE\n    PRAMPTA user. If the same user re-binds, we return their existing\n    link idempotently; if a DIFFERENT user claims it, 409.\n  * consumed_at + consumed_by_link_id lock the assertion so replaying\n    the same signed body cannot mint a second link.","operationId":"bind_identity_v1_identity_bind_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BindIn"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BindOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/identity/links":{"get":{"tags":["identity-v2"],"summary":"List My Identity Links","description":"Return the current user's verified provider identity links.\n\nDistinct from ``/linked-accounts``, which lists the user's self-declared\nv1 provider claims (not cryptographically verified). A row appears here\nONLY when a signed provider assertion has been redeemed via /bind\n(docs §6.2). external_subject_hash is deliberately NOT surfaced — it's\nonly used internally as a stable dedupe key, not something the user\nneeds to see.","operationId":"list_my_identity_links_v1_identity_links_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkListOut"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/provider/webhooks":{"post":{"tags":["identity-v2"],"summary":"Receive Webhook","description":"Signed inbound event from a provider (identity revocation / disowned\nuser). Trust chain matches other identity-v2 endpoints — same\ncredential auth, same Ed25519 signature against the provider org's\n``signing_public_key_hex``, same PRAMPTA_ASSERTION_AUDIENCE requirement.\n\nIdempotency: ``UNIQUE(provider_id, event_id)`` guarantees a redelivery\nlands on the SAME persisted row. Rows are recorded even when the\nsignature fails or the event type is unknown — a malicious retry\npattern must be auditable, not invisible. Failed rows land in the\n``dead_letter`` / ``manual_review`` states so an operator can inspect\nthem separately from the healthy stream.","operationId":"receive_webhook_v1_provider_webhooks_post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookIn"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/oauth/authorize":{"get":{"tags":["oauth"],"summary":"Describe Authorization","description":"Validate an authorization request and describe it for the consent screen.\n\nIssues nothing. Its only side effect is telling the frontend whether to show\na login, a consent prompt, or to proceed straight to POST.","operationId":"describe_authorization_v1_oauth_authorize_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"client_id","in":"query","required":true,"schema":{"type":"string","title":"Client Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}},{"name":"scope","in":"query","required":true,"schema":{"type":"string","title":"Scope"}},{"name":"state","in":"query","required":true,"schema":{"type":"string","title":"State"}},{"name":"code_challenge","in":"query","required":true,"schema":{"type":"string","title":"Code Challenge"}},{"name":"response_type","in":"query","required":false,"schema":{"type":"string","default":"code","title":"Response Type"}},{"name":"code_challenge_method","in":"query","required":false,"schema":{"type":"string","default":"S256","title":"Code Challenge Method"}},{"name":"nonce","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nonce"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeDescribeOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["oauth"],"summary":"Decide Authorization","description":"Record the user's decision and, on approval, mint an authorization code.\n\nEvery parameter is re-validated here against the client registration —\nnothing is carried over in server state from the GET, so a tampered POST\ncannot widen scope or point the code at a different redirect.","operationId":"decide_authorization_v1_oauth_authorize_post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeDecisionIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeDecisionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/oauth/token":{"post":{"tags":["oauth"],"summary":"Issue Token","description":"Exchange an authorization code, or rotate a refresh token.","operationId":"issue_token_v1_oauth_token_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_issue_token_v1_oauth_token_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/oauth/revoke":{"post":{"tags":["oauth"],"summary":"Revoke Token","description":"Revoke a token. Revoking a refresh token kills its whole grant.\n\nPer RFC 7009 this returns 200 even for an unknown token — a revocation\nendpoint that distinguished valid from invalid tokens would be an oracle.","operationId":"revoke_token_v1_oauth_revoke_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_revoke_token_v1_oauth_revoke_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/oauth/userinfo":{"get":{"tags":["oauth"],"summary":"Userinfo","description":"Minimal subject info for the bearer's provider.\n\nDeliberately returns NO email, no username, no real name, and nothing about\nany provider other than the caller's. A provider learns that a stable\nPRAMPTA user exists and what they authorized — nothing more. Widening this\nresponse is a privacy decision, not a convenience one.","operationId":"userinfo_v1_oauth_userinfo_get","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/oauth/link-provider":{"post":{"tags":["oauth"],"summary":"Link Provider Identity","description":"Bind the token's PRAMPTA user to the caller's provider account.\n\nRequires an access token carrying the `identity:link` scope. The user is\ntaken from the TOKEN, never from the request body — a provider cannot link\nan account to a user who did not authorize it, because it has no way to\nobtain a token for that user.","operationId":"link_provider_identity_v1_oauth_link_provider_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkProviderIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkProviderOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/oauth/unlink-provider":{"post":{"tags":["oauth"],"summary":"Unlink Provider Identity","description":"Provider-initiated unlink: the user is gone on the provider's side.\n\nMarks the link revoked rather than deleting it — the audit trail of what\nthat link once authorized has to survive, and /verify refuses a revoked\nlink with PG_IDENTITY_REVOKED. Re-linking later restores it.\n\nThis does NOT revoke the OAuth grant. The two are separate on purpose: a\nprovider disowning an account is not the same as the user withdrawing\nconsent, and conflating them would let a provider silently drop a grant\nthe user still wants. The user revokes consent from their own side.","operationId":"unlink_provider_identity_v1_oauth_unlink_provider_post","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnlinkProviderOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/":{"post":{"tags":["provider-onboarding"],"summary":"Create Application","description":"Start a draft application.\n\nA RESERVED provider_id is deliberately allowed here — this is the sanctioned\nroute to claiming one. `core/reserved_names` only blocks self-serve *org*\ncreation; granting the id still requires an operator further down.\n\nrequire_2fa (not get_current_user): same reasoning as organization\ncreation (core/auth.py) — this is the front door to becoming a trusted\nAPI-level actor that can eventually hold a production credential and\nsign entitlements. A leaked or guessed password alone should not be\nenough to start that. Later steps in this flow (submit, verify-email,\nverify-domain) inherit the gate for free: they all operate on an\napplication this same 2FA'd account created.","operationId":"create_application_v1_provider_applications__post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["provider-onboarding"],"summary":"List Applications","description":"Applicants see their own applications; operators see the full queue.\n\n`mine=true` forces the applicant view even for an operator — the caller\nstates which of the two lists it wants rather than having it depend on\nwho is asking (2026-08-28). The Developer Dashboard is a personal \"my\napplication\" page and passes it; without that, an operator opening their\nOWN dashboard silently got the whole queue and the page showed it\nsomebody else's application (whichever was newest), offering applicant\nactions against it. The admin queue (ApplicationsSection) omits it.","operationId":"list_applications_v1_provider_applications__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"mine","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Mine"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}":{"get":{"tags":["provider-onboarding"],"summary":"Get Application","operationId":"get_application_v1_provider_applications__app_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["provider-onboarding"],"summary":"Update Application","description":"Edit a draft — or, since 2026-08-25, a SUBMITTED application that has\nnot been granted anything yet (no sandbox key). The submitted form used to\nfreeze entirely, which dead-ended applicants whose account email can't sit\non their claimed domain: their one self-service fix was correcting the\ndomain, and the record wasn't editable. Nothing has been granted at this\npoint, and every gate (email-on-domain, DNS TXT) re-checks against the\nUPDATED values at grant time, so editing now is safe. Once a credential\nexists, the freeze is real again: the record is what a key was minted\nagainst.","operationId":"update_application_v1_provider_applications__app_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/recent-decisions":{"get":{"tags":["provider-onboarding"],"summary":"Recent Decisions","description":"A provider's own recent /verify outcomes — allows AND refusals, with\nthe reason. Pre-v1.0.0 audit gap (7.14): a provider had no way to see WHY\na generation was blocked at runtime. GET /v1/audit/mine does not cover\nthis — it scopes by `actor`, and a verify event's actor is the LICENSEE,\nnever the provider, so a provider's own team is never in that scope\n(Buddian's licensee is each end user's personal org via Connect AI, not\nanything Buddian is a member of). Scoped here by `metadata_->>provider_id`\ninstead, using the same JSON-field query pattern GET /v1/audit/mine\nalready relies on for `subject_id` — proven to behave the same on SQLite\nand Postgres, which a naive JSON-path query is NOT guaranteed to (see\nCLAUDE.md's SQLite-forgives-what-Postgres-rejects notes).\n\nNo decision content beyond what the provider already received in the\noriginal signed response — prompt_hash, subject_id, reason, timestamps —\nnothing about the end user beyond what verify() already echoed to them.","operationId":"recent_decisions_v1_provider_applications__app_id__recent_decisions_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/rights-holder-contact":{"put":{"tags":["provider-onboarding"],"summary":"Set Rights Holder Contact","description":"Change where rights holders reach you — at any stage, keys or not: a\ncontact that goes stale after approval is the one that matters most.","operationId":"set_rights_holder_contact_v1_provider_applications__app_id__rights_holder_contact_put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RightsHolderContactIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/redirect-uris":{"put":{"tags":["provider-onboarding"],"summary":"Set Redirect Uris","description":"Let a provider manage its own return addresses after its keys exist.\n\nBefore this, an application's list froze the moment a key was minted, and\nthe Apply form never collected one — so every self-served provider ended\nup with an EMPTY list, which production's Connect AI exchange refuses\n(journey map D5). The only way out was an operator editing it by hand.\n\nHeld to the application's own domain: a provider may only send users back\nto itself. Written to the credential AND the sign-in client of every\nenvironment that exists, through the one shared writer (D6).","operationId":"set_redirect_uris_v1_provider_applications__app_id__redirect_uris_put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectUrisIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/submit":{"post":{"tags":["provider-onboarding"],"summary":"Submit Application","description":"Submit for review. Everything an operator needs to judge must be present\n— an incomplete application wastes a human's time, so it is refused here\nrather than rejected later.","operationId":"submit_application_v1_provider_applications__app_id__submit_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/verify-email":{"post":{"tags":["provider-onboarding"],"summary":"Verify Business Email","description":"Prove the submitter holds a verified address ON the claimed domain —\nand, the moment that's proven, mint a SANDBOX credential right here, no\noperator involved. Synthetic subjects only, so there is nothing for a\nhuman to protect by making the applicant wait.\n\nA verified gmail address proves the applicant owns an inbox, not that they\nspeak for the company. Requiring the address to be on the applied-for\ndomain is what makes this step mean something — and it is deliberately\nchecked against the ACCOUNT's verified email, not a value in the request.","operationId":"verify_business_email_v1_provider_applications__app_id__verify_email_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/verify-domain":{"post":{"tags":["provider-onboarding"],"summary":"Initiate Domain Verification","description":"Issue a DNS TXT challenge — same mechanism organizations already use.","operationId":"initiate_domain_verification_v1_provider_applications__app_id__verify_domain_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/verify-domain/confirm":{"post":{"tags":["provider-onboarding"],"summary":"Confirm Domain Verification","description":"Check the TXT record — and if it's there, grant credentials right\nhere, no operator involved. Domain ownership (only the real company can\npublish a DNS record under it) is the bar the founder chose for real-\nsubject access; see the module docstring for the reasoning.\n\nDNS-first (2026-08-25): an applicant whose PRAMPTA account email can\nnever sit on their claimed domain (a founder on gmail) previously had NO\nself-service path past the email gate. A TXT record under the domain is\nSTRONGER company-control evidence than an inbox on it, so arriving via\nDNS marks company verification itself and grants BOTH tiers: sandbox and\nproduction, each with its own one-time secret set (\"sandbox\" key in the\nresponse).","operationId":"confirm_domain_verification_v1_provider_applications__app_id__verify_domain_confirm_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/approve-sandbox":{"post":{"tags":["provider-onboarding"],"summary":"Approve Sandbox","description":"Grant Tier 1: synthetic subjects only, no production access.\n\nSandbox is where a provider proves its integration behaves — it is not a\nlesser form of production, and nothing here touches a real subject.","operationId":"approve_sandbox_v1_provider_applications__app_id__approve_sandbox_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/approve-production":{"post":{"tags":["provider-onboarding"],"summary":"Approve Production","description":"Grant Tier 2: production credentials, real subjects, receipts mandatory.\n\nRequires the domain to be verified. Tier 3 (trusted commercial) is NOT\nreachable from here — it additionally needs a security review and a signed\nagreement, which are processes outside this system (assessment §12).","operationId":"approve_production_v1_provider_applications__app_id__approve_production_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/reject":{"post":{"tags":["provider-onboarding"],"summary":"Reject Application","description":"Reject with a reason. The reason is applicant-visible — a rejection the\napplicant cannot act on just produces a resubmission.","operationId":"reject_application_v1_provider_applications__app_id__reject_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/suspend":{"post":{"tags":["provider-onboarding"],"summary":"Suspend Application","description":"Kill switch. Disables every credential and OAuth client this application\nproduced, and revokes live runtime pairs, so access stops on the next\nrequest rather than at the next credential rotation. Reversible.","operationId":"suspend_application_v1_provider_applications__app_id__suspend_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/provider-applications/{app_id}/revoke":{"post":{"tags":["provider-onboarding"],"summary":"Revoke Application","description":"Terminal. Unlike suspension there is no path back — a revoked provider\nreapplies from scratch, and the record of why stays in the audit chain.","operationId":"revoke_application_v1_provider_applications__app_id__revoke_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/developer/providers":{"get":{"tags":["developer"],"summary":"List My Providers","description":"Providers this user administers, with just enough to pick one.","operationId":"list_my_providers_v1_developer_providers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/developer/providers/{provider_id}":{"get":{"tags":["developer"],"summary":"Get My Provider","description":"Everything a provider needs to configure its integration.","operationId":"get_my_provider_v1_developer_providers__provider_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/developer/providers/{provider_id}/profile":{"patch":{"tags":["developer"],"summary":"Update My Provider Profile","description":"A provider edits how it is PRESENTED — name, tagline, website, logo —\nshown to people connecting their account and in the directory. Nothing\ntrust-bearing (badge, tier, listing) is reachable here; those stay the\noperator's and the application's (connect_ai.py).","operationId":"update_my_provider_profile_v1_developer_providers__provider_id__profile_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/developer/providers/{provider_id}/listing":{"post":{"tags":["developer"],"summary":"Submit For Listing","description":"Put a provider that passed every check into the Connect AI directory.\n\nSelf-service because every check is already automatic and hard to fake:\na production grant (domain address + DNS record), the Step 2 loop proven\non the production key, a return address, good standing. What keeps\nwatching after listing is the risk engine and user reports, which suspend\n— and a suspended provider leaves the directory on its own.","operationId":"submit_for_listing_v1_developer_providers__provider_id__listing_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/developer/providers/{provider_id}/rotate-credential":{"post":{"tags":["developer"],"summary":"Rotate Own Credential","description":"Rotate the runtime credential for one environment. Old secret dies now.\n\nSelf-service by design: this is what a provider reaches for at 3am after\nleaking a secret, and making them wait for an operator would mean the\nstolen credential stays live until someone reads an email.","operationId":"rotate_own_credential_v1_developer_providers__provider_id__rotate_credential_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/developer/providers/{provider_id}/rotate-oauth-secret":{"post":{"tags":["developer"],"summary":"Rotate Own Oauth Secret","description":"Rotate the OAuth client secret for one environment.\n\nSeparate from the runtime credential on purpose: they authenticate\ndifferent channels, and rotating one must not silently invalidate the\nother — a provider recovering from one leak should not take its whole\nintegration down.","operationId":"rotate_own_oauth_secret_v1_developer_providers__provider_id__rotate_oauth_secret_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/developer/providers/{provider_id}/events":{"get":{"tags":["developer"],"summary":"My Provider Events","description":"Audit events for this provider — the integration's own log.\n\nScoped by the provider id inside the event, so a provider cannot read\nanother's trail. Nothing here is PRAMPTA-internal: these are the events\nthe provider itself caused.","operationId":"my_provider_events_v1_developer_providers__provider_id__events_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/developer/providers/{provider_id}/health":{"get":{"tags":["developer"],"summary":"My Provider Health","description":"Operational facts a provider can act on.\n\nDeliberately excludes the risk score and the auto-suspend threshold. What\nis here — authorizations issued, receipts returned, completeness — the\nprovider can already derive from its own logs, so showing it leaks nothing\nand tells them precisely what to fix. What is withheld is PRAMPTA's\njudgement, because a bad actor who knows the bar will sit just beneath it.","operationId":"my_provider_health_v1_developer_providers__provider_id__health_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/developer/sandbox/fixtures":{"get":{"tags":["developer"],"summary":"Sandbox Fixtures","description":"The sandbox conformance catalogue.\n\nThis IS the spec: each fixture pins the exact outcome /verify must return,\nso a provider can assert against it in its own test suite rather than\nguessing what \"handled correctly\" means. Published openly to any signed-in\ndeveloper — there is nothing secret about the expected behaviour of a fake\nsubject, and hiding it would only make integrations worse.\n\n`sbx-unknown` is listed but deliberately NOT seeded: an integration has to\ncope with a subject that does not exist.","operationId":"sandbox_fixtures_v1_developer_sandbox_fixtures_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/checkout/sessions":{"get":{"tags":["checkout"],"summary":"List My Sessions","description":"The buyer's own purchase history.","operationId":"list_my_sessions_v1_checkout_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["checkout"],"summary":"Create Session","description":"Price a purchase and open a checkout session.\n\nThe split is computed HERE, server-side, and frozen on the row. It is never\naccepted from the request — a client-supplied split is a client-chosen\npayout. Freezing it also means a later config change cannot silently\nrewrite what a rights holder was promised for a sale already in flight.","operationId":"create_session_v1_checkout_sessions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/checkout/sessions/{session_id}":{"get":{"tags":["checkout"],"summary":"Get Session","operationId":"get_session_v1_checkout_sessions__session_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/checkout/sessions/{session_id}/confirm-payment":{"post":{"tags":["checkout"],"summary":"Confirm Payment","description":"Record payment and fulfil the purchase in one step.\n\nOperator-only while the PSP is `manual`: the buyer must not be able to\ndeclare their own payment received. When a real processor is wired, its\nsigned webhook takes this seat — the authority moves from a human to a\nverifiable signature, and nothing else about the flow changes.\n\nFulfilment is idempotent: confirming twice returns the same licence rather\nthan minting a second one.","operationId":"confirm_payment_v1_checkout_sessions__session_id__confirm_payment_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmPaymentIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/checkout/sessions/{session_id}/refund":{"post":{"tags":["checkout"],"summary":"Refund Session","description":"Refund a purchase and withdraw what it granted.\n\nMoney back means rights back: the entitlement becomes `refunded` and any\nminted licence is REVOKED, not deleted — the audit trail of what that\nlicence once authorized has to survive the refund.","operationId":"refund_session_v1_checkout_sessions__session_id__refund_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefundIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/checkout/obligations/outbound":{"get":{"tags":["checkout"],"summary":"Outbound Obligations","description":"Payee shares owed on OUT-OF-BAND sales — money PRAMPTA holds or has\npromised on behalf of payees, with no Stripe transfer to move it.\n\n`_send_split_transfers` (api/payments.py) only ever moves money for\npsp==\"stripe\" sessions; a bank-transfer sale an operator confirms owes\nthe provider and rights holder exactly the same shares, but until now\nthose cents existed only as frozen columns plus one audit entry — an\nuntracked payable. This is the tracking: every non-stripe session that\nreached paid/fulfilled with a share still unmarked, and the totals.\nSettling an obligation stays a manual, out-of-band act by nature; what\nchanged is that it can no longer be forgotten.","operationId":"outbound_obligations_v1_checkout_obligations_outbound_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/attestations/template":{"get":{"tags":["attestations"],"summary":"Get Attestation Template","description":"The exact clauses a claimant must acknowledge.\n\nPublic and unauthenticated: this is the text of a legal representation\npeople are asked to make. Hiding it until someone is mid-registration\nwould be the opposite of informed consent.","operationId":"get_attestation_template_v1_attestations_template_get","parameters":[{"name":"version","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/attestations":{"post":{"tags":["attestations"],"summary":"Create Attestation","description":"Record an attestation. Never updates — re-attesting supersedes.\n\nThis is deliberately its own act rather than a field on subject\nregistration: a claim about legal authority deserves its own record, its\nown timestamp, and its own audit event, and it can legitimately be made\nagain later (new template version, changed role, corrected legal name)\nwithout touching the subject.","operationId":"create_attestation_v1_subjects__subject_id__attestations_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttestationIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["attestations"],"summary":"List Attestations","description":"The claim history for a subject, newest first.\n\nVisible to the subject's controller and to operators. Superseded records\nare INCLUDED — the history is the point, and hiding earlier claims would\nmake it impossible to see that someone changed their story.","operationId":"list_attestations_v1_subjects__subject_id__attestations_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/lifecycle":{"get":{"tags":["attestations"],"summary":"Get Subject Lifecycle","description":"What this subject is allowed to do, and what it is not, and why.","operationId":"get_subject_lifecycle_v1_subjects__subject_id__lifecycle_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["attestations"],"summary":"Set Subject Lifecycle","description":"Move a subject along the trust ladder.\n\nOperator-only for every transition EXCEPT the two an owner legitimately\ndrives themselves: submitting for verification, and archiving their own\nsubject. Everything else — verifying, enabling commercially, suspending —\nis a judgement about evidence, and letting the claimant make it would make\nthe ladder decorative.","operationId":"set_subject_lifecycle_v1_subjects__subject_id__lifecycle_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleTransitionIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/authority-records":{"post":{"tags":["authority-review"],"summary":"Open Record","description":"Open a review of a claim of authority over this subject.","operationId":"open_record_v1_subjects__subject_id__authority_records_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}/evidence":{"post":{"tags":["authority-review"],"summary":"Add Evidence","description":"Attach a document. Encrypted before it touches the database.","operationId":"add_evidence_v1_authority_records__record_id__evidence_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}/evidence/{evidence_id}":{"delete":{"tags":["authority-review"],"summary":"Remove Evidence","description":"Remove a document from a draft — including uploading the wrong file,\nwhich people do, and which should not require support to undo.","operationId":"remove_evidence_v1_authority_records__record_id__evidence__evidence_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}},{"name":"evidence_id","in":"path","required":true,"schema":{"type":"string","title":"Evidence Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}/evidence/{evidence_id}/content":{"get":{"tags":["authority-review"],"summary":"Read Evidence","description":"Decrypt and return one document. The only endpoint that does.\n\nLogged BEFORE the bytes are produced, and the log is committed even if\ndecryption then fails — an access that errored is still an access, and a\nlog written only on success is a log that can be evaded.","operationId":"read_evidence_v1_authority_records__record_id__evidence__evidence_id__content_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}},{"name":"evidence_id","in":"path","required":true,"schema":{"type":"string","title":"Evidence Id"}},{"name":"reason","in":"query","required":false,"schema":{"type":"string","default":"","title":"Reason"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}/submit":{"post":{"tags":["authority-review"],"summary":"Submit Record","description":"Freeze the evidence set and put the record in the queue.","operationId":"submit_record_v1_authority_records__record_id__submit_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}/withdraw":{"post":{"tags":["authority-review"],"summary":"Withdraw Record","operationId":"withdraw_record_v1_authority_records__record_id__withdraw_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}/assign":{"post":{"tags":["authority-review"],"summary":"Assign Record","description":"An operator takes the review.\n\nRefused if the operator is the claimant. Grading your own homework is the\nexact failure the whole ladder exists to prevent, and an operator account\ncan also own subjects.","operationId":"assign_record_v1_authority_records__record_id__assign_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}/decide":{"post":{"tags":["authority-review"],"summary":"Decide Record","description":"Approve, reject, or send back for more evidence.","operationId":"decide_record_v1_authority_records__record_id__decide_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__authority_review__DecisionIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records":{"get":{"tags":["authority-review"],"summary":"List Records","description":"The claimant's own records, or — for an operator — the review queue.","operationId":"list_records_v1_authority_records_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"subject_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}":{"get":{"tags":["authority-review"],"summary":"Get Record","operationId":"get_record_v1_authority_records__record_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/authority-records/{record_id}/access-log":{"get":{"tags":["authority-review"],"summary":"Get Access Log","description":"Who opened this person's documents.\n\nVisible to the CLAIMANT, not just to operators. Someone who handed over a\npassport is entitled to know who looked at it, and a read log only visible\nto the people doing the reading protects the wrong party.","operationId":"get_access_log_v1_authority_records__record_id__access_log_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/{subject_id}/disputes":{"post":{"tags":["disputes"],"summary":"File Dispute","description":"Contest a claim over this subject. Restricts it immediately.","operationId":"file_dispute_v1_subjects__subject_id__disputes_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisputeIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["disputes"],"summary":"List Subject Disputes","description":"What is contested here. The subject's controller needs to see this\nwithout being told to go and find it.","operationId":"list_subject_disputes_v1_subjects__subject_id__disputes_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"subject_id","in":"path","required":true,"schema":{"type":"string","title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}/respond":{"post":{"tags":["disputes"],"summary":"Respond","description":"The subject's side of it.","operationId":"respond_v1_disputes__dispute_id__respond_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}/withdraw":{"post":{"tags":["disputes"],"summary":"Withdraw","operationId":"withdraw_v1_disputes__dispute_id__withdraw_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}/assign":{"post":{"tags":["disputes"],"summary":"Assign","operationId":"assign_v1_disputes__dispute_id__assign_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}/resolve":{"post":{"tags":["disputes"],"summary":"Resolve","description":"Uphold or reject. Either way the reason is recorded and both sides see it.","operationId":"resolve_v1_disputes__dispute_id__resolve_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}/evidence":{"post":{"tags":["disputes"],"summary":"Add Dispute Evidence","description":"Either side may attach documents while the dispute is open.","operationId":"add_dispute_evidence_v1_disputes__dispute_id__evidence_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}/evidence/{evidence_id}/content":{"get":{"tags":["disputes"],"summary":"Read Dispute Evidence","description":"Read one document. Logged before the bytes are produced.\n\nThe other SIDE cannot read it — only the uploader and operators. Evidence in\na rights dispute routinely contains contracts and identity documents, and\nhanding them to the person you are contesting would make filing a dispute a\nway to extract someone's papers.","operationId":"read_dispute_evidence_v1_disputes__dispute_id__evidence__evidence_id__content_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}},{"name":"evidence_id","in":"path","required":true,"schema":{"type":"string","title":"Evidence Id"}},{"name":"reason","in":"query","required":false,"schema":{"type":"string","default":"","title":"Reason"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}/access-log":{"get":{"tags":["disputes"],"summary":"Dispute Access Log","operationId":"dispute_access_log_v1_disputes__dispute_id__access_log_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes":{"get":{"tags":["disputes"],"summary":"List Disputes","operationId":"list_disputes_v1_disputes_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}":{"get":{"tags":["disputes"],"summary":"Get Dispute","operationId":"get_dispute_v1_disputes__dispute_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/disputes/{dispute_id}/appeals":{"post":{"tags":["disputes"],"summary":"File Appeal","description":"Ask for a decided dispute to be looked at again.\n\nFiling changes NOTHING about the subject. If merely filing lifted a\nsuspension, every suspended subject would file one and the suspension would\nmean nothing. Only the outcome moves anything.","operationId":"file_appeal_v1_disputes__dispute_id__appeals_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"dispute_id","in":"path","required":true,"schema":{"type":"string","title":"Dispute Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppealIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/appeals/{appeal_id}/evidence":{"post":{"tags":["disputes"],"summary":"Add Appeal Evidence","description":"Attach a document to an open appeal.\n\n`new_evidence` would be a hollow ground without somewhere to put the\nevidence, so appeals reuse the same encrypted vault and read log as A4/A5 —\nwith their own context, so an appeal's documents never leak into the closed\ndispute's file.","operationId":"add_appeal_evidence_v1_appeals__appeal_id__evidence_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"appeal_id","in":"path","required":true,"schema":{"type":"string","title":"Appeal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvidenceIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/appeals/{appeal_id}/withdraw":{"post":{"tags":["disputes"],"summary":"Withdraw Appeal","operationId":"withdraw_appeal_v1_appeals__appeal_id__withdraw_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"appeal_id","in":"path","required":true,"schema":{"type":"string","title":"Appeal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/appeals/{appeal_id}/assign":{"post":{"tags":["disputes"],"summary":"Assign Appeal","description":"An operator takes the appeal.\n\nRefused if they are the appellant, always. Refused if they made the original\nruling ONLY when the deployment has enough operators to forbid it — see\nAPPEAL_REQUIRES_DIFFERENT_REVIEWER.","operationId":"assign_appeal_v1_appeals__appeal_id__assign_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"appeal_id","in":"path","required":true,"schema":{"type":"string","title":"Appeal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/appeals/{appeal_id}/decide":{"post":{"tags":["disputes"],"summary":"Decide Appeal","description":"Grant or deny an appeal.\n\nGranting does DIFFERENT things depending on what was appealed, and neither\nof them is \"flip the verdict\":\n\n* An upheld dispute overturned → the subject is restored to where it was\n  before the dispute, exactly as a rejection would have left it.\n* A rejected dispute overturned → the dispute REOPENS for review. The appeal\n  says the decision was wrong, not that the opposite is right; deciding the\n  dispute again on the merits is the honest consequence.","operationId":"decide_appeal_v1_appeals__appeal_id__decide_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"appeal_id","in":"path","required":true,"schema":{"type":"string","title":"Appeal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppealDecisionIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/appeals":{"get":{"tags":["disputes"],"summary":"List Appeals","operationId":"list_appeals_v1_appeals_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/appeals/{appeal_id}":{"get":{"tags":["disputes"],"summary":"Get Appeal","operationId":"get_appeal_v1_appeals__appeal_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"appeal_id","in":"path","required":true,"schema":{"type":"string","title":"Appeal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/approvals/":{"get":{"tags":["operator-approvals"],"summary":"List Approvals","description":"Staff who can decide approvals see the whole queue; anyone else sees only\nwhat they requested (so a requester can track their own pending action).","operationId":"list_approvals_v1_approvals__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/approvals":{"get":{"tags":["operator-approvals"],"summary":"List Approvals","description":"Staff who can decide approvals see the whole queue; anyone else sees only\nwhat they requested (so a requester can track their own pending action).","operationId":"list_approvals_v1_approvals_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/approvals/{approval_id}":{"get":{"tags":["operator-approvals"],"summary":"Get Approval","operationId":"get_approval_v1_approvals__approval_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"approval_id","in":"path","required":true,"schema":{"type":"string","title":"Approval Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/approvals/{approval_id}/withdraw":{"post":{"tags":["operator-approvals"],"summary":"Withdraw","operationId":"withdraw_v1_approvals__approval_id__withdraw_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"approval_id","in":"path","required":true,"schema":{"type":"string","title":"Approval Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/approvals/{approval_id}/reject":{"post":{"tags":["operator-approvals"],"summary":"Reject","operationId":"reject_v1_approvals__approval_id__reject_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"approval_id","in":"path","required":true,"schema":{"type":"string","title":"Approval Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__operator_approvals__DecisionIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/approvals/{approval_id}/approve":{"post":{"tags":["operator-approvals"],"summary":"Approve","description":"A second, different operator agrees. This re-runs the original request\nend to end, so a legality check that would now fail (state moved on) still\nfails here — approval is not a bypass of the checks the first call made.","operationId":"approve_v1_approvals__approval_id__approve_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"approval_id","in":"path","required":true,"schema":{"type":"string","title":"Approval Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__operator_approvals__DecisionIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/policy/rules":{"get":{"tags":["policy"],"summary":"List Rules","operationId":"list_rules_v1_policy_rules_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/policy/versions":{"get":{"tags":["policy"],"summary":"List Versions","operationId":"list_versions_v1_policy_versions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/payments/webhook/{psp}":{"post":{"tags":["payments"],"summary":"Psp Webhook","description":"Receive and settle a payment notification.\n\nAlways returns 200 for an authentic notification, even when it is\nrejected on the merits — a PSP retries non-2xx, and endlessly redelivering\nan event we have correctly decided not to honour helps nobody. A FORGED\nnotification gets 400: that one is not a delivery problem.","operationId":"psp_webhook_v1_payments_webhook__psp__post","parameters":[{"name":"psp","in":"path","required":true,"schema":{"type":"string","title":"Psp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v2/requests":{"post":{"tags":["pre-gen v2"],"summary":"Post Request","description":"Ask for permission for one subject of one job. Returns the signed answer.","operationId":"post_request_v2_requests_post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Env"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v2/reports":{"post":{"tags":["pre-gen v2"],"summary":"Post Report","description":"Record what happened under an answer (or with no answer). A report never\ngrants anything. Returns the registry's signed acknowledgement.","operationId":"post_report_v2_reports_post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Env"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v2/keys":{"post":{"tags":["pre-gen v2"],"summary":"Post Keys","description":"The provider's signing keys (§4.9). `first`: once, signed by the key it\nnames, which proves possession. `rotation`: names the current keyset as\n`previous`, signed by the new key and by the current one. /v2 reports are\nverified with the current key — and /v1 receipts from this provider must be\nsigned with it too (receipts.py). Authenticated by the provider's own\ncredential. Already acknowledged reports keep their acknowledgements.","operationId":"post_keys_v2_keys_post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Env"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v2/keys/{provider_id}":{"get":{"tags":["pre-gen v2"],"summary":"Get Keys","description":"A provider's keysets, oldest first: public keys, so anyone can check a\nreport against the key that was current when it was acknowledged.","operationId":"get_keys_v2_keys__provider_id__get","parameters":[{"name":"provider_id","in":"path","required":true,"schema":{"type":"string","title":"Provider Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/offers":{"post":{"tags":["priced-offers"],"summary":"Create Offer","description":"Publish a price for a subject. Created in `draft` — publishing is a\nsecond, deliberate act, so a half-written offer is never purchasable.","operationId":"create_offer_v1_offers_post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["priced-offers"],"summary":"List Offers","description":"What a buyer may purchase for this subject. Public: a price a buyer\ncannot see before authenticating is not really a published price.","operationId":"list_offers_v1_offers_get","parameters":[{"name":"subject_id","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Subject Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/offers/{offer_id}/status":{"post":{"tags":["priced-offers"],"summary":"Set Offer Status","description":"Activate, pause or withdraw. Note what is NOT here: editing price or\nterms. Those supersede into a new version rather than mutating a row\nbuyers may already hold a quote against.","operationId":"set_offer_status_v1_offers__offer_id__status_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"offer_id","in":"path","required":true,"schema":{"type":"string","title":"Offer Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferStatusIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/offers/{offer_id}":{"get":{"tags":["priced-offers"],"summary":"Get Offer","operationId":"get_offer_v1_offers__offer_id__get","parameters":[{"name":"offer_id","in":"path","required":true,"schema":{"type":"string","title":"Offer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/quotes":{"post":{"tags":["priced-offers"],"summary":"Create Quote","description":"Freeze an offer's price for this buyer.\n\nEverything a payment could later disagree with is copied here and never\nupdated — the offer may be repriced or withdrawn afterwards, and a quote\nalready issued still says what was promised.","operationId":"create_quote_v1_quotes_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteIn"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/quotes/{quote_id}":{"get":{"tags":["priced-offers"],"summary":"Get Quote","operationId":"get_quote_v1_quotes__quote_id__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"quote_id","in":"path","required":true,"schema":{"type":"string","title":"Quote Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/quotes/{quote_id}/accept-terms":{"post":{"tags":["priced-offers"],"summary":"Accept Terms","description":"Record explicit agreement to the exact terms quoted.\n\nThe client echoes back the hash it displayed. A mismatch means the buyer\nwas shown something other than what this quote froze, and agreeing to it\nwould record consent to text they never saw.","operationId":"accept_terms_v1_quotes__quote_id__accept_terms_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"quote_id","in":"path","required":true,"schema":{"type":"string","title":"Quote Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptTermsIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/detections/":{"post":{"tags":["subject-detection"],"summary":"Report Detection","description":"Record what the provider's local text match suggested, BEFORE the user\nhas answered. Purely advisory — creates no entitlement, no licence.","operationId":"report_detection_v1_subjects_detections__post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/detections/{detection_id}/confirm":{"post":{"tags":["subject-detection"],"summary":"Confirm Detection","description":"Record the user's actual answer. Still advisory-only: confirming here\ndoes not itself authorize anything -- the caller still calls /verify\n(optionally echoing this detection_id) exactly as it would have anyway.","operationId":"confirm_detection_v1_subjects_detections__detection_id__confirm_post","parameters":[{"name":"detection_id","in":"path","required":true,"schema":{"type":"string","title":"Detection Id"}},{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/subjects/detections/{detection_id}":{"get":{"tags":["subject-detection"],"summary":"Get Detection","operationId":"get_detection_v1_subjects_detections__detection_id__get","parameters":[{"name":"detection_id","in":"path","required":true,"schema":{"type":"string","title":"Detection Id"}},{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/verification/request":{"post":{"tags":["verification"],"summary":"Request Verification","description":"File a verification request. One pending request at a time — a second\nfiling on top of an unreviewed one would just be a way to flood the queue,\nnot a way to get seen sooner.\n\nRequires 2FA (require_2fa): the verified badge is a trust signal other\nusers and licensees rely on, so the account earning it should itself be\nprotected by more than a password.","operationId":"request_verification_v1_verification_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationRequestBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/verification/status":{"get":{"tags":["verification"],"summary":"Verification Status","description":"What Settings -> Verification renders: verified or not, and the most\nrecent request (pending, or the outcome of the last one that finished).","operationId":"verification_status_v1_verification_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/verification/requests":{"get":{"tags":["verification"],"summary":"List Verification Requests","operationId":"list_verification_requests_v1_verification_requests_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/verification/requests/{request_id}":{"patch":{"tags":["verification"],"summary":"Decide Verification Request","operationId":"decide_verification_request_v1_verification_requests__request_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecideRequestBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/2fa/status":{"get":{"tags":["two-factor"],"summary":"Status","operationId":"status_v1_2fa_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/2fa/setup":{"post":{"tags":["two-factor"],"summary":"Setup","description":"Generates a new secret (not yet active) and returns it for manual\nentry plus a QR code. Calling this again before /2fa/enable simply\nreplaces the pending secret — nothing is committed to \"enabled\" yet.","operationId":"setup_v1_2fa_setup_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/2fa/enable":{"post":{"tags":["two-factor"],"summary":"Enable","operationId":"enable_v1_2fa_enable_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnableRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/2fa/disable":{"post":{"tags":["two-factor"],"summary":"Disable","description":"Disabling is a downgrade of the account's own security, so it's\nstep-up authenticated — the same bar enabling it needed — not just a\nvalid session token.\n\nA Google-only account has NO password (hashed_password is \"\" — see\ngoogle_auth in api/auth.py) and no way to ever set one (password reset\nis local-only). Requiring a password unconditionally here meant 2FA was\nPERMANENTLY undisableable for such an account: every call 401'd, with no\npath out short of us editing the database directly (2026-08 founder\nreport — they hit exactly this after enabling 2FA on a Google account).\nSo the step-up proof is the password when the account has one, and a\ntyped confirmation of the username when it doesn't. Either way the\ncurrent TOTP/backup code is still required, unchanged — that's the part\nactually proving continued possession of the second factor.","operationId":"disable_v1_2fa_disable_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisableRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/users/{username}":{"get":{"tags":["users"],"summary":"Get Public User","description":"Public profile lookup by @username (case-insensitive — usernames are\nstored as typed, but people retype handles from memory).\n\nDeactivated accounts 404 the same as a nonexistent username — there is\nno separate \"this account was suspended\" signal to leak to a visitor.\nOnly what already renders elsewhere (Library creator attribution,\nSettings header) is exposed here: nothing new becomes public by way of\nthis endpoint existing.","operationId":"get_public_user_v1_users__username__get","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/assertions/":{"post":{"tags":["assertions"],"summary":"Create Assertion","description":"Issue (or, if already issued, return) the pg.assertion.v1 for a\ndecision this provider/licensee pair already receipted. Idempotent —\nC2PA embedding may need to re-fetch the same assertion later, and it\nshould be byte-identical each time, not re-signed with a new issued_at.","operationId":"create_assertion_v1_assertions__post","parameters":[{"name":"X-Provider-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Provider-Id"}},{"name":"X-Licensee-ID","in":"header","required":true,"schema":{"type":"string","title":"X-Licensee-Id"}},{"name":"authorization","in":"header","required":true,"schema":{"type":"string","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssertionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/assertions/{decision_id}":{"get":{"tags":["assertions"],"summary":"Get Assertion","description":"Fetch a previously issued assertion — public and unauthenticated, same\nreasoning as the Merkle inclusion-proof endpoints: a third party checking\na C2PA manifest's embedded PRE-GEN assertion needs to be able to fetch and\nverify it without going through the registry's own auth.","operationId":"get_assertion_v1_assertions__decision_id__get","parameters":[{"name":"decision_id","in":"path","required":true,"schema":{"type":"string","title":"Decision Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/connect/onboard":{"post":{"tags":["connect"],"summary":"Onboard","description":"Create (if missing) the payee's Stripe connected account and return a\nfresh onboarding link. Safe to call repeatedly — an existing account is\nreused, only the (short-lived) link is minted new each time.","operationId":"onboard_v1_connect_onboard_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/connect/status":{"get":{"tags":["connect"],"summary":"Status","description":"Live payout-readiness for the caller (or `org_id`). Nothing here is\ncached — see models/stripe_connect_account.py's docstring for why.","operationId":"status_v1_connect_status_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pg/{code}":{"get":{"tags":["pg-resolver"],"summary":"Resolve Pg Code","description":"Existence + coarse status for a PG code, no account required.\n\nResponse shape is deliberately minimal and stable -- exactly\n{\"kind\", \"found\", \"status\"}, nothing else, so a future field addition\nhere is a considered decision (see the response test's exact key-set\nassertion), not an accidental leak.","operationId":"resolve_pg_code_v1_pg__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credits/entries":{"get":{"tags":["credits"],"summary":"List Public Entries","description":"The credits roll itself: approved names, oldest first — the order is\nthe content, so it is submission order, never alphabetical.","operationId":"list_public_entries_v1_credits_entries_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["credits"],"summary":"Submit Entry","description":"Ask to be credited. Open to anyone, signed in or not.","operationId":"submit_entry_v1_credits_entries_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/v1/credits/entries/queue":{"get":{"tags":["credits"],"summary":"List Queue","operationId":"list_queue_v1_credits_entries_queue_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"pending","title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credits/entries/{entry_id}/decide":{"post":{"tags":["credits"],"summary":"Decide Entry","operationId":"decide_entry_v1_credits_entries__entry_id__decide_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecideRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credits/entries/{entry_id}":{"patch":{"tags":["credits"],"summary":"Rename Entry","description":"Change the credited name itself — nothing else about the entry.\n\nSeparate from decide_entry on purpose: renaming isn't a decision about\nwhether the entry belongs on the roll, it's a correction to what it\nsays (a typo, a preferred spelling, a name someone asked to be updated).\nWorks on an entry of any status, not just approved ones — fixing a\npending submission's name before approving it is the more common case\nin practice, not the exception.","operationId":"rename_entry_v1_credits_entries__entry_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenameRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["credits"],"summary":"Delete Entry","description":"Remove a row outright.\n\nDeliberately a real delete, not another status: `rejected` is the record\nthat a stranger's SUBMISSION was considered and turned down, and it is\nworth keeping. An operator adding \"@marco_rossi\" with a typo has not\nconsidered anything — leaving that in a rejected pile forever would turn\na queue people read into a bin of the founder's own mis-clicks.\n\nThe audit entry survives the row (it records the name), so the deletion\nitself is still accountable even though what was deleted is gone.","operationId":"delete_entry_v1_credits_entries__entry_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credits/entries/{entry_id}/kind":{"patch":{"tags":["credits"],"summary":"Set Entry Kind","description":"Move a name between the two tiers — in practice, promoting a supporter\nto contributor once they have actually made something.\n\nThis is the whole point of having two kinds: the supporter tier is not a\nconsolation prize, it is a visible step below a step someone can climb.\nDemotion is allowed by the same call rather than forbidden, because the\nrealistic reason to need it is an operator's own mis-click, and a\none-way door would mean fixing that in the database by hand.\n\nSeparate from decide() and rename() for the reason those two are separate\nfrom each other: they answer different questions (does this belong on the\nroll / what does it say / which tier is it), and one endpoint answering\nall three makes every caller pass fields it does not mean to change.","operationId":"set_entry_kind_v1_credits_entries__entry_id__kind_patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetKindRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credits/entries/direct":{"post":{"tags":["credits"],"summary":"Add Entry Directly","description":"An operator adds a name straight onto the public roll — no contact\nemail, no links, no review queue. This is the founder-curation path\n(crediting a supporter who didn't go through the public form\nthemselves), not a shortcut around the submission form's own rules for\neveryone else: those still apply in full to anyone using POST\n/entries. Lands `approved` immediately, same as scripts/\nseed_test_credits.py did one-off from a shell — this is that same\ncapability, reachable from the admin panel instead of a script someone\nhas to copy into the container.","operationId":"add_entry_directly_v1_credits_entries_direct_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectAddRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/keys":{"get":{"tags":["keys"],"summary":"Get Keys","description":"Return the operator signed key set.\n\nContains current key, historical keys, grace period info,\nand an Ed25519 signature over the key set (signed by current key).\nClients can use this to verify key rotation is legitimate.","operationId":"get_keys_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/pg-policy":{"get":{"tags":["well-known"],"summary":"Pg Policy","operationId":"pg_policy__well_known_pg_policy_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/healthz":{"get":{"summary":"Healthz","description":"Health check — verifies DB connectivity.","operationId":"healthz_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/version":{"get":{"summary":"Version","description":"What is actually running, right now, on whatever this is.\n\nA deploy that half-lands — UI shipped but a backend feature flag still\noff, or vice versa — is invisible from the outside without this: commit\nand app version come from the deploy pipeline (deploy.sh exports\nGIT_COMMIT/APP_VERSION, docker-compose passes them through; both read\n\"unknown\" off a plain local checkout), and `features` is read live from\nsettings — never hand-copied — so it cannot drift from what the process\nactually enforces.","operationId":"version_version_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AcceptTermsIn":{"properties":{"terms_hash":{"type":"string","maxLength":64,"minLength":0,"title":"Terms Hash"},"commercial_terms_hash":{"anyOf":[{"type":"string","maxLength":64,"minLength":64},{"type":"null"}],"title":"Commercial Terms Hash"}},"type":"object","required":["terms_hash"],"title":"AcceptTermsIn"},"AddMemberRequest":{"properties":{"licensee_id":{"type":"string","title":"Licensee Id"}},"type":"object","required":["licensee_id"],"title":"AddMemberRequest"},"AppealDecisionIn":{"properties":{"action":{"type":"string","maxLength":16,"title":"Action"},"note":{"type":"string","maxLength":2000,"minLength":1,"title":"Note"}},"type":"object","required":["action","note"],"title":"AppealDecisionIn"},"AppealIn":{"properties":{"grounds":{"type":"string","maxLength":32,"title":"Grounds","default":"decision_unsupported"},"statement":{"type":"string","maxLength":5000,"minLength":10,"title":"Statement"}},"type":"object","required":["statement"],"title":"AppealIn"},"ApplicationIn":{"properties":{"provider_id":{"type":"string","maxLength":50,"minLength":3,"title":"Provider Id"},"legal_name":{"type":"string","maxLength":255,"title":"Legal Name","default":""},"brand_name":{"type":"string","maxLength":255,"title":"Brand Name","default":""},"domain":{"type":"string","maxLength":255,"title":"Domain","default":""},"website":{"type":"string","maxLength":500,"title":"Website","default":""},"privacy_policy_url":{"type":"string","maxLength":500,"title":"Privacy Policy Url","default":""},"terms_url":{"type":"string","maxLength":500,"title":"Terms Url","default":""},"security_contact":{"type":"string","maxLength":255,"title":"Security Contact","default":""},"technical_contact":{"type":"string","maxLength":255,"title":"Technical Contact","default":""},"rights_holder_contact":{"type":"string","maxLength":255,"title":"Rights Holder Contact","default":""},"requested_scopes":{"items":{"type":"string"},"type":"array","title":"Requested Scopes"},"requested_redirect_uris":{"items":{"type":"string"},"type":"array","title":"Requested Redirect Uris"}},"type":"object","required":["provider_id"],"title":"ApplicationIn"},"ApproveRequestBody":{"properties":{"subject_signature_hex":{"type":"string","title":"Subject Signature Hex","default":""},"response_message":{"type":"string","title":"Response Message","default":""}},"type":"object","title":"ApproveRequestBody"},"AssertionBody":{"properties":{"provider_id":{"type":"string","maxLength":100,"minLength":1,"title":"Provider Id"},"external_user_id":{"type":"string","maxLength":255,"minLength":1,"title":"External User Id"},"external_subject_hash":{"type":"string","maxLength":64,"minLength":64,"title":"External Subject Hash"},"provider_account_status":{"type":"string","pattern":"^(active|suspended|deleted)$","title":"Provider Account Status","default":"active"},"email_hash":{"anyOf":[{"type":"string","maxLength":64,"minLength":64},{"type":"null"}],"title":"Email Hash"},"timestamp":{"type":"string","maxLength":64,"minLength":1,"title":"Timestamp"},"audience":{"type":"string","maxLength":64,"minLength":1,"title":"Audience"},"nonce":{"type":"string","maxLength":64,"minLength":4,"title":"Nonce"},"assertion_id":{"type":"string","maxLength":64,"minLength":1,"title":"Assertion Id"}},"type":"object","required":["provider_id","external_user_id","external_subject_hash","timestamp","audience","nonce","assertion_id"],"title":"AssertionBody","description":"Fields that go into the signed body. `signature` is separate — the\nsignature is computed over ``canonical_json(body)`` where ``body`` is\nTHIS dict, so any change here changes the wire contract."},"AssertionIn":{"properties":{"body":{"$ref":"#/components/schemas/AssertionBody"},"signature":{"type":"string","maxLength":128,"minLength":128,"title":"Signature"}},"type":"object","required":["body","signature"],"title":"AssertionIn"},"AssertionOut":{"properties":{"schema_version":{"type":"string","title":"Schema Version","default":"pg.identity.v1"},"assertion_id":{"type":"string","title":"Assertion Id"},"id":{"type":"string","title":"Id"},"signature_verified":{"type":"boolean","title":"Signature Verified"},"audience":{"type":"string","title":"Audience"},"provider_id":{"type":"string","title":"Provider Id"},"external_subject_hash":{"type":"string","title":"External Subject Hash"}},"type":"object","required":["assertion_id","id","signature_verified","audience","provider_id","external_subject_hash"],"title":"AssertionOut"},"AssertionRequest":{"properties":{"decision_id":{"type":"string","title":"Decision Id"}},"type":"object","required":["decision_id"],"title":"AssertionRequest"},"AttestationIn":{"properties":{"role":{"type":"string","maxLength":32,"minLength":1,"title":"Role"},"acknowledged_clauses":{"type":"object","title":"Acknowledged Clauses"},"attestation_version":{"type":"string","maxLength":16,"title":"Attestation Version","default":"v1"},"jurisdiction":{"type":"string","maxLength":8,"title":"Jurisdiction","default":""},"legal_name":{"type":"string","maxLength":255,"title":"Legal Name","default":""},"business_name":{"type":"string","maxLength":255,"title":"Business Name","default":""},"authority_basis":{"type":"string","maxLength":40,"title":"Authority Basis","default":""},"claimant_org_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Claimant Org Id"}},"type":"object","required":["role"],"title":"AttestationIn"},"AuthorizeDecisionIn":{"properties":{"client_id":{"type":"string","maxLength":64,"minLength":1,"title":"Client Id"},"redirect_uri":{"type":"string","maxLength":2048,"minLength":1,"title":"Redirect Uri"},"scope":{"type":"string","maxLength":512,"minLength":1,"title":"Scope"},"state":{"type":"string","maxLength":512,"minLength":1,"title":"State"},"code_challenge":{"type":"string","maxLength":128,"minLength":43,"title":"Code Challenge"},"code_challenge_method":{"type":"string","maxLength":8,"title":"Code Challenge Method","default":"S256"},"nonce":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Nonce"},"response_type":{"type":"string","maxLength":16,"title":"Response Type","default":"code"},"approved":{"type":"boolean","title":"Approved"}},"type":"object","required":["client_id","redirect_uri","scope","state","code_challenge","approved"],"title":"AuthorizeDecisionIn"},"AuthorizeDecisionOut":{"properties":{"redirect_to":{"type":"string","title":"Redirect To"},"post_message_origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Post Message Origin"}},"type":"object","required":["redirect_to","post_message_origin"],"title":"AuthorizeDecisionOut"},"AuthorizeDescribeOut":{"properties":{"status":{"type":"string","title":"Status"},"client_id":{"type":"string","title":"Client Id"},"provider_id":{"type":"string","title":"Provider Id"},"client_name":{"type":"string","title":"Client Name"},"environment":{"type":"string","title":"Environment"},"redirect_uri":{"type":"string","title":"Redirect Uri"},"scopes":{"items":{"type":"object"},"type":"array","title":"Scopes"},"previously_granted":{"type":"boolean","title":"Previously Granted"}},"type":"object","required":["status","client_id","provider_id","client_name","environment","redirect_uri","scopes","previously_granted"],"title":"AuthorizeDescribeOut"},"AvatarUpdateRequest":{"properties":{"avatar_url":{"type":"string","title":"Avatar Url"}},"type":"object","required":["avatar_url"],"title":"AvatarUpdateRequest"},"BanRequest":{"properties":{"banned":{"type":"boolean","title":"Banned"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["banned"],"title":"BanRequest"},"BindIn":{"properties":{"id":{"type":"string","maxLength":64,"minLength":1,"title":"Id","description":"ProviderIdentityAssertion row id (returned by /provider/identity-assertions)"},"provider_id":{"type":"string","maxLength":100,"minLength":1,"title":"Provider Id"}},"type":"object","required":["id","provider_id"],"title":"BindIn"},"BindOut":{"properties":{"link_id":{"type":"string","title":"Link Id"},"prampta_user_id":{"type":"string","title":"Prampta User Id"},"provider_id":{"type":"string","title":"Provider Id"},"external_user_id":{"type":"string","title":"External User Id"},"external_subject_hash":{"type":"string","title":"External Subject Hash"},"verification_method":{"type":"string","title":"Verification Method"},"verified_at":{"type":"string","title":"Verified At"}},"type":"object","required":["link_id","prampta_user_id","provider_id","external_user_id","external_subject_hash","verification_method","verified_at"],"title":"BindOut"},"Body_issue_token_v1_oauth_token_post":{"properties":{"grant_type":{"type":"string","title":"Grant Type"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"redirect_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect Uri"},"code_verifier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code Verifier"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"}},"type":"object","required":["grant_type"],"title":"Body_issue_token_v1_oauth_token_post"},"Body_revoke_token_v1_oauth_revoke_post":{"properties":{"token":{"type":"string","title":"Token"},"token_type_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token Type Hint"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"}},"type":"object","required":["token"],"title":"Body_revoke_token_v1_oauth_revoke_post"},"BreachReport":{"properties":{"action":{"type":"string","title":"Action","default":"notice"},"detail":{"type":"string","maxLength":2000,"title":"Detail","default":""},"receipt_id":{"type":"string","maxLength":100,"title":"Receipt Id","default":""},"evidence_url":{"type":"string","maxLength":1000,"title":"Evidence Url","default":""}},"type":"object","title":"BreachReport","description":"A rights holder saying: this generation is outside what I licensed."},"BulkRegisterRequest":{"properties":{"subjects":{"items":{"$ref":"#/components/schemas/BulkSubjectItem"},"type":"array","title":"Subjects"},"attestation":{"type":"string","title":"Attestation","default":""},"evidence_ref":{"type":"string","title":"Evidence Ref","default":""},"std_ack_version":{"type":"string","title":"Std Ack Version","default":""}},"type":"object","required":["subjects"],"title":"BulkRegisterRequest"},"BulkSubjectItem":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases","default":[]},"rules_text":{"type":"string","title":"Rules Text","default":""},"visibility":{"type":"string","title":"Visibility","default":"public"}},"type":"object","required":["subject_id"],"title":"BulkSubjectItem"},"ChangePasswordRequest":{"properties":{"current_password":{"type":"string","title":"Current Password"},"new_password":{"type":"string","title":"New Password"}},"type":"object","required":["current_password","new_password"],"title":"ChangePasswordRequest"},"CheckoutCreate":{"properties":{"quote_id":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Quote Id"},"subject_id":{"type":"string","maxLength":255,"title":"Subject Id","default":""},"provider_id":{"type":"string","maxLength":100,"title":"Provider Id","default":""},"licence_cents":{"type":"integer","maximum":100000000.0,"minimum":0.0,"title":"Licence Cents","default":0},"license_class":{"type":"string","pattern":"^(RND|PRM)$","title":"License Class","default":"PRM"},"quantity":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Quantity","default":1},"duration_days":{"type":"integer","maximum":3650.0,"minimum":1.0,"title":"Duration Days","default":1},"currency":{"type":"string","maxLength":3,"minLength":3,"title":"Currency","default":"USD"},"allowed_use":{"type":"object","title":"Allowed Use"}},"type":"object","title":"CheckoutCreate","description":"Open a checkout session.\n\nTwo shapes, and the difference matters:\n\n* `quote_id` — the supported path. Price, currency and terms come from the\n  frozen quote, so the buyer chooses WHAT to buy and never what to pay.\n* the legacy fields — `licence_cents` off the request body, i.e. the buyer\n  naming their own price. Retained only so pre-offer integrations do not\n  break, and refused outright once PRICED_OFFERS_ENABLED is on."},"ClaimRequest":{"properties":{"intent":{"type":"string","title":"Intent","default":"consent"},"evidence":{"type":"string","title":"Evidence","default":""},"new_public_key_hex":{"type":"string","title":"New Public Key Hex","default":""},"proof_signature_hex":{"type":"string","title":"Proof Signature Hex","default":""}},"type":"object","title":"ClaimRequest"},"ClaimResolveRequest":{"properties":{"action":{"type":"string","title":"Action"},"note":{"type":"string","title":"Note","default":""}},"type":"object","required":["action"],"title":"ClaimResolveRequest"},"CloseIn":{"properties":{"outcome":{"type":"string","enum":["removed","licensed","no_issue","unresolved"],"title":"Outcome"},"note":{"type":"string","maxLength":2000,"title":"Note","default":""},"license_id":{"type":"string","maxLength":32,"title":"License Id","default":""}},"type":"object","required":["outcome"],"title":"CloseIn"},"ConfirmDeletionRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"ConfirmDeletionRequest"},"ConfirmIn":{"properties":{"subject_id":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Subject Id"}},"type":"object","title":"ConfirmIn"},"ConfirmPaymentIn":{"properties":{"psp":{"type":"string","maxLength":24,"title":"Psp","default":"manual"},"psp_reference":{"type":"string","maxLength":255,"minLength":1,"title":"Psp Reference"}},"type":"object","required":["psp_reference"],"title":"ConfirmPaymentIn","description":"Confirmation that money actually arrived.\n\n`psp_reference` is the processor's own id for the payment. It is stored\nUNIQUE per PSP so a webhook redelivery lands on the same row instead of\ncreating a second purchase."},"CounterOfferBody":{"properties":{"price_cents":{"type":"integer","exclusiveMinimum":0.0,"title":"Price Cents"}},"type":"object","required":["price_cents"],"title":"CounterOfferBody"},"CreateExceptionRequest":{"properties":{"category":{"type":"string","title":"Category"},"allowed_for_product":{"type":"string","title":"Allowed For Product","default":""},"conditions":{"items":{"type":"object"},"type":"array","title":"Conditions","default":[]},"effective_from":{"type":"integer","title":"Effective From"},"effective_to":{"type":"integer","title":"Effective To"},"subject_signature_hex":{"type":"string","title":"Subject Signature Hex"}},"type":"object","required":["category","effective_from","effective_to","subject_signature_hex"],"title":"CreateExceptionRequest"},"CreateGroupRequest":{"properties":{"display_name":{"type":"string","title":"Display Name","default":""}},"type":"object","title":"CreateGroupRequest"},"CreateLicenseRequestBody":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"use_case":{"type":"string","title":"Use Case"},"purpose":{"type":"string","title":"Purpose","default":""},"duration_days":{"type":"integer","title":"Duration Days","default":365},"message":{"type":"string","title":"Message","default":""},"licensee_id":{"type":"string","title":"Licensee Id","default":""},"provider_id":{"type":"string","title":"Provider Id","default":""},"prompt_hash":{"type":"string","title":"Prompt Hash","default":""},"modality":{"type":"string","title":"Modality","default":""},"product_name":{"type":"string","title":"Product Name","default":""},"return_url":{"type":"string","title":"Return Url","default":""},"movie_resume_id":{"type":"string","title":"Movie Resume Id","default":""},"movie_license_request_id":{"type":"string","title":"Movie License Request Id","default":""},"payment_status":{"type":"string","title":"Payment Status","default":""},"payment_processor":{"type":"string","title":"Payment Processor","default":""},"payment_amount_cents":{"type":"integer","title":"Payment Amount Cents","default":0},"payment_currency":{"type":"string","title":"Payment Currency","default":""},"movie_payment_id":{"type":"string","title":"Movie Payment Id","default":""},"payment_confirmed_at":{"type":"string","title":"Payment Confirmed At","default":""},"proposed_price_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Proposed Price Cents"},"non_commercial_affirmed":{"type":"boolean","title":"Non Commercial Affirmed","default":false},"project_name":{"type":"string","maxLength":400,"title":"Project Name","default":""},"project_confidential":{"type":"boolean","title":"Project Confidential","default":false},"company_name":{"type":"string","maxLength":400,"title":"Company Name","default":""},"company_website":{"type":"string","maxLength":400,"title":"Company Website","default":""},"placements":{"items":{"type":"string"},"type":"array","maxItems":8,"title":"Placements"}},"type":"object","required":["subject_id","use_case"],"title":"CreateLicenseRequestBody"},"CreateOfferRequest":{"properties":{"group_id":{"type":"string","title":"Group Id"},"target_mode":{"type":"string","title":"Target Mode","default":"link"},"target_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Value"},"auto_approve":{"type":"boolean","title":"Auto Approve","default":false},"max_claims":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Claims"},"expires_in_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In Days"}},"type":"object","required":["group_id"],"title":"CreateOfferRequest"},"CreateOrgRequest":{"properties":{"org_id":{"type":"string","title":"Org Id"},"display_name":{"type":"string","title":"Display Name"},"org_type":{"type":"string","title":"Org Type","default":"provider"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"contact_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contact Email"},"description":{"type":"string","title":"Description","default":""}},"type":"object","required":["org_id","display_name"],"title":"CreateOrgRequest"},"CustodyRequest":{"properties":{"mode":{"type":"string","title":"Mode"},"public_key_hex":{"type":"string","title":"Public Key Hex","default":""},"proof_signature_hex":{"type":"string","title":"Proof Signature Hex","default":""}},"type":"object","required":["mode"],"title":"CustodyRequest"},"DecideRequest":{"properties":{"action":{"type":"string","title":"Action"},"review_note":{"type":"string","title":"Review Note","default":""}},"type":"object","required":["action"],"title":"DecideRequest"},"DecideRequestBody":{"properties":{"action":{"type":"string","title":"Action"},"note":{"type":"string","maxLength":2000,"title":"Note","default":""}},"type":"object","required":["action"],"title":"DecideRequestBody"},"DeleteAccountRequest":{"properties":{"confirm_phrase":{"type":"string","title":"Confirm Phrase","default":""},"totp_code":{"type":"string","title":"Totp Code","default":""}},"type":"object","title":"DeleteAccountRequest"},"DetectIn":{"properties":{"prompt_hash":{"type":"string","maxLength":64,"minLength":1,"title":"Prompt Hash"},"candidate_subject_ids":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Candidate Subject Ids"}},"type":"object","required":["prompt_hash"],"title":"DetectIn"},"DirectAddRequest":{"properties":{"name":{"type":"string","title":"Name"},"kind":{"type":"string","title":"Kind","default":"supporter"}},"type":"object","required":["name"],"title":"DirectAddRequest"},"DirectoryListingUpdate":{"properties":{"listing_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Listing Status"},"tagline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tagline"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"capabilities":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Capabilities"}},"type":"object","title":"DirectoryListingUpdate"},"DisableRequest":{"properties":{"password":{"type":"string","title":"Password","default":""},"confirm_username":{"type":"string","title":"Confirm Username","default":""},"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"DisableRequest"},"DismissIn":{"properties":{"note":{"type":"string","maxLength":1000,"title":"Note","default":""}},"type":"object","title":"DismissIn"},"DisputeIn":{"properties":{"grounds":{"type":"string","maxLength":40,"title":"Grounds","default":"ownership"},"statement":{"type":"string","maxLength":5000,"minLength":10,"title":"Statement"},"disputant_org_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Disputant Org Id"}},"type":"object","required":["statement"],"title":"DisputeIn"},"EmailTokenRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"EmailTokenRequest"},"EnableRequest":{"properties":{"code":{"type":"string","maxLength":8,"minLength":6,"title":"Code"}},"type":"object","required":["code"],"title":"EnableRequest"},"ErrorDetail":{"properties":{"detail":{"anyOf":[{"type":"string"},{"type":"object"}],"title":"Detail"}},"type":"object","required":["detail"],"title":"ErrorDetail"},"EvidenceIn":{"properties":{"kind":{"type":"string","maxLength":40,"title":"Kind"},"filename":{"type":"string","maxLength":255,"title":"Filename","default":""},"content_type":{"type":"string","maxLength":100,"title":"Content Type","default":"application/octet-stream"},"content_base64":{"type":"string","title":"Content Base64"}},"type":"object","required":["kind","content_base64"],"title":"EvidenceIn"},"ExceptionResponse":{"properties":{"exception_id":{"type":"string","title":"Exception Id"},"license_id":{"type":"string","title":"License Id"},"category":{"type":"string","title":"Category"},"allowed_for_product":{"type":"string","title":"Allowed For Product"},"effective_from":{"type":"integer","title":"Effective From"},"effective_to":{"type":"integer","title":"Effective To"},"status":{"type":"string","title":"Status"}},"type":"object","required":["exception_id","license_id","category","allowed_for_product","effective_from","effective_to","status"],"title":"ExceptionResponse"},"ExchangeCodeRequest":{"properties":{"code":{"type":"string","title":"Code"},"provider_id":{"type":"string","title":"Provider Id"},"external_id":{"type":"string","title":"External Id"},"redirect_uri":{"type":"string","title":"Redirect Uri"}},"type":"object","required":["code","provider_id","external_id","redirect_uri"],"title":"ExchangeCodeRequest"},"FileIn":{"properties":{"filename":{"type":"string","maxLength":255,"title":"Filename","default":""},"content_type":{"type":"string","maxLength":100,"title":"Content Type","default":"application/octet-stream"},"content_base64":{"type":"string","title":"Content Base64"}},"type":"object","required":["content_base64"],"title":"FileIn"},"GitHubAuthRequest":{"properties":{"code":{"type":"string","title":"Code"},"redirect_uri":{"type":"string","title":"Redirect Uri","default":""},"accepted_terms":{"type":"boolean","title":"Accepted Terms","default":false},"accepted_privacy":{"type":"boolean","title":"Accepted Privacy","default":false},"age_affirmed":{"type":"boolean","title":"Age Affirmed","default":false},"terms_version":{"type":"string","title":"Terms Version","default":""},"privacy_version":{"type":"string","title":"Privacy Version","default":""}},"type":"object","required":["code"],"title":"GitHubAuthRequest"},"GoogleAuthRequest":{"properties":{"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"redirect_uri":{"type":"string","title":"Redirect Uri","default":""},"access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Token"},"accepted_terms":{"type":"boolean","title":"Accepted Terms","default":false},"accepted_privacy":{"type":"boolean","title":"Accepted Privacy","default":false},"age_affirmed":{"type":"boolean","title":"Age Affirmed","default":false},"terms_version":{"type":"string","title":"Terms Version","default":""},"privacy_version":{"type":"string","title":"Privacy Version","default":""}},"type":"object","title":"GoogleAuthRequest"},"GrantActionRequest":{"properties":{"action":{"type":"string","title":"Action"},"note":{"type":"string","title":"Note","default":""},"scope":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Scope"},"agent_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent User Id"}},"type":"object","required":["action"],"title":"GrantActionRequest"},"GroupUpdateRequest":{"properties":{"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"GroupUpdateRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IndexEntry":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases"},"status":{"type":"string","title":"Status"},"visibility":{"type":"string","title":"Visibility"},"reference_only":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Reference Only"},"authority_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authority Status"},"rights_holder":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rights Holder"},"visual_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visual Description"},"visual_descriptions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Visual Descriptions"},"gallery":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Gallery"},"source_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Source Urls"}},"type":"object","required":["subject_id","aliases","status","visibility"],"title":"IndexEntry"},"InquiryRequest":{"properties":{"agency_name":{"type":"string","title":"Agency Name"},"email":{"type":"string","title":"Email"},"contact_name":{"type":"string","title":"Contact Name","default":""},"client_count":{"type":"string","title":"Client Count","default":""},"message":{"type":"string","title":"Message","default":""}},"type":"object","required":["agency_name","email"],"title":"InquiryRequest"},"IntendedUse":{"properties":{"channel":{"type":"string","title":"Channel","default":""},"product_name":{"type":"string","title":"Product Name","default":""},"project_name":{"type":"string","title":"Project Name","default":""},"categories":{"items":{"type":"string"},"type":"array","title":"Categories","default":[]},"modality":{"type":"string","title":"Modality","default":""},"territory":{"type":"string","title":"Territory","default":""},"rights":{"items":{"type":"string"},"type":"array","title":"Rights","default":[]},"use_case":{"type":"string","title":"Use Case","default":""},"campaign_id":{"type":"string","title":"Campaign Id","default":""}},"type":"object","title":"IntendedUse"},"IssueLicenseRequestBody":{"properties":{"body":{"$ref":"#/components/schemas/app__api__license_requests__LicenseBody"},"subject_signature_hex":{"type":"string","title":"Subject Signature Hex","default":""},"response_message":{"type":"string","title":"Response Message","default":""}},"type":"object","required":["body"],"title":"IssueLicenseRequestBody"},"IssueLicenseRequestResponse":{"properties":{"request_id":{"type":"string","title":"Request Id"},"subject_id":{"type":"string","title":"Subject Id"},"licensee_id":{"type":"string","title":"Licensee Id","default":""},"provider_id":{"type":"string","title":"Provider Id","default":""},"prompt_hash":{"type":"string","title":"Prompt Hash","default":""},"modality":{"type":"string","title":"Modality","default":""},"product_name":{"type":"string","title":"Product Name","default":""},"return_url":{"type":"string","title":"Return Url","default":""},"movie_resume_id":{"type":"string","title":"Movie Resume Id","default":""},"movie_license_request_id":{"type":"string","title":"Movie License Request Id","default":""},"payment_status":{"type":"string","title":"Payment Status","default":""},"payment_processor":{"type":"string","title":"Payment Processor","default":""},"payment_amount_cents":{"type":"integer","title":"Payment Amount Cents","default":0},"payment_currency":{"type":"string","title":"Payment Currency","default":""},"movie_payment_id":{"type":"string","title":"Movie Payment Id","default":""},"payment_confirmed_at":{"type":"string","title":"Payment Confirmed At","default":""},"use_case":{"type":"string","title":"Use Case"},"purpose":{"type":"string","title":"Purpose"},"message":{"type":"string","title":"Message","default":""},"duration_days":{"type":"integer","title":"Duration Days"},"status":{"type":"string","title":"Status"},"requester":{"type":"string","title":"Requester","default":""},"requester_licensee_id":{"type":"string","title":"Requester Licensee Id","default":""},"response_message":{"type":"string","title":"Response Message","default":""},"license_id":{"type":"string","title":"License Id","default":""},"pending_return_url":{"type":"string","title":"Pending Return Url","default":""},"final_return_url":{"type":"string","title":"Final Return Url","default":""},"created_at":{"type":"string","title":"Created At"},"resolved_at":{"type":"string","title":"Resolved At","default":""},"licensed_at":{"type":"string","title":"Licensed At","default":""},"negotiation_round":{"type":"integer","title":"Negotiation Round","default":0},"proposed_price_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Proposed Price Cents"},"proposed_currency":{"type":"string","title":"Proposed Currency","default":"USD"},"proposed_by":{"type":"string","title":"Proposed By","default":""},"project_name":{"type":"string","title":"Project Name","default":""},"project_confidential":{"type":"boolean","title":"Project Confidential","default":false},"company_name":{"type":"string","title":"Company Name","default":""},"company_website":{"type":"string","title":"Company Website","default":""},"placements":{"items":{"type":"string"},"type":"array","title":"Placements","default":[]},"policy_warnings":{"items":{"type":"object"},"type":"array","title":"Policy Warnings","default":[]}},"type":"object","required":["request_id","subject_id","use_case","purpose","duration_days","status","created_at"],"title":"IssueLicenseRequestResponse"},"IssuePresignedRequest":{"properties":{"body":{"$ref":"#/components/schemas/PresignedLicenseBody"},"subject_signature_hex":{"type":"string","title":"Subject Signature Hex","default":""}},"type":"object","required":["body"],"title":"IssuePresignedRequest"},"LicenseBodyInput":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"licensee_id":{"type":"string","title":"Licensee Id"},"license_class":{"type":"string","title":"License Class"},"scope":{"items":{"type":"string"},"type":"array","title":"Scope","default":[]},"deny_categories":{"items":{"type":"string"},"type":"array","title":"Deny Categories","default":[]},"immutable_denials":{"items":{"type":"string"},"type":"array","title":"Immutable Denials","default":[]},"required_obligations":{"type":"object","title":"Required Obligations","default":{}},"expires_at":{"type":"integer","title":"Expires At"},"contract_start":{"type":"integer","title":"Contract Start","default":0},"product_name":{"type":"string","title":"Product Name","default":""},"project_name":{"type":"string","title":"Project Name","default":""},"asset_visual_description":{"type":"string","title":"Asset Visual Description","default":""},"purpose":{"type":"object","title":"Purpose","default":{}},"extensions":{"items":{"type":"object"},"type":"array","title":"Extensions","default":[]},"rules_text":{"type":"string","title":"Rules Text","default":""}},"type":"object","required":["subject_id","licensee_id","license_class","expires_at"],"title":"LicenseBodyInput"},"LicenseIssueRequest":{"properties":{"body":{"$ref":"#/components/schemas/app__api__licenses__LicenseBody"},"subject_signature":{"type":"string","title":"Subject Signature"}},"type":"object","required":["body","subject_signature"],"title":"LicenseIssueRequest"},"LicenseRequestResponse":{"properties":{"request_id":{"type":"string","title":"Request Id"},"subject_id":{"type":"string","title":"Subject Id"},"licensee_id":{"type":"string","title":"Licensee Id","default":""},"provider_id":{"type":"string","title":"Provider Id","default":""},"prompt_hash":{"type":"string","title":"Prompt Hash","default":""},"modality":{"type":"string","title":"Modality","default":""},"product_name":{"type":"string","title":"Product Name","default":""},"return_url":{"type":"string","title":"Return Url","default":""},"movie_resume_id":{"type":"string","title":"Movie Resume Id","default":""},"movie_license_request_id":{"type":"string","title":"Movie License Request Id","default":""},"payment_status":{"type":"string","title":"Payment Status","default":""},"payment_processor":{"type":"string","title":"Payment Processor","default":""},"payment_amount_cents":{"type":"integer","title":"Payment Amount Cents","default":0},"payment_currency":{"type":"string","title":"Payment Currency","default":""},"movie_payment_id":{"type":"string","title":"Movie Payment Id","default":""},"payment_confirmed_at":{"type":"string","title":"Payment Confirmed At","default":""},"use_case":{"type":"string","title":"Use Case"},"purpose":{"type":"string","title":"Purpose"},"message":{"type":"string","title":"Message","default":""},"duration_days":{"type":"integer","title":"Duration Days"},"status":{"type":"string","title":"Status"},"requester":{"type":"string","title":"Requester","default":""},"requester_licensee_id":{"type":"string","title":"Requester Licensee Id","default":""},"response_message":{"type":"string","title":"Response Message","default":""},"license_id":{"type":"string","title":"License Id","default":""},"pending_return_url":{"type":"string","title":"Pending Return Url","default":""},"final_return_url":{"type":"string","title":"Final Return Url","default":""},"created_at":{"type":"string","title":"Created At"},"resolved_at":{"type":"string","title":"Resolved At","default":""},"licensed_at":{"type":"string","title":"Licensed At","default":""},"negotiation_round":{"type":"integer","title":"Negotiation Round","default":0},"proposed_price_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Proposed Price Cents"},"proposed_currency":{"type":"string","title":"Proposed Currency","default":"USD"},"proposed_by":{"type":"string","title":"Proposed By","default":""},"project_name":{"type":"string","title":"Project Name","default":""},"project_confidential":{"type":"boolean","title":"Project Confidential","default":false},"company_name":{"type":"string","title":"Company Name","default":""},"company_website":{"type":"string","title":"Company Website","default":""},"placements":{"items":{"type":"string"},"type":"array","title":"Placements","default":[]}},"type":"object","required":["request_id","subject_id","use_case","purpose","duration_days","status","created_at"],"title":"LicenseRequestResponse"},"LicenseStatusRequest":{"properties":{"status":{"type":"string","title":"Status"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["status"],"title":"LicenseStatusRequest"},"LifecycleTransitionIn":{"properties":{"target":{"type":"string","maxLength":32,"minLength":1,"title":"Target"},"reason":{"type":"string","maxLength":500,"title":"Reason","default":""}},"type":"object","required":["target"],"title":"LifecycleTransitionIn"},"LinkListItem":{"properties":{"id":{"type":"string","title":"Id"},"provider_id":{"type":"string","title":"Provider Id"},"external_user_id":{"type":"string","title":"External User Id"},"external_username":{"type":"string","title":"External Username"},"verification_method":{"type":"string","title":"Verification Method"},"verified_at":{"type":"string","title":"Verified At"},"last_asserted_at":{"type":"string","title":"Last Asserted At"},"revoked_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revoked At"},"revoked_reason":{"type":"string","title":"Revoked Reason"}},"type":"object","required":["id","provider_id","external_user_id","external_username","verification_method","verified_at","last_asserted_at","revoked_at","revoked_reason"],"title":"LinkListItem"},"LinkListOut":{"properties":{"links":{"items":{"$ref":"#/components/schemas/LinkListItem"},"type":"array","title":"Links"}},"type":"object","required":["links"],"title":"LinkListOut"},"LinkProviderIn":{"properties":{"external_user_id":{"type":"string","maxLength":255,"minLength":1,"title":"External User Id"},"external_username":{"type":"string","maxLength":255,"title":"External Username","default":""}},"type":"object","required":["external_user_id"],"title":"LinkProviderIn"},"LinkProviderOut":{"properties":{"link_id":{"type":"string","title":"Link Id"},"provider_id":{"type":"string","title":"Provider Id"},"external_user_id":{"type":"string","title":"External User Id"},"verification_method":{"type":"string","title":"Verification Method"},"verified_at":{"type":"string","title":"Verified At"},"created":{"type":"boolean","title":"Created"}},"type":"object","required":["link_id","provider_id","external_user_id","verification_method","verified_at","created"],"title":"LinkProviderOut"},"LinkRequest":{"properties":{"provider":{"type":"string","title":"Provider"},"external_id":{"type":"string","title":"External Id"},"external_username":{"type":"string","title":"External Username","default":""},"provider_name":{"type":"string","title":"Provider Name","default":""},"provider_domain":{"type":"string","title":"Provider Domain","default":""},"connect_redirect_uri":{"type":"string","title":"Connect Redirect Uri","default":""}},"type":"object","required":["provider","external_id"],"title":"LinkRequest"},"LintRequest":{"properties":{"rules_text":{"type":"string","title":"Rules Text","default":""},"scope":{"items":{"type":"string"},"type":"array","title":"Scope","default":[]},"allowed_channels":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Channels"},"allowed_territories":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Territories"},"deny_categories":{"items":{"type":"string"},"type":"array","title":"Deny Categories","default":[]},"immutable_denials":{"items":{"type":"string"},"type":"array","title":"Immutable Denials","default":[]},"required_obligations":{"type":"object","title":"Required Obligations","default":{}}},"type":"object","title":"LintRequest"},"Login2FARequest":{"properties":{"mfa_token":{"type":"string","title":"Mfa Token"},"code":{"type":"string","title":"Code"}},"type":"object","required":["mfa_token","code"],"title":"Login2FARequest"},"LoginRequest":{"properties":{"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"}},"type":"object","required":["username","password"],"title":"LoginRequest"},"MemberOverrideRequest":{"properties":{"member_licensee_id":{"type":"string","title":"Member Licensee Id"},"remove_modalities":{"items":{"type":"string"},"type":"array","title":"Remove Modalities","default":[]},"deny_categories":{"items":{"type":"string"},"type":"array","title":"Deny Categories","default":[]},"expires_at":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["member_licensee_id"],"title":"MemberOverrideRequest"},"MemberRoleRequest":{"properties":{"role":{"type":"string","title":"Role"}},"type":"object","required":["role"],"title":"MemberRoleRequest"},"MessageIn":{"properties":{"text":{"type":"string","maxLength":5000,"title":"Text","default":""},"link":{"type":"string","maxLength":1000,"title":"Link","default":""},"file":{"anyOf":[{"$ref":"#/components/schemas/FileIn"},{"type":"null"}]}},"type":"object","title":"MessageIn"},"NegotiationResponseBody":{"properties":{"action":{"type":"string","title":"Action"}},"type":"object","required":["action"],"title":"NegotiationResponseBody"},"ObservationRequest":{"properties":{"schema_version":{"type":"string","enum":["pg.observation.v1"],"const":"pg.observation.v1","title":"Schema Version"},"event_id":{"type":"string","maxLength":100,"minLength":1,"pattern":"^[A-Za-z0-9_.:-]+$","title":"Event Id"},"output_id":{"type":"string","maxLength":100,"minLength":1,"pattern":"^[A-Za-z0-9_.:-]+$","title":"Output Id"},"subject_id":{"type":"string","maxLength":255,"minLength":2,"title":"Subject Id"},"event_type":{"type":"string","enum":["output.created","output.modified","output.published","publication.removed"],"title":"Event Type"},"output_hash":{"type":"string","pattern":"^[0-9a-f]{64}$","title":"Output Hash"},"occurred_at":{"type":"string","format":"date-time","title":"Occurred At"},"declared_purpose":{"type":"string","enum":["personal","commercial","educational","research","editorial","unknown"],"title":"Declared Purpose","default":"unknown"},"parent_output_hash":{"anyOf":[{"type":"string","pattern":"^[0-9a-f]{64}$"},{"type":"null"}],"title":"Parent Output Hash"},"publication_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Publication Url"},"decision_id":{"anyOf":[{"type":"string","maxLength":40,"minLength":1},{"type":"null"}],"title":"Decision Id"},"visual_match":{"anyOf":[{"$ref":"#/components/schemas/VisualMatch"},{"type":"null"}]}},"additionalProperties":false,"type":"object","required":["schema_version","event_id","output_id","subject_id","event_type","output_hash","occurred_at"],"title":"ObservationRequest"},"OfferIn":{"properties":{"subject_id":{"type":"string","maxLength":255,"minLength":1,"title":"Subject Id"},"price_amount_cents":{"type":"integer","maximum":100000000.0,"minimum":1.0,"title":"Price Amount Cents"},"currency":{"type":"string","maxLength":3,"minLength":3,"title":"Currency","default":"USD"},"use_case":{"type":"string","maxLength":24,"title":"Use Case","default":"commercial"},"license_class":{"type":"string","pattern":"^(RND|PRM)$","title":"License Class","default":"PRM"},"modality":{"type":"string","maxLength":24,"title":"Modality","default":""},"territory":{"type":"string","maxLength":64,"title":"Territory","default":""},"duration_days":{"type":"integer","maximum":3650.0,"minimum":1.0,"title":"Duration Days","default":1},"max_uses":{"anyOf":[{"type":"integer","maximum":10000000.0,"minimum":1.0},{"type":"null"}],"title":"Max Uses"},"transferability":{"type":"string","maxLength":32,"title":"Transferability","default":"provider_only"},"provider_scope":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Provider Scope"},"granted_rights":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Granted Rights"},"tax_behavior":{"type":"string","maxLength":16,"title":"Tax Behavior","default":"exclusive"},"terms_text":{"type":"string","maxLength":20000,"title":"Terms Text","default":""},"refund_policy":{"type":"string","maxLength":2000,"title":"Refund Policy","default":""},"valid_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Valid Until"}},"type":"object","required":["subject_id","price_amount_cents"],"title":"OfferIn"},"OfferStatusIn":{"properties":{"status":{"type":"string","maxLength":16,"title":"Status"}},"type":"object","required":["status"],"title":"OfferStatusIn"},"OnboardRequest":{"properties":{"org_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Id"}},"type":"object","title":"OnboardRequest"},"OnboardResponse":{"properties":{"onboarding_url":{"type":"string","title":"Onboarding Url"}},"type":"object","required":["onboarding_url"],"title":"OnboardResponse"},"OptOutRequest":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"reason_class":{"type":"string","title":"Reason Class"},"scope":{"type":"string","title":"Scope","default":"all_modalities"},"authority_proof":{"type":"object","title":"Authority Proof","default":{}},"subject_signature":{"type":"string","title":"Subject Signature"}},"type":"object","required":["subject_id","reason_class","subject_signature"],"title":"OptOutRequest"},"OrgAvatarRequest":{"properties":{"avatar_url":{"type":"string","title":"Avatar Url"}},"type":"object","required":["avatar_url"],"title":"OrgAvatarRequest"},"PairInitiateRequest":{"properties":{"provider_id":{"type":"string","title":"Provider Id"},"licensee_id":{"type":"string","title":"Licensee Id"}},"type":"object","required":["provider_id","licensee_id"],"title":"PairInitiateRequest"},"PasswordResetConfirm":{"properties":{"token":{"type":"string","title":"Token"},"new_password":{"type":"string","title":"New Password"}},"type":"object","required":["token","new_password"],"title":"PasswordResetConfirm"},"PasswordResetRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"PasswordResetRequest"},"PreferencesUpdateRequest":{"properties":{"email_notify_events":{"type":"boolean","title":"Email Notify Events"}},"type":"object","required":["email_notify_events"],"title":"PreferencesUpdateRequest"},"PresignedLicenseBody":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"licensee_id":{"type":"string","title":"Licensee Id"},"license_class":{"type":"string","title":"License Class"},"scope":{"items":{"type":"string"},"type":"array","title":"Scope","default":[]},"deny_categories":{"items":{"type":"string"},"type":"array","title":"Deny Categories","default":[]},"immutable_denials":{"items":{"type":"string"},"type":"array","title":"Immutable Denials","default":[]},"required_obligations":{"type":"object","title":"Required Obligations","default":{}},"expires_at":{"type":"integer","title":"Expires At"},"contract_start":{"type":"integer","title":"Contract Start","default":0},"product_name":{"type":"string","title":"Product Name","default":""},"project_name":{"type":"string","title":"Project Name","default":""},"asset_visual_description":{"type":"string","title":"Asset Visual Description","default":""},"purpose":{"type":"object","title":"Purpose","default":{}},"extensions":{"items":{"type":"object"},"type":"array","title":"Extensions","default":[]},"allowed_channels":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Channels"},"allowed_territories":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Territories"},"rules_text":{"type":"string","title":"Rules Text","default":""},"granted_rights":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Granted Rights"},"output_survives_termination":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Output Survives Termination"}},"type":"object","required":["subject_id","licensee_id","license_class","expires_at"],"title":"PresignedLicenseBody"},"ProfileIn":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Display Name"},"tagline":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Tagline"},"website":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Website"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"}},"type":"object","title":"ProfileIn"},"ProviderCredentialCreate":{"properties":{"provider_id":{"type":"string","title":"Provider Id"},"display_name":{"type":"string","title":"Display Name","default":""},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"allowed_redirect_uris":{"items":{"type":"string"},"type":"array","title":"Allowed Redirect Uris","default":[]},"adopt_existing_org":{"type":"boolean","title":"Adopt Existing Org","default":false}},"type":"object","required":["provider_id"],"title":"ProviderCredentialCreate"},"ProviderCredentialUpdate":{"properties":{"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"allowed_redirect_uris":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Redirect Uris"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},"type":"object","title":"ProviderCredentialUpdate"},"ProviderVetoRequest":{"properties":{"blocked_providers":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Blocked Providers"},"allowed_providers":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Providers"}},"type":"object","title":"ProviderVetoRequest","description":"Who may generate this subject at all.\n\nSent as whole lists rather than add/remove operations: a rights holder\nreviewing \"who can use my face\" should see and confirm the complete\nanswer, not accumulate one they can no longer recall."},"QuoteIn":{"properties":{"offer_id":{"type":"string","maxLength":40,"minLength":1,"title":"Offer Id"},"provider_id":{"type":"string","maxLength":100,"minLength":1,"title":"Provider Id"},"quantity":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Quantity","default":1},"project_name":{"type":"string","maxLength":400,"title":"Project Name","default":""},"project_confidential":{"type":"boolean","title":"Project Confidential","default":false},"provider_user_id":{"type":"string","maxLength":255,"title":"Provider User Id","default":""},"provider_identity_link_id":{"type":"string","maxLength":36,"title":"Provider Identity Link Id","default":""},"idempotency_key":{"type":"string","maxLength":128,"title":"Idempotency Key","default":""}},"type":"object","required":["offer_id","provider_id"],"title":"QuoteIn"},"ReceiptAck":{"properties":{"status":{"type":"string","enum":["recorded","already_recorded"],"title":"Status"},"decision_id":{"type":"string","title":"Decision Id"},"receipt_hash":{"type":"string","title":"Receipt Hash"},"compliant":{"type":"boolean","title":"Compliant"},"provider_signature_verified":{"type":"boolean","title":"Provider Signature Verified"},"schema_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema Version","description":"Only on `recorded`: the body version hashed."},"obligation_violations":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Obligation Violations","description":"Only on `recorded`: required obligations the receipt did not report as applied."},"provider_signed_event_type":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Provider Signed Event Type","description":"Only on `recorded`."}},"type":"object","required":["status","decision_id","receipt_hash","compliant","provider_signature_verified"],"title":"ReceiptAck","description":"PRAMPTA's answer to a receipt. `receipt_hash` is the SHA-256 of the canonical receipt body it built from\nthe bytes sent (app/core/receipt_body.py): a client counts its receipt as filed only when this hash and\n`decision_id` are its own. The identical receipt sent again gets `already_recorded` with the same hash."},"ReceiptEventRequest":{"properties":{"event_type":{"type":"string","title":"Event Type"},"output_hash":{"type":"string","title":"Output Hash","default":""}},"type":"object","required":["event_type"],"title":"ReceiptEventRequest"},"ReceiptRequest":{"properties":{"schema_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema Version"},"v":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"V"},"decision_id":{"type":"string","title":"Decision Id"},"prompt_hash":{"type":"string","title":"Prompt Hash"},"event_type":{"type":"string","title":"Event Type","default":"output_accepted"},"output_hash":{"type":"string","title":"Output Hash","default":""},"model":{"type":"string","title":"Model","default":""},"obligations_applied":{"type":"object","title":"Obligations Applied","default":{}},"watermark_embedded":{"type":"boolean","title":"Watermark Embedded","default":false},"generated_at":{"type":"integer","title":"Generated At","default":0},"provider_signature":{"type":"string","title":"Provider Signature","default":""}},"type":"object","required":["decision_id","prompt_hash"],"title":"ReceiptRequest"},"RecordIn":{"properties":{"basis":{"type":"string","maxLength":40,"title":"Basis","default":"self"},"requested_state":{"type":"string","maxLength":32,"title":"Requested State","default":"verified"},"claimant_note":{"type":"string","maxLength":2000,"title":"Claimant Note","default":""},"claimant_org_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Claimant Org Id"},"authority_expires_at":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Authority Expires At"}},"type":"object","title":"RecordIn"},"RedirectUrisIn":{"properties":{"redirect_uris":{"items":{"type":"string"},"type":"array","title":"Redirect Uris"}},"type":"object","title":"RedirectUrisIn"},"RefreshRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"RefreshRequest"},"RefundIn":{"properties":{"reason":{"type":"string","maxLength":500,"minLength":1,"title":"Reason"}},"type":"object","required":["reason"],"title":"RefundIn"},"RegisterPresignedOptOutRequest":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"reason_class":{"type":"string","title":"Reason Class"},"scope":{"type":"string","title":"Scope","default":"all_modalities"},"subject_signature_hex":{"type":"string","title":"Subject Signature Hex"}},"type":"object","required":["subject_id","reason_class","subject_signature_hex"],"title":"RegisterPresignedOptOutRequest"},"RegisterRequest":{"properties":{"username":{"type":"string","title":"Username"},"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"},"display_name":{"type":"string","title":"Display Name","default":""},"captcha_token":{"type":"string","title":"Captcha Token","default":""},"accepted_terms":{"type":"boolean","title":"Accepted Terms","default":false},"accepted_privacy":{"type":"boolean","title":"Accepted Privacy","default":false},"age_affirmed":{"type":"boolean","title":"Age Affirmed","default":false},"terms_version":{"type":"string","title":"Terms Version","default":""},"privacy_version":{"type":"string","title":"Privacy Version","default":""}},"type":"object","required":["username","email","password"],"title":"RegisterRequest"},"RejectIn":{"properties":{"reason":{"type":"string","maxLength":500,"minLength":1,"title":"Reason"}},"type":"object","required":["reason"],"title":"RejectIn"},"ReleaseAck":{"properties":{"status":{"type":"string","enum":["released","already_released"],"title":"Status"},"decision_id":{"type":"string","title":"Decision Id"}},"type":"object","required":["status","decision_id"],"title":"ReleaseAck"},"ReleaseRequest":{"properties":{"reason":{"type":"string","maxLength":500,"title":"Reason","default":""}},"type":"object","title":"ReleaseRequest"},"RenameRequest":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"RenameRequest"},"ReportCreate":{"properties":{"target_type":{"type":"string","title":"Target Type","default":"subject"},"target_id":{"type":"string","title":"Target Id"},"reason":{"type":"string","title":"Reason","default":"other"},"details":{"type":"string","maxLength":3000,"title":"Details","default":""}},"type":"object","required":["target_id"],"title":"ReportCreate"},"ReportRequest":{"properties":{"message":{"type":"string","title":"Message"},"level":{"type":"string","title":"Level","default":"error"},"stack":{"type":"string","title":"Stack","default":""},"url":{"type":"string","title":"Url","default":""},"user_agent":{"type":"string","title":"User Agent","default":""},"user_note":{"type":"string","title":"User Note","default":""},"context":{"type":"object","title":"Context","default":{}}},"type":"object","required":["message"],"title":"ReportRequest"},"ReportResolve":{"properties":{"status":{"type":"string","title":"Status"},"action":{"type":"string","title":"Action","default":"none"},"note":{"type":"string","title":"Note","default":""}},"type":"object","required":["status"],"title":"ReportResolve"},"ReportedIn":{"properties":{"ncmec_report_id":{"type":"string","maxLength":64,"minLength":1,"title":"Ncmec Report Id"}},"type":"object","required":["ncmec_report_id"],"title":"ReportedIn"},"ReservedNameRequest":{"properties":{"term":{"type":"string","title":"Term"},"label":{"type":"string","title":"Label","default":""}},"type":"object","required":["term"],"title":"ReservedNameRequest"},"ResolveClaimRequest":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"ResolveClaimRequest"},"ResolveIn":{"properties":{"action":{"type":"string","maxLength":20,"title":"Action"},"note":{"type":"string","maxLength":2000,"minLength":1,"title":"Note"},"evidence_ids":{"items":{"type":"string"},"type":"array","title":"Evidence Ids"},"outcome_state":{"type":"string","maxLength":32,"title":"Outcome State","default":"suspended"}},"type":"object","required":["action","note"],"title":"ResolveIn"},"ResolveLicenseRequestBody":{"properties":{"status":{"type":"string","title":"Status"},"response_message":{"type":"string","title":"Response Message","default":""}},"type":"object","required":["status"],"title":"ResolveLicenseRequestBody"},"RespondInviteRequest":{"properties":{"accept":{"type":"boolean","title":"Accept"}},"type":"object","required":["accept"],"title":"RespondInviteRequest"},"ResponseIn":{"properties":{"response_statement":{"type":"string","maxLength":5000,"minLength":1,"title":"Response Statement"}},"type":"object","required":["response_statement"],"title":"ResponseIn"},"ReviewIn":{"properties":{"notes":{"type":"string","maxLength":2000,"title":"Notes","default":""}},"type":"object","title":"ReviewIn"},"RevocationRequest":{"properties":{"dimension":{"type":"string","title":"Dimension"},"value":{"type":"string","title":"Value","default":""},"reason":{"type":"string","title":"Reason","default":""},"effective_at":{"type":"integer","title":"Effective At","default":0}},"type":"object","required":["dimension"],"title":"RevocationRequest"},"RightsHolderContactIn":{"properties":{"rights_holder_contact":{"type":"string","maxLength":255,"title":"Rights Holder Contact"}},"type":"object","required":["rights_holder_contact"],"title":"RightsHolderContactIn"},"RiskFlagRequest":{"properties":{"action":{"type":"string","title":"Action"},"flags":{"items":{"type":"string"},"type":"array","title":"Flags"}},"type":"object","required":["action","flags"],"title":"RiskFlagRequest"},"RiskWindowReset":{"properties":{"reason":{"type":"string","title":"Reason","default":""}},"type":"object","title":"RiskWindowReset"},"RotateIn":{"properties":{"environment":{"type":"string","pattern":"^(sandbox|production)$","title":"Environment"}},"type":"object","required":["environment"],"title":"RotateIn"},"RotateKeyRequest":{"properties":{"new_public_key_hex":{"type":"string","title":"New Public Key Hex"},"proof_old_signature_hex":{"type":"string","title":"Proof Old Signature Hex"},"proof_new_signature_hex":{"type":"string","title":"Proof New Signature Hex"}},"type":"object","required":["new_public_key_hex","proof_old_signature_hex","proof_new_signature_hex"],"title":"RotateKeyRequest"},"RotateSigningKeyRequest":{"properties":{"public_key_hex":{"type":"string","title":"Public Key Hex"},"proof_signature_hex":{"type":"string","title":"Proof Signature Hex"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["public_key_hex","proof_signature_hex"],"title":"RotateSigningKeyRequest"},"SetKindRequest":{"properties":{"kind":{"type":"string","title":"Kind"}},"type":"object","required":["kind"],"title":"SetKindRequest"},"SignAndIssueRequest":{"properties":{"body":{"$ref":"#/components/schemas/LicenseBodyInput"},"private_key_base64":{"type":"string","title":"Private Key Base64"}},"type":"object","required":["body","private_key_base64"],"title":"SignAndIssueRequest"},"SignAndRegisterOptOutRequest":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"reason_class":{"type":"string","title":"Reason Class"},"scope":{"type":"string","title":"Scope","default":"all_modalities"},"private_key_base64":{"type":"string","title":"Private Key Base64"}},"type":"object","required":["subject_id","reason_class","private_key_base64"],"title":"SignAndRegisterOptOutRequest"},"SignedDecision":{"properties":{"schema_version":{"type":"string","title":"Schema Version","default":"pg.decision.v1"},"decision_id":{"type":"string","title":"Decision Id"},"nonce":{"type":"string","title":"Nonce","default":""},"allowed":{"type":"boolean","title":"Allowed"},"disposition":{"type":"string","title":"Disposition","default":"allow"},"policy_version":{"type":"string","title":"Policy Version","default":""},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"subject_id":{"type":"string","title":"Subject Id","default":""},"licensee_id":{"type":"string","title":"Licensee Id","default":""},"provider_id":{"type":"string","title":"Provider Id","default":""},"license_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"License Id"},"prompt_hash":{"type":"string","title":"Prompt Hash","default":""},"model":{"type":"string","title":"Model","default":""},"modality":{"type":"string","title":"Modality","default":""},"intended_use":{"type":"object","title":"Intended Use","default":{}},"obligations":{"type":"object","title":"Obligations","default":{}},"rules_text":{"type":"string","title":"Rules Text","default":""},"rules_text_hash":{"type":"string","title":"Rules Text Hash","default":""},"subject_authority":{"type":"string","title":"Subject Authority","default":""},"watermark_payload":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Watermark Payload"},"is_hard_refusal":{"type":"boolean","title":"Is Hard Refusal","default":false},"issued_at":{"type":"integer","title":"Issued At","default":0},"expires_at":{"type":"integer","title":"Expires At","default":0},"revocation_epoch":{"type":"integer","title":"Revocation Epoch","default":0},"max_cache_age_seconds":{"type":"integer","title":"Max Cache Age Seconds","default":0},"cache_scope":{"type":"string","title":"Cache Scope","default":"not_cacheable"},"provider_user_binding":{"type":"string","title":"Provider User Binding","default":"unbound"},"provider_identity_link_id":{"type":"string","title":"Provider Identity Link Id","default":""},"generation_id":{"type":"string","title":"Generation Id","default":""},"detection_id":{"type":"string","title":"Detection Id","default":""},"operator_key_id":{"type":"string","title":"Operator Key Id","default":""},"operator_signature":{"type":"string","title":"Operator Signature","default":""},"remediation":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Remediation"}},"type":"object","required":["decision_id","allowed"],"title":"SignedDecision","description":"Cryptographically signed decision — verifiable by SDK/provider."},"SigningKeyRequest":{"properties":{"public_key_hex":{"type":"string","title":"Public Key Hex"},"proof_signature_hex":{"type":"string","title":"Proof Signature Hex"}},"type":"object","required":["public_key_hex","proof_signature_hex"],"title":"SigningKeyRequest"},"StaffRoleRequest":{"properties":{"role":{"type":"string","title":"Role"}},"type":"object","required":["role"],"title":"StaffRoleRequest"},"StatsResponse":{"properties":{"users":{"type":"integer","title":"Users"},"subjects":{"type":"integer","title":"Subjects"},"new_users_today":{"type":"integer","title":"New Users Today"},"new_subjects_today":{"type":"integer","title":"New Subjects Today"},"latest_usernames":{"items":{"type":"string"},"type":"array","title":"Latest Usernames"},"active_licenses":{"type":"integer","title":"Active Licenses"},"opt_outs":{"type":"integer","title":"Opt Outs"},"verifications":{"type":"integer","title":"Verifications"}},"type":"object","required":["users","subjects","new_users_today","new_subjects_today","latest_usernames","active_licenses","opt_outs","verifications"],"title":"StatsResponse"},"StatusResponse":{"properties":{"has_account":{"type":"boolean","title":"Has Account"},"transfers_active":{"type":"boolean","title":"Transfers Active"},"requirements_due":{"type":"boolean","title":"Requirements Due"}},"type":"object","required":["has_account","transfers_active","requirements_due"],"title":"StatusResponse"},"SubjectBannerRequest":{"properties":{"banner_url":{"type":"string","title":"Banner Url"}},"type":"object","required":["banner_url"],"title":"SubjectBannerRequest"},"SubjectDetailResponse":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"pg_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pg Code"},"status":{"type":"string","title":"Status"},"visibility":{"type":"string","title":"Visibility"},"rules_text":{"type":"string","title":"Rules Text"},"extra_deny_categories":{"items":{"type":"string"},"type":"array","title":"Extra Deny Categories","default":[]},"extra_obligations":{"type":"object","title":"Extra Obligations","default":{}},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases"},"subject_type":{"type":"string","title":"Subject Type"},"risk_flags":{"items":{"type":"string"},"type":"array","title":"Risk Flags"},"profile":{"type":"object","title":"Profile","default":{}},"visual_description":{"type":"string","title":"Visual Description"},"visual_descriptions":{"items":{"type":"string"},"type":"array","title":"Visual Descriptions"},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price"},"authority_status":{"type":"string","title":"Authority Status"},"lifecycle_status":{"type":"string","title":"Lifecycle Status","default":"self_attested"},"owner_verified":{"type":"boolean","title":"Owner Verified","default":false},"availability":{"type":"object","title":"Availability","default":{}},"managing_org_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Managing Org Id"},"public_key_hex":{"type":"string","title":"Public Key Hex"},"key_custody":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Custody"},"banner_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Banner Url"},"gallery":{"items":{"type":"string"},"type":"array","title":"Gallery"},"banner_pos":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Banner Pos"},"banner_pos_x":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Banner Pos X"},"auto_approve_requests":{"type":"boolean","title":"Auto Approve Requests"},"creator_use":{"type":"boolean","title":"Creator Use","default":false},"auto_approve_use_cases":{"items":{"type":"string"},"type":"array","title":"Auto Approve Use Cases"},"auto_approve_max_duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Approve Max Duration Days"},"auto_approve_require_payment":{"type":"boolean","title":"Auto Approve Require Payment"},"tiers":{"items":{"$ref":"#/components/schemas/TierEntry"},"type":"array","title":"Tiers"},"tier_policy":{"type":"object","title":"Tier Policy"},"registered_at":{"type":"string","title":"Registered At"},"controls":{"type":"boolean","title":"Controls","default":false}},"type":"object","required":["subject_id","status","visibility","rules_text","aliases","subject_type","risk_flags","visual_description","visual_descriptions","price","authority_status","managing_org_id","public_key_hex","banner_url","gallery","banner_pos","banner_pos_x","auto_approve_requests","auto_approve_use_cases","auto_approve_max_duration_days","auto_approve_require_payment","tiers","tier_policy","registered_at"],"title":"SubjectDetailResponse","description":"GET /v1/subjects/{subject_id}."},"SubjectEntry":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"pg_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pg Code"},"status":{"type":"string","title":"Status"},"visibility":{"type":"string","title":"Visibility"},"rules_text":{"type":"string","title":"Rules Text"},"extra_deny_categories":{"items":{"type":"string"},"type":"array","title":"Extra Deny Categories","default":[]},"extra_obligations":{"type":"object","title":"Extra Obligations","default":{}},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases"},"subject_type":{"type":"string","title":"Subject Type"},"risk_flags":{"items":{"type":"string"},"type":"array","title":"Risk Flags"},"profile":{"type":"object","title":"Profile","default":{}},"visual_description":{"type":"string","title":"Visual Description"},"visual_descriptions":{"items":{"type":"string"},"type":"array","title":"Visual Descriptions"},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price"},"authority_status":{"type":"string","title":"Authority Status"},"lifecycle_status":{"type":"string","title":"Lifecycle Status","default":"self_attested"},"owner_verified":{"type":"boolean","title":"Owner Verified","default":false},"availability":{"type":"object","title":"Availability","default":{}},"managing_org_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Managing Org Id"},"public_key_hex":{"type":"string","title":"Public Key Hex"},"key_custody":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Custody"},"banner_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Banner Url"},"gallery":{"items":{"type":"string"},"type":"array","title":"Gallery"},"banner_pos":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Banner Pos"},"banner_pos_x":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Banner Pos X"},"auto_approve_requests":{"type":"boolean","title":"Auto Approve Requests"},"creator_use":{"type":"boolean","title":"Creator Use","default":false},"auto_approve_use_cases":{"items":{"type":"string"},"type":"array","title":"Auto Approve Use Cases"},"auto_approve_max_duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Approve Max Duration Days"},"auto_approve_require_payment":{"type":"boolean","title":"Auto Approve Require Payment"},"tiers":{"items":{"$ref":"#/components/schemas/TierEntry"},"type":"array","title":"Tiers"},"tier_policy":{"type":"object","title":"Tier Policy"},"registered_at":{"type":"string","title":"Registered At"},"license_classes":{"items":{"type":"string"},"type":"array","title":"License Classes"},"controls":{"type":"boolean","title":"Controls"},"creator_username":{"type":"string","title":"Creator Username"},"creator_display_name":{"type":"string","title":"Creator Display Name"},"creator_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creator Avatar Url"},"creator_verified":{"type":"boolean","title":"Creator Verified","default":false},"creator_kind":{"type":"string","title":"Creator Kind","default":"user"}},"type":"object","required":["subject_id","status","visibility","rules_text","aliases","subject_type","risk_flags","visual_description","visual_descriptions","price","authority_status","managing_org_id","public_key_hex","banner_url","gallery","banner_pos","banner_pos_x","auto_approve_requests","auto_approve_use_cases","auto_approve_max_duration_days","auto_approve_require_payment","tiers","tier_policy","registered_at","license_classes","controls","creator_username","creator_display_name","creator_avatar_url"],"title":"SubjectEntry","description":"One row of GET /v1/subjects/ (Library / My subjects)."},"SubjectGalleryRequest":{"properties":{"gallery":{"items":{"type":"string"},"type":"array","title":"Gallery"}},"type":"object","required":["gallery"],"title":"SubjectGalleryRequest"},"SubjectIndexResponse":{"properties":{"version":{"type":"integer","title":"Version"},"count":{"type":"integer","title":"Count"},"subjects":{"items":{"$ref":"#/components/schemas/IndexEntry"},"type":"array","title":"Subjects"}},"type":"object","required":["version","count","subjects"],"title":"SubjectIndexResponse"},"SubjectListResponse":{"properties":{"subjects":{"items":{"$ref":"#/components/schemas/SubjectEntry"},"type":"array","title":"Subjects"},"count":{"type":"integer","title":"Count"},"kinds":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Kinds"}},"type":"object","required":["subjects","count"],"title":"SubjectListResponse"},"SubjectRegisterRequest":{"properties":{"subject_id":{"type":"string","maxLength":255,"title":"Subject Id"},"public_key_hex":{"type":"string","title":"Public Key Hex","default":""},"proof_signature_hex":{"type":"string","title":"Proof Signature Hex","default":""},"managed":{"type":"boolean","title":"Managed","default":true},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases","default":[]},"subject_type":{"type":"string","title":"Subject Type","default":"unspecified"},"risk_flags":{"items":{"type":"string"},"type":"array","title":"Risk Flags","default":[]},"profile":{"type":"object","title":"Profile","default":{}},"visibility":{"type":"string","title":"Visibility","default":"public"},"rules_text":{"type":"string","maxLength":5000,"title":"Rules Text","default":""},"extra_deny_categories":{"items":{"type":"string"},"type":"array","title":"Extra Deny Categories","default":[]},"extra_obligations":{"type":"object","title":"Extra Obligations","default":{}},"rights_attestation":{"type":"string","maxLength":2000,"title":"Rights Attestation","default":""},"metadata":{"type":"object","title":"Metadata","default":{}},"std_ack_version":{"type":"string","maxLength":40,"title":"Std Ack Version","default":""}},"type":"object","required":["subject_id"],"title":"SubjectRegisterRequest"},"SubjectStatusTransition":{"properties":{"new_status":{"type":"string","title":"New Status"},"reason":{"type":"string","title":"Reason","default":""},"authority_proof":{"type":"object","title":"Authority Proof","default":{}},"subject_signature_hex":{"type":"string","title":"Subject Signature Hex","default":""}},"type":"object","required":["new_status"],"title":"SubjectStatusTransition"},"SubjectTypeRequest":{"properties":{"subject_type":{"type":"string","title":"Subject Type"}},"type":"object","required":["subject_type"],"title":"SubjectTypeRequest"},"SubjectUpdateRequest":{"properties":{"aliases":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Aliases"},"rules_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rules Text"},"extra_deny_categories":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Extra Deny Categories"},"extra_obligations":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Extra Obligations"},"visibility":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility"},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price"},"auto_approve_requests":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Approve Requests"},"creator_use":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Creator Use"},"auto_approve_use_cases":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Auto Approve Use Cases"},"auto_approve_max_duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Approve Max Duration Days"},"auto_approve_require_payment":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Approve Require Payment"},"tier_policy":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Tier Policy"},"banner_pos":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Banner Pos"},"banner_pos_x":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Banner Pos X"},"profile":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Profile"},"subject_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Type"}},"type":"object","title":"SubjectUpdateRequest"},"SubmitRequest":{"properties":{"name":{"type":"string","title":"Name"},"contact_email":{"type":"string","title":"Contact Email","default":""},"profile_link":{"type":"string","title":"Profile Link","default":""},"work_links":{"items":{"type":"string"},"type":"array","title":"Work Links","default":[]},"reward_ack":{"type":"boolean","title":"Reward Ack","default":false}},"type":"object","required":["name"],"title":"SubmitRequest"},"TierEntry":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"description":{"type":"string","title":"Description"},"license_class":{"type":"string","title":"License Class"},"deny":{"items":{"type":"string"},"type":"array","title":"Deny"},"paid":{"type":"boolean","title":"Paid"},"price":{"type":"string","title":"Price"},"price_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Cents"},"duration_days":{"type":"integer","title":"Duration Days"},"disposition":{"type":"string","title":"Disposition"},"access_mode":{"type":"string","title":"Access Mode","default":"request"},"available":{"type":"boolean","title":"Available"}},"type":"object","required":["key","label","description","license_class","deny","paid","price","duration_days","disposition","available"],"title":"TierEntry"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token","default":""},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"user":{"type":"object","title":"User"}},"type":"object","required":["access_token","user"],"title":"TokenResponse"},"TransferOwnershipRequest":{"properties":{"username":{"type":"string","title":"Username"}},"type":"object","required":["username"],"title":"TransferOwnershipRequest"},"TrustedIssuerRequest":{"properties":{"trusted":{"type":"boolean","title":"Trusted","default":true},"note":{"type":"string","title":"Note","default":""}},"type":"object","title":"TrustedIssuerRequest"},"UnlinkProviderOut":{"properties":{"unlinked":{"type":"boolean","title":"Unlinked"},"link_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Link Id"}},"type":"object","required":["unlinked","link_id"],"title":"UnlinkProviderOut"},"UpdateInquiryRequest":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"UpdateInquiryRequest"},"UpdateOrgRequest":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Display Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"contact_email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Contact Email"},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"},"website":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Website"}},"type":"object","title":"UpdateOrgRequest"},"UpdateReportRequest":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"UpdateReportRequest"},"UserResponse":{"properties":{"id":{"type":"string","title":"Id"},"username":{"type":"string","title":"Username"},"email":{"type":"string","title":"Email"},"display_name":{"type":"string","title":"Display Name"},"role":{"type":"string","title":"Role"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"auth_provider":{"type":"string","title":"Auth Provider","default":"local"},"has_password":{"type":"boolean","title":"Has Password","default":true},"email_verified":{"type":"boolean","title":"Email Verified","default":false},"email_kind":{"type":"string","title":"Email Kind","default":"business"},"email_notify_events":{"type":"boolean","title":"Email Notify Events","default":true},"verified":{"type":"boolean","title":"Verified","default":false},"totp_enabled":{"type":"boolean","title":"Totp Enabled","default":false},"pending_deletion_purge_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pending Deletion Purge At"}},"type":"object","required":["id","username","email","display_name","role"],"title":"UserResponse"},"UsernameUpdateRequest":{"properties":{"username":{"type":"string","title":"Username"}},"type":"object","required":["username"],"title":"UsernameUpdateRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerificationRequestBody":{"properties":{"note":{"type":"string","maxLength":2000,"title":"Note","default":""}},"type":"object","title":"VerificationRequestBody"},"VerifyRequest":{"properties":{"subject_id":{"type":"string","title":"Subject Id","default":""},"prompt_hash":{"type":"string","title":"Prompt Hash","default":""},"intended_use":{"$ref":"#/components/schemas/IntendedUse","default":{"channel":"","product_name":"","project_name":"","categories":[],"modality":"","territory":"","rights":[],"use_case":"","campaign_id":""}},"model":{"type":"string","title":"Model","default":""},"modality":{"type":"string","title":"Modality","default":""},"provider_user_id":{"type":"string","title":"Provider User Id","default":""},"provider_identity_link_id":{"type":"string","title":"Provider Identity Link Id","default":""},"generation_id":{"type":"string","title":"Generation Id","default":""},"idempotency_key":{"type":"string","title":"Idempotency Key","default":""},"license_id":{"type":"string","title":"License Id","default":""},"detection_id":{"type":"string","title":"Detection Id","default":""},"requester_email":{"type":"string","title":"Requester Email","default":""},"return_url":{"type":"string","title":"Return Url","default":""}},"type":"object","title":"VerifyRequest"},"VisualMatch":{"properties":{"method":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[A-Za-z0-9_.:/-]+$","title":"Method"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence"},"basis":{"type":"string","enum":["output_frames","output_image","input_image"],"title":"Basis"},"reference_ids":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Reference Ids"}},"additionalProperties":false,"type":"object","required":["method","confidence","basis"],"title":"VisualMatch","description":"The provider's own finding that an output LOOKS LIKE this subject, with\nno name in the prompt (co-founder spec, 2026-09-27). Computed by the\nprovider against the references the Library already serves; PRAMPTA never\nreceives pixels, frames or embeddings — only this claim. A signal for the\nrights holder to review, never a gate and never authorization."},"WebhookBody":{"properties":{"provider_id":{"type":"string","maxLength":100,"minLength":1,"title":"Provider Id"},"event_id":{"type":"string","maxLength":128,"minLength":1,"title":"Event Id"},"event_type":{"type":"string","maxLength":64,"minLength":1,"title":"Event Type"},"payload":{"type":"object","title":"Payload"},"event_timestamp":{"type":"string","maxLength":64,"minLength":1,"title":"Event Timestamp"},"audience":{"type":"string","maxLength":64,"minLength":1,"title":"Audience"}},"type":"object","required":["provider_id","event_id","event_type","event_timestamp","audience"],"title":"WebhookBody","description":"Signed body a provider posts to /provider/webhooks. Signature covers\n``canonical_json(body)``.\n\nTwo idempotency defenses layer here: this envelope carries ``event_id``\nwhich the DB enforces UNIQUE per provider, AND the semantic actions\n(e.g. re-revoking an already-revoked link) are no-ops so a replay that\nslips past the envelope check still lands in a stable state."},"WebhookCreateRequest":{"properties":{"pair_id":{"type":"string","title":"Pair Id"},"url":{"type":"string","title":"Url"},"events":{"type":"string","title":"Events","default":"*"}},"type":"object","required":["pair_id","url"],"title":"WebhookCreateRequest"},"WebhookIn":{"properties":{"body":{"$ref":"#/components/schemas/WebhookBody"},"signature":{"type":"string","maxLength":128,"minLength":128,"title":"Signature"}},"type":"object","required":["body","signature"],"title":"WebhookIn"},"WebhookListItem":{"properties":{"id":{"type":"string","title":"Id"},"pair_id":{"type":"string","title":"Pair Id"},"url":{"type":"string","title":"Url"},"events":{"type":"string","title":"Events"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","pair_id","url","events","is_active"],"title":"WebhookListItem"},"WebhookOut":{"properties":{"id":{"type":"string","title":"Id"},"provider_id":{"type":"string","title":"Provider Id"},"event_id":{"type":"string","title":"Event Id"},"event_type":{"type":"string","title":"Event Type"},"status":{"type":"string","title":"Status"},"applied":{"type":"object","title":"Applied"},"signature_verified":{"type":"boolean","title":"Signature Verified"}},"type":"object","required":["id","provider_id","event_id","event_type","status","applied","signature_verified"],"title":"WebhookOut"},"WebhookResponse":{"properties":{"id":{"type":"string","title":"Id"},"pair_id":{"type":"string","title":"Pair Id"},"url":{"type":"string","title":"Url"},"secret":{"type":"string","title":"Secret"},"events":{"type":"string","title":"Events"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","pair_id","url","secret","events","is_active"],"title":"WebhookResponse"},"app__api__authority_review__DecisionIn":{"properties":{"action":{"type":"string","maxLength":20,"title":"Action"},"note":{"type":"string","maxLength":2000,"title":"Note","default":""},"evidence_ids":{"items":{"type":"string"},"type":"array","title":"Evidence Ids"},"lifecycle_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lifecycle State"}},"type":"object","required":["action"],"title":"DecisionIn"},"app__api__csam__OpenIn":{"properties":{"subject_id":{"type":"string","maxLength":255,"minLength":1,"title":"Subject Id"},"note":{"type":"string","maxLength":2000,"title":"Note","default":""},"report_id":{"anyOf":[{"type":"string","maxLength":36},{"type":"null"}],"title":"Report Id"}},"type":"object","required":["subject_id"],"title":"OpenIn"},"app__api__groups__InviteMemberRequest":{"properties":{"username":{"type":"string","title":"Username"}},"type":"object","required":["username"],"title":"InviteMemberRequest"},"app__api__license_requests__LicenseBody":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"licensee_id":{"type":"string","title":"Licensee Id"},"license_class":{"type":"string","title":"License Class"},"scope":{"items":{"type":"string"},"type":"array","title":"Scope","default":[]},"deny_categories":{"items":{"type":"string"},"type":"array","title":"Deny Categories","default":[]},"immutable_denials":{"items":{"type":"string"},"type":"array","title":"Immutable Denials","default":[]},"required_obligations":{"type":"object","title":"Required Obligations","default":{}},"expires_at":{"type":"integer","title":"Expires At"},"contract_start":{"type":"integer","title":"Contract Start","default":0},"product_name":{"type":"string","title":"Product Name","default":""},"project_name":{"type":"string","title":"Project Name","default":""},"asset_visual_description":{"type":"string","title":"Asset Visual Description","default":""},"purpose":{"type":"object","title":"Purpose","default":{}},"extensions":{"items":{"type":"object"},"type":"array","title":"Extensions","default":[]},"allowed_channels":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Channels"},"allowed_territories":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Territories"},"rules_text":{"type":"string","title":"Rules Text","default":""}},"type":"object","required":["subject_id","licensee_id","license_class","expires_at"],"title":"LicenseBody"},"app__api__licenses__LicenseBody":{"properties":{"subject_id":{"type":"string","title":"Subject Id"},"licensee_id":{"type":"string","title":"Licensee Id"},"license_class":{"type":"string","title":"License Class"},"scope":{"items":{"type":"string"},"type":"array","title":"Scope","default":[]},"deny_categories":{"items":{"type":"string"},"type":"array","title":"Deny Categories","default":[]},"immutable_denials":{"items":{"type":"string"},"type":"array","title":"Immutable Denials","default":[]},"required_obligations":{"type":"object","title":"Required Obligations","default":{}},"expires_at":{"type":"integer","title":"Expires At"},"contract_start":{"type":"integer","title":"Contract Start","default":0},"product_name":{"type":"string","title":"Product Name","default":""},"project_name":{"type":"string","title":"Project Name","default":""},"asset_visual_description":{"type":"string","title":"Asset Visual Description","default":""},"purpose":{"type":"object","title":"Purpose","default":{}},"extensions":{"items":{"type":"object"},"type":"array","title":"Extensions","default":[]},"granted_rights":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Granted Rights"},"output_survives_termination":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Output Survives Termination"}},"type":"object","required":["subject_id","licensee_id","license_class","expires_at"],"title":"LicenseBody"},"app__api__licenses__RescindRequest":{"properties":{"reason":{"type":"string","title":"Reason","default":""}},"type":"object","title":"RescindRequest"},"app__api__operator_approvals__DecisionIn":{"properties":{"note":{"type":"string","maxLength":2000,"title":"Note","default":""}},"type":"object","title":"DecisionIn"},"app__api__opt_outs__RescindRequest":{"properties":{"subject_signature_hex":{"type":"string","title":"Subject Signature Hex","default":""}},"type":"object","title":"RescindRequest"},"app__api__organizations__InviteMemberRequest":{"properties":{"username":{"type":"string","title":"Username"},"role":{"type":"string","title":"Role","default":"member"}},"type":"object","required":["username"],"title":"InviteMemberRequest"},"app__api__usage_cases__OpenIn":{"properties":{"text":{"type":"string","maxLength":5000,"title":"Text","default":""},"link":{"type":"string","maxLength":1000,"title":"Link","default":""},"file":{"anyOf":[{"$ref":"#/components/schemas/FileIn"},{"type":"null"}]},"reason":{"type":"string","enum":["no_licence","outside_licence","lookalike","other"],"title":"Reason"}},"type":"object","required":["reason"],"title":"OpenIn"}},"securitySchemes":{"OAuth2PasswordBearer":{"type":"oauth2","flows":{"password":{"scopes":{},"tokenUrl":"/v1/auth/login"}}}}}}