{"openapi":"3.1.0","info":{"title":"center-alpha","version":"0.1.0"},"paths":{"/api/health":{"get":{"tags":["health"],"summary":"Health","description":"Liveness — process is up. No dependency checks (those belong in /ready).","operationId":"health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Health Api Health Get"}}}}}}},"/api/ready":{"get":{"tags":["health"],"summary":"Ready","description":"Readiness — the pod can actually serve: DB reachable + Redis reachable.\nReturns 503 (so the LB pulls the pod) when either dependency is down.","operationId":"ready_api_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/register":{"post":{"tags":["auth"],"summary":"Register","description":"Open registration, in the order that makes abuse cheapest to refuse.\n\nGuards run cheapest-and-most-decisive first: the kill-switch, then the\ncaptcha (one HTTP call, kills scripted floods outright), then the per-IP\nthrottle, and only then the DNS-touching address check. The account itself\nis created UNVERIFIED and unpaid — the welcome credits arrive when the code\nfrom the confirmation email is entered, so a farm that never reads mail\nfarms nothing.","operationId":"register_api_v1_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["auth"],"summary":"Login","description":"Password sign-in. The captcha runs BEFORE the password is checked, so a\ncredential-stuffing run never even reaches the hashing work — that is the\npoint of putting one here at all.\n\nThe captcha only exists when Turnstile is configured, though, so the\nfailed-attempt throttle behind it is what actually caps guessing on a\ndeployment without keys (which is every deployment until they are set).","operationId":"login_api_v1_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"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"}}}}}}},"/api/v1/auth/me":{"get":{"tags":["auth"],"summary":"Me","operationId":"me_api_v1_auth_me_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":{"$ref":"#/components/schemas/UserOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/password":{"post":{"tags":["auth"],"summary":"Set Password","description":"Set or change the caller's own password.\n\nThis is what makes a Google account an ordinary account: sign in with\nGoogle once, set a password here, and email + password works forever after\n— including on the day Google is unreachable or the Google account is gone.","operationId":"set_password_api_v1_auth_password_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/PasswordSetRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/email/check":{"post":{"tags":["auth"],"summary":"Check Email","description":"Is this address usable — shape, does the domain accept mail, is it a\nburner. Public so the signup form can say \"gmial.com doesn't exist\" while\nthe person is still typing, instead of after they press the button.\n\nDeliberately says NOTHING about whether an account already exists: that\nwould turn this into an address-enumeration oracle.","operationId":"check_email_api_v1_auth_email_check_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCheckRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCheckResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/email/status":{"get":{"tags":["auth"],"summary":"Email Status","description":"Where this account stands: confirmed or not, what confirming pays, and\nwhether a code is already out there (so the UI never mails a duplicate).","operationId":"email_status_api_v1_auth_email_status_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":{"$ref":"#/components/schemas/VerifyStateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/email/send-code":{"post":{"tags":["auth"],"summary":"Send Verification Code","description":"(Re)send the confirmation code to the account's own address.\n\nRate-limited hard (see quotas.check_email_verify_send): the endpoint mails\nan address someone typed, so an unbounded button here is both our bill and\na stranger's inbox.","operationId":"send_verification_code_api_v1_auth_email_send_code_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/VerifyStateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/email/verify":{"post":{"tags":["auth"],"summary":"Verify Email","description":"Confirm the address with the emailed code — and collect the credits.","operationId":"verify_email_api_v1_auth_email_verify_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/VerifyCodeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyStateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/google/start":{"post":{"tags":["auth"],"summary":"Google Start","description":"Hand the SPA the URL to send the browser to. No auth: this is the public\nsign-in entry point (the ``link`` mode is authorised at the callback, where\na session actually exists).","operationId":"google_start_api_v1_auth_google_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleStartRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleStartResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/google/callback":{"post":{"tags":["auth"],"summary":"Google Callback","description":"Finish a sign-in: code → Google identity → our user → our JWT.\n\nExisting user (by google_sub, or by verified email on their first Google\nsign-in) → straight in. Nobody matches → a brand-new account, created\nthrough the same path a form signup takes: the registration kill-switch and\nthe per-IP throttle apply, and the signup bonus is granted.","operationId":"google_callback_api_v1_auth_google_callback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleCallbackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/google/link":{"post":{"tags":["auth"],"summary":"Google Link","description":"Attach a Google account to the account already signed in (profile page).","operationId":"google_link_api_v1_auth_google_link_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/GoogleCallbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["auth"],"summary":"Google Unlink","operationId":"google_unlink_api_v1_auth_google_link_delete","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/UserOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tokens":{"get":{"tags":["tokens"],"summary":"List Tokens","operationId":"list_tokens_api_v1_tokens_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":{"type":"array","items":{"$ref":"#/components/schemas/ApiTokenOut"},"title":"Response List Tokens Api V1 Tokens Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["tokens"],"summary":"Create Token","operationId":"create_token_api_v1_tokens_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/TokenCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTokenCreatedOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tokens/{token_id}/toggle":{"post":{"tags":["tokens"],"summary":"Toggle Token","description":"Pause/resume a key. Disabling keeps the hash, so enabling it again makes\nthe SAME plaintext work — integrations don't need a new key.","operationId":"toggle_token_api_v1_tokens__token_id__toggle_post","parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"integer","title":"Token Id"}},{"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/ApiTokenOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tokens/{token_id}":{"delete":{"tags":["tokens"],"summary":"Delete Token","description":"Delete the key PERMANENTLY (the row disappears from the list). To just\npause it, use /toggle instead.","operationId":"delete_token_api_v1_tokens__token_id__delete","parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"integer","title":"Token Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/ping":{"get":{"tags":["me"],"summary":"Ping","description":"Cheap authenticated no-op: validates the API key, spends nothing.","operationId":"ping_api_v1_me_ping_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"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/PingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/features":{"get":{"tags":["me"],"summary":"My Features","description":"The resolved switches for the caller, plus the audiences they landed in.\n\nPublic features only (see services/features.public_map) — an internal\nexperiment must not be readable from devtools, and for a gate like payments\nthe list of early accounts is itself information.\n\nAnonymous callers get the defaults: they have no segments, and the open\nstudio's behaviour must not depend on rules written about accounts. The\nendpoint answers rather than 401s precisely so the SPA can ask once, before\nit knows whether anyone is signed in.\n\n`segments` is advisory — it exists so support can ask \"what do you see?\" and\nget an answer that explains itself. Nothing may be authorised from it: the\ngate is the feature value, resolved here, and re-checked by the endpoint\nthat does the work.","operationId":"my_features_api_v1_me_features_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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","title":"Response My Features Api V1 Me Features Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/usage":{"get":{"tags":["me"],"summary":"My Usage","description":"The current user's own usage events (+ this browser's anonymous runs),\nnewest first.","operationId":"my_usage_api_v1_me_usage_get","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":"source","in":"query","required":false,"schema":{"anyOf":[{"enum":["web","api","bridge"],"type":"string"},{"type":"null"}],"title":"Source"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Action"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyUsageEventOut"},"title":"Response My Usage Api V1 Me Usage Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/usage/summary":{"get":{"tags":["me"],"summary":"My Usage Summary","description":"Last-30-days rollup for the profile page chips.","operationId":"my_usage_summary_api_v1_me_usage_summary_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":{"$ref":"#/components/schemas/MyUsageSummaryOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/favorites":{"get":{"tags":["me"],"summary":"List Favorites","description":"The current user's pinned studio tools, in their chosen order.","operationId":"list_favorites_api_v1_me_favorites_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":{"type":"array","items":{"$ref":"#/components/schemas/FavoriteOut"},"title":"Response List Favorites Api V1 Me Favorites Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["me"],"summary":"Add Favorite","description":"Pin a studio tool. Idempotent — re-pinning returns the existing pin (still\n201), never an error. 404 if the operation isn't a live studio tool.","operationId":"add_favorite_api_v1_me_favorites_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/FavoriteAddIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FavoriteOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/favorites/{operation_id}":{"delete":{"tags":["me"],"summary":"Remove Favorite","description":"Unpin a studio tool. Idempotent — 204 whether or not it was pinned.","operationId":"remove_favorite_api_v1_me_favorites__operation_id__delete","parameters":[{"name":"operation_id","in":"path","required":true,"schema":{"type":"integer","title":"Operation Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/favorites/reorder":{"patch":{"tags":["me"],"summary":"Reorder Favorites","description":"Set pin order by list position. Ids not owned by the user are ignored.\nReturns the reordered list.","operationId":"reorder_favorites_api_v1_me_favorites_reorder_patch","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/FavoriteReorderIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FavoriteOut"},"title":"Response Reorder Favorites Api V1 Me Favorites Reorder Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs":{"post":{"tags":["jobs"],"summary":"Submit Job","operationId":"submit_job_api_v1_jobs_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/JobSubmit"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["jobs"],"summary":"List Jobs","operationId":"list_jobs_api_v1_jobs_get","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":"mine","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Mine"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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":"array","items":{"$ref":"#/components/schemas/JobOut"},"title":"Response List Jobs Api V1 Jobs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/api":{"post":{"tags":["jobs"],"summary":"Submit Job Api","operationId":"submit_job_api_api_v1_jobs_api_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobSubmit"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/upload":{"post":{"tags":["jobs"],"summary":"Submit Job Upload","description":"ONE call: send the file and what to do with it, get a job back.\n\nThe two-step flow (POST /uploads → POST /jobs/api) still exists and is the\nonly option for big files — the CDN caps proxied bodies at ~100 MB, so\nmulti-GB video must go straight to storage via the presigned routes. For\neverything else this is the whole API: submit here, then poll GET /jobs/{id}.\n\n`params` is a JSON object as a form field; `file_url` is injected from the\nuploaded file and always wins, so callers can't point the job at someone\nelse's object by smuggling a file_url in.","operationId":"submit_job_upload_api_v1_jobs_upload_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_submit_job_upload_api_v1_jobs_upload_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/{job_id}":{"get":{"tags":["jobs"],"summary":"Get Job","operationId":"get_job_api_v1_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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":{"$ref":"#/components/schemas/JobOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/{job_id}/repeat":{"post":{"tags":["jobs"],"summary":"Repeat Job","description":"Re-run one of YOUR jobs with its original operation + params (fresh file\nURLs and all). Same billing as a fresh submit — the estimate is debited and\nrefunded on failure. Works with the panel JWT or an API key, so bots can\nretry a failed job with one call.","operationId":"repeat_job_api_v1_jobs__job_id__repeat_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/{job_id}/cancel":{"post":{"tags":["jobs"],"summary":"Cancel Job","operationId":"cancel_job_api_v1_jobs__job_id__cancel_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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":{"$ref":"#/components/schemas/JobOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/packages":{"get":{"tags":["billing"],"summary":"List Packages","operationId":"list_packages_api_v1_billing_packages_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":{"type":"array","items":{"$ref":"#/components/schemas/PackageOut"},"title":"Response List Packages Api V1 Billing Packages Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/plans":{"get":{"tags":["billing"],"summary":"List Plan Offers","description":"Tiers a user can actually buy — priced, public and active, all three.\n\nPrices are resolved PER USER: an early customer sees the price they locked,\nnot today's list price, and the page must not quote them a number that the\ncheckout would then refuse to charge. Empty while payments are not live, and\nempty for an account the payments feature has not been switched on for.","operationId":"list_plan_offers_api_v1_billing_plans_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":{"type":"array","items":{"$ref":"#/components/schemas/PlanOfferOut"},"title":"Response List Plan Offers Api V1 Billing Plans Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/balance":{"get":{"tags":["billing"],"summary":"Balance","operationId":"balance_api_v1_billing_balance_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":{"$ref":"#/components/schemas/BalanceOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/subscription":{"get":{"tags":["billing"],"summary":"My Subscription","operationId":"my_subscription_api_v1_billing_subscription_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":{"anyOf":[{"$ref":"#/components/schemas/SubscriptionOut"},{"type":"null"}],"title":"Response My Subscription Api V1 Billing Subscription Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/ledger":{"get":{"tags":["billing"],"summary":"Ledger","description":"Own ledger, newest first — filterable by movement type and pageable, so\nthe client-facing analysis page (/ledger) can slice it.","operationId":"ledger_api_v1_billing_ledger_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"entry_type","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/LedgerEntryType"},{"type":"null"}],"title":"Entry Type"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LedgerEntryOut"},"title":"Response Ledger Api V1 Billing Ledger Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/checkout":{"post":{"tags":["billing"],"summary":"Checkout","description":"Buy a one-off credit pack. These credits never expire.","operationId":"checkout_api_v1_billing_checkout_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/CheckoutRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/subscribe":{"post":{"tags":["billing"],"summary":"Subscribe","description":"Buy a term on a plan. Charged at the user's locked price, not the list one.\n\nCrypto cannot auto-charge, so this is a prepaid term the user re-buys — there\nis deliberately no \"cancel\" endpoint, because there is nothing to cancel.","operationId":"subscribe_api_v1_billing_subscribe_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/SubscribeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/admin/payments":{"get":{"tags":["billing"],"summary":"Admin List Payments","description":"Payments, newest first. Filter by `partially_paid` to find what needs a call.","operationId":"admin_list_payments_api_v1_billing_admin_payments_get","parameters":[{"name":"payment_status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/PaymentStatus"},{"type":"null"}],"title":"Payment Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PaymentOut"},"title":"Response Admin List Payments Api V1 Billing Admin Payments Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/admin/payments/{order_id}/resolve":{"post":{"tags":["billing"],"summary":"Admin Resolve Payment","description":"Settle a payment the system deliberately would not settle on its own.\n\nUnderpayments are never auto-credited (see services/payments) — this is where\na human decides between granting in full, granting pro-rata, and refusing.","operationId":"admin_resolve_payment_api_v1_billing_admin_payments__order_id__resolve_post","parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","title":"Order Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolvePaymentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/admin/topup":{"post":{"tags":["billing"],"summary":"Manual Topup","operationId":"manual_topup_api_v1_billing_admin_topup_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/ManualTopUpRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/overview":{"get":{"tags":["stats"],"summary":"Overview","operationId":"overview_api_v1_stats_overview_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":{"type":"object","title":"Response Overview Api V1 Stats Overview Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/usage":{"get":{"tags":["stats"],"summary":"Usage","operationId":"usage_api_v1_stats_usage_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":730,"minimum":1,"default":30,"title":"Days"}},{"name":"mine","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Mine"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UsagePoint"},"title":"Response Usage Api V1 Stats Usage Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/usage/services":{"get":{"tags":["stats"],"summary":"Usage Services","operationId":"usage_services_api_v1_stats_usage_services_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":730,"minimum":1,"default":30,"title":"Days"}},{"name":"mine","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Mine"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ServiceUsage"},"title":"Response Usage Services Api V1 Stats Usage Services Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/usage/summary":{"get":{"tags":["stats"],"summary":"Usage Summary","description":"Headline tiles for the analytics page: submissions, credits, job\noutcomes (done/failed), active users — platform-wide for admins.","operationId":"usage_summary_api_v1_stats_usage_summary_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":730,"minimum":1,"default":30,"title":"Days"}},{"name":"mine","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Mine"}},{"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/UsageSummaryStats"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/logs":{"get":{"tags":["stats"],"summary":"Logs","operationId":"logs_api_v1_stats_logs_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RequestLogOut"},"title":"Response Logs Api V1 Stats Logs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/studio/tools":{"get":{"tags":["studio"],"summary":"Tools","operationId":"tools_api_v1_studio_tools_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/StudioTool"},"type":"array","title":"Response Tools Api V1 Studio Tools Get"}}}}}}},"/api/v1/studio/run":{"post":{"tags":["studio"],"summary":"Run","operationId":"run_api_v1_studio_run_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/StudioRunRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioRunOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/studio/batch":{"post":{"tags":["studio"],"summary":"Run Batch","operationId":"run_batch_api_v1_studio_batch_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/BatchRunRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/studio/batches":{"get":{"tags":["studio"],"summary":"List Batches","operationId":"list_batches_api_v1_studio_batches_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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":"array","items":{"$ref":"#/components/schemas/BatchOut"},"title":"Response List Batches Api V1 Studio Batches Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/studio/batches/{batch_id}":{"get":{"tags":["studio"],"summary":"Get Batch","operationId":"get_batch_api_v1_studio_batches__batch_id__get","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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":{"$ref":"#/components/schemas/BatchOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/studio/batches/{batch_id}/cancel":{"post":{"tags":["studio"],"summary":"Cancel Batch","operationId":"cancel_batch_api_v1_studio_batches__batch_id__cancel_post","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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":{"$ref":"#/components/schemas/BatchOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/studio/batches/{batch_id}/repeat":{"post":{"tags":["studio"],"summary":"Repeat Batch","description":"Re-run a previous batch on the same source files + operation.","operationId":"repeat_batch_api_v1_studio_batches__batch_id__repeat_post","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/config":{"get":{"tags":["public"],"summary":"Public Config","description":"What anonymous web visitors are currently allowed to do, whether we're in\na maintenance window, and how to reach support. Public so the SPA can adapt\nbefore (or without) sign-in.","operationId":"public_config_api_v1_public_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicConfig"}}}}}}},"/api/v1/public/feedback":{"post":{"tags":["public"],"summary":"Send Feedback","description":"Relay one support message to the owner's Telegram chat.\n\nDeliberately reports failure (503) instead of a comforting 202: a client who\njust typed out a bug report must not be told it was delivered when it wasn't.\n\nGuard order is cheapest-and-least-consuming first, so abuse is rejected\nbefore it costs anything: honeypot → browser check (anonymous only) →\ncontent → duplicate → volume limits → send.","operationId":"send_feedback_api_v1_public_feedback_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/FeedbackIn"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/analytics/collect":{"post":{"tags":["analytics"],"summary":"Collect","description":"Ingest a batch of web events. Fail-open, always 202.","operationId":"collect_api_v1_analytics_collect_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/CollectBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Collect Api V1 Analytics Collect Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/uploads":{"post":{"tags":["uploads"],"summary":"Upload","operationId":"upload_api_v1_uploads_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_api_v1_uploads_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Upload Api V1 Uploads Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/uploads/presign":{"post":{"tags":["uploads"],"summary":"Presign","description":"Presigned PUT for a DIRECT browser→R2 upload — bypasses the app + the\nCloudflare ~100 MB proxy body limit so multi-GB videos upload fine. The browser\nPUTs the file to `put_url` with the given Content-Type, then passes `url` to the\nstudio as the file. Local-dev storage can't presign → the client falls back to\nthe multipart POST above.","operationId":"presign_api_v1_uploads_presign_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/PresignRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Presign Api V1 Uploads Presign Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/uploads/multipart/create":{"post":{"tags":["uploads"],"summary":"Multipart Create","description":"Start a direct browser→R2 multipart upload. Same guards as /presign;\nthis is the ONLY multipart endpoint that consumes the anon upload quota.","operationId":"multipart_create_api_v1_uploads_multipart_create_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/MultipartCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Multipart Create Api V1 Uploads Multipart Create Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/uploads/multipart/sign-part":{"post":{"tags":["uploads"],"summary":"Multipart Sign Part","description":"Presigned URL for ONE part. Called ~50×/file — no upload quota, but\nbounded: per-IP rpm guard + only uploads we minted (Redis record from\ncreate) + only parts within the budget the CLAIMED size implies.","operationId":"multipart_sign_part_api_v1_uploads_multipart_sign_part_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/MultipartSignPartRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Multipart Sign Part Api V1 Uploads Multipart Sign Part Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/uploads/multipart/complete":{"post":{"tags":["uploads"],"summary":"Multipart Complete","description":"Stitch the uploaded parts; returns the same shape as /presign so the\nclient can hand the file straight to the studio.","operationId":"multipart_complete_api_v1_uploads_multipart_complete_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/MultipartCompleteRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Multipart Complete Api V1 Uploads Multipart Complete Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/uploads/multipart/abort":{"post":{"tags":["uploads"],"summary":"Multipart Abort","description":"Best-effort cleanup of an abandoned multipart upload (frees R2 storage).","operationId":"multipart_abort_api_v1_uploads_multipart_abort_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/MultipartAbortRequest"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/uploads/download":{"get":{"tags":["uploads"],"summary":"Download Proxy","description":"Stream a result file back through our origin with an attachment header so\nthe browser saves it (cross-origin `download` attrs + R2 CORS don't apply).","operationId":"download_proxy_api_v1_uploads_download_get","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","title":"Url"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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"}}}}}}},"/api/v1/tg/deliver":{"post":{"tags":["telegram"],"summary":"Deliver","description":"Create a single-use Telegram delivery link for a finished note video.","operationId":"deliver_api_v1_tg_deliver_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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/DeliverRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliverResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tg/webhook/{bot_id}":{"post":{"tags":["telegram"],"summary":"Webhook","description":"Per-bot Telegram update sink. Verifies the bot's secret header, then does\nthe heavy delivery work in a background task so we return 200 immediately.","operationId":"webhook_api_v1_tg_webhook__bot_id__post","parameters":[{"name":"bot_id","in":"path","required":true,"schema":{"type":"integer","title":"Bot Id"}},{"name":"x-telegram-bot-api-secret-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Telegram-Bot-Api-Secret-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Update"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Webhook Api V1 Tg Webhook  Bot Id  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/upload-sessions":{"post":{"tags":["upload-bridge"],"summary":"Create Upload Session","operationId":"create_upload_session_api_v1_upload_sessions_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/UploadSessionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSessionCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["upload-bridge"],"summary":"List Upload Sessions","description":"The owner's recent sessions, newest first — powers the web \"Upload\nlinks\" page. Lazily expires overdue rows and syncs the first few\nprocessing ones so the listing reflects live state.","operationId":"list_upload_sessions_api_v1_upload_sessions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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":"array","items":{"$ref":"#/components/schemas/UploadSessionOut"},"title":"Response List Upload Sessions Api V1 Upload Sessions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/upload-sessions/api":{"post":{"tags":["upload-bridge"],"summary":"Create Upload Session Api","operationId":"create_upload_session_api_api_v1_upload_sessions_api_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSessionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSessionCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/upload-sessions/{session_id}":{"get":{"tags":["upload-bridge"],"summary":"Get Upload Session","description":"Status poll for the session owner (panel JWT or API key). Syncs the\nlinked job from the upstream on read — same on-demand refresh model as\nGET /jobs/{id}.","operationId":"get_upload_session_api_v1_upload_sessions__session_id__get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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":{"$ref":"#/components/schemas/UploadSessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["upload-bridge"],"summary":"Delete Upload Session","description":"Delete one of YOUR links — active or spent. Its files are deleted with\nit (in-flight upload aborted, stored source removed from the bucket) and\nstill-running linked jobs are canceled + refunded. The link's token stops\nworking immediately.","operationId":"delete_upload_session_api_v1_upload_sessions__session_id__delete","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/upload-sessions/{session_id}/archive":{"get":{"tags":["upload-bridge"],"summary":"Download Archive","description":"All the link's uploaded files as ONE .zip, streamed — files come\nstraight from storage through this response (store-only zip, zip64, no\ndisk buffering). Files that vanished from storage are skipped.","operationId":"download_archive_api_v1_upload_sessions__session_id__archive_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"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"}}}}}}},"/api/v1/public/upload-sessions/{token}":{"get":{"tags":["upload-bridge"],"summary":"Public Session Info","description":"Safe public snapshot for the upload page. Never returns keys, bucket\ninternals, the owner or anything about other sessions.","operationId":"public_session_info_api_v1_public_upload_sessions__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSessionPublicInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/upload-sessions/{token}/multipart/init":{"post":{"tags":["upload-bridge"],"summary":"Public Multipart Init","description":"Start the direct browser→bucket upload. Validates size/type against the\nsession BEFORE any presigned URL exists. Re-init while still open restarts\na failed attempt (the previous multipart upload is aborted).","operationId":"public_multipart_init_api_v1_public_upload_sessions__token__multipart_init_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BridgeMultipartInit"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Public Multipart Init Api V1 Public Upload Sessions  Token  Multipart Init Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/upload-sessions/{token}/multipart/sign-part":{"post":{"tags":["upload-bridge"],"summary":"Public Multipart Sign Part","description":"Presigned URL for ONE part. Key/upload_id come from the session row —\nthe client can't point us at foreign keys. Bounded by the part budget the\ndeclared size implies + the shared sign-part rpm guard.","operationId":"public_multipart_sign_part_api_v1_public_upload_sessions__token__multipart_sign_part_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BridgeSignPart"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Public Multipart Sign Part Api V1 Public Upload Sessions  Token  Multipart Sign Part Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/upload-sessions/{token}/multipart/complete":{"post":{"tags":["upload-bridge"],"summary":"Public Multipart Complete","description":"Stitch + verify the object, then run the pinned operation through the\nnormal job path (identical billing to POST /jobs/api) and notify the\nclient's callback. The session is single-use: a second complete is a 409.","operationId":"public_multipart_complete_api_v1_public_upload_sessions__token__multipart_complete_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BridgeComplete"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Public Multipart Complete Api V1 Public Upload Sessions  Token  Multipart Complete Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/upload-sessions/{token}/multipart/abort":{"post":{"tags":["upload-bridge"],"summary":"Public Multipart Abort","description":"Best-effort cleanup of a canceled/failed attempt. The session goes back\nto created so the user can retry while the link is still valid.","operationId":"public_multipart_abort_api_v1_public_upload_sessions__token__multipart_abort_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/health":{"get":{"tags":["health"],"summary":"Health","description":"Liveness — process is up. No dependency checks (those belong in /ready).","operationId":"health_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Health Api V1 Health Get"}}}}}}},"/api/v1/ready":{"get":{"tags":["health"],"summary":"Ready","description":"Readiness — the pod can actually serve: DB reachable + Redis reachable.\nReturns 503 (so the LB pulls the pod) when either dependency is down.","operationId":"ready_api_v1_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"summary":"Index","operationId":"index__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Index  Get"}}}}}}}},"components":{"schemas":{"ApiTokenCreatedOut":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"last4":{"type":"string","title":"Last4"},"is_active":{"type":"boolean","title":"Is Active"},"revoked_by_admin":{"type":"boolean","title":"Revoked By Admin"},"max_per_day":{"type":"integer","title":"Max Per Day"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"plaintext":{"type":"string","title":"Plaintext"}},"type":"object","required":["id","name","last4","is_active","revoked_by_admin","max_per_day","last_used_at","created_at","plaintext"],"title":"ApiTokenCreatedOut","description":"Returned once on creation — includes the plaintext token."},"ApiTokenOut":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"last4":{"type":"string","title":"Last4"},"is_active":{"type":"boolean","title":"Is Active"},"revoked_by_admin":{"type":"boolean","title":"Revoked By Admin"},"max_per_day":{"type":"integer","title":"Max Per Day"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","last4","is_active","revoked_by_admin","max_per_day","last_used_at","created_at"],"title":"ApiTokenOut"},"BalanceOut":{"properties":{"balance":{"type":"integer","title":"Balance"},"expiring":{"type":"integer","title":"Expiring","default":0},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["balance"],"title":"BalanceOut"},"BatchOut":{"properties":{"id":{"type":"string","title":"Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"status":{"$ref":"#/components/schemas/BatchStatus"},"total":{"type":"integer","title":"Total"},"done":{"type":"integer","title":"Done"},"failed":{"type":"integer","title":"Failed"},"estimated_cost":{"type":"integer","title":"Estimated Cost"},"result_zip_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result Zip Url"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"params":{"type":"object","title":"Params"},"sources":{"items":{"type":"string"},"type":"array","title":"Sources","default":[]}},"type":"object","required":["id","title","status","total","done","failed","estimated_cost","result_zip_url","error","created_at","finished_at","operation_key","params"],"title":"BatchOut"},"BatchRunRequest":{"properties":{"operation_id":{"type":"integer","title":"Operation Id"},"file_urls":{"items":{"type":"string"},"type":"array","minItems":1,"title":"File Urls"},"preset_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Preset Index"},"naming":{"type":"string","title":"Naming","default":"keep"},"params":{"type":"object","title":"Params"}},"type":"object","required":["operation_id","file_urls"],"title":"BatchRunRequest"},"BatchStatus":{"type":"string","enum":["queued","processing","done","failed","canceled"],"title":"BatchStatus"},"Body_submit_job_upload_api_v1_jobs_upload_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"},"service_slug":{"type":"string","title":"Service Slug"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"params":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Params"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"high_priority":{"type":"boolean","title":"High Priority","default":false}},"type":"object","required":["file","service_slug"],"title":"Body_submit_job_upload_api_v1_jobs_upload_post"},"Body_upload_api_v1_uploads_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_api_v1_uploads_post"},"BridgeComplete":{"properties":{"parts":{"items":{"$ref":"#/components/schemas/BridgePart"},"type":"array","maxItems":10000,"minItems":1,"title":"Parts"}},"type":"object","required":["parts"],"title":"BridgeComplete"},"BridgeMultipartInit":{"properties":{"filename":{"type":"string","maxLength":300,"minLength":1,"title":"Filename"},"size":{"type":"integer","exclusiveMinimum":0.0,"title":"Size"},"content_type":{"type":"string","title":"Content Type","default":"application/octet-stream"},"checksum":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Checksum"}},"type":"object","required":["filename","size"],"title":"BridgeMultipartInit"},"BridgePart":{"properties":{"part_number":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Part Number"},"etag":{"type":"string","maxLength":256,"minLength":1,"title":"Etag"}},"type":"object","required":["part_number","etag"],"title":"BridgePart"},"BridgeSignPart":{"properties":{"part_number":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Part Number"}},"type":"object","required":["part_number"],"title":"BridgeSignPart"},"CheckoutRequest":{"properties":{"package_id":{"type":"integer","title":"Package Id"}},"type":"object","required":["package_id"],"title":"CheckoutRequest"},"CheckoutResponse":{"properties":{"order_id":{"type":"string","title":"Order Id"},"reference":{"type":"string","title":"Reference"},"redirect_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect Url"},"status":{"type":"string","title":"Status"},"balance":{"type":"integer","title":"Balance"}},"type":"object","required":["order_id","reference","redirect_url","status","balance"],"title":"CheckoutResponse"},"CollectBody":{"properties":{"events":{"items":{"type":"object"},"type":"array","title":"Events"}},"type":"object","title":"CollectBody"},"DeliverRequest":{"properties":{"result_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result Url"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"},"bot_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bot Id"}},"type":"object","title":"DeliverRequest"},"DeliverResponse":{"properties":{"deep_link":{"type":"string","title":"Deep Link"},"token":{"type":"string","title":"Token"},"bot_id":{"type":"integer","title":"Bot Id"}},"type":"object","required":["deep_link","token","bot_id"],"title":"DeliverResponse"},"EmailCheckRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"}},"type":"object","required":["email"],"title":"EmailCheckRequest"},"EmailCheckResponse":{"properties":{"acceptable":{"type":"boolean","title":"Acceptable"},"verdict":{"type":"string","title":"Verdict"}},"type":"object","required":["acceptable","verdict"],"title":"EmailCheckResponse"},"FavoriteAddIn":{"properties":{"operation_id":{"type":"integer","title":"Operation Id"}},"type":"object","required":["operation_id"],"title":"FavoriteAddIn"},"FavoriteOut":{"properties":{"operation_id":{"type":"integer","title":"Operation Id"},"service_slug":{"type":"string","title":"Service Slug"},"operation_key":{"type":"string","title":"Operation Key"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"sort_order":{"type":"integer","title":"Sort Order"}},"type":"object","required":["operation_id","service_slug","operation_key","label","sort_order"],"title":"FavoriteOut"},"FavoriteReorderIn":{"properties":{"operation_ids":{"items":{"type":"integer"},"type":"array","title":"Operation Ids"}},"type":"object","title":"FavoriteReorderIn"},"FeedbackIn":{"properties":{"message":{"type":"string","maxLength":2000,"minLength":1,"title":"Message"},"website":{"type":"string","maxLength":200,"title":"Website","default":""},"contact":{"type":"string","maxLength":200,"title":"Contact","default":""},"page":{"type":"string","maxLength":500,"title":"Page","default":""},"error":{"type":"string","maxLength":500,"title":"Error","default":""}},"type":"object","required":["message"],"title":"FeedbackIn"},"FeedbackOut":{"properties":{"ok":{"type":"boolean","title":"Ok"}},"type":"object","required":["ok"],"title":"FeedbackOut"},"GoogleCallbackRequest":{"properties":{"code":{"type":"string","maxLength":2048,"minLength":1,"title":"Code"},"state":{"type":"string","maxLength":256,"minLength":1,"title":"State"}},"type":"object","required":["code","state"],"title":"GoogleCallbackRequest"},"GoogleStartRequest":{"properties":{"next":{"type":"string","title":"Next","default":"/"},"mode":{"type":"string","title":"Mode","default":"login"}},"type":"object","title":"GoogleStartRequest"},"GoogleStartResponse":{"properties":{"authorization_url":{"type":"string","title":"Authorization Url"}},"type":"object","required":["authorization_url"],"title":"GoogleStartResponse"},"GoogleTokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"created":{"type":"boolean","title":"Created","default":false},"next":{"type":"string","title":"Next","default":"/"}},"type":"object","required":["access_token"],"title":"GoogleTokenResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JobOut":{"properties":{"id":{"type":"string","title":"Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"service_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Service Id"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"params":{"type":"object","title":"Params"},"result":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Result"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"estimated_cost":{"type":"integer","title":"Estimated Cost"},"final_cost":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Final Cost"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"}},"type":"object","required":["id","status","service_id","operation_key","params","result","error","estimated_cost","final_cost","created_at","finished_at"],"title":"JobOut"},"JobStatus":{"type":"string","enum":["queued","processing","done","failed","canceled"],"title":"JobStatus"},"JobSubmit":{"properties":{"service_slug":{"type":"string","title":"Service Slug"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"params":{"type":"object","title":"Params"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"high_priority":{"type":"boolean","title":"High Priority","default":false}},"type":"object","required":["service_slug"],"title":"JobSubmit"},"LedgerEntryOut":{"properties":{"id":{"type":"integer","title":"Id"},"entry_type":{"$ref":"#/components/schemas/LedgerEntryType"},"amount":{"type":"integer","title":"Amount"},"balance_after":{"type":"integer","title":"Balance After"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","entry_type","amount","balance_after","job_id","description","created_at"],"title":"LedgerEntryOut"},"LedgerEntryType":{"type":"string","enum":["purchase","signup_bonus","debit","refund","adjust","subscription","expire","daily_free"],"title":"LedgerEntryType"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"},"captcha_token":{"type":"string","maxLength":4096,"title":"Captcha Token","default":""}},"type":"object","required":["email","password"],"title":"LoginRequest"},"ManualTopUpRequest":{"properties":{"user_id":{"type":"integer","title":"User Id"},"credits":{"type":"integer","maximum":1000000.0,"exclusiveMinimum":0.0,"title":"Credits"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["user_id","credits"],"title":"ManualTopUpRequest","description":"Admin-only manual credit grant.\n\nStrictly positive: this endpoint is called \"top-up\" everywhere it appears,\nand a negative number here quietly TOOK credits off a customer — a debit\ndressed as a grant, journalled as \"Manual top-up by <admin>\". Taking credits\naway is a different decision that deserves its own deliberate action, not a\nminus sign typed into a box labelled \"grant\"."},"MarketingConfig":{"properties":{"ga4_id":{"type":"string","title":"Ga4 Id"},"google_ads_id":{"type":"string","title":"Google Ads Id"},"google_ads_signup_label":{"type":"string","title":"Google Ads Signup Label"},"google_ads_purchase_label":{"type":"string","title":"Google Ads Purchase Label"},"meta_pixel_id":{"type":"string","title":"Meta Pixel Id"},"consent_required":{"type":"boolean","title":"Consent Required"}},"type":"object","required":["ga4_id","google_ads_id","google_ads_signup_label","google_ads_purchase_label","meta_pixel_id","consent_required"],"title":"MarketingConfig","description":"Ad-network counter ids the SPA loads (empty string = that network is off,\nso its script is never fetched). Public by nature — a pixel id is visible in\npage source on every site that runs one; there is no secret here.\n\nThey are served at RUNTIME rather than baked into the bundle because Vite\ninlines `import.meta.env` at build time: a marketer swapping a counter, or\nthe owner killing a pixel after a complaint, would otherwise need a rebuild\nand a redeploy."},"MultipartAbortRequest":{"properties":{"key":{"type":"string","maxLength":1024,"minLength":1,"title":"Key"},"upload_id":{"type":"string","maxLength":4096,"minLength":1,"title":"Upload Id"}},"type":"object","required":["key","upload_id"],"title":"MultipartAbortRequest"},"MultipartCompleteRequest":{"properties":{"key":{"type":"string","maxLength":1024,"minLength":1,"title":"Key"},"upload_id":{"type":"string","maxLength":4096,"minLength":1,"title":"Upload Id"},"parts":{"items":{"$ref":"#/components/schemas/MultipartPart"},"type":"array","maxItems":10000,"minItems":1,"title":"Parts"},"content_type":{"type":"string","title":"Content Type","default":"application/octet-stream"}},"type":"object","required":["key","upload_id","parts"],"title":"MultipartCompleteRequest"},"MultipartCreateRequest":{"properties":{"filename":{"type":"string","maxLength":300,"minLength":1,"title":"Filename"},"size":{"type":"integer","exclusiveMinimum":0.0,"title":"Size"},"content_type":{"type":"string","title":"Content Type","default":"application/octet-stream"}},"type":"object","required":["filename","size"],"title":"MultipartCreateRequest"},"MultipartPart":{"properties":{"part_number":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Part Number"},"etag":{"type":"string","maxLength":256,"minLength":1,"title":"Etag"}},"type":"object","required":["part_number","etag"],"title":"MultipartPart"},"MultipartSignPartRequest":{"properties":{"key":{"type":"string","maxLength":1024,"minLength":1,"title":"Key"},"upload_id":{"type":"string","maxLength":4096,"minLength":1,"title":"Upload Id"},"part_number":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Part Number"}},"type":"object","required":["key","upload_id","part_number"],"title":"MultipartSignPartRequest"},"MyUsageEventOut":{"properties":{"id":{"type":"integer","title":"Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"source":{"type":"string","title":"Source"},"action":{"type":"string","title":"Action"},"service_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Slug"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"items":{"type":"integer","title":"Items"},"cost":{"type":"integer","title":"Cost"},"plan_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Slug"},"ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"},"token_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token Label"}},"type":"object","required":["id","created_at","source","action","service_slug","operation_key","items","cost","plan_slug","ip","token_label"],"title":"MyUsageEventOut","description":"One journal row for the owner's eyes — includes the caller IP (it is\nthe user's own activity: who/where/when), but never email/scope."},"MyUsageSummaryOut":{"properties":{"days":{"type":"integer","title":"Days"},"events":{"type":"integer","title":"Events"},"items":{"type":"integer","title":"Items"},"credits_spent":{"type":"integer","title":"Credits Spent"},"web_count":{"type":"integer","title":"Web Count"},"api_count":{"type":"integer","title":"Api Count"}},"type":"object","required":["days","events","items","credits_spent","web_count","api_count"],"title":"MyUsageSummaryOut"},"PackageOut":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"credits":{"type":"integer","title":"Credits"},"price_cents":{"type":"integer","title":"Price Cents"},"currency":{"type":"string","title":"Currency"},"discount_pct":{"type":"number","title":"Discount Pct"},"is_active":{"type":"boolean","title":"Is Active"},"sort_order":{"type":"integer","title":"Sort Order"}},"type":"object","required":["id","name","credits","price_cents","currency","discount_pct","is_active","sort_order"],"title":"PackageOut"},"PasswordSetRequest":{"properties":{"current_password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Password"},"new_password":{"type":"string","maxLength":128,"minLength":8,"title":"New Password"}},"type":"object","required":["new_password"],"title":"PasswordSetRequest"},"PaymentOut":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"type":"integer","title":"User Id"},"user_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Email"},"provider":{"type":"string","title":"Provider"},"order_id":{"type":"string","title":"Order Id"},"provider_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Ref"},"kind":{"type":"string","title":"Kind"},"credits":{"type":"integer","title":"Credits"},"amount_cents":{"type":"integer","title":"Amount Cents"},"currency":{"type":"string","title":"Currency"},"pay_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pay Currency"},"actually_paid_cents":{"type":"integer","title":"Actually Paid Cents"},"status":{"type":"string","title":"Status"},"credited_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Credited At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","user_id","provider","order_id","provider_ref","kind","credits","amount_cents","currency","pay_currency","actually_paid_cents","status","credited_at","created_at"],"title":"PaymentOut","description":"One purchase attempt, for the admin payments view."},"PaymentStatus":{"type":"string","enum":["waiting","confirming","paid","partially_paid","failed","expired","refunded"],"title":"PaymentStatus","description":"Provider-agnostic lifecycle. Adapters map their own vocabulary onto this.\n\nOnly ``paid`` grants credits. ``partially_paid`` is deliberately terminal-ish\nand NOT credited automatically: underpayment is the common crypto failure\n(user pays the amount but not the network fee), and it needs a human to\ndecide between topping up, refunding, or crediting pro-rata."},"PingOut":{"properties":{"ok":{"type":"boolean","title":"Ok","default":true},"token_label":{"type":"string","title":"Token Label"},"plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan"},"credits":{"type":"integer","title":"Credits"}},"type":"object","required":["token_label","plan","credits"],"title":"PingOut"},"PlanOfferOut":{"properties":{"id":{"type":"integer","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"price_cents":{"type":"integer","title":"Price Cents"},"currency":{"type":"string","title":"Currency"},"period_credits":{"type":"integer","title":"Period Credits"},"period_days":{"type":"integer","title":"Period Days"},"priority":{"type":"integer","title":"Priority"},"max_concurrent":{"type":"integer","title":"Max Concurrent"},"max_batch_files":{"type":"integer","title":"Max Batch Files"},"sort_order":{"type":"integer","title":"Sort Order"},"is_locked_price":{"type":"boolean","title":"Is Locked Price","default":false},"list_price_cents":{"type":"integer","title":"List Price Cents","default":0}},"type":"object","required":["id","slug","name","price_cents","currency","period_credits","period_days","priority","max_concurrent","max_batch_files","sort_order"],"title":"PlanOfferOut","description":"A purchasable tier, as shown on the pricing page."},"PresignRequest":{"properties":{"filename":{"type":"string","maxLength":300,"minLength":1,"title":"Filename"},"content_type":{"type":"string","title":"Content Type","default":"application/octet-stream"}},"type":"object","required":["filename"],"title":"PresignRequest"},"PublicConfig":{"properties":{"anon_enabled":{"type":"boolean","title":"Anon Enabled"},"anon_allow_heavy":{"type":"boolean","title":"Anon Allow Heavy"},"anon_allow_batch":{"type":"boolean","title":"Anon Allow Batch"},"registration_enabled":{"type":"boolean","title":"Registration Enabled"},"google_auth_enabled":{"type":"boolean","title":"Google Auth Enabled"},"turnstile_site_key":{"type":"string","title":"Turnstile Site Key"},"email_verification_enabled":{"type":"boolean","title":"Email Verification Enabled"},"verify_bonus_credits":{"type":"integer","title":"Verify Bonus Credits"},"studio_tiles_v2":{"type":"boolean","title":"Studio Tiles V2"},"telegram_bots":{"items":{"$ref":"#/components/schemas/TgBotPublic"},"type":"array","title":"Telegram Bots"},"telegram_enabled":{"type":"boolean","title":"Telegram Enabled"},"maintenance":{"type":"boolean","title":"Maintenance"},"maintenance_message":{"type":"string","title":"Maintenance Message"},"support":{"$ref":"#/components/schemas/SupportConfig"},"marketing":{"$ref":"#/components/schemas/MarketingConfig"}},"type":"object","required":["anon_enabled","anon_allow_heavy","anon_allow_batch","registration_enabled","google_auth_enabled","turnstile_site_key","email_verification_enabled","verify_bonus_credits","studio_tiles_v2","telegram_bots","telegram_enabled","maintenance","maintenance_message","support","marketing"],"title":"PublicConfig"},"RegisterRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"captcha_token":{"type":"string","maxLength":4096,"title":"Captcha Token","default":""},"utm_source":{"type":"string","maxLength":120,"title":"Utm Source","default":""},"utm_medium":{"type":"string","maxLength":120,"title":"Utm Medium","default":""},"utm_campaign":{"type":"string","maxLength":160,"title":"Utm Campaign","default":""}},"type":"object","required":["email","password"],"title":"RegisterRequest"},"RegisterResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"email_verified":{"type":"boolean","title":"Email Verified","default":true},"verification_available":{"type":"boolean","title":"Verification Available","default":false}},"type":"object","required":["access_token"],"title":"RegisterResponse","description":"Signed in immediately — plus whether the address still needs confirming,\nand whether confirming is even on offer (a mail provider is configured)."},"RequestLogOut":{"properties":{"id":{"type":"integer","title":"Id"},"service_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Service Id"},"token_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Token Id"},"method":{"type":"string","title":"Method"},"path":{"type":"string","title":"Path"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"credits_charged":{"type":"integer","title":"Credits Charged"},"client_ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Ip"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","service_id","token_id","method","path","status_code","duration_ms","credits_charged","client_ip","created_at"],"title":"RequestLogOut"},"ResolvePaymentRequest":{"properties":{"action":{"type":"string","enum":["credit","reject"],"title":"Action"},"credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credits"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["action"],"title":"ResolvePaymentRequest","description":"Close out a payment an operator had to judge — an underpayment, usually.\n\n``credits`` lets the operator grant pro-rata rather than all-or-nothing, which\nis the common fair outcome when someone underpaid by the network fee."},"ServiceUsage":{"properties":{"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"requests":{"type":"integer","title":"Requests"},"credits":{"type":"integer","title":"Credits"},"failed":{"type":"integer","title":"Failed","default":0}},"type":"object","required":["slug","name","requests","credits"],"title":"ServiceUsage"},"StudioPreset":{"properties":{"index":{"type":"integer","title":"Index"},"label":{"anyOf":[{"type":"string"},{"additionalProperties":{"type":"string"},"type":"object"}],"title":"Label"}},"type":"object","required":["index","label"],"title":"StudioPreset"},"StudioRunOut":{"properties":{"id":{"type":"string","title":"Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"service_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Service Id"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"params":{"type":"object","title":"Params"},"result":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Result"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"estimated_cost":{"type":"integer","title":"Estimated Cost"},"final_cost":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Final Cost"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"},"complexity_score":{"type":"integer","title":"Complexity Score","default":0},"complexity_tier":{"type":"string","title":"Complexity Tier","default":"light"},"queued":{"type":"boolean","title":"Queued","default":false}},"type":"object","required":["id","status","service_id","operation_key","params","result","error","estimated_cost","final_cost","created_at","finished_at"],"title":"StudioRunOut","description":"Job + a complexity hint so the browser knows how to present it:\n`queued`=true → big job, tell the user to check history; else inline result."},"StudioRunRequest":{"properties":{"operation_id":{"type":"integer","title":"Operation Id"},"file_url":{"type":"string","maxLength":1000,"minLength":8,"title":"File Url"},"preset_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Preset Index"},"params":{"type":"object","title":"Params"}},"type":"object","required":["operation_id","file_url"],"title":"StudioRunRequest"},"StudioTool":{"properties":{"operation_id":{"type":"integer","title":"Operation Id"},"service_slug":{"type":"string","title":"Service Slug"},"operation_key":{"type":"string","title":"Operation Key"},"label":{"anyOf":[{"type":"string"},{"additionalProperties":{"type":"string"},"type":"object"}],"title":"Label"},"group":{"anyOf":[{"type":"string"},{"additionalProperties":{"type":"string"},"type":"object"}],"title":"Group"},"accepts":{"items":{"type":"string"},"type":"array","title":"Accepts"},"presets":{"items":{"$ref":"#/components/schemas/StudioPreset"},"type":"array","title":"Presets"},"credits_per_call":{"type":"integer","title":"Credits Per Call"},"config":{"type":"object","title":"Config","default":{}}},"type":"object","required":["operation_id","service_slug","operation_key","label","group","accepts","presets","credits_per_call"],"title":"StudioTool"},"SubscribeRequest":{"properties":{"plan_id":{"type":"integer","title":"Plan Id"}},"type":"object","required":["plan_id"],"title":"SubscribeRequest"},"SubscriptionOut":{"properties":{"id":{"type":"integer","title":"Id"},"plan_id":{"type":"integer","title":"Plan Id"},"plan_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Name"},"status":{"type":"string","title":"Status"},"period_start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Period Start"},"period_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Period End"},"credits_per_period":{"type":"integer","title":"Credits Per Period"},"auto_renew":{"type":"boolean","title":"Auto Renew"}},"type":"object","required":["id","plan_id","status","period_start","period_end","credits_per_period","auto_renew"],"title":"SubscriptionOut"},"SupportConfig":{"properties":{"email":{"type":"string","title":"Email"},"telegram":{"type":"string","title":"Telegram"},"site":{"type":"string","title":"Site"},"popup_on_error":{"type":"boolean","title":"Popup On Error"},"feedback_enabled":{"type":"boolean","title":"Feedback Enabled"}},"type":"object","required":["email","telegram","site","popup_on_error","feedback_enabled"],"title":"SupportConfig","description":"Where a stuck client should turn. Everything here is admin-editable in\nSettings → Support & feedback; empty fields are simply not rendered."},"TgBotPublic":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"username":{"type":"string","title":"Username"}},"type":"object","required":["id","name","username"],"title":"TgBotPublic","description":"A delivery bot the SPA may offer — public identity only (no secrets)."},"TokenCreate":{"properties":{"name":{"type":"string","maxLength":120,"minLength":1,"title":"Name"},"max_per_day":{"type":"integer","title":"Max Per Day","default":0}},"type":"object","required":["name"],"title":"TokenCreate"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"}},"type":"object","required":["access_token"],"title":"TokenResponse"},"UploadSessionCreate":{"properties":{"service_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Slug"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"params":{"type":"object","title":"Params"},"operations":{"anyOf":[{"items":{"$ref":"#/components/schemas/UploadSessionOperation"},"type":"array","maxItems":10},{"type":"null"}],"title":"Operations"},"max_files":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Max Files","default":1},"bundle_zip":{"type":"boolean","title":"Bundle Zip","default":false},"expires_in_seconds":{"anyOf":[{"type":"integer","maximum":604800.0,"minimum":60.0},{"type":"null"}],"title":"Expires In Seconds"},"max_file_size_bytes":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Max File Size Bytes"},"allowed_mime_types":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":50},{"type":"null"}],"title":"Allowed Mime Types"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url"},"callback_secret":{"anyOf":[{"type":"string","maxLength":128,"minLength":16},{"type":"null"}],"title":"Callback Secret"},"delete_after_processing":{"type":"boolean","title":"Delete After Processing","default":false},"metadata":{"type":"object","title":"Metadata"}},"type":"object","title":"UploadSessionCreate","description":"Create body — operations use the exact same names and semantics as\nPOST /jobs/api. Either the single service_slug/operation_key/params triple\nOR the multi-op ``operations`` list (one job per entry on the same file)."},"UploadSessionCreated":{"properties":{"id":{"type":"string","title":"Id"},"upload_url":{"type":"string","title":"Upload Url"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"status":{"$ref":"#/components/schemas/UploadSessionStatus"},"estimated_cost":{"type":"integer","title":"Estimated Cost"},"callback_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Secret"}},"type":"object","required":["id","upload_url","expires_at","status","estimated_cost"],"title":"UploadSessionCreated"},"UploadSessionFileEntry":{"properties":{"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"},"size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Size Bytes"},"mime_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mime Type"},"uploaded_ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uploaded Ip"},"uploaded_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uploaded At"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"job_ids":{"items":{"type":"string"},"type":"array","title":"Job Ids","default":[]},"skipped":{"items":{"type":"object"},"type":"array","title":"Skipped","default":[]}},"type":"object","required":["filename","size_bytes","mime_type","uploaded_ip","uploaded_at","url"],"title":"UploadSessionFileEntry","description":"One completed upload within a (possibly multi-file) session."},"UploadSessionFileOut":{"properties":{"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"},"size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Size Bytes"},"mime_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mime Type"},"checksum":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checksum"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"}},"type":"object","required":["filename","size_bytes","mime_type","checksum","url"],"title":"UploadSessionFileOut"},"UploadSessionOperation":{"properties":{"service_slug":{"type":"string","title":"Service Slug"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"params":{"type":"object","title":"Params"}},"type":"object","required":["service_slug"],"title":"UploadSessionOperation","description":"One processing step — same triple POST /jobs/api takes."},"UploadSessionOut":{"properties":{"id":{"type":"string","title":"Id"},"status":{"$ref":"#/components/schemas/UploadSessionStatus"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"service_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Slug"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"operations":{"items":{"$ref":"#/components/schemas/UploadSessionOperation"},"type":"array","title":"Operations"},"estimated_cost":{"type":"integer","title":"Estimated Cost"},"max_files":{"type":"integer","title":"Max Files"},"bundle_zip":{"type":"boolean","title":"Bundle Zip"},"files":{"items":{"$ref":"#/components/schemas/UploadSessionFileEntry"},"type":"array","title":"Files"},"file":{"$ref":"#/components/schemas/UploadSessionFileOut"},"uploaded_ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uploaded Ip"},"job":{"anyOf":[{"$ref":"#/components/schemas/JobOut"},{"type":"null"}]},"jobs":{"items":{"$ref":"#/components/schemas/JobOut"},"type":"array","title":"Jobs"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["id","status","expires_at","created_at","service_slug","operation_key","operations","estimated_cost","max_files","bundle_zip","files","file","uploaded_ip","job","jobs","error"],"title":"UploadSessionOut"},"UploadSessionPublicInfo":{"properties":{"status":{"$ref":"#/components/schemas/UploadSessionStatus"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"max_file_size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max File Size Bytes"},"allowed_mime_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Mime Types"},"service_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Slug"},"operation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Operation Key"},"max_files":{"type":"integer","title":"Max Files"},"files_uploaded":{"type":"integer","title":"Files Uploaded"}},"type":"object","required":["status","expires_at","max_file_size_bytes","allowed_mime_types","service_slug","operation_key","max_files","files_uploaded"],"title":"UploadSessionPublicInfo","description":"Safe subset for the anonymous /u/<token> page — never leaks the owner,\nkeys, bucket internals or other sessions."},"UploadSessionStatus":{"type":"string","enum":["created","uploading","uploaded","processing","done","failed","expired"],"title":"UploadSessionStatus"},"UsagePoint":{"properties":{"day":{"type":"string","title":"Day"},"requests":{"type":"integer","title":"Requests"},"credits":{"type":"integer","title":"Credits"}},"type":"object","required":["day","requests","credits"],"title":"UsagePoint"},"UsageSummaryStats":{"properties":{"days":{"type":"integer","title":"Days"},"requests":{"type":"integer","title":"Requests"},"items":{"type":"integer","title":"Items"},"credits":{"type":"integer","title":"Credits"},"active_users":{"type":"integer","title":"Active Users"},"jobs_total":{"type":"integer","title":"Jobs Total"},"jobs_done":{"type":"integer","title":"Jobs Done"},"jobs_failed":{"type":"integer","title":"Jobs Failed"}},"type":"object","required":["days","requests","items","credits","active_users","jobs_total","jobs_done","jobs_failed"],"title":"UsageSummaryStats"},"UserOut":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"type":"string","format":"email","title":"Email"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"role":{"$ref":"#/components/schemas/UserRole"},"is_active":{"type":"boolean","title":"Is Active"},"auto_recharge":{"type":"boolean","title":"Auto Recharge"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"plan_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plan Id"},"has_password":{"type":"boolean","title":"Has Password","default":true},"google_linked":{"type":"boolean","title":"Google Linked","default":false},"email_verified":{"type":"boolean","title":"Email Verified","default":true},"marketing_opt_in":{"type":"boolean","title":"Marketing Opt In","default":false}},"type":"object","required":["id","email","full_name","role","is_active","auto_recharge","created_at"],"title":"UserOut"},"UserRole":{"type":"string","enum":["client","admin"],"title":"UserRole"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerifyCodeRequest":{"properties":{"code":{"type":"string","maxLength":12,"minLength":4,"title":"Code"}},"type":"object","required":["code"],"title":"VerifyCodeRequest"},"VerifyStateResponse":{"properties":{"email_verified":{"type":"boolean","title":"Email Verified"},"granted_credits":{"type":"integer","title":"Granted Credits","default":0},"bonus_credits":{"type":"integer","title":"Bonus Credits","default":0},"available":{"type":"boolean","title":"Available","default":false},"code_pending":{"type":"boolean","title":"Code Pending","default":false},"resend_available_in":{"type":"integer","title":"Resend Available In","default":0}},"type":"object","required":["email_verified"],"title":"VerifyStateResponse"}}}}