{"openapi":"3.1.0","info":{"title":"Rosto","version":"0.1.0"},"paths":{"/v1/models":{"get":{"summary":"List Models","description":"The generation-model picker for the platform/Console (the switch).","operationId":"list_models_v1_models_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Models V1 Models Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/styles":{"get":{"summary":"List Styles","description":"The house-style picker. Separate from /v1/models: a MODEL is which engine\ndraws, a STYLE is what it draws — a cheap model can render any style.","operationId":"list_styles_v1_styles_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Styles V1 Styles Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/keys":{"post":{"summary":"Issue Key","description":"Mint a scoped, tenant-owning API key (admin only). The secret is returned\nONCE and never stored — only its hash is persisted.","operationId":"issue_key_v1_keys_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueKeyIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Issue Key V1 Keys Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/claims":{"post":{"summary":"Mint Claim","operationId":"mint_claim_v1_claims_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Mint Claim V1 Claims Post"}}}}}}},"/v1/claims/collect":{"post":{"summary":"Collect Claim","operationId":"collect_claim_v1_claims_collect_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimCollectIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Collect Claim V1 Claims Collect Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/invites/redeem":{"post":{"summary":"Redeem Invite","description":"Console onboarding: exchange a valid, single-use invite code for a fresh\ncreate+read key. Spend is capped by the invite (single-use) + rate limits.","operationId":"redeem_invite_v1_invites_redeem_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Redeem Invite V1 Invites Redeem Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/insights":{"get":{"summary":"Insights Summary","description":"Anonymous product statistics (admin only): consent declarations,\ncapture sources, persona roles, moderation rejection reasons — counters\nwith NO tenant/avatar/email dimensions by construction (app/insights.py).","operationId":"insights_summary_v1_insights_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Insights Summary V1 Insights Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credits":{"get":{"summary":"Get Credits","description":"This key's own credit balance + the per-op price (the Console/MCP read it).\n\n`purchasable` is deliberately separate from `enabled`: metering and *being\nable to buy* are independent flags, and conflating them is what made the\ndashboard show a \"Top up\" button in a deployment with no payment provider —\na call-to-action whose only destination said you cannot top up.","operationId":"get_credits_v1_credits_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Credits V1 Credits Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Grant Credits","description":"Grant credits to a tenant (admin/ops; Stripe grants via the webhook below).","operationId":"grant_credits_v1_credits_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Grant Credits V1 Credits Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/packs":{"get":{"summary":"Billing Packs","description":"The purchasable credit packs, the hosting plan, and this tenant's plan\nstatus. Ownership is one-time (packs); hosting is the subscription.","operationId":"billing_packs_v1_billing_packs_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Billing Packs V1 Billing Packs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/subscribe":{"post":{"summary":"Billing Subscribe","description":"Start a Stripe Checkout for the hosting subscription (badge-free fleet\nhosting + the monthly included avatar); returns the hosted payment URL.","operationId":"billing_subscribe_v1_billing_subscribe_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/SubscribeIn"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Billing Subscribe V1 Billing Subscribe Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/plans":{"post":{"summary":"Set Plan","description":"Set a tenant's hosting-plan record directly (admin/ops). This is how\nplatform deals are comped — e.g. Digaso gets badge-free serving via an\n'active' record here, no Stripe subscription involved.","operationId":"set_plan_v1_plans_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Plan V1 Plans Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/checkout":{"post":{"summary":"Billing Checkout","description":"Start a Stripe Checkout for a pack; returns the hosted payment URL.","operationId":"billing_checkout_v1_billing_checkout_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Billing Checkout V1 Billing Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/webhook":{"post":{"summary":"Billing Webhook","description":"Stripe webhook: grants credits on a completed checkout (signature-verified).","operationId":"billing_webhook_v1_billing_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Billing Webhook V1 Billing Webhook Post"}}}}}}},"/healthz":{"get":{"summary":"Healthz","operationId":"healthz_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Healthz Healthz Get"}}}}}}},"/v1/avatars":{"post":{"summary":"Create Avatar","operationId":"create_avatar_v1_avatars_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhotoIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Avatar V1 Avatars Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/personas":{"get":{"summary":"Persona Catalog","description":"The role/look registry for persona pickers (Console + MCP). These ids\nare the ONLY inputs persona creation accepts — free text never reaches\nthe image prompt (docs/character-policy.md safety contract).","operationId":"persona_catalog_v1_personas_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Persona Catalog V1 Personas Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/persona":{"post":{"summary":"Create Persona Avatar","description":"Mint a wholly SYNTHETIC role-typed persona avatar: generate a\nfictional portrait (registry-only prompt), moderate it fail-closed, then\nrun the exact same creation pipeline as an upload. Same rate limits,\nsame credit hold, same approval flow — one extra image call of cost.","operationId":"create_persona_avatar_v1_avatars_persona_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonaIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Persona Avatar V1 Avatars Persona Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/frames":{"post":{"summary":"Build Frames","operationId":"build_frames_v1_avatars__avatar_id__frames_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/frames/{avatar_id}":{"post":{"summary":"Internal Build Frames","description":"Cloud Tasks worker: does the build off the request path. Publicly\nreachable (the LB has no per-path auth), so gated by a shared secret. A 5xx\nmakes Cloud Tasks retry; honest per-frame skips are a 200 (not a failure).","operationId":"internal_build_frames_internal_frames__avatar_id__post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-internal-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Internal Build Frames Internal Frames  Avatar Id  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}":{"get":{"summary":"Get Manifest","operationId":"get_manifest_v1_avatars__avatar_id__get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Manifest V1 Avatars  Avatar Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Avatar","operationId":"delete_avatar_v1_avatars__avatar_id__delete","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/base":{"get":{"summary":"Get Base Asset","description":"Stream the owner's base image (owner-authed; works pre-approval, unlike /pub).","operationId":"get_base_asset_v1_avatars__avatar_id__base_get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/frames/{frame_id}":{"get":{"summary":"Get Frame Asset","description":"Stream one owner expression frame by id (owner-authed; works pre-approval).","operationId":"get_frame_asset_v1_avatars__avatar_id__frames__frame_id__get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"frame_id","in":"path","required":true,"schema":{"type":"string","title":"Frame Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/masks/{frame_id}":{"get":{"summary":"Get Frame Mask Asset","description":"The frame's feathered diff matte (the smooth region mask the rig applies).","operationId":"get_frame_mask_asset_v1_avatars__avatar_id__masks__frame_id__get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"frame_id","in":"path","required":true,"schema":{"type":"string","title":"Frame Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/signoff":{"post":{"summary":"Signoff Avatar","description":"Record the owner's likeness verdict — the human half of the M1 gate. Turns\na test avatar into validation evidence (does this actually look like them?).","operationId":"signoff_avatar_v1_avatars__avatar_id__signoff_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignoffIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Signoff Avatar V1 Avatars  Avatar Id  Signoff Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/stickers":{"get":{"summary":"Sticker Pack","description":"Download this avatar's animated reaction stickers as a ZIP of looping\nGIFs (optionally captioned — Customoji-style, text revealed in sync with\nthe performance). Rendered server-side from the stored frames at zero\nmodel cost. Same approval gate as export; the community-hosting badge\nrule applies (plan holders get unstamped GIFs).","operationId":"sticker_pack_v1_avatars__avatar_id__stickers_get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"caption","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption"}},{"name":"clips","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clips"}},{"name":"captions","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Captions"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/export":{"get":{"summary":"Export Avatar","description":"Download the avatar as a standalone, self-hostable ZIP — the \"you own it\"\nguarantee made literal (portable manifest + base + frames + rig + runnable\nindex.html + protocol README). Gated on approval so it can't bypass\npay-on-approval: you can take your copy once you've accepted (and paid for) it.","operationId":"export_avatar_v1_avatars__avatar_id__export_get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/approve":{"post":{"summary":"Approve Avatar","description":"Accept a finished avatar: it becomes publicly embeddable, and the retained\nphoto is destroyed.\n\nThis is NOT a payment step any more. Accepting used to levy the per-avatar\ncharge (pay-on-approval), which put a price inside the label of the button\nthat answers \"is this you?\" — the one question the Mirror exists to ask.\nMaking it and hosting it are free; the charge moved to `/own`\n(BUSINESS.md §Decisions resolved 2026-08-17). Idempotent.","operationId":"approve_avatar_v1_avatars__avatar_id__approve_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Approve Avatar V1 Avatars  Avatar Id  Approve Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/own":{"post":{"summary":"Own Avatar","description":"Buy this avatar: one credit, and the downloadable bundle unlocks.\n\nThe single charge in the product. `1 credit = 1 owned avatar` — the\nanti-credit-confusion rule — so a premium avatar costs the credits it quoted\nat creation (`meta.credit_cost`). Idempotent: owning an owned avatar is a\nno-op, never a second charge. Buying also settles the build allowance, so an\navatar bought before it was built does not additionally consume the free one.","operationId":"own_avatar_v1_avatars__avatar_id__own_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Own Avatar V1 Avatars  Avatar Id  Own Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/photo":{"get":{"summary":"Get Retained Photo","description":"The owner's retained photo, served ONLY to them and ONLY while it's retained\n(for the Console's on-accept deletion moment). 404 once deleted.","operationId":"get_retained_photo_v1_avatars__avatar_id__photo_get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/report":{"post":{"summary":"Report Defect","description":"Report a quality problem. We check the avatar ourselves: a confirmed defect\nunlocks a free re-roll (and refunds if already paid); if it looks fine we don't\nauto-grant one — we escalate to a human queue and ask the user to wait.","operationId":"report_defect_v1_avatars__avatar_id__report_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Report Defect V1 Avatars  Avatar Id  Report Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/reroll":{"post":{"summary":"Reroll","description":"Regenerate this avatar's base from the retained photo (same id + token).\n\nTwo ways in, and they exist for different reasons:\n\n1. **\"Try again\", before anything is built.** Since 2026-08-17 making a base\n   costs nothing, so not liking your first draw is not a support case — it is\n   the product working. This used to be routed through `/report`, which\n   adjudicates defects in a BUILT expression set: at stage 1 there is nothing\n   to adjudicate, so it always fell through to the escalate branch and filed a\n   human review ticket. The button said \"Try again\" and delivered a support\n   queue entry. Bounded by the per-day create rate limit, like any other\n   generation.\n2. **A confirmed defect, after the build.** Unchanged: `reroll_granted` is set\n   by `/report` when we can see a real defect, and it re-runs the frames too.","operationId":"reroll_v1_avatars__avatar_id__reroll_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reviews":{"get":{"summary":"List Reviews","description":"The human-review queue: reports our automated check couldn't confirm.","operationId":"list_reviews_v1_reviews_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Reviews V1 Reviews Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/validation":{"get":{"summary":"Validation Summary","description":"The M1 diverse-face gate readout: faces built, mean/per-AU frame yield,\nweakest AUs to tune, likeness sign-offs, and whether the gate passes. Every\nreal-face test build + sign-off feeds this — testing IS the evidence.","operationId":"validation_summary_v1_validation_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Validation Summary V1 Validation Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/grant-reroll":{"post":{"summary":"Grant Reroll","description":"Admin override: grant a re-roll after human review (and clear the queue item).","operationId":"grant_reroll_v1_avatars__avatar_id__grant_reroll_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Grant Reroll V1 Avatars  Avatar Id  Grant Reroll Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/domains":{"put":{"summary":"Set Domains","description":"Lock (or unlock) an avatar's /pub serving to host patterns (owner-level).\nPatterns: `example.com` (exact) or `*.example.com` (subdomains). [] unlocks.","operationId":"set_domains_v1_avatars__avatar_id__domains_put","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainsIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Domains V1 Avatars  Avatar Id  Domains Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/verify":{"post":{"summary":"Verify Watermark","description":"Check whether an image is a Rosto avatar (by its invisible watermark) and,\nif it's yours, which one. Authenticated only. Abuse-guarded: capped per key\nper day; on breach the account is flagged to admins and blocked.","operationId":"verify_watermark_v1_verify_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Verify Watermark V1 Verify Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/avatars/{avatar_id}/rotate-token":{"post":{"summary":"Rotate Token","description":"Kill switch for an embedded avatar: the old /pub URLs die immediately\n(the store purges the CDN at the same choke point). Owner-level (`manage`).","operationId":"rotate_token_v1_avatars__avatar_id__rotate_token_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Rotate Token V1 Avatars  Avatar Id  Rotate Token Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/pub/{token}/manifest.json":{"get":{"summary":"Public Manifest","operationId":"public_manifest_pub__token__manifest_json_get","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"}}}}}}},"/pub/{token}/sticker/{clip}.gif":{"get":{"summary":"Public Sticker","description":"ONE reaction, as a GIF you can actually look at.\n\nThe sticker pack shipped as a ZIP download and nothing else, so the only way\nto find out what your own reactions looked like was to download an archive,\nunpack it, and open eight files. Owner, 2026-08-18: \"I don't see GIFs.\" A\npack you cannot preview is a promise, not a feature.\n\nRendered on demand from frames that already exist — no model call — and\ncached, because the inputs are immutable for a given content hash.","operationId":"public_sticker_pub__token__sticker__clip__gif_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"clip","in":"path","required":true,"schema":{"type":"string","title":"Clip"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/pub/{token}/poster":{"get":{"summary":"Public Poster","description":"The base portrait at a STABLE url — a still of the face, for an `<img>`.\n\nEvery surface that shows an avatar was blank until four sequential round\ntrips finished: HTML → avatar-rig.js (57.7 KB gzipped) → manifest.json → the\nbase image. Nothing could shortcut it, because the base's URL is content-\naddressed (`/pub/{token}/{content_hash}.png`) and the hash is only learnable\nFROM the manifest. So a poster was not merely missing, it was impossible.\n\nThis route is that missing shortcut: one hop, cacheable, no JavaScript. The\nrig still takes over once it loads; the difference is that the visitor sees\nthe face immediately instead of an empty box.","operationId":"public_poster_pub__token__poster_get","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"}}}}}}},"/pub/{token}/{asset}":{"get":{"summary":"Public Asset","operationId":"public_asset_pub__token___asset__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"asset","in":"path","required":true,"schema":{"type":"string","title":"Asset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/rig/avatar-rig.js":{"get":{"summary":"Rig Js","operationId":"rig_js_rig_avatar_rig_js_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/tts":{"post":{"summary":"Tts Speak","description":"A real neural voice for the demo. Public but bounded: dormant (501) until a\nkey is configured, per-IP daily rate-limited, and hard-capped in length so it\nstays a cheap demo. The playground falls back to the browser voice on any of\nthese.","operationId":"tts_speak_tts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TtsIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/rig/demo":{"get":{"summary":"Rig Demo","operationId":"rig_demo_rig_demo_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/rig/vector-rig.js":{"get":{"summary":"Vector Rig Js","operationId":"vector_rig_js_rig_vector_rig_js_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/vector/vector-rig.js":{"get":{"summary":"Vector Rig Js Relative","description":"The demo page references the runtime RELATIVELY (so the conformance\nharness can serve page+runtime from a bare temp dir); this makes the\nrelative URL resolve under /vector/demo too.","operationId":"vector_rig_js_relative_vector_vector_rig_js_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/vector/demo":{"get":{"summary":"Vector Demo","operationId":"vector_demo_vector_demo_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/vector/demo-manifest.json":{"get":{"summary":"Vector Demo Manifest","operationId":"vector_demo_manifest_vector_demo_manifest_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console":{"get":{"summary":"Home","operationId":"home_console_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/console/onboard":{"post":{"summary":"Onboard","operationId":"onboard_console_onboard_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/logout":{"post":{"summary":"Logout","operationId":"logout_console_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/login":{"post":{"summary":"Login Email","operationId":"login_email_console_login_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/oauth/{provider}":{"get":{"summary":"Oauth Start","operationId":"oauth_start_console_oauth__provider__get","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","title":"Provider"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/oauth/{provider}/callback":{"get":{"summary":"Oauth Callback","operationId":"oauth_callback_console_oauth__provider__callback_get","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","title":"Provider"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/claim":{"get":{"summary":"Claim Page","operationId":"claim_page_console_claim_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}},"post":{"summary":"Claim Approve","operationId":"claim_approve_console_claim_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/verify":{"get":{"summary":"Verify Email","operationId":"verify_email_console_verify_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/admin":{"get":{"summary":"Admin Gate","operationId":"admin_gate_console_admin_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}},"post":{"summary":"Admin Login","operationId":"admin_login_console_admin_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/admin/logout":{"post":{"summary":"Admin Logout","operationId":"admin_logout_console_admin_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/age":{"post":{"summary":"Confirm Age","operationId":"confirm_age_console_age_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/new":{"get":{"summary":"New Form","operationId":"new_form_console_new_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}},"post":{"summary":"Create","operationId":"create_console_new_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/new-persona":{"post":{"summary":"New Persona","operationId":"new_persona_console_new_persona_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/a/{avatar_id}":{"get":{"summary":"Avatar Page","operationId":"avatar_page_console_a__avatar_id__get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"err","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Err"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/frames":{"post":{"summary":"Build","operationId":"build_console_a__avatar_id__frames_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/approve":{"post":{"summary":"Approve","operationId":"approve_console_a__avatar_id__approve_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/photo":{"get":{"summary":"Retained Photo","operationId":"retained_photo_console_a__avatar_id__photo_get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/report":{"post":{"summary":"Report","operationId":"report_console_a__avatar_id__report_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/reroll":{"post":{"summary":"Reroll","operationId":"reroll_console_a__avatar_id__reroll_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/stickers":{"get":{"summary":"Download Stickers","description":"Stream the reaction-sticker ZIP (thin proxy over /v1 .../stickers).","operationId":"download_stickers_console_a__avatar_id__stickers_get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}},{"name":"caption","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption"}},{"name":"captions","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Captions"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/own":{"post":{"summary":"Own","description":"Buy this avatar — the single charge. Back to the Mirror either way; the\npage itself then shows either the download or the reason it can't.","operationId":"own_console_a__avatar_id__own_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/download":{"get":{"summary":"Download","description":"Stream the standalone avatar ZIP back to the browser (the 'Own it' button).\nThin proxy over /v1/avatars/{id}/export with the session's key.","operationId":"download_console_a__avatar_id__download_get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/signoff":{"post":{"summary":"Signoff","description":"Record the owner's likeness verdict (the M1 human sign-off), then back.","operationId":"signoff_console_a__avatar_id__signoff_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/rotate":{"post":{"summary":"Rotate","operationId":"rotate_console_a__avatar_id__rotate_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/domains":{"post":{"summary":"Set Domains","operationId":"set_domains_console_a__avatar_id__domains_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/a/{avatar_id}/delete":{"post":{"summary":"Delete","operationId":"delete_console_a__avatar_id__delete_post","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/console/billing":{"get":{"summary":"Billing Page","operationId":"billing_page_console_billing_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/console/billing/capacity":{"post":{"summary":"Billing Capacity","description":"Record the purchase-capacity confirmation, then back to the packs.","operationId":"billing_capacity_console_billing_capacity_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/billing/subscribe":{"post":{"summary":"Billing Subscribe","description":"Start the hosting subscription — the badge-free plan.\n\nSame shape as the pack checkout, including the purchase-capacity gate: a\nsubscription is still a purchase, and a minor still cannot form one.","operationId":"billing_subscribe_console_billing_subscribe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/billing/checkout":{"post":{"summary":"Billing Checkout","operationId":"billing_checkout_console_billing_checkout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/console/a/{avatar_id}/clip":{"get":{"summary":"Clip Studio","operationId":"clip_studio_console_a__avatar_id__clip_get","parameters":[{"name":"avatar_id","in":"path","required":true,"schema":{"type":"string","title":"Avatar Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mcp":{"post":{"summary":"Mcp Endpoint","operationId":"mcp_endpoint_mcp_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/llms.txt":{"get":{"summary":"Llms Txt","operationId":"llms_txt_llms_txt_get","responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/docs":{"get":{"summary":"Docs Alias","description":"`/docs` is where developers look first. It used to be FastAPI's Swagger UI\n(see the note on the FastAPI() constructor in app/main.py); the API explorer\nnow lives at /api-explorer and this address serves the actual documentation.","operationId":"docs_alias_docs_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/docs-site":{"get":{"summary":"Docs Site","operationId":"docs_site_docs_site_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/docs-site/avatar-package":{"get":{"summary":"Avatar Package Spec","description":"The canonical, versioned `avatar-package/1.0` protocol — the portable format\nevery avatar ships in, whether embedded from a hosted token or downloaded as a\nstandalone, self-hostable bundle. Linked from the bundle's README/AGENTS.md.","operationId":"avatar_package_spec_docs_site_avatar_package_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/playground":{"get":{"summary":"Playground","description":"The full demo console. Deliberately NOT in the top nav: the homepage\nmakes the argument, this is where someone who wants to drive it goes.","operationId":"playground_playground_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/motion-lab":{"get":{"summary":"Motion Lab","description":"The motion lab (web/motion-lab.html) — the A/B instrument for the motion\nwork. Real runtime, real frames, real baked scene; see the file header.","operationId":"motion_lab_motion_lab_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/hero/scene.json":{"get":{"summary":"Hero Scene","description":"The baked scene — audio URLs, viseme track, and the prosody schedule.","operationId":"hero_scene_hero_scene_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/how-it-works":{"get":{"summary":"How It Works","operationId":"how_it_works_how_it_works_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/use-cases":{"get":{"summary":"Use Cases","operationId":"use_cases_use_cases_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/trust":{"get":{"summary":"Trust","operationId":"trust_trust_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/terms":{"get":{"summary":"Terms","operationId":"terms_terms_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/privacy":{"get":{"summary":"Privacy","operationId":"privacy_privacy_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/pricing":{"get":{"summary":"Pricing","operationId":"pricing_pricing_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/compare":{"get":{"summary":"Compare","operationId":"compare_compare_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/why":{"get":{"summary":"Why","operationId":"why_why_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/hero/manifest.json":{"get":{"summary":"Hero Manifest","operationId":"hero_manifest_hero_manifest_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/hero/{asset}":{"get":{"summary":"Hero Asset","operationId":"hero_asset_hero__asset__get","parameters":[{"name":"asset","in":"path","required":true,"schema":{"type":"string","title":"Asset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/waitlist":{"post":{"summary":"Waitlist","operationId":"waitlist_waitlist_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"CheckoutIn":{"properties":{"pack_id":{"type":"string","minLength":1,"title":"Pack Id"},"success_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Success Url"},"cancel_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cancel Url"}},"type":"object","required":["pack_id"],"title":"CheckoutIn"},"ClaimCollectIn":{"properties":{"user_code":{"type":"string","maxLength":32,"minLength":4,"title":"User Code"}},"type":"object","required":["user_code"],"title":"ClaimCollectIn"},"DomainsIn":{"properties":{"domains":{"items":{"type":"string"},"type":"array","title":"Domains","default":[]}},"type":"object","title":"DomainsIn"},"GrantIn":{"properties":{"tenant":{"type":"string","minLength":1,"title":"Tenant"},"amount":{"type":"integer","exclusiveMinimum":0.0,"title":"Amount"},"reason":{"type":"string","title":"Reason","default":"grant"}},"type":"object","required":["tenant","amount"],"title":"GrantIn"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IssueKeyIn":{"properties":{"tenant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes","default":["create","read"]}},"type":"object","title":"IssueKeyIn"},"PersonaIn":{"properties":{"role_id":{"type":"string","maxLength":40,"minLength":1,"title":"Role Id"},"look_id":{"type":"string","maxLength":40,"minLength":1,"title":"Look Id","default":"look-1"},"gen_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gen Model"},"name":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Name"}},"type":"object","required":["role_id"],"title":"PersonaIn"},"PhotoIn":{"properties":{"image_base64":{"type":"string","maxLength":6000000,"minLength":100,"title":"Image Base64"},"mime_type":{"type":"string","title":"Mime Type"},"consent_attested":{"type":"boolean","title":"Consent Attested","default":false},"gen_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gen Model"},"style_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style Id"},"character_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character Class"},"name":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Name"},"source":{"anyOf":[{"type":"string","pattern":"^(camera|upload)$"},{"type":"null"}],"title":"Source"},"subject":{"anyOf":[{"type":"string","pattern":"^(self|consented_other|synthetic)$"},{"type":"null"}],"title":"Subject"}},"type":"object","required":["image_base64","mime_type"],"title":"PhotoIn"},"PlanIn":{"properties":{"tenant":{"type":"string","minLength":1,"title":"Tenant"},"plan":{"type":"string","minLength":1,"title":"Plan"},"status":{"type":"string","title":"Status","default":"active"}},"type":"object","required":["tenant","plan"],"title":"PlanIn"},"RedeemIn":{"properties":{"code":{"type":"string","minLength":1,"title":"Code"}},"type":"object","required":["code"],"title":"RedeemIn"},"SignoffIn":{"properties":{"resembles":{"type":"boolean","title":"Resembles"},"notes":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Notes"}},"type":"object","required":["resembles"],"title":"SignoffIn"},"SubscribeIn":{"properties":{"success_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Success Url"},"cancel_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cancel Url"},"interval":{"type":"string","title":"Interval","default":"month"}},"type":"object","title":"SubscribeIn"},"TtsIn":{"properties":{"text":{"type":"string","minLength":1,"title":"Text"},"style":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Style"},"voice":{"anyOf":[{"type":"string","maxLength":24},{"type":"null"}],"title":"Voice"}},"type":"object","required":["text"],"title":"TtsIn"},"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"},"VerifyIn":{"properties":{"image_base64":{"anyOf":[{"type":"string","maxLength":6000000,"minLength":1},{"type":"null"}],"title":"Image Base64"},"svg_base64":{"anyOf":[{"type":"string","maxLength":6000000,"minLength":1},{"type":"null"}],"title":"Svg Base64"}},"type":"object","title":"VerifyIn"}}}}