{"openapi":"3.1.0","info":{"title":"Badge","description":"Badge — the credential layer for AI agents. Screen · Hire · Trust.","version":"0.1.153"},"servers":[{"url":"https://api.badgeia.com"}],"paths":{"/api/v1/auth/register":{"post":{"tags":["auth"],"summary":"Register","description":"Register a new user with email and password.\n\nSets `badge_session` + `badge_refresh` cookies AND returns the access\ntoken in the JSON body. The body-token return is transitional — the\nSDK + curl users rely on it; once those clients adopt cookies we can\ndrop it (separate PR).\n\nBRIEF-LP-000 §6.3 — fires the canonical `signup_completed` event on 201.\n`time_to_complete_ms` is measured from handler entry to response build\nvia perf_counter — captures the server-side cost of the signup path,\nwhich is the relevant counter-metric (BRIEF §5: p95 latency must not\nregress >20ms).\n\nv0.1.29: the legacy `user_signed_up` parallel-fire event was removed\nafter the v0.1.24 deprecation window. Downstream PostHog Insights /\ndashboards must consume `signup_completed`.","operationId":"register_api_v1_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}},"required":true},"responses":{"201":{"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/login":{"post":{"tags":["auth"],"summary":"Login","description":"Login with email and password.\n\nSets HttpOnly session + refresh cookies AND returns the access token\nin the JSON body for non-cookie clients (Badge SDK, curl). See module\ndocstring for the cookie attribute set.\n\nLockout is enforced via Redis (PR-F #2 / HIGH #8, per account since\n#1414). Failed attempts increment a counter keyed on the normalised email\n(any address) and two keyed on `source_ip` (any account).\n`AUTH_LOCKOUT_THRESHOLD` (5) on the account or `AUTH_LOCKOUT_IP_THRESHOLD`\n(50) on the address within 15 minutes, or `AUTH_LOCKOUT_IP_HOURLY_THRESHOLD`\n(150) on the address within an hour, returns 429, with the same body\nevery time. Successful login, or a completed password reset, clears the\naccount counter only.\n\nFail-closed: if Redis is unavailable, return 503 — never silently\nallow login. Unlike the general rate limiter (which fails open by\ndesign — it's a guard rail), this IS the auth correctness boundary.","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/refresh":{"post":{"tags":["auth"],"summary":"Refresh Session","description":"Rotate the refresh cookie and issue a new access cookie.\n\nThe refresh cookie is set with ``Path=/api/v1/auth/refresh`` so it\nonly rides on this endpoint. On any failure (missing, expired,\nrevoked, or chain-replay) we clear both cookies and return 401. On\nsuccess we set new cookies and return ``{\"ok\": true}``.\n\nThe frontend wraps this around 401 responses on `/auth/me` to\ntransparently extend the session without a UI redirect.","operationId":"refresh_session_api_v1_auth_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Refresh Session Api V1 Auth Refresh Post"}}}}}}},"/api/v1/auth/forgot-password":{"post":{"tags":["auth"],"summary":"Forgot Password","description":"Begin a password reset (SEC-AUTH-013).\n\nALWAYS returns 202 with the same generic body regardless of whether the\nemail resolves to an account — no enumeration via status, body, or shape.\nWhen the email DOES resolve to an email/password account, we mint a\nsingle-use, 1h, hashed-at-rest reset token and email a link; we also emit\n`password_reset_requested`.\n\nAccounts with no password_hash (GitHub-OAuth-only) are treated as\n\"no account to reset\" — we don't send a reset link for a password that\ndoesn't exist, but we still return the identical generic body.\n\nRate-limited via the middleware `auth` bucket (see rate_limiter\n`_categorize_request`) so the email-send can't be used to mail-bomb a\nvictim or brute-probe the user table.\n\nAnti-enumeration timing (security-auditor finding): the email send is a\nmulti-hundred-ms Resend round-trip in prod. If we awaited it inline, the\nexists branch would return measurably slower than the unknown/OAuth-only\nbranch — a timing oracle that re-enables enumeration despite the\nidentical response shape. So the send is dispatched as a BackgroundTask,\nwhich runs AFTER the response is flushed; both branches return on the\nsame fast timeline (the in-request work is only a sub-ms token mint +\naudit insert).","operationId":"forgot_password_api_v1_auth_forgot_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Forgot Password Api V1 Auth Forgot Password Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/reset-password":{"post":{"tags":["auth"],"summary":"Reset Password","description":"Complete a password reset (SEC-AUTH-013).\n\nValidates the token (exists, not expired, not used), enforces the signup\npassword-strength policy (done by the schema → 422 on weak), sets the new\nhash, marks the token used (single-use), and **revokes every refresh-token\nchain for the user** so any session an attacker established with the old\npassword is killed. Emits `password_reset_completed`.\n\n#1414 (security review F2): a completed reset also clears the account's\nsign-in lockout counter. Anyone who knows an account's email can keep its\npassword sign-in locked by sending five wrong passwords every window; proving\nmailbox control is the owner's way back in. The per-address counter is\nleft alone, as on a successful sign-in.\n\nAny token failure (missing / expired / already used) → ONE opaque 400 so\na prober can't distinguish the cases.","operationId":"reset_password_api_v1_auth_reset_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Reset Password Api V1 Auth Reset Password Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/verify-email":{"post":{"tags":["auth"],"summary":"Verify Email","description":"Confirm an email address (SEC-AUTH-012).\n\nValidates the single-use token, sets `email_verified=True`, emits\n`email_verified`. Idempotent at the user level: a user who is already\nverified and re-submits an *unused* token still gets a 200 (we just set\nthe already-true flag). A reused / expired / unknown token → opaque 400.","operationId":"verify_email_api_v1_auth_verify_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Verify Email Api V1 Auth Verify Email Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/resend-verification":{"post":{"tags":["auth"],"summary":"Resend Verification","description":"Re-send the verification email to the authenticated user (SEC-AUTH-012).\n\nAuthed (the caller proves who they are via session), so no enumeration\nsurface. Idempotent: if the user is already verified we no-op with a\ngeneric 202 (no new token, no email). Rate-limited via the `auth` bucket.","operationId":"resend_verification_api_v1_auth_resend_verification_post","responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Resend Verification Api V1 Auth Resend Verification Post"}}}}}}},"/api/v1/auth/github":{"get":{"tags":["auth"],"summary":"Github Oauth Redirect","description":"Initiate GitHub OAuth flow.\nIn dev mode (no client ID configured), redirects to the dev callback.\nIn production, redirects to GitHub's authorize URL.","operationId":"github_oauth_redirect_api_v1_auth_github_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/github/callback":{"get":{"tags":["auth"],"summary":"Github Oauth Callback","description":"Handle the GitHub OAuth callback (GET — GitHub redirects the user\nhere with ?code=... after they authorize the app on github.com).\n\nPost-PR-G the callback sets `badge_session` + `badge_refresh` cookies\non the redirect response itself and lands the browser on\n`{FRONTEND_URL}/auth/callback` *without* the URL fragment. The SPA's\ncallback page used to parse a JWT out of `window.location.hash`; now\nit just calls `/auth/me` (which auto-attaches the new cookie) and\nredirects into the app.\n\nPutting the JWT in the URL fragment was a pragmatic workaround when\nwe were stuck with localStorage and didn't want the token in server\naccess logs — but fragments still leak via document.referrer to\nthird-party scripts on the callback page, and to the browser's\nhistory. HttpOnly cookies have neither problem.\n\nNOTE: this endpoint was previously @router.post — GitHub does GET\nredirects, so the old wiring returned 405. Verified 2026-05-17.\n\nBRIEF-LP-000 §6.3 — `signup_completed` (canonical) fires on the new-\nuser branch. The login branch (`is_new=False`) fires `user_logged_in`\nonly, since the user already had a signup event from a prior session.\n\nv0.1.29: the legacy `user_signed_up` parallel-fire event was removed\nafter the v0.1.24 deprecation window.","operationId":"github_oauth_callback_api_v1_auth_github_callback_get","parameters":[{"name":"code","in":"query","required":false,"schema":{"type":"string","default":"","title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"","title":"State"}},{"name":"dev","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Dev"}},{"name":"error","in":"query","required":false,"schema":{"type":"string","default":"","title":"Error"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/me":{"get":{"tags":["auth"],"summary":"Get Current User Info","description":"Return the current authenticated user's stored profile and read models.\n\nThis GET is deliberately side-effect-free. ``SameSite=Lax`` cookies may\naccompany a cross-site top-level safe-method navigation, so username or\nbilling reconciliation belongs on an explicit non-GET/operator path. A\nlegacy null remains null rather than being fabricated during identity read.\n\nAlso enriches the payload with `agent_count` (the user's ACTIVE Agent rows,\nvia the same `count_active_agents` the paywall uses — soft-deleted agents\nare excluded) and `team_count` (accepted, user-bound TeamMember rows).\nThe former drives the onboarding checklist; the latter exposes /team in\nthe sidebar for invited members regardless of their personal plan or run\ncount. arena_run_count and monthly_run_count are already User columns.","operationId":"get_current_user_info_api_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}}}},"patch":{"tags":["auth"],"summary":"Update Current User","description":"Update current user's profile.","operationId":"update_current_user_api_v1_auth_me_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/apply-team-override":{"post":{"tags":["auth"],"summary":"Apply Team Override","description":"Self-service: if the current user is active, email-verified, and their\nemail appears in `TEAM_OVERRIDE_EMAILS`, set their plan to \"team\"\n(idempotent; never downgrades enterprise). Otherwise 403.\n\nBacks the lifespan boot hook with an on-demand path so founders/\ninternal accounts can elevate themselves without waiting for a\nredeploy cycle. The rejection is deliberately generic so the endpoint\nnever reflects an allowlist address or deployment configuration.","operationId":"apply_team_override_api_v1_auth_apply_team_override_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Apply Team Override Api V1 Auth Apply Team Override Post"}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","description":"Logout the current user.\n\nThree things happen:\n  1. Blacklist the access token's JTI so it can't be replayed in the\n     remaining window before its natural expiry.\n  2. Revoke the exact refresh row bound into the signed access JWT. The\n     path-scoped refresh cookie does not need to ride on this request and\n     other devices remain active.\n  3. Clear both cookies on the response.\n\nReturns 200 with a JSON body. The cookies are cleared via\n``Set-Cookie: ...=; Max-Age=0`` on the response (browsers will drop\nthem; subsequent requests won't carry them).\n\nToken source: the ``badge_session`` cookie first (post-PR-G default),\nfalling back to ``Authorization: Bearer`` for non-cookie clients. The\npre-PR-F ``as_session`` cookie was dead code and was removed.","operationId":"logout_api_v1_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/users/me/deletion":{"get":{"tags":["account-deletion"],"summary":"Preview Deletion","description":"Counts-only preview for the confirmation screen.\n\nEvery field is an integer, a hash, or a boolean. Nothing here narrows to a\nspecific agent, run, or address, so the response is safe to log verbatim.","operationId":"preview_deletion_api_v1_users_me_deletion_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Preview Deletion Api V1 Users Me Deletion Get"}}}}}},"post":{"tags":["account-deletion"],"summary":"Request Deletion","description":"Start the grace clock. Deletes nothing — the finalizer does that later.","operationId":"request_deletion_api_v1_users_me_deletion_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletionRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Request Deletion Api V1 Users Me Deletion Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["account-deletion"],"summary":"Cancel Deletion","description":"Cancel during grace and restore the account.\n\nReachable because `get_current_user` admits accounts inside their grace\nwindow — see `auth.is_pending_deletion`. No second factor: the user already\nauthenticated, and restoring an account is not a destructive act. Making\ncancellation harder than deletion would be exactly backwards.","operationId":"cancel_deletion_api_v1_users_me_deletion_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Cancel Deletion Api V1 Users Me Deletion Delete"}}}}}}},"/api/v1/users/me/deletion/confirmation-link":{"post":{"tags":["account-deletion"],"summary":"Send Confirmation Link","description":"Mail the single-use second factor to an OAuth-only account.\n\nRefused for password accounts: they already have a second factor, and\noffering an email route as well would widen the ceremony to whichever\nfactor an attacker finds easier.","operationId":"send_confirmation_link_api_v1_users_me_deletion_confirmation_link_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmationLinkRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Send Confirmation Link Api V1 Users Me Deletion Confirmation Link Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/csp-reports":{"post":{"tags":["security"],"summary":"Collect Csp Report","operationId":"collect_csp_report_api_v1_csp_reports_post","responses":{"204":{"description":"Successful Response"}}}},"/api/v1/billing/pending-payment":{"get":{"tags":["billing"],"summary":"Pending Payment","description":"Rehydrate an unresolved, authenticated plan-change payment.\n\nRecovery intentionally does NOT depend on ``require_billing_enabled``.\n``BILLING_ENABLED`` prevents creation of new money-moving operations; it\nmust not strand a hosted invoice created before the kill switch flipped.\n\nThe canonical subscription id and customer id both come from the\nauthenticated user's row. Stripe is then re-read with the invoice expanded\nand both identities are checked again before any URL is returned. No local\nplan state is changed here; signed Stripe webhooks remain the sole\nentitlement writer.","operationId":"pending_payment_api_v1_billing_pending_payment_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingPaymentResponse"}}}}}}},"/api/v1/billing/status":{"get":{"tags":["billing"],"summary":"Billing Status","description":"Public — does NOT honour ``require_billing_enabled``.\n\nUsed by the frontend to decide whether to render the upgrade flow\n(BILLING_ENABLED=true) or the \"Pro — coming soon · sign up for early\naccess\" panel (BILLING_ENABLED=false). Anonymous and authenticated\ncallers both need this — the /pricing page renders for anon visitors\nand has to know what to show before there's a session.","operationId":"billing_status_api_v1_billing_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingStatusResponse"}}}}}}},"/api/v1/billing/notify-me":{"post":{"tags":["billing"],"summary":"Notify Me","description":"Public — does NOT honour ``require_billing_enabled``.\n\nEmail-capture endpoint for the \"Pro — coming soon\" panel on /pricing.\nLower-cases + stores the email in `pro_waitlist`. Idempotent: a second\nsubmission of the same address returns 200 ``{queued: false, reason:\n\"already_queued\"}`` rather than a 409 or a 500 — the user gets the\nsame \"you're on the list\" affordance whether they're new or already\nin. Spam protection comes from the RateLimitMiddleware \"write\" bucket\n(60 RPM per IP; CLAUDE.md and middleware/rate_limiter.py).","operationId":"notify_me_api_v1_billing_notify_me_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotifyMeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotifyMeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/enterprise-waitlist":{"post":{"tags":["billing"],"summary":"Enterprise Waitlist","description":"Public — does NOT honour ``require_billing_enabled``.\n\nInbound demand-capture for the published Enterprise tier on /pricing\n(BIZ-007 §6 step 1). §7 gates all further Enterprise build-out on **≥3\n`enterprise_waitlist` entries**; this endpoint is what makes that gate\nmeasurable. Mirrors ``notify_me``'s storage (lower-case + `email`\nUNIQUE idempotency) but NOT its response shape: an unauthenticated\ncaller must not learn whether an address was already on the list, so\nthe insert and the duplicate path both return the identical\n``{queued: true}`` (security-auditor finding on PR #492 — enumeration\noracle closed here rather than inherited from the pro_waitlist\nprecedent). Available regardless of BILLING_ENABLED — Enterprise is\ninbound-only and never touches Stripe checkout.\n\nCAPTURE is deliberately unthrottled beyond the shared RateLimitMiddleware\n\"write\" bucket (60 RPM per IP) that fronts /notify-me: a tighter capture\nbucket would cost real Enterprise leads to stop junk rows we can scrub\nfrom /admin, and a lost lead is lost revenue. The two costs a flood\nactually imposes are bounded elsewhere instead —\n\n  * outbound EMAIL, by two layers in ``_notify_enterprise_lead``: the\n    per-SOURCE daily allowance (``app/services/lead_capture_budget.py``,\n    residual finding 5 of the PR #599 review) in front of the GLOBAL\n    hourly+daily ceiling (``app/services/notification_budget.py``,\n    security-auditor finding 2 on PR #519);\n  * junk ROWS, by the ``enterprise_waitlist`` retention family in\n    ``app/services/auth_retention_service.py``, which prunes only\n    never-contacted rows past a long window.\n\nNeither can reject a signup: the row commits first and this response is\nidentical either way.","operationId":"enterprise_waitlist_api_v1_billing_enterprise_waitlist_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnterpriseWaitlistRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnterpriseWaitlistResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/checkout":{"post":{"tags":["billing"],"summary":"Create Checkout Session","description":"Start a paid subscription, or move an existing one to a different plan.\n\nThree outcomes:\n\n  * ``DevUpgradeResponse`` — dev mode (no Stripe key): instant Pro upgrade.\n  * ``PlanChangeResponse`` — the customer already holds a billable Stripe\n    subscription, so the requested tier/cadence is applied to THAT\n    subscription and no Checkout session exists. See\n    ``_select_plan_change_target``.\n  * ``CheckoutResponse`` — no live subscription: a normal Stripe Checkout\n    session to redirect to.\n\nThe middle case is the whole point. Stripe Checkout in ``mode:\nsubscription`` can only ever CREATE a subscription, so sending a paying\ncustomer through it to change tiers charges them twice and leaves two\nsubscriptions' webhooks fighting over one ``plan`` column.","operationId":"create_checkout_session_api_v1_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/CheckoutResponse"},{"$ref":"#/components/schemas/DevUpgradeResponse"},{"$ref":"#/components/schemas/PlanChangeResponse"}],"title":"Response Create Checkout Session Api V1 Billing Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/portal":{"post":{"tags":["billing"],"summary":"Create Portal Session","description":"Create a Stripe Customer Portal session.\n\nIn dev mode, returns current plan info without changing anything.\n\nThis remains available when ``BILLING_ENABLED`` is false. That flag blocks\ncreation/cancellation; an authenticated existing customer still needs the\nprovider-hosted portal to resolve an invoice or update a failing card.","operationId":"create_portal_session_api_v1_billing_portal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PortalResponse"},{"$ref":"#/components/schemas/DevUpgradeResponse"}],"title":"Response Create Portal Session Api V1 Billing Portal Post"}}}}}}},"/api/v1/billing/cancel":{"post":{"tags":["billing"],"summary":"Cancel Subscription","description":"Cancel subscription and downgrade to free plan.\n\nIn dev mode, directly sets user plan to free.\nIn production, cancels the Stripe subscription.","operationId":"cancel_subscription_api_v1_billing_cancel_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DevUpgradeResponse"}}}}}}},"/api/v1/certify/diagnostic":{"get":{"tags":["certify"],"summary":"Certify Diagnostic","description":"Ungated flag-state surface (does NOT honour require_certify_enabled).\n\nReports the parsed flag + tuning + whether a real Price is configured, so a\nthree-hop env-render failure (config → compose → cd.yml) is diagnosable\nwithout SSH. Never echoes any secret or price id.","operationId":"certify_diagnostic_api_v1_certify_diagnostic_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertifyDiagnostic"}}}}}}},"/api/v1/certify/eligibility":{"get":{"tags":["certify"],"summary":"Certify Eligibility","description":"Whether the Certify offer may be shown for an agent (drives the card gate).\n\nThe offer renders ONLY when the caller owns the agent AND the agent has a\nlive (non-mock) dispatch capability (§7.1 risk #1 + §6.1.6): we never dangle\na $39 paid cert on an agent that can only produce a simulated run.","operationId":"certify_eligibility_api_v1_certify_eligibility_get","parameters":[{"name":"agent_id","in":"query","required":true,"schema":{"type":"string","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertifyEligibility"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/certify/status":{"get":{"tags":["certify"],"summary":"Certify Status","description":"Latest owner-visible certification progress, including quota pauses.","operationId":"certify_status_api_v1_certify_status_get","parameters":[{"name":"agent_id","in":"query","required":true,"schema":{"type":"string","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertifyStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/certify/checkout":{"post":{"tags":["certify"],"summary":"Certify Checkout","description":"Start a one-off $39 certification purchase (Badge-direct, mode:payment).\n\nGate order (each a hard stop): flag → ownership → EU waiver → integrity\n(live capability) → Stripe config. In dev with no Stripe key, short-circuits\nto a paid certification + dispatched deep screening so the flow is drivable\nlocally (the no-mock-cert guard in certify_service still holds).","operationId":"certify_checkout_api_v1_certify_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertifyCheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/CertifyCheckoutResponse"},{"$ref":"#/components/schemas/CertifyDevGrantResponse"}],"title":"Response Certify Checkout Api V1 Certify Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pmf/respond":{"post":{"tags":["pmf"],"summary":"Submit Pmf Response","description":"Submit a PMF survey response.","operationId":"submit_pmf_response_api_v1_pmf_respond_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PMFResponseCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PMFResponseRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pmf/dismiss":{"post":{"tags":["pmf"],"summary":"Dismiss Pmf Survey","description":"Mark PMF survey as shown without responding.","operationId":"dismiss_pmf_survey_api_v1_pmf_dismiss_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PMFResponseRead"},{"additionalProperties":true,"type":"object"}],"title":"Response Dismiss Pmf Survey Api V1 Pmf Dismiss Post"}}}}}}},"/api/v1/pmf/results":{"get":{"tags":["pmf"],"summary":"Get Pmf Results","description":"Get PMF survey results breakdown (aggregated from all users).\n\nArgs:\n    user: Current authenticated user\n    db: Database session\n    days: How many days of results to aggregate (default: 30)\n\nReturns:\n    PMFResultsRead with breakdown of responses and NPS score","operationId":"get_pmf_results_api_v1_pmf_results_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PMFResultsRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stripe/webhook":{"post":{"tags":["stripe"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events.\n\nCurrently handled:\n  - customer.subscription.created\n  - customer.subscription.updated\n  - customer.subscription.deleted\n  - customer.subscription.pending_update_applied\n  - customer.subscription.pending_update_expired\n  - account.updated  (Stripe Connect Express — mirrors a seller's\n    charges_enabled / payouts_enabled capability flags onto the User)\n  - checkout.session.completed  (F-01 Increment 2 — marketplace destination\n    charge confirmed: mint the hired clone, flip the purchase\n    AWAITING_PAYMENT → COMPLETED, record realized revenue, fire playbook_hired)\n  - checkout.session.expired / .async_payment_failed  (flip\n    AWAITING_PAYMENT → FAILED so the buyer can retry; no clone)\n\nReturns:\n  - 200 with `{\"status\": \"ok\", \"event_type\": ..., \"deduplicated\": false}`\n    on first-time processing.\n  - 200 with `{\"status\": \"ok\", \"deduplicated\": true}` on a replay\n    (so Stripe stops retrying).\n  - 400 on signature failure / malformed payload / malformed signature\n    header (no body, missing header, expired timestamp, bad HMAC).\n  - 503 with detail \"Stripe not configured\" when the env secret is\n    unset (matched by the Sentry allowlist — see rule #7).","operationId":"stripe_webhook_api_v1_stripe_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Stripe Webhook Api V1 Stripe Webhook Post"}}}}}}},"/api/v1/agents":{"get":{"tags":["agents"],"summary":"List Agents","description":"List agents.\n\nVisibility rules (PRD-003 FR-06):\n  - Authenticated: returns the caller's own agents (any visibility).\n  - Unauthenticated: returns only public agents.\n\nThe additive ``scope=personal`` and exact ``team_id`` filters are\nauthenticated workspace-switcher reads. They are mutually exclusive and\nare applied before count/pagination.","operationId":"list_agents_api_v1_agents_get","parameters":[{"name":"scope","in":"query","required":false,"schema":{"anyOf":[{"const":"personal","type":"string"},{"type":"null"}],"description":"When set to personal, return only the caller's personal agents.","title":"Scope"},"description":"When set to personal, return only the caller's personal agents."},{"name":"team_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Return only agents in this accessible team workspace.","title":"Team Id"},"description":"Return only agents in this accessible team workspace."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"active_only","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Active Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["agents"],"summary":"Create Agent","description":"Register a new agent on the platform.\n\nAuth: a logged-in session/JWT, OR an API key with `write` scope (passed via\n`X-API-Key` or `Authorization: Bearer <key>`).\n\nSupported registration accepts a customer-hosted `http_endpoint` or an\nexplicit simulated mock screen. Badge does not accept provider\ncredentials, Assistant bundles, provider reconciliation grants, or\nstored-provider dispatch. Retired legacy records may remain while the\nmigration erasure gates complete; that is not a no-secrets claim.","operationId":"create_agent_api_v1_agents_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegisterResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/bulk":{"post":{"tags":["agents"],"summary":"Bulk Create Agents","description":"Bulk-register agents from CSV / a registry export (RES-009 §X #13).\n\nEach row is processed independently: a duplicate name in row 7 doesn't\nblock rows 8..N. The response gives a per-row status with the original\nindex so the UI can render line-numbered errors next to the upload preview.\n\nDuplicates are reported as \"skipped_duplicate\" rather than an error\nbecause re-running the same CSV is a common workflow (re-import after\na fix in row 12 shouldn't fail rows 1-11 that already exist).","operationId":"bulk_create_agents_api_v1_agents_bulk_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBulkCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBulkResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/transfer-to-workspace":{"post":{"tags":["agents"],"summary":"Transfer Agent To Workspace","operationId":"transfer_agent_to_workspace_api_v1_agents__agent_id__transfer_to_workspace_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentTransferToWorkspace"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/otlp-token":{"post":{"tags":["agents"],"summary":"Mint Or Rotate Agent Otlp Token","description":"Mint or rotate the single-reveal receiver credential for an HTTP agent.","operationId":"mint_or_rotate_agent_otlp_token_api_v1_agents__agent_id__otlp_token_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentOtlpTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["agents"],"summary":"Revoke Agent Otlp Token","description":"Idempotently revoke an agent-scoped OTLP receiver credential.","operationId":"revoke_agent_otlp_token_api_v1_agents__agent_id__otlp_token_delete","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}":{"get":{"tags":["agents"],"summary":"Get Agent","description":"Get a single agent by ID.\n\nPrivate agents are 404 for anyone other than the owner — we don't distinguish\n\"doesn't exist\" from \"is private\" to non-owners on purpose.","operationId":"get_agent_api_v1_agents__agent_id__get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["agents"],"summary":"Update Agent","description":"Update agent metadata. Requires authentication and ownership verification.","operationId":"update_agent_api_v1_agents__agent_id__patch","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["agents"],"summary":"Delete Agent","description":"Deactivate an agent and irreversibly discard its stored credentials.","operationId":"delete_agent_api_v1_agents__agent_id__delete","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/blueprint":{"get":{"tags":["agents"],"summary":"Get Agent Blueprint","description":"Aggregate telemetry from up to ten most recent visible runs.","operationId":"get_agent_blueprint_api_v1_agents__agent_id__blueprint_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlueprintRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/blueprint/versions":{"get":{"tags":["agents"],"summary":"Get Agent Blueprint Timeline","description":"OTEL-002d — the Evidence version timeline (ADR-018 D6).\n\nVisibility is derived from RUNS, not versions: an entry appears only if\nat least one run THIS CALLER can see is bound to it, and its run_count\ncounts exactly those runs — a version minted solely by private runs is\ninvisible to anonymous readers (the same cohort discipline as the D3\nowner-only version_number). Tier projection lives in\nserialize_timeline_entry, the single choke point.","operationId":"get_agent_blueprint_timeline_api_v1_agents__agent_id__blueprint_versions_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlueprintTimelineRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/frontier":{"get":{"tags":["agents"],"summary":"Get Agent Frontier","description":"The \"Hiring Frontier\" variant group for an agent (PRD-016 FR-3).\n\nResolves the group: root = ``agent.variant_of or agent.id``; members = the\nroot plus every agent whose ``variant_of`` points at the root. Returns\nper-variant aggregates (pass-rate, pass^k, mean cost/task, provenance,\nmodel) computed from existing runs.\n\nVisibility: a private requested agent is 404 for non-owners (same rule as\nGET /agents/{id}). Private MEMBERS are excluded for non-owner viewers\n(leak-safety) and included for the owner. Anonymous callers see public\nagents fine. No owner-only fields (user_id, keys) are ever in the response.","operationId":"get_agent_frontier_api_v1_agents__agent_id__frontier_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrontierRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/admin/scrub-public":{"post":{"tags":["agents"],"summary":"Admin Scrub Public Agents","description":"Admin-only escape hatch to scrub leaked test/demo agents from the\npublic Talent Pool + Compare + Registry surfaces.\n\nSoft-fix only — flips `is_public` to False, leaves the row otherwise\nintact so the owner can still find it under their own /agents. Added\n2026-05-17 after an E2E session left a handful of throwaway agents\n('v0.1.7 verify', 'QA Test Agent', etc.) visible on /compare.\n\nReturns the count + names of rows updated so the operator can sanity-\ncheck what they just touched. ADMIN_EMAILS gate via require_admin.","operationId":"admin_scrub_public_agents_api_v1_agents_admin_scrub_public_post","parameters":[{"name":"name_pattern","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"description":"Case-insensitive substring. Any agent whose name contains this string will be flipped to is_public=false.","title":"Name Pattern"},"description":"Case-insensitive substring. Any agent whose name contains this string will be flipped to is_public=false."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Scrub Public Agents Api V1 Agents Admin Scrub Public Post"}}}},"403":{"description":"Admin only"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tasks":{"get":{"tags":["tasks"],"summary":"List Tasks","description":"List all benchmark tasks.","operationId":"list_tasks_api_v1_tasks_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TaskDomain"},{"type":"null"}],"title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_TaskRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["tasks"],"summary":"Create Task","description":"Create a new benchmark task. Admin-only — tasks are global catalog rows\nthat every user can run against; only operators should add them.","operationId":"create_task_api_v1_tasks_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskAdminRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tasks/secret-suites/diagnostic":{"get":{"tags":["tasks"],"summary":"Secret Suites Diagnostic","description":"Operator diagnostic: parsed flag state + per-suite COUNTS only.\n\nSECURITY (AC-C1-1): returns identifiers + counts, never an answer key.\nThe underlying query (services.secret_suites.suite_diagnostic) does not\nselect ``expected_output``.","operationId":"secret_suites_diagnostic_api_v1_tasks_secret_suites_diagnostic_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretSuiteDiagnostic"}}}}}}},"/api/v1/tasks/secret-suites/rotate":{"post":{"tags":["tasks"],"summary":"Secret Suites Rotate","description":"Rotate a secret suite: bump ``suite_version`` for every task in it.\n\nRotation makes a leaked answer go stale — runs recorded under the old\nversion keep their recorded version (the run snapshots it at finalize), so\na builder who memorised the previous answers gets no credit on the new\nversion. Operator-driven (no automatic rotation). 404 when the suite has no\ntasks (so a typo'd suite_id can't silently no-op).","operationId":"secret_suites_rotate_api_v1_tasks_secret_suites_rotate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretSuiteRotateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretSuiteRotateResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tasks/{task_id}/retire":{"post":{"tags":["tasks"],"summary":"Retire Task","description":"One-way operator retire: set ``is_active = false`` — nothing else.\n\nThe catalog deliberately has no general mutation endpoint (contents and\nsecret-ness are set at create time), but a mislabeled task — e.g. a\n\"Holdout\" authored with ``is_secret=false``, its answer key publicly\nreadable — must be removable over HTTP: SSH is forbidden and ops are\nHTTP-driven (UX-AUDIT A3). Retiring only deactivates: it never edits,\nun-retires, or deletes, so recorded runs/scores keep their history.\nIdempotent — retiring a retired task reports ``was_active=false``.","operationId":"retire_task_api_v1_tasks__task_id__retire_post","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskRetireResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tasks/{task_id}":{"get":{"tags":["tasks"],"summary":"Get Task","operationId":"get_task_api_v1_tasks__task_id__get","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/task-submissions":{"post":{"tags":["task-submissions"],"summary":"Submit Task","description":"Any authenticated user can submit a candidate task.","operationId":"submit_task_api_v1_task_submissions_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSubmissionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSubmissionRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["task-submissions"],"summary":"List Submissions","description":"Admin queue — defaults to ALL statuses if no filter; flagged-then-newest sort.","operationId":"list_submissions_api_v1_task_submissions_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status: pending|approved|rejected|withdrawn","title":"Status"},"description":"Filter by status: pending|approved|rejected|withdrawn"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_TaskSubmissionRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/task-submissions/mine":{"get":{"tags":["task-submissions"],"summary":"List My Submissions","description":"Submitter sees their own submissions, newest first.","operationId":"list_my_submissions_api_v1_task_submissions_mine_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_TaskSubmissionRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/task-submissions/{submission_id}/withdraw":{"post":{"tags":["task-submissions"],"summary":"Withdraw Submission","description":"Submitter pulls their own PENDING submission. No-op if already\nreviewed (approved/rejected/withdrawn).","operationId":"withdraw_submission_api_v1_task_submissions__submission_id__withdraw_post","parameters":[{"name":"submission_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Submission Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSubmissionRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/task-submissions/{submission_id}/approve":{"post":{"tags":["task-submissions"],"summary":"Approve Submission","description":"Mint a Task from this submission and mark approved.","operationId":"approve_submission_api_v1_task_submissions__submission_id__approve_post","parameters":[{"name":"submission_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Submission Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSubmissionApprove"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSubmissionRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/task-submissions/{submission_id}/reject":{"post":{"tags":["task-submissions"],"summary":"Reject Submission","description":"Mark rejected with a required reason.","operationId":"reject_submission_api_v1_task_submissions__submission_id__reject_post","parameters":[{"name":"submission_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Submission Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSubmissionReject"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSubmissionRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs":{"post":{"tags":["runs"],"summary":"Create Run","description":"Submit a new arena run. The run is enqueued immediately and executed\nasynchronously. Poll GET /runs/{run_id} to check status.","operationId":"create_run_api_v1_runs_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunCreate"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunCreateRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["runs"],"summary":"List Runs","description":"List runs with optional filters.\n\nVisibility (PRD-003 FR-06): runs of private agents are only visible to the\nagent's owner. Everything else is public.\n\nWhen ``mine=true`` and the request is authenticated, the visibility window\nnarrows further to runs of agents the caller owns. ``mine`` is silently\nignored for unauthenticated callers (no user → no \"mine\").\n\nThe additive ``scope=personal`` and exact ``team_id`` filters use immutable\nrun ownership snapshots, are mutually exclusive with each other and\n``mine=true``, and are applied before count/pagination.","operationId":"list_runs_api_v1_runs_get","parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent Id"}},{"name":"task_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Task Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/RunStatus"},{"type":"null"}],"title":"Status"}},{"name":"scope","in":"query","required":false,"schema":{"anyOf":[{"const":"personal","type":"string"},{"type":"null"}],"description":"When set to personal, return only the caller's personal run snapshots.","title":"Scope"},"description":"When set to personal, return only the caller's personal run snapshots."},{"name":"team_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Return only run snapshots in this accessible team workspace.","title":"Team Id"},"description":"Return only run snapshots in this accessible team workspace."},{"name":"mine","in":"query","required":false,"schema":{"type":"boolean","description":"When true and the request is authenticated, restrict results to runs of agents the caller owns. Used by the dashboard's 'Recent Runs' panel so a personal view never leaks public runs from other users.","default":false,"title":"Mine"},"description":"When true and the request is authenticated, restrict results to runs of agents the caller owns. Used by the dashboard's 'Recent Runs' panel so a personal view never leaks public runs from other users."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_RunRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/export.csv":{"get":{"tags":["runs"],"summary":"Export Runs Csv","description":"Export run history as CSV — Pro feature (PRD-003 FR-07).\n\nOwner-scoped: only returns runs of agents the caller owns. Free users get\na **402 Pro feature** which the frontend's `withPlanCheck` surfaces via\nthe `UpgradeModal`.","operationId":"export_runs_csv_api_v1_runs_export_csv_get","parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/preflight":{"get":{"tags":["runs"],"summary":"Get Screening Preflight","description":"Expose the configured execution ceiling used by Screen disclosures.","operationId":"get_screening_preflight_api_v1_runs_preflight_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningPreflightRead"}}}}}}},"/api/v1/runs/{run_id}":{"get":{"tags":["runs"],"summary":"Get Run","operationId":"get_run_api_v1_runs__run_id__get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["runs"],"summary":"Update Run","description":"Update run status and result fields (used by agents to report outcomes).\n\n**Model Sweep result contract (PRD-016, requires `SWEEPS_ENABLED`):**\nreport which model served the run plus token counts and Badge computes\nthe cost axis for your Hiring Frontier — no SDK, plain curl:\n\n```bash\ncurl -X PATCH \"$API/api/v1/runs/$RUN_ID\" \\\n  -H \"Content-Type: application/json\" -b \"$COOKIES\" \\\n  -d '{\n    \"status\": \"completed\", \"success\": true,\n    \"model\": \"claude-haiku-4-5\",\n    \"input_tokens\": 18234, \"output_tokens\": 2101,\n    \"unit_cost_override_usd\": 0.021\n  }'\n```\n\nCost resolution for non-metered runs: known `model` in the pricing\ntable → computed from tokens; else `unit_cost_override_usd` (total $\nfor this run, 0–100) when given; else cost stays null. Any self-report\nmarks the run `self_reported` — it plots amber on the frontier and can\nnever mint a verified cert. Metered runs (Badge dispatched on a\ncustomer key) reject these fields with 409 `run_is_metered`; while the\nflag is off they return 400 `sweeps_disabled`.","operationId":"update_run_api_v1_runs__run_id__patch","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/otlp-ingest-receipt":{"get":{"tags":["runs"],"summary":"Get Otlp Ingest Receipt","description":"Return Badge's bounded receipt to the immutable run owner/admin only.","operationId":"get_otlp_ingest_receipt_api_v1_runs__run_id__otlp_ingest_receipt_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtlpIngestReceiptRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/trace":{"get":{"tags":["runs"],"summary":"Get Run Trace","operationId":"get_run_trace_api_v1_runs__run_id__trace_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunTraceRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/batch":{"post":{"tags":["runs"],"summary":"Batch Create Runs","description":"Submit multiple runs at once for an agent across different tasks.\nReturns list of created runs.\n\nWP-I (ROAD-002 §WP-I, 2026-07-02): this endpoint is an AUTHENTICATED write.\nIt resolves the caller via ``require_user_or_api_key(\"write\")`` — the same\ncanonical dependency ``POST /agents`` uses — so a session/JWT user OR an\nAPI key carrying ``write`` scope authenticates as its owner, and an\nanonymous request gets a 401. Previously the handler used\n``get_current_user_optional``, which does not accept API-key auth: the Badge\nMCP server and SDK callers (who authenticate with ``X-API-Key`` /\n``Authorization: Bearer <key>``) fell through to ``user is None`` and ran\nUNMETERED — no ``monthly_run_count`` attribution and the wrong rate-limit\ncategory on a prod site with live billing. Requiring auth here means every\nbatch reserves against the owner's monthly run quota, exactly like the\nsingle-run path. (There is no per-tier cost cap: that feature was removed\n2026-07-27 because Badge bills a flat subscription and meters no customer\nLLM spend.)","operationId":"batch_create_runs_api_v1_runs_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRunCreate"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/RunRead"},"type":"array","title":"Response Batch Create Runs Api V1 Runs Batch Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/blueprint":{"get":{"tags":["runs"],"summary":"Get Run Blueprint","description":"Return the bounded public Blueprint projection, never raw provenance.","operationId":"get_run_blueprint_api_v1_runs__run_id__blueprint_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlueprintRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/steps":{"get":{"tags":["runs"],"summary":"Get Run Execution Steps","description":"Get execution steps for a run.\n\nReturns detailed breakdown of each step the agent took during execution,\nincluding model calls, tool invocations, token usage, and latency.","operationId":"get_run_execution_steps_api_v1_runs__run_id__steps_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ExecutionStepRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/logs":{"get":{"tags":["runs"],"summary":"Get Run Logs","description":"Get logs for a run.\n\nReturns structured logs captured during execution, filterable by level\n(debug, info, warn, error) and source (system, agent, evaluator).","operationId":"get_run_logs_api_v1_runs__run_id__logs_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}},{"name":"level","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Level"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_RunLogRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/readiness":{"get":{"tags":["screening-sessions"],"summary":"Get Agent Readiness","operationId":"get_agent_readiness_api_v1_agents__agent_id__readiness_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentReadinessRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/readiness/check":{"post":{"tags":["screening-sessions"],"summary":"Check Agent Readiness","operationId":"check_agent_readiness_api_v1_agents__agent_id__readiness_check_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentReadinessRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/screening-sessions":{"get":{"tags":["screening-sessions"],"summary":"List Agent Screening Sessions","operationId":"list_agent_screening_sessions_api_v1_agents__agent_id__screening_sessions_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ScreeningSessionRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/screening-sessions/{session_id}":{"get":{"tags":["screening-sessions"],"summary":"Get Screening Session","operationId":"get_screening_session_api_v1_screening_sessions__session_id__get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningSessionDetailRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/phases":{"get":{"tags":["screening-sessions"],"summary":"Get Run Phases","operationId":"get_run_phases_api_v1_runs__run_id__phases_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RunPhaseEventRead"},"title":"Response Get Run Phases Api V1 Runs  Run Id  Phases Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/verify/{run_id}":{"get":{"tags":["verify"],"summary":"Verify Run","description":"Verify a run's certificate. Public, anonymous, cache-friendly.\n\nFlag-off → 404 explicit (CLAUDE.md rule #4). The fingerprint is\nRECOMPUTED server-side from the persisted run fields and the\nsignature checked against it, so any post-signing mutation of a\nsigned field reads as `valid: false` (AC-03).","operationId":"verify_run_api_v1_verify__run_id__get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/verify/pro-interest":{"post":{"tags":["verify"],"summary":"Verified Pro Interest","description":"Capture interest in the deferred \"verify a private run / white-label\"\ntier (§5 `verified_pro_interest`). Reuses the pro_waitlist table +\nidempotent-insert pattern; fires the PostHog willingness-to-pay\nsignal. NO billing code (TODO §3 U-01 — billing paused).\n\nPublic + flag-independent (we collect interest even when the feature\nflag posture changes), mirroring /billing/notify-me.","operationId":"verified_pro_interest_api_v1_verify_pro_interest_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProInterestRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProInterestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/verify/sbom":{"post":{"tags":["verify"],"summary":"Verify Exported Sbom","description":"Check the Ed25519 signature on a CycloneDX SBOM exported by Badge.\n\nPublic (a buyer's security team has no Badge account). Flag off -> 404.\nA bad signature is a 200 with ``valid=false`` and no identity fields: the\nanswer to \"is this document authentic\" must not echo unauthenticated\ncontent back as if it were trusted.","operationId":"verify_exported_sbom_api_v1_verify_sbom_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SbomVerifyResponse"}}}}}}},"/api/v1/verify/report/{report_id}":{"get":{"tags":["verify"],"summary":"Verify Savings Report","description":"#1296 — is this stored savings report authentic and unaltered?\n\nPublic (a partner's finance team has no Badge account). The report id is an\nunguessable UUID. The stored payload is re-hashed and the signature\nre-checked on every call, and ``agent_id`` / ``generated_at`` are served\nfrom the SIGNED payload (and must match the row), so a row edited after\nsigning answers ``valid=false``. ``headline`` repeats the signed headline\nfacts at PUBLIC precision, for a PUBLIC agent only, so the holder of a\nPDF/CSV can compare them with the file. Flag off or unknown id -> 404.\n\nThis proves the STORED report. To check a file you were handed, POST it to\n``/verify/report``.","operationId":"verify_savings_report_api_v1_verify_report__report_id__get","parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Report Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportVerifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/verify/report":{"post":{"tags":["verify"],"summary":"Verify Downloaded Report","description":"#1296 — check the report FILE you were handed (the JSON download).\n\nBody: the document from ``GET /savings-reports/{id}?format=json``. The\nsignature is checked over ``badge-savings-report-v1 NUL`` + canonical JSON\nof its ``payload``, so an edited figure, name or agent id fails. An integral\nnumber respelt by a JSON tool (``0.0`` -> ``0``) is not an edit (#1424);\n``canonical_form`` says whether the current or the pre-#1424 form matched. A bad\nsignature answers 200 with ``valid=false`` and no identity fields: an\nunauthenticated document is never echoed back as if it were trusted.\nHostile bodies (oversize, bad UTF-8, too deep, duplicate keys) are 413/422,\nnever 500. Public; flag off -> 404.","operationId":"verify_downloaded_report_api_v1_verify_report_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportBodyVerifyResponse"}}}}}}},"/.well-known/badge-verification-key.json":{"get":{"tags":["verify"],"summary":"Verification Public Key","description":"Publish the Ed25519 public key for offline third-party verification.\n\nReturns the raw public key as base64url + the key_id + the algorithm\nso a verifier can reconstruct an Ed25519PublicKey and check any\ncertificate's signature without trusting Badge's server (§9 Q2).\n\nWhen verification is disabled or the signing key is unavailable in a\nnon-dev env, returns an empty `keys` list (the document still exists —\nwell-known endpoints should resolve, not 404) so a verifier sees\n\"no published key\" rather than a server error.\n\nThe document is static for the life of a key — served with a 1h\nCache-Control so CDNs/clients don't re-fetch on every verification\n(security-auditor LOW follow-up). The per-request public-key\nderivation is ~µs (Ed25519), so we keep it un-memoized to stay\ncorrect across a key rotation rather than caching in-process.","operationId":"verification_public_key__well_known_badge_verification_key_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/capabilities/top":{"get":{"tags":["capabilities"],"summary":"Get Top Agents By Domain","description":"Get top agents for a specific domain/skill.\n\nReturns agents with highest proficiency in the given domain, ranked by score.","operationId":"get_top_agents_by_domain_api_v1_capabilities_top_get","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":100,"title":"Domain"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AgentCapabilityRead"},"title":"Response Get Top Agents By Domain Api V1 Capabilities Top Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/capabilities/{agent_id}":{"get":{"tags":["capabilities"],"summary":"Get Agent Capabilities","description":"Get capabilities for a specific agent.\n\nReturns paginated list of demonstrated capabilities with proficiency scores.","operationId":"get_agent_capabilities_api_v1_capabilities__agent_id__get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AgentCapabilityRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/stats":{"get":{"tags":["stats"],"summary":"Get Agent Stats","description":"Get comprehensive stats for an agent including:\n- total_runs, successful_runs, failed_runs\n- avg_latency_ms, avg_cost_usd\n- best_task (highest success rate)\n- worst_task (lowest success rate)\n- recent_runs (last 10)\n\nNOTE: stats are publicly accessible for leaderboard agents","operationId":"get_agent_stats_api_v1_agents__agent_id__stats_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/performance-history":{"get":{"tags":["stats"],"summary":"Get Performance History","description":"Get performance history bucketed by day, with regression detection.\nCompares the last 7-day window against the prior 7-day window.\n\nNOTE: stats are publicly accessible for leaderboard agents","operationId":"get_performance_history_api_v1_agents__agent_id__performance_history_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PerformanceHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/one-pager.pdf":{"get":{"tags":["stats"],"summary":"Get One Pager Pdf","description":"Single-page PDF summary of the agent (RES-009 §X #16).\n\nComposite + radar + best/worst tasks + share URL on one A4 page.\nDesigned for procurement decks and portfolio links — not for in-app\nviewing (the live profile is richer).\n\nfpdf2 builds the PDF in-memory; we stream the bytes back without\ntouching the filesystem. Public agents are downloadable by anyone;\nprivate agents require ownership (same visibility rule as the JSON\n/agents/{id}/stats endpoint).","operationId":"get_one_pager_pdf_api_v1_agents__agent_id__one_pager_pdf_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}},"application/pdf":{}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/challenges":{"get":{"tags":["challenges"],"summary":"List Challenges","description":"List all challenges.","operationId":"list_challenges_api_v1_challenges_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ChallengeRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["challenges"],"summary":"Create Challenge","description":"Create a new challenge. Admin-only — challenges are global catalog\nrows visible to every user; only operators can author them.","operationId":"create_challenge_api_v1_challenges_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/challenges/{challenge_id}":{"get":{"tags":["challenges"],"summary":"Get Challenge","description":"Get a challenge by ID.","operationId":"get_challenge_api_v1_challenges__challenge_id__get","parameters":[{"name":"challenge_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Challenge Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/challenges/{challenge_id}/enter":{"post":{"tags":["challenges"],"summary":"Enter Challenge","description":"Enter a challenge by submitting runs for all tasks in the challenge.\nReturns list of created runs.","operationId":"enter_challenge_api_v1_challenges__challenge_id__enter_post","parameters":[{"name":"challenge_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Challenge Id"}},{"name":"agent_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RunRead"},"title":"Response Enter Challenge Api V1 Challenges  Challenge Id  Enter Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/custom-benchmarks":{"post":{"tags":["custom-benchmarks"],"summary":"Create Benchmark","operationId":"create_benchmark_api_v1_custom_benchmarks_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomBenchmarkCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomBenchmarkRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/custom-benchmarks/mine":{"get":{"tags":["custom-benchmarks"],"summary":"List My Benchmarks","operationId":"list_my_benchmarks_api_v1_custom_benchmarks_mine_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CustomBenchmarkRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/custom-benchmarks/{benchmark_id}/upload":{"post":{"tags":["custom-benchmarks"],"summary":"Upload Tasks","description":"Bulk-add tasks to an existing benchmark. Idempotent in the sense\nthat you can call it repeatedly to grow the suite — each call appends.\n\nSchema validation already enforces per-field caps and the 500-task\nlimit per request. We additionally enforce a global suite cap so a\nuser can't loop and balloon a single suite past the safe ceiling.","operationId":"upload_tasks_api_v1_custom_benchmarks__benchmark_id__upload_post","parameters":[{"name":"benchmark_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Benchmark Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomBenchmarkUpload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/custom-benchmarks/{benchmark_id}":{"get":{"tags":["custom-benchmarks"],"summary":"Get Benchmark","operationId":"get_benchmark_api_v1_custom_benchmarks__benchmark_id__get","parameters":[{"name":"benchmark_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Benchmark Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomBenchmarkDetailRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["custom-benchmarks"],"summary":"Delete Benchmark","operationId":"delete_benchmark_api_v1_custom_benchmarks__benchmark_id__delete","parameters":[{"name":"benchmark_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Benchmark Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/graphql":{"get":{"summary":"Handle Http Get","operationId":"handle_http_get_graphql_get","responses":{"200":{"description":"The GraphiQL integrated development environment.","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found if GraphiQL or query via GET are not enabled."}}},"post":{"summary":"Handle Http Post","operationId":"handle_http_post_graphql_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/leaderboard":{"get":{"tags":["leaderboard"],"summary":"Get Leaderboard","description":"Public leaderboard — agents ranked by composite score (descending).\nOnly includes agents with at least one completed run (overall score, task_id IS NULL).\n\nArgs:\n    period: Time scoping for the leaderboard\n        - all_time: All runs (default)\n        - day: Runs from last 24 hours\n        - week: Runs from last 7 days\n        - month: Runs from last 30 days\n        - 7d, 30d, 90d: Legacy formats (also supported)\n    domain: Filter by task domain (e.g., code_generation, data_extraction)\n        - If specified, only includes agents' scores for that domain\n    verified_only: UX-AUDIT 2026-07-11 A1 — restrict the board to agents\n        holding a signed real-execution credential (same predicate that\n        renders the ✓ mark, via seo_service.verified_agents_select()).\n        Defaults to false so existing API/MCP consumers see no change.\n\nDeprecated response fields (UX-AUDIT 2026-07-11 B1/H4 — kept for external\nAPI/MCP consumers, no first-party UI reads them anymore):\n    elo_rating: constant 1200 — no ELO update ever ran\n        (services/scoring.py never touches it). Do not rank on it.\n    trending: derived from run *recency*, not score movement — the two\n        window averages below aggregate the same all-time composite, so a\n        real score trend can never register. Treat as a coarse\n        \"recently active\" hint at best.","operationId":"get_leaderboard_api_v1_leaderboard_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"all_time","title":"Period"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by task domain","title":"Domain"},"description":"Filter by task domain"},{"name":"verified_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only include agents with at least one cryptographically signed real-execution run (the green ✓ on the board). Simulated-only and unverified agents are excluded from items AND total. Default false for backward compatibility; the public board surfaces opt in.","default":false,"title":"Verified Only"},"description":"Only include agents with at least one cryptographically signed real-execution run (the green ✓ on the board). Simulated-only and unverified agents are excluded from items AND total. Default false for backward compatibility; the public board surfaces opt in."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_LeaderboardEntry_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/promo-codes":{"get":{"tags":["playbook-pricing"],"summary":"List My Promo Codes","description":"Cross-playbook codes index for the current creator (PRD-008 FR-15).\n\nThe per-playbook list at `GET /playbooks/{id}/promo-codes` is fine when\nyou're already on a playbook's page, but creators with multiple paid\nplaybooks need a single dashboard. We join PromoCode → Playbook → Agent\n→ User and filter by `Agent.user_id == current user`.\n\nReturns each row enriched with `playbook_name` so the UI can render\n\"LAUNCH20 — Customer support bot\" in one column without a second fetch.","operationId":"list_my_promo_codes_api_v1_playbooks_promo_codes_get","parameters":[{"name":"include_revoked","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Revoked"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OwnedPromoCodeRead"},"title":"Response List My Promo Codes Api V1 Playbooks Promo Codes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/recommended-price":{"get":{"tags":["playbook-pricing"],"summary":"Get Recommended Price","description":"P25/P50/P75 of comparable playbooks (FR-10).\n\nComparables are paid public playbooks. `domain` and `difficulty` are\noptional filters surfaced via the Playbook.notes blob — Phase 2 will\npromote them to first-class columns. Returns null below the\n`PRICING_RECOMMEND_MIN_COMPARABLES` threshold (caller renders blank).","operationId":"get_recommended_price_api_v1_playbooks_recommended_price_get","parameters":[{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Domain"}},{"name":"difficulty","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Difficulty"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RecommendedPriceResponse"},{"type":"null"}],"title":"Response Get Recommended Price Api V1 Playbooks Recommended Price Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/price-experiments":{"post":{"tags":["playbook-pricing"],"summary":"Create Price Experiment","description":"Create a new draft experiment (FR-06).\n\nValidations beyond the schema:\n  - Caller owns the playbook.\n  - Variants span ≤ 5x range (PRD-008 FR-06).\n  - No active running experiment on this playbook.\n  - No active introductory pricing window (ADR-009 Q-04 — 409 Conflict).","operationId":"create_price_experiment_api_v1_playbooks__playbook_id__price_experiments_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceExperimentCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceExperimentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["playbook-pricing"],"summary":"List Price Experiments","description":"List experiments for a playbook (creator-only).","operationId":"list_price_experiments_api_v1_playbooks__playbook_id__price_experiments_get","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PriceExperimentRead"},"title":"Response List Price Experiments Api V1 Playbooks  Playbook Id  Price Experiments Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/price-experiments/{exp_id}/start":{"post":{"tags":["playbook-pricing"],"summary":"Start Price Experiment","description":"Transition a draft experiment → running.\n\nRe-checks the \"no other running exp\" rule (something might have started\nbetween create and start). Sets `started_at` and `ends_at` (started_at +\nPRICING_EXPERIMENTS_AUTO_CONCLUDE_DAYS).","operationId":"start_price_experiment_api_v1_playbooks__playbook_id__price_experiments__exp_id__start_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"exp_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Exp Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceExperimentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/price-experiments/{exp_id}/conclude":{"post":{"tags":["playbook-pricing"],"summary":"Conclude Price Experiment","description":"Conclude a running experiment + promote winner to canonical price (FR-07).\n\nWinner-selection priority:\n  1. `payload.winner_variant_label` (creator override).\n  2. Highest-conversion variant (computed from assignments).\n  3. Control (if there's no signal at all).\n\nAll three branches write a `playbook_price_history` row with reason\n`experiment_concluded` + the experiment id (for forensics dashboards).","operationId":"conclude_price_experiment_api_v1_playbooks__playbook_id__price_experiments__exp_id__conclude_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"exp_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Exp Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceExperimentConcludeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceExperimentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/price-experiments/{exp_id}/cancel":{"post":{"tags":["playbook-pricing"],"summary":"Cancel Price Experiment","description":"Cancel a draft or running experiment without promoting any winner.","operationId":"cancel_price_experiment_api_v1_playbooks__playbook_id__price_experiments__exp_id__cancel_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"exp_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Exp Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceExperimentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/price-experiments/{exp_id}/results":{"get":{"tags":["playbook-pricing"],"summary":"Get Experiment Results","description":"Per-variant stats for the creator dashboard (FR-08, FR-14).\n\nHidden from non-creators — buyers don't get to peek at conversion data.","operationId":"get_experiment_results_api_v1_playbooks__playbook_id__price_experiments__exp_id__results_get","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"exp_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Exp Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceExperimentResults"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/promo-codes":{"post":{"tags":["playbook-pricing"],"summary":"Create Promo Code","description":"Creator creates a discount code (FR-09).\n\nCode is normalised to UPPERCASE before persistence + uniqueness check.\nUniqueness is per-playbook (two playbooks can both have a code \"LAUNCH20\").","operationId":"create_promo_code_api_v1_playbooks__playbook_id__promo_codes_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoCodeCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoCodeRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["playbook-pricing"],"summary":"List Promo Codes","description":"List promo codes for a playbook (creator-only).","operationId":"list_promo_codes_api_v1_playbooks__playbook_id__promo_codes_get","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"include_revoked","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Revoked"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PromoCodeRead"},"title":"Response List Promo Codes Api V1 Playbooks  Playbook Id  Promo Codes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/promo-codes/{promo_id}":{"delete":{"tags":["playbook-pricing"],"summary":"Revoke Promo Code","description":"Revoke a promo code (ADR-009 Q-06 — kill switch via revoked_at).\n\nIdempotent: revoking an already-revoked code returns 204 silently rather\nthan 410, since the buyer-side validate endpoint is the one that returns\n410 Gone for *use* of a revoked code.","operationId":"revoke_promo_code_api_v1_playbooks__playbook_id__promo_codes__promo_id__delete","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"promo_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Promo Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/promo-codes/validate":{"post":{"tags":["playbook-pricing"],"summary":"Validate Promo Code","description":"Buyer-side validation for the purchase modal (FR-12).\n\nReturns `valid=true` + the discount math when usable; otherwise returns\n`valid=false` + a human-readable `reason` (without leaking which check\nfailed beyond what the buyer already knows).","operationId":"validate_promo_code_api_v1_playbooks__playbook_id__promo_codes_validate_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoValidateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoValidateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/price-quote":{"get":{"tags":["playbook-pricing"],"summary":"Get Price Quote","description":"Buyer-side: compute the price *this viewer* should pay (FR-05).\n\nLogic:\n  1. If a running experiment exists, bucket the viewer (sticky) and\n     return the variant's price as `price_cents`.\n  2. Otherwise return canonical `list_price_cents` as `price_cents`.\n  3. If a valid anchor (FR-11) exists, attach `anchor_was_cents`.\n  4. If `promo_code` is provided AND active, apply discount on top and\n     return `effective_price_cents` post-discount.\n\nNo auth required — this powers the public buyer page. We do NOT persist\na `playbook_price_assignments` row from this endpoint; we only persist\nwhen the buyer actually clicks \"Hire\" (i.e., from the purchase endpoint).\nReason: persisting on every page-view would balloon the table and bias\nthe bucket-stickiness check toward the wrong side of the funnel.","operationId":"get_price_quote_api_v1_playbooks__playbook_id__price_quote_get","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}},{"name":"promo_code","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Promo Code"}},{"name":"bucket_cookie","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Bucket Cookie"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceQuoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/anchor-price":{"get":{"tags":["playbook-pricing"],"summary":"Get Anchor Price","description":"Anchor-only quote (FR-11) — for SSR pages that don't need variant logic.\n\nReuses the price-quote response shape so callers can render the same\n\"Was/Now\" badge component regardless of which endpoint they hit.","operationId":"get_anchor_price_api_v1_playbooks__playbook_id__anchor_price_get","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceQuoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/price-experiments/auto-conclude":{"post":{"tags":["playbook-pricing"],"summary":"Auto Conclude Stale Experiments","description":"Sweep running experiments past the auto-conclude window (ADR-009 Q-02).\n\nAdmin-only (gated via ADMIN_EMAILS). Intended to be hit by a cron-ish job\nonce an hour. Inconclusive sweep:\n  - winner = control variant.\n  - status = CONCLUDED_INCONCLUSIVE.\n  - No price change (canonical stays as-is).\n\nReturns counts so monitoring can alert on `concluded_inconclusive` ratio\n> 40% (the ADR-009 re-evaluation trigger).","operationId":"auto_conclude_stale_experiments_api_v1_admin_price_experiments_auto_conclude_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Auto Conclude Stale Experiments Api V1 Admin Price Experiments Auto Conclude Post"}}}}}}},"/api/v1/playbooks/my/payout-email":{"get":{"tags":["playbooks"],"summary":"Get My Payout Email","description":"Return the caller's stored marketplace payout email (or null).","operationId":"get_my_payout_email_api_v1_playbooks_my_payout_email_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutEmailRead"}}}}}},"put":{"tags":["playbooks"],"summary":"Set My Payout Email","description":"Store the caller's payout email (F-01 lean v1).\n\nThis is the ONLY payout detail collected in lean v1 — no KYC, no bank\ndetails. A user can only set their own payout email (the seller identity is\n`current_user`, never a path/body-supplied user id), so there is no\ncross-user write surface here. When Stripe Connect lands (deferred), this\nemail seeds the Connect onboarding link.","operationId":"set_my_payout_email_api_v1_playbooks_my_payout_email_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutEmailUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutEmailRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/my/connect/onboard":{"post":{"tags":["playbooks"],"summary":"Connect Onboard","description":"Start (or resume) Stripe Connect Express onboarding for the caller.\n\nCreates a Stripe Express account on first call (persisting its `acct_…` id\nso a retry reuses it rather than orphaning a second account), then mints a\nsingle-use Account Link the frontend redirects the seller to. The seller\ncompletes KYB on Stripe's hosted flow; we learn the outcome via the\n`/connect/status` poll and the `account.updated` webhook.\n\nFail-safe (CLAUDE.md rule #7): 503 \"Stripe not configured\" when\nSTRIPE_SECRET_KEY is unset — allowlisted in the Sentry before_send filter.","operationId":"connect_onboard_api_v1_playbooks_my_connect_onboard_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectOnboardResponse"}}}}}}},"/api/v1/playbooks/my/connect/status":{"get":{"tags":["playbooks"],"summary":"Connect Status","description":"Report the caller's Stripe Connect onboarding state.\n\nNo account yet → all-false (the frontend shows \"Set up payouts\"). Otherwise\nwe fetch the live account, persist `charges_enabled`/`payouts_enabled` back\nonto the User (so the rest of the app can gate on a fresh value without\nanother Stripe round-trip), and return them plus `details_submitted`.\n\nFail-safe (CLAUDE.md rule #7): 503 \"Stripe not configured\" when\nSTRIPE_SECRET_KEY is unset — checked first so the contract is uniform\nregardless of whether the caller has an account id.","operationId":"connect_status_api_v1_playbooks_my_connect_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectStatusResponse"}}}}}}},"/api/v1/playbooks/my/earnings":{"get":{"tags":["playbooks"],"summary":"Get My Earnings","description":"Creator-side earnings dashboard.\n\nAggregates PlaybookPurchase rows where the current user is the seller.\n\nF-01 lean v1: COMPLETED is REALIZED (paid-out) revenue — zero in lean v1\nsince payouts are deferred. PENDING is recorded-but-unsettled — surfaced\nseparately as `pending_*` so the dashboard shows what's owed without ever\nclaiming it has been paid. Returns lifetime totals + last-30-days +\nper-playbook breakdown.","operationId":"get_my_earnings_api_v1_playbooks_my_earnings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EarningsSummary"}}}}}}},"/api/v1/playbooks/{playbook_id}/clone":{"post":{"tags":["playbooks"],"summary":"Clone Playbook","description":"Clone a public playbook (\"Hire\") to a different agent.\n\nFree playbooks: anyone with a target agent can clone.\nPaid playbooks (PRD-007): require an active (PENDING or COMPLETED)\nPlaybookPurchase row for (buyer=current_user, source=this playbook). If none\nexists, returns 402 so the frontend can route the user through the purchase\nflow.","operationId":"clone_playbook_api_v1_playbooks__playbook_id__clone_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookCloneCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/purchase":{"post":{"tags":["playbooks"],"summary":"Purchase Playbook","description":"Hire a paid public playbook through Stripe Connect. This endpoint is\nfail-closed: without both billing authorization and a configured Stripe key,\nit returns an explicit 503 before creating a purchase or clone.\n\nMoney is INT cents everywhere. Platform fee is computed via integer math so\nreconciliation is exact: `fee + earnings == price_paid`.","operationId":"purchase_playbook_api_v1_playbooks__playbook_id__purchase_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookPurchaseCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookCheckoutRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/declared-configurations":{"get":{"tags":["playbooks"],"summary":"List Declared Configurations","description":"Return an editor-only, allowlisted declaration history for Evidence.\n\nThe full Playbook serializer contains prompts, examples, tools, and notes.\nReusing it for the Blueprint-adjacent card would make a frontend omission\nthe only disclosure control, so this endpoint constructs the narrow\nprojection server-side after resolving current personal/workspace edit\nauthority.","operationId":"list_declared_configurations_api_v1_playbooks_declared_configurations_get","parameters":[{"name":"agent_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeclaredConfigurationCollection"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks":{"get":{"tags":["playbooks"],"summary":"List Playbooks","description":"List only playbooks owned by the authenticated user.","operationId":"list_playbooks_api_v1_playbooks_get","parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent Id"}},{"name":"active_only","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Active Only"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_PlaybookRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["playbooks"],"summary":"Create Playbook","description":"Create a new playbook for an agent (v1).","operationId":"create_playbook_api_v1_playbooks_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/public":{"get":{"tags":["playbooks"],"summary":"List Public Playbooks","description":"List public playbooks for transfer learning — browse what top agents use.","operationId":"list_public_playbooks_api_v1_playbooks_public_get","parameters":[{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"created_at","title":"Sort"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_PlaybookPublicRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/marketplace":{"get":{"tags":["playbooks"],"summary":"List Marketplace Playbooks","description":"RES-014-ITER-1 MINOR 11 — `/playbooks/marketplace` alias of\n`/playbooks/public`.\n\nThe persona test hit `/playbooks/marketplace` (the natural name for the\npublic playbook listing) and got a **422**: with no literal `/marketplace`\nroute, the request fell through to `GET /playbooks/{playbook_id}`, where\n\"marketplace\" failed UUID parsing → Unprocessable Entity. That's the\nCLAUDE.md rule-5 collision family (a literal path losing to the `{id}`\ncatch-all) AND rule-4 (a confusing 422 where a real resource should\nanswer).\n\nThis literal route is DEFINED ABOVE `/{playbook_id}` in this same router,\nso it wins. It delegates to the existing public-listing handler — one\nbehaviour, two URLs — rather than duplicating the query.","operationId":"list_marketplace_playbooks_api_v1_playbooks_marketplace_get","parameters":[{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"created_at","title":"Sort"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_PlaybookPublicRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}":{"get":{"tags":["playbooks"],"summary":"Get Playbook","operationId":"get_playbook_api_v1_playbooks__playbook_id__get","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookPublicRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["playbooks"],"summary":"Update Playbook","description":"Update a playbook by creating a new version.\n\nThe current version is deactivated, and a new version is created\nwith the updated fields. Unchanged fields carry over.","operationId":"update_playbook_api_v1_playbooks__playbook_id__put","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["playbooks"],"summary":"Deactivate Playbook","description":"Soft-delete a playbook.","operationId":"deactivate_playbook_api_v1_playbooks__playbook_id__delete","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/set-default":{"post":{"tags":["playbooks"],"summary":"Set Default Playbook","description":"Set a playbook as the default for its agent.","operationId":"set_default_playbook_api_v1_playbooks__playbook_id__set_default_post","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/playbooks/{playbook_id}/history":{"get":{"tags":["playbooks"],"summary":"Get Playbook History","description":"Get the version history chain for a playbook.","operationId":"get_playbook_history_api_v1_playbooks__playbook_id__history_get","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlaybookPublicRead"},"title":"Response Get Playbook History Api V1 Playbooks  Playbook Id  History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/lab/runs":{"post":{"tags":["prompt-lab"],"summary":"Create Lab Runs","description":"Submit lab runs for one or more playbooks × tasks.\n\nThis is the core Prompt Lab execution endpoint. Pass multiple playbook_ids\nto compare playbooks side-by-side on the same tasks.","operationId":"create_lab_runs_api_v1_lab_runs_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabRunBatchCreate"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LabRunRead"},"title":"Response Create Lab Runs Api V1 Lab Runs Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["prompt-lab"],"summary":"List Lab Runs","description":"List only the authenticated builder's Lab runs.","operationId":"list_lab_runs_api_v1_lab_runs_get","parameters":[{"name":"playbook_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Playbook Id"}},{"name":"task_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Task Id"}},{"name":"experiment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Experiment Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_LabRunRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/lab/runs/{lab_run_id}":{"get":{"tags":["prompt-lab"],"summary":"Get Lab Run","operationId":"get_lab_run_api_v1_lab_runs__lab_run_id__get","parameters":[{"name":"lab_run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lab Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabRunRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/lab/experiments":{"post":{"tags":["prompt-lab"],"summary":"Create Lab Experiment","description":"Create a named experiment to organize lab runs.\n\nExperiments help group related lab runs and provide a way to track\nvariations and iterations over time.","operationId":"create_lab_experiment_api_v1_lab_experiments_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabExperimentCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabExperimentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["prompt-lab"],"summary":"List Lab Experiments","description":"List all lab experiments for the current user.\n\nReturns paginated list of experiments, newest first.","operationId":"list_lab_experiments_api_v1_lab_experiments_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_LabExperimentRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/lab/experiments/{experiment_id}":{"get":{"tags":["prompt-lab"],"summary":"Get Lab Experiment","description":"Get details for a specific lab experiment.","operationId":"get_lab_experiment_api_v1_lab_experiments__experiment_id__get","parameters":[{"name":"experiment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Experiment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabExperimentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["prompt-lab"],"summary":"Update Lab Experiment","description":"Update a lab experiment.","operationId":"update_lab_experiment_api_v1_lab_experiments__experiment_id__patch","parameters":[{"name":"experiment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Experiment Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabExperimentUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabExperimentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/lab/experiments/{experiment_id}/mlflow-export":{"get":{"tags":["prompt-lab"],"summary":"Export Experiment Mlflow","description":"Export experiment data in MLflow-compatible JSON format.","operationId":"export_experiment_mlflow_api_v1_lab_experiments__experiment_id__mlflow_export_get","parameters":[{"name":"experiment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Experiment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Export Experiment Mlflow Api V1 Lab Experiments  Experiment Id  Mlflow Export Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registry/schema":{"get":{"tags":["registry"],"summary":"Get Manifest Schema","description":"Return the JSON Schema for the agent manifest format.","operationId":"get_manifest_schema_api_v1_registry_schema_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Manifest Schema Api V1 Registry Schema Get"}}}}}}},"/api/v1/registry/discover":{"post":{"tags":["registry"],"summary":"Discover Agent","description":"Fetch and validate an agent manifest from a URL.\n\nTries: {url}/.well-known/agent.json first, then {url}/agent.json as fallback.\nAlso pings the health endpoint if declared in the manifest.\n\nRequires authentication — registry mutation/discovery is a logged-in-only\naction (SEC-AUTH per Phase-1 audit). Without auth, an unauth caller could\ncycle the discovery loop to consume server CPU + outbound bandwidth.","operationId":"discover_agent_api_v1_registry_discover_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManifestDiscoverRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManifestDiscoverResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registry/register":{"post":{"tags":["registry"],"summary":"Register From Manifest","description":"Discover an agent manifest and register it in the platform.\n\nFetches the manifest, extracts metadata, and creates the agent record.\nIf an agent with the same name already exists, returns 409.\n\nRequires authentication — the resulting agent is stamped with\n`user_id = user.id` so ownership / private-agent gating works\nconsistently with directly-created agents.","operationId":"register_from_manifest_api_v1_registry_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManifestDiscoverRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registry/agents":{"get":{"tags":["registry"],"summary":"Browse Registry","description":"Browse the agent registry with filtering and search.","operationId":"browse_registry_api_v1_registry_agents_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by domain (e.g. code_generation)","title":"Domain"},"description":"Filter by domain (e.g. code_generation)"},{"name":"model_provider","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by model provider (e.g. openai)","title":"Model Provider"},"description":"Filter by model provider (e.g. openai)"},{"name":"architecture","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by architecture (e.g. react)","title":"Architecture"},"description":"Filter by architecture (e.g. react)"},{"name":"registry_status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by registry status","title":"Registry Status"},"description":"Filter by registry status"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Search name, description, tags","title":"Search"},"description":"Search name, description, tags"},{"name":"include_reference","in":"query","required":false,"schema":{"type":"boolean","description":"Include Badge house 'reference' agents (the seeded calibration set). Default False — reference variants would otherwise drown real agents.","default":false,"title":"Include Reference"},"description":"Include Badge house 'reference' agents (the seeded calibration set). Default False — reference variants would otherwise drown real agents."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AgentRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registry/agents/{agent_id}":{"get":{"tags":["registry"],"summary":"Get Registry Agent","description":"Get full registry details for an agent.","operationId":"get_registry_agent_api_v1_registry_agents__agent_id__get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registry/agents/{agent_id}/verify":{"post":{"tags":["registry"],"summary":"Trigger Verification","description":"Trigger a benchmark verification run for an agent.\n\nSets status to 'verifying' and queues a background task that:\n1. Runs the agent against all active tasks\n2. Computes scores\n3. Updates registry_status to 'verified' or 'failed'\n4. Sets verified_at timestamp\n\nRequires authentication and agent ownership. We return 404 (not 403)\nwhen `agent.user_id != user.id` so the endpoint doesn't double as an\nexistence oracle for someone else's agents.","operationId":"trigger_verification_api_v1_registry_agents__agent_id__verify_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registry/agents/{agent_id}/refresh":{"post":{"tags":["registry"],"summary":"Refresh Manifest","description":"Re-fetch the manifest from the agent's manifest_url and update fields.\n\nRequires authentication and agent ownership. 404 (not 403) on a\ncross-user refresh attempt — same existence-oracle reasoning as\n`trigger_verification`.","operationId":"refresh_manifest_api_v1_registry_agents__agent_id__refresh_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provenance/status":{"get":{"tags":["provenance"],"summary":"Provenance Status","description":"Public flag probe — does NOT honour ``require_bpp_enabled`` (the\nfrontend needs a definitive false to collapse chips to the legacy set).\n\n``blueprint_versions`` (#928): the Evidence timeline gates its fetch on\nthis instead of probing its own flag-dark 404 — an unconditional probe\nprinted a console error on every agent-detail visit in a dark\nenvironment (caught by the #844 golden path's browserErrors gate).\n``approvals`` (#1300) works the same way: the approvals UI gates every\nfetch on it instead of probing a flag-dark 404. Additive; every field\nfails-conservative to false on the client.\n``audit_log`` (#1385) is the same for the workspace audit log: the /team\npage used to probe ``GET /teams/{id}/audit-log`` on every load to decide\nwhether to show its link, a flag-dark 404 Chromium prints as a console\nerror. Only booleans live here; the flag is not a secret.","operationId":"provenance_status_api_v1_provenance_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Response Provenance Status Api V1 Provenance Status Get"}}}}}}},"/api/v1/provenance/otlp":{"post":{"tags":["provenance"],"summary":"Ingest Otlp Traces","description":"OTLP/HTTP trace receiver (BPP-3).\n\nAccepts an ``ExportTraceServiceRequest`` as OTLP/JSON\n(``application/json``) or OTLP/protobuf (``application/x-protobuf``),\nprojects every span through the ``GENAI_ACCEPTED_ATTRS`` whitelist\n(privacy-critical — arbitrary attributes, including prompt bodies, are\ndropped and NEVER reach the DB), and merges the result into\n``run.provenance[\"observed\"]``.","operationId":"ingest_otlp_traces_api_v1_provenance_otlp_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/provenance/metering/keys":{"post":{"tags":["provenance"],"summary":"Mint Metering Key","description":"Owner-only: mint a per-agent BYOK virtual key from the LiteLLM proxy.\n\n404s (via ``require_bpp_metering_enabled``) unless BOTH ``BPP_ENABLED``\nand ``BPP_METERING_ENABLED`` are true. 404s again if the agent doesn't\nexist or isn't owned by the caller (no probe oracle — same detail either\nway). 503s if the gateway is unreachable/misconfigured\n(``BppMeteringUnavailable`` — an intentional fail-safe, allow-listed in\n``app/observability/sentry.py`` so it doesn't page on every attempt\nbefore the founder finishes setup).","operationId":"mint_metering_key_api_v1_provenance_metering_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MintMeteringKeyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MintMeteringKeyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provenance/metering/status":{"get":{"tags":["provenance"],"summary":"Metering Status","description":"Diagnostic probe pairing both metering flags with a live gateway\nreachability check — same \"pair every flag with a diagnostic\" rationale\nas ``GET /health/dependencies`` (three-hop plumbing trap). 404s unless\nBOTH ``BPP_ENABLED`` and ``BPP_METERING_ENABLED`` are true.","operationId":"metering_status_api_v1_provenance_metering_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Response Metering Status Api V1 Provenance Metering Status Get"}}}}}}},"/api/v1/provenance/reconciliation/audit":{"post":{"tags":["provenance"],"summary":"Reconciliation Audit","description":"BPP-001 W5b — admin-triggered L3 audit lottery.\n\n``require_admin`` is a parameter dependency, so it resolves BEFORE this\nbody ever runs: a non-admin caller gets 403 regardless of the\nreconciliation flag's state. The flag check\n(``require_bpp_reconciliation_enabled`` — 404 unless BOTH ``BPP_ENABLED``\nand ``BPP_RECONCILIATION_ENABLED`` are true) is the first line of the\nbody, so an authenticated admin with the flag off gets 404. This exact\nordering mirrors the ``/tasks/secret-suites/*`` precedent\n(``app/routers/tasks.py``): 403 (non-admin) takes priority over 404\n(flag-off) because the admin dependency always resolves first.\n\nSelects up to ``k`` certifications via the deterministic seeded audit\nlottery (``select_audit_candidates`` — Townsend costly-state-\nverification, see its docstring) and reconciles each one in turn against\nits owner-granted provider usage scope. Certifications with no grant on\nfile are never selected in the first place. Returns\nprovider/verdict/delta_pct/cost_scope only — never any key material.","operationId":"reconciliation_audit_api_v1_provenance_reconciliation_audit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReconciliationAuditRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReconciliationAuditResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/provenance/reconciliation/bond":{"post":{"tags":["provenance"],"summary":"Reconciliation Bond","description":"POLICY + STUB ONLY — refundable-bond / slash-on-mismatch policy.\n\nRES-017 §L3 pairs the audit lottery with a refundable bond an agent\nowner posts when opting into reconciliation: post a bond at grant time,\nget it back in full if every audited reconciliation comes back\n\"consistent\", have it partially slashed if an audit comes back\n\"delta_flagged\" (the economic backstop behind the probabilistic-audit\nargument in ``select_audit_candidates`` — a bond makes cheating\nnegative-expected-value even for a builder willing to gamble on not\nbeing sampled).\n\nThis endpoint is a STUB: it never creates a Stripe object and never\nmoves money (BLOCKED on the founder — escrow/bond product + payments\ninfra is a separate, founder-approved workstream). It always returns\n503 (never 501): ``app/observability/sentry.py``'s ``before_send``\nfilter only special-cases 503 against its ``_INTENTIONAL_503_PHRASES``\nallowlist, so a 501 here would page Sentry on every single call to a\npermanently-unbuilt feature. 404s (via\n``require_bpp_reconciliation_enabled``) unless BOTH ``BPP_ENABLED`` and\n``BPP_RECONCILIATION_ENABLED`` are true.","operationId":"reconciliation_bond_api_v1_provenance_reconciliation_bond_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/selfhost/licence":{"get":{"tags":["selfhost"],"summary":"Get Licence","operationId":"get_licence_api_v1_selfhost_licence_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Licence Api V1 Selfhost Licence Get"}}}}}}},"/api/v1/agents/{agent_id}/drift-alerts":{"get":{"tags":["drift-alerts"],"summary":"List Drift Alerts","operationId":"list_drift_alerts_api_v1_agents__agent_id__drift_alerts_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"include_acknowledged","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Include Acknowledged"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriftAlertList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/drift-alerts/{alert_id}/ack":{"post":{"tags":["drift-alerts"],"summary":"Acknowledge Drift Alert","operationId":"acknowledge_drift_alert_api_v1_agents__agent_id__drift_alerts__alert_id__ack_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriftAlertRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/drift-settings":{"get":{"tags":["drift-alerts"],"summary":"Get Drift Settings","operationId":"get_drift_settings_api_v1_agents__agent_id__drift_settings_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriftSettingsRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["drift-alerts"],"summary":"Put Drift Settings","operationId":"put_drift_settings_api_v1_agents__agent_id__drift_settings_put","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriftSettingsUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriftSettingsRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/drift/evaluate":{"post":{"tags":["drift-alerts"],"summary":"Evaluate Drift","operationId":"evaluate_drift_api_v1_agents__agent_id__drift_evaluate_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriftEvaluateResult"}}}},"429":{"description":"Rate limited; body carries retry_after_seconds"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/schedules":{"post":{"tags":["schedules"],"summary":"Create Schedule","operationId":"create_schedule_api_v1_agents__agent_id__schedules_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["schedules"],"summary":"List Schedules","operationId":"list_schedules_api_v1_agents__agent_id__schedules_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleRead"},"title":"Response List Schedules Api V1 Agents  Agent Id  Schedules Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/schedules/{schedule_id}":{"get":{"tags":["schedules"],"summary":"Get Schedule","operationId":"get_schedule_api_v1_schedules__schedule_id__get","parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Schedule Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["schedules"],"summary":"Update Schedule","operationId":"update_schedule_api_v1_schedules__schedule_id__patch","parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Schedule Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["schedules"],"summary":"Delete Schedule","operationId":"delete_schedule_api_v1_schedules__schedule_id__delete","parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Schedule Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/schedules/{schedule_id}/history":{"get":{"tags":["schedules"],"summary":"Schedule History","operationId":"schedule_history_api_v1_schedules__schedule_id__history_get","parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Schedule Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ScheduleHistoryItem_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/sbom":{"get":{"tags":["sbom"],"summary":"Export Agent Sbom","operationId":"export_agent_sbom_api_v1_agents__agent_id__sbom_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"format","in":"query","required":false,"schema":{"const":"cyclonedx","type":"string","default":"cyclonedx","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/savings-report":{"post":{"tags":["savings-report"],"summary":"Generate Savings Report","operationId":"generate_savings_report_api_v1_agents__agent_id__savings_report_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/SavingsReportGenerateRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavingsReportCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["savings-report"],"summary":"Latest Savings Report","operationId":"latest_savings_report_api_v1_agents__agent_id__savings_report_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavingsReportCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/savings-reports/{report_id}":{"get":{"tags":["savings-report"],"summary":"Get Savings Report","operationId":"get_savings_report_api_v1_savings_reports__report_id__get","parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Report Id"}},{"name":"format","in":"query","required":false,"schema":{"enum":["json","csv","pdf"],"type":"string","default":"json","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}},"text/csv":{},"application/pdf":{}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/savings-report":{"get":{"tags":["savings-report"],"summary":"Workspace Savings Report","operationId":"workspace_savings_report_api_v1_teams__team_id__savings_report_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Window Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceSavingsReport"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scorecards/status":{"get":{"tags":["scorecards"],"summary":"Scorecards Status","description":"Public flag probe — never gated, always 200 with a definitive bool so\nthe frontend can collapse to the legacy builder when the flag is off.","operationId":"scorecards_status_api_v1_scorecards_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Response Scorecards Status Api V1 Scorecards Status Get"}}}}}}},"/api/v1/decisions-probe/status":{"get":{"tags":["decisions-probe"],"summary":"Decisions Probe Status","description":"Public flag probe — never gated, always 200 with a definitive bool so\nthe frontend collapses the painted-door CTA off when the flag is off.","operationId":"decisions_probe_status_api_v1_decisions_probe_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Response Decisions Probe Status Api V1 Decisions Probe Status Get"}}}}}}},"/api/v1/api-keys":{"post":{"tags":["api-keys"],"summary":"Create Api Key","description":"Create a new API key. The full key is returned only once — store it securely.","operationId":"create_api_key_api_v1_api_keys_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["api-keys"],"summary":"List Api Keys","description":"List all API keys (without revealing the actual keys).","operationId":"list_api_keys_api_v1_api_keys_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ApiKeyRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/api-keys/bulk/revoke":{"post":{"tags":["api-keys"],"summary":"Bulk Revoke Api Keys","description":"Soft-revoke many keys in one call.\n\nPass `{\"all\": true}` to revoke every active key for this user, or\n`{\"ids\": [\"uuid1\",\"uuid2\",...]}` to revoke a specific set. Already-inactive\nkeys in the request are silently skipped (idempotent). Keys belonging to\nother users are silently skipped (no enumeration via mismatched IDs).","operationId":"bulk_revoke_api_keys_api_v1_api_keys_bulk_revoke_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyBulkRevoke"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyBulkRevokeResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/api-keys/{key_id}/rotate":{"post":{"tags":["api-keys"],"summary":"Rotate Api Key","description":"Rotate a key: mint a new one with the same name + scopes + rate limits,\nsoft-revoke the old one. Returns the NEW full key (shown once).\n\nUse this when a key may have been leaked or as part of regular hygiene.\nThe new key takes effect immediately; the old key is dead immediately\n(no overlap window — clients should swap atomically).","operationId":"rotate_api_key_api_v1_api_keys__key_id__rotate_post","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRotated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/api-keys/{key_id}/usage":{"get":{"tags":["api-keys"],"summary":"Get Api Key Usage","description":"Per-key usage summary. Derived from existing counters — no event log.","operationId":"get_api_key_usage_api_v1_api_keys__key_id__usage_get","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyUsage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/api-keys/{key_id}":{"get":{"tags":["api-keys"],"summary":"Get Api Key","operationId":"get_api_key_api_v1_api_keys__key_id__get","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["api-keys"],"summary":"Update Api Key","description":"Update API key settings (name, scopes, rate limits, active status).","operationId":"update_api_key_api_v1_api_keys__key_id__patch","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["api-keys"],"summary":"Revoke Api Key","description":"Revoke (deactivate) an API key.","operationId":"revoke_api_key_api_v1_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/badges/run/{run_id}/verified.svg":{"get":{"tags":["badges"],"summary":"Get Verified Badge","description":"SVG verified-state badge for a single run — the embeddable credential.\n\nHonest by construction:\n  * verification flag off, unknown/private run, or unsigned run →\n    neutral \"Unverified\" badge (never a green ✓ for something we\n    can't vouch for).\n  * simulated run → amber \"◐ Simulated\".\n  * signed real-execution run → green \"✓ Verified\".\n\nVisibility: a private run renders the same neutral \"Unverified\" badge\nas an unknown id, so the embed never leaks that a private run exists\n(AC-04 / CLAUDE.md rule #8).\n\nBRIEF-RES-014-A §5 / AC-07 — this is the ONE place we can observe a\nverified card being rendered on an EXTERNAL surface (a README, a blog).\nEvery render fires `verified_embed_viewed` server-side, tagged with the\n`referrer` (the embedding site) and the `verified_state`, so the embed →\n/verify → signup loop is measurable. The cache header (max-age=300) means\na busy README won't fire on every page-load, only ~once per 5 min per CDN\nedge — which is the right granularity (placement count, not raw hits).","operationId":"get_verified_badge_api_v1_badges_run__run_id__verified_svg_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"style","in":"query","required":false,"schema":{"type":"string","pattern":"^(flat|flat-square)$","default":"flat","title":"Style"}}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/badges/{agent_id}.svg":{"get":{"tags":["badges"],"summary":"Get Badge","description":"Generate an SVG badge for an agent's score.\n\nQuery parameters:\n- style: \"flat\" (default) or \"flat-square\"\n- metric: \"composite\" (default), \"success_rate\", \"reliability\", or \"elo\"\n\nROAD-002 §WP-F — every successful render fires a server-side PostHog\n`badge_rendered` event (agent_id + referrer ORIGIN only, no PII),\nthrottled in-process to once per (badge, referrer origin) per hour so a\nbusy README doesn't fire per pixel-load. The throttle is a lock-guarded\ndict lookup and the capture is fire-and-forget — the route stays cheap\nand keeps its 1h public Cache-Control. Not-found badges emit nothing.","operationId":"get_badge_api_v1_badges__agent_id__svg_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"style","in":"query","required":false,"schema":{"type":"string","pattern":"^(flat|flat-square)$","default":"flat","title":"Style"}},{"name":"metric","in":"query","required":false,"schema":{"type":"string","pattern":"^(composite|success_rate|reliability|elo)$","default":"composite","title":"Metric"}}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/regression-alerts":{"get":{"tags":["regression-alerts"],"summary":"List Regression Alerts","description":"List regression alerts for the current user.\n\nOptionally filter by agent_id. Returns paginated list of active and resolved alerts owned by the user.","operationId":"list_regression_alerts_api_v1_regression_alerts_get","parameters":[{"name":"agent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_RegressionAlertRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/regression-alerts/active":{"get":{"tags":["regression-alerts"],"summary":"Get Active Regression Alerts","description":"Get all unresolved regression alerts for the current user.\n\nReturns only alerts where resolved_at is NULL.\nIf no user is authenticated, returns empty list.","operationId":"get_active_regression_alerts_api_v1_regression_alerts_active_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_RegressionAlertRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/regression-alerts/{alert_id}/resolve":{"patch":{"tags":["regression-alerts"],"summary":"Resolve Regression Alert","description":"Mark a regression alert as resolved.\n\nSets resolved_at to the current timestamp.","operationId":"resolve_regression_alert_api_v1_regression_alerts__alert_id__resolve_patch","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Alert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegressionAlertRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks":{"post":{"tags":["webhooks"],"summary":"Create Webhook","description":"Create a new webhook subscription.","operationId":"create_webhook_api_v1_webhooks_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["webhooks"],"summary":"List Webhooks","description":"List all webhook subscriptions.","operationId":"list_webhooks_api_v1_webhooks_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/{webhook_id}":{"get":{"tags":["webhooks"],"summary":"Get Webhook","operationId":"get_webhook_api_v1_webhooks__webhook_id__get","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["webhooks"],"summary":"Update Webhook","description":"Update webhook settings.","operationId":"update_webhook_api_v1_webhooks__webhook_id__patch","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["webhooks"],"summary":"Delete Webhook","operationId":"delete_webhook_api_v1_webhooks__webhook_id__delete","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/{webhook_id}/test":{"post":{"tags":["webhooks"],"summary":"Test Webhook Endpoint","description":"Send a test ping to verify webhook connectivity.","operationId":"test_webhook_endpoint_api_v1_webhooks__webhook_id__test_post","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/{webhook_id}/deliveries":{"get":{"tags":["webhooks"],"summary":"List Webhook Deliveries","description":"Per-webhook delivery log, newest first.\n\nPowers the dashboard panel: full request body, response code/body,\nlatency, retry attempt number, and any transport error per attempt.","operationId":"list_webhook_deliveries_api_v1_webhooks__webhook_id__deliveries_get","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_WebhookDeliveryRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/resend":{"post":{"tags":["webhooks"],"summary":"Receive Resend Webhook","description":"Verify raw Svix bytes and fold one provider event into current state.","operationId":"receive_resend_webhook_api_v1_webhooks_resend_post","responses":{"204":{"description":"Successful Response"}}}},"/api/v1/teams":{"post":{"tags":["teams"],"summary":"Create Team","operationId":"create_team_api_v1_teams_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["teams"],"summary":"List Teams","operationId":"list_teams_api_v1_teams_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_TeamRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/invitations/preview":{"post":{"tags":["teams"],"summary":"Preview Invitation","operationId":"preview_invitation_api_v1_teams_invitations_preview_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInvitationAccept"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInvitationPreview"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/invitations/claim":{"post":{"tags":["teams"],"summary":"Claim Invitation","description":"Bind a presented token to this account so onboarding survives a new tab.\n\nThe raw token reaches the browser once, in a URL fragment, and lives in\n`sessionStorage`. A first-time invitee must verify their email before they\ncan accept, and their mail client opens that verification link in a NEW\ntab — which shares no `sessionStorage`. So the token was guaranteed to be\ngone at the moment it was needed. This records, server-side, that this\naccount held it, and lets the client drop the token immediately afterwards\nrather than parking a live 7-day bearer credential in browser storage.\n\nDeliberately does NOT require `email_verified`: the entire point is to land\nthe binding BEFORE the invitee leaves for their mailbox. It grants nothing\n— `accept_invitation` re-checks verification, account state, email match\nand the workspace plan under lock.\n\nTakes no Team lock and refuses nothing on the plan — a claim is a binding\nrather than a grant, so it needs neither, which keeps it out of the Team →\nInvitation ordering the rest of this file uses. It does REPORT, read-only and\nafter the commit, when accept would refuse for SSO below Enterprise (#1420,\nsecurity LOW-4): `refusal` in the answer, so the page says so before Join\nand names the workspace, which a 403 body would not carry.\n\nIt does lock `users[me]` FIRST, and that is not decoration. Writing\n`claimed_by_user_id` makes Postgres take a `FOR KEY SHARE` on that user row\nthrough the foreign key — so without this line the lock order here would be\nInvitation → User while `accept_invitation` takes Team → User → Invitation.\nSame user, two tabs (claim fires on page load, accept on click) and that is\na genuine cycle: `40P01`, one side 500s. SQLite has no row locks, so CI\nwould never have shown it. Taking the user row up front makes both paths\nacquire User before Invitation.","operationId":"claim_invitation_api_v1_teams_invitations_claim_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInvitationAccept"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamClaimedInvitationRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/invitations/pending":{"get":{"tags":["teams"],"summary":"List Pending Invitations","description":"Invitations this account claimed and can still act on.\n\nKeyed on `claimed_by_user_id`, never on the caller's email address. That\ndistinction is the whole authorization model: `users.email_verified` is a\nsingle mutable boolean with no record of WHICH address it was proved for\n(migration 043 backfilled every pre-existing row to true; GitHub sign-in\nre-points `users.email` and re-asserts the flag), so \"verified, and the\nstring matches\" is not proof of control of that mailbox. Listing on the\naddress alone would also turn every undeliverable invitation — bounced,\nsuppressed, or never sent at all because `RESEND_API_KEY` is unset — from\na grant nobody can redeem into one anybody at that address can.\n\nFiltered down to invitations that will actually accept, including the\nworkspace's plan, so the UI never offers a \"Join\" that 402s. An invitee\nwith nothing here is shown how to get a fresh link, not an error.\n\nNOT behind a feature flag: a flagged-off listing returns `[]`, which is\nindistinguishable from \"you have no invitations\" and would silently\nreproduce the dead end this endpoint exists to remove (CLAUDE.md rule 4).","operationId":"list_pending_invitations_api_v1_teams_invitations_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamPendingInvitationList"}}}}}}},"/api/v1/teams/invitations/accept":{"post":{"tags":["teams"],"summary":"Accept Invitation","operationId":"accept_invitation_api_v1_teams_invitations_accept_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInvitationRedeem"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamWithMembers"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}":{"patch":{"tags":["teams"],"summary":"Update Team","description":"Owner-only workspace settings. Today: audit-log retention (#1298).\n\nThe only settable field belongs to the audit log, so with\n``AUDIT_LOG_ENABLED`` off the route 404s rather than accepting a setting\nnothing would act on (rule #4).","operationId":"update_team_api_v1_teams__team_id__patch","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["teams"],"summary":"Get Team","operationId":"get_team_api_v1_teams__team_id__get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamWithMembers"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/analytics":{"get":{"tags":["teams"],"summary":"Get Team Analytics","description":"TEAM-003 W1-T1.1 — Owner analytics (absorbs IMPROVE-001 B3).\n\nRead-only aggregates computed from EXISTING data:\n  * per-member contribution (runs initiated, workspace agents registered,\n    Team Scorecards published),\n  * shared workspace-agent usage,\n  * seat + monthly-run cap utilization,\n  * provenance (real vs simulated) split on every run count + a 30-day\n    runs/day series — simulated (mock) activity must never read as real\n    performance (BRIEF-IMPROVE-002 §6/§10, mirrors the Talent Pool chips).\n\nGate: ``TeamPermission.VIEW_WORKSPACE_ANALYTICS`` (Owner + Admin). A member\nor viewer who lacks it gets 403; a non-member stays opaque with 404,\nmatching the cross-tenant existence-hiding posture of\n``require_team_permission``. The client cannot self-authorize — this\nendpoint is the real gate.\n\nEvery query below is a plain ``COUNT(*) … GROUP BY`` on indexed columns, so\nthe read runs identically on Postgres and the aiosqlite test path\n(CLAUDE.md rule #6). No cost is invented (no per-member cost, no LLM cost).","operationId":"get_team_analytics_api_v1_teams__team_id__analytics_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamAnalyticsRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/invitations":{"post":{"tags":["teams"],"summary":"Create Invitation","operationId":"create_invitation_api_v1_teams__team_id__invitations_post","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInvitationCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInvitationIssuedRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/invitations/{invitation_id}/resend":{"post":{"tags":["teams"],"summary":"Resend Invitation","operationId":"resend_invitation_api_v1_teams__team_id__invitations__invitation_id__resend_post","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"invitation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Invitation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInvitationIssuedRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/invitations/{invitation_id}":{"delete":{"tags":["teams"],"summary":"Cancel Invitation","operationId":"cancel_invitation_api_v1_teams__team_id__invitations__invitation_id__delete","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"invitation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Invitation Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/members":{"post":{"tags":["teams"],"summary":"Retired Immediate Member Creation","operationId":"retired_immediate_member_creation_api_v1_teams__team_id__members_post","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"410":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/members/{member_id}":{"patch":{"tags":["teams"],"summary":"Change Member Role","operationId":"change_member_role_api_v1_teams__team_id__members__member_id__patch","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"member_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Member Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMemberRoleUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMemberRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["teams"],"summary":"Remove Member","operationId":"remove_member_api_v1_teams__team_id__members__member_id__delete","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"member_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Member Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/audit-log":{"get":{"tags":["audit-log"],"summary":"List Audit Events","description":"Newest first. ``from`` inclusive, ``to`` exclusive.","operationId":"list_audit_events_api_v1_teams__team_id__audit_log_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Action"}},{"name":"actor_user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor User Id"}},{"name":"target_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Target Type"}},{"name":"target_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Target Id"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AuditEventRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/audit-log/export":{"get":{"tags":["audit-log"],"summary":"Export Audit Events","description":"Ascending ``seq``, 1,000-row chunks, no count query.\n\n``format=jsonl&include=checkpoints`` appends one line per signed\ncheckpoint (``\"record_type\": \"checkpoint\"``) after the events, so the\nreceipts travel with the export. CSV has no trailer: 422.\n\nThe export itself is recorded first and committed before streaming, so the\nchain-head lock is not held for the length of the download. Rows are\nbounded by the head as of that commit; later writes are not included.","operationId":"export_audit_events_api_v1_teams__team_id__audit_log_export_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"format","in":"query","required":false,"schema":{"enum":["csv","jsonl"],"type":"string","default":"csv","title":"Format"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Action"}},{"name":"actor_user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor User Id"}},{"name":"target_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Target Type"}},{"name":"target_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Target Id"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To"}},{"name":"include","in":"query","required":false,"schema":{"anyOf":[{"const":"checkpoints","type":"string"},{"type":"null"}],"title":"Include"}}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/audit-log/verify":{"get":{"tags":["audit-log"],"summary":"Verify Audit Chain","operationId":"verify_audit_chain_api_v1_teams__team_id__audit_log_verify_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditVerifyRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/audit-log/checkpoint":{"post":{"tags":["audit-log"],"summary":"Checkpoint Audit Chain","description":"Sign the current head. Returns the latest checkpoint if nothing changed.","operationId":"checkpoint_audit_chain_api_v1_teams__team_id__audit_log_checkpoint_post","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditCheckpointRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/audit-log/checkpoints":{"get":{"tags":["audit-log"],"summary":"List Audit Checkpoints","description":"Every signed checkpoint, ascending. Keep copies outside Badge: a\nreceipt held off-site is what detects a database owner rewriting history.","operationId":"list_audit_checkpoints_api_v1_teams__team_id__audit_log_checkpoints_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuditCheckpointRead"},"title":"Response List Audit Checkpoints Api V1 Teams  Team Id  Audit Log Checkpoints Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/audit-log/{event_id}/redact":{"post":{"tags":["audit-log"],"summary":"Redact Audit Event","description":"Replace one event's metadata with a tombstone; the chain stays valid.","operationId":"redact_audit_event_api_v1_teams__team_id__audit_log__event_id__redact_post","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEventRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/status":{"get":{"tags":["sso"],"summary":"Sso Status","operationId":"sso_status_api_v1_auth_sso_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoStatusRead"}}}}}}},"/api/v1/auth/sso/discover":{"get":{"tags":["sso"],"summary":"Discover Sso","description":"Which workspace signs in addresses on ``domain``.\n\nTakes the domain, not the email: the query string lands in access logs,\nand the local part is nobody's business here. Reveals only that a domain\nuses SSO, and which provider.","operationId":"discover_sso_api_v1_auth_sso_discover_get","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":253,"title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoDiscoverRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/sso":{"get":{"tags":["sso"],"summary":"Get Team Sso","operationId":"get_team_sso_api_v1_teams__team_id__sso_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoConfigRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["sso"],"summary":"Put Team Sso","description":"Replace the workspace's SSO configuration. Owner only, Enterprise only.\n\nBelow Enterprise, a configured workspace accepts only exposure-reducing\nedits (``_exposure_increase``, #1420).","operationId":"put_team_sso_api_v1_teams__team_id__sso_put","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoConfigUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoConfigRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["sso"],"summary":"Delete Team Sso","description":"Turn SSO off for the workspace (PRD-011 FR-07 rollback path).\n\nNo plan check: an owner whose subscription lapsed must still be able to\nswitch SSO off. Identity links are kept, so turning SSO back on with the\nsame IdP needs no re-linking.","operationId":"delete_team_sso_api_v1_teams__team_id__sso_delete","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/sso/domains/{domain}/verify":{"post":{"tags":["sso"],"summary":"Verify Team Sso Domain","description":"Prove a claimed domain by its DNS TXT record (security F1).\n\nOwner only, Enterprise plan, in the auth rate bucket. 409 (readable) when the\nrecord is not there yet; the claim stays pending.","operationId":"verify_team_sso_domain_api_v1_teams__team_id__sso_domains__domain__verify_post","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoConfigRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/pending":{"get":{"tags":["sso"],"summary":"Get Sso Pending","description":"What the consent page shows. Only the browser holding the cookie gets an answer.","operationId":"get_sso_pending_api_v1_auth_sso_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoPendingRead"}}}}}}},"/api/v1/auth/sso/pending/confirm":{"post":{"tags":["sso"],"summary":"Confirm Sso Pending","description":"Consent with the account's current password, then sign in (#1393).","operationId":"confirm_sso_pending_api_v1_auth_sso_pending_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoPendingConfirm"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/pending/cancel":{"post":{"tags":["sso"],"summary":"Cancel Sso Pending","description":"Drop the pending hand-off (\"Not now\"). Nothing is linked.","operationId":"cancel_sso_pending_api_v1_auth_sso_pending_cancel_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoPendingCancel"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/sso/pending/github":{"get":{"tags":["sso"],"summary":"Github Consent Start","description":"Consent by signing in with GitHub: a GitHub OAuth round bound to this link.\n\nThe GitHub state marker carries ``sha256(pending cookie)``, and the GitHub\nstate cookie binds the round to this browser, so the callback can finish\nonly the link this browser was shown.","operationId":"github_consent_start_api_v1_auth_sso_pending_github_get","parameters":[{"name":"csrf","in":"query","required":false,"schema":{"type":"string","maxLength":128,"default":"","title":"Csrf"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/saml/{team_id}/metadata":{"get":{"tags":["sso"],"summary":"Saml Metadata","description":"SP metadata for the IdP admin. Public: it carries no secret.","operationId":"saml_metadata_api_v1_auth_saml__team_id__metadata_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/saml/{team_id}/login":{"get":{"tags":["sso"],"summary":"Saml Login","operationId":"saml_login_api_v1_auth_saml__team_id__login_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/saml/{team_id}/acs":{"post":{"tags":["sso"],"summary":"Saml Acs","description":"Assertion Consumer Service (HTTP-POST binding).","operationId":"saml_acs_api_v1_auth_saml__team_id__acs_post","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/google-sso":{"get":{"tags":["sso"],"summary":"Google Sso Start","operationId":"google_sso_start_api_v1_auth_google_sso_get","parameters":[{"name":"team_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/google-sso/callback":{"get":{"tags":["sso"],"summary":"Google Sso Callback","operationId":"google_sso_callback_api_v1_auth_google_sso_callback_get","parameters":[{"name":"code","in":"query","required":false,"schema":{"type":"string","default":"","title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"","title":"State"}},{"name":"error","in":"query","required":false,"schema":{"type":"string","default":"","title":"Error"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/approval-policy":{"get":{"tags":["approvals"],"summary":"Get Approval Policy","operationId":"get_approval_policy_api_v1_teams__team_id__approval_policy_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalPolicyRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["approvals"],"summary":"Put Approval Policy","description":"Replace the policy. ``?dry_run=true`` only reports which standing approvals the\nnew policy would end (``would_revoke`` / ``affected``) and writes nothing.","operationId":"put_approval_policy_api_v1_teams__team_id__approval_policy_put","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Dry Run"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalPolicyWrite"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ApprovalPolicySaved"},{"$ref":"#/components/schemas/PolicyDryRun"}],"title":"Response Put Approval Policy Api V1 Teams  Team Id  Approval Policy Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/approval-policy/suites":{"get":{"tags":["approvals"],"summary":"Approval Policy Suites","description":"Suites this workspace's agents have run: what ``required_suite_ids`` may name.","operationId":"approval_policy_suites_api_v1_teams__team_id__approval_policy_suites_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SuiteOption"},"title":"Response Approval Policy Suites Api V1 Teams  Team Id  Approval Policy Suites Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/approvals/access":{"get":{"tags":["approvals"],"summary":"Approvals Access","description":"What this caller may do, from their role and the policy's ``approver_roles``,\nso the UI never guesses from role names. A lapsed workspace plan withholds actions.","operationId":"approvals_access_api_v1_teams__team_id__approvals_access_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalAccess"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/approvals":{"get":{"tags":["approvals"],"summary":"Approval Queue","operationId":"approval_queue_api_v1_teams__team_id__approvals_get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/approvals":{"post":{"tags":["approvals"],"summary":"Request Approval","operationId":"request_approval_api_v1_agents__agent_id__approvals_post","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["approvals"],"summary":"Approval History","operationId":"approval_history_api_v1_agents__agent_id__approvals_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/approvals/current":{"get":{"tags":["approvals"],"summary":"Current Agent Approval","description":"Members get the full record, or ``200 {\"status\": \"none\"}`` (so an agent page\nnever logs a console 404); everyone else, on a PUBLIC agent only, gets the\nbounded record or a 404.","operationId":"current_agent_approval_api_v1_agents__agent_id__approvals_current_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ApprovalRead"},{"$ref":"#/components/schemas/PublicApproval"},{"$ref":"#/components/schemas/NoCurrentApproval"}],"title":"Response Current Agent Approval Api V1 Agents  Agent Id  Approvals Current Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/approvals/{approval_id}/approve":{"post":{"tags":["approvals"],"summary":"Approve Request","operationId":"approve_request_api_v1_approvals__approval_id__approve_post","parameters":[{"name":"approval_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Approval Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DecisionComment"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/approvals/{approval_id}/reject":{"post":{"tags":["approvals"],"summary":"Reject Request","operationId":"reject_request_api_v1_approvals__approval_id__reject_post","parameters":[{"name":"approval_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Approval Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequiredComment"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/approvals/{approval_id}/revoke":{"post":{"tags":["approvals"],"summary":"Revoke Request","operationId":"revoke_request_api_v1_approvals__approval_id__revoke_post","parameters":[{"name":"approval_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Approval Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/suites":{"get":{"tags":["marketplace"],"summary":"List Suites","description":"List benchmark suites with filtering and pagination.\n\nQuery parameters:\n- domain: Filter by domain (code_generation, data_extraction, tool_use, customer_support, rag, research, writing, reasoning, custom)\n- difficulty: Filter by difficulty (easy, medium, hard, mixed)\n- search: Search in name and description\n- featured_only: Only show featured suites\n- sort_by: Sort by \"newest\", \"popular\" (downloads), or \"rating\"","operationId":"list_suites_api_v1_marketplace_suites_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by domain","title":"Domain"},"description":"Filter by domain"},{"name":"difficulty","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by difficulty","title":"Difficulty"},"description":"Filter by difficulty"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"featured_only","in":"query","required":false,"schema":{"type":"boolean","description":"Show only featured suites","default":false,"title":"Featured Only"},"description":"Show only featured suites"},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","description":"Sort order: newest, popular, or rating","default":"newest","title":"Sort By"},"description":"Sort order: newest, popular, or rating"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_BenchmarkSuiteRead_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["marketplace"],"summary":"Create Suite","description":"Create a platform-global benchmark suite (admin only).","operationId":"create_suite_api_v1_marketplace_suites_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BenchmarkSuiteCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BenchmarkSuiteWithTasks"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/suites/{suite_id}":{"get":{"tags":["marketplace"],"summary":"Get Suite","description":"Get a single suite with all its task IDs.","operationId":"get_suite_api_v1_marketplace_suites__suite_id__get","parameters":[{"name":"suite_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Suite Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BenchmarkSuiteWithTasks"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/suites/{suite_id}/install":{"post":{"tags":["marketplace"],"summary":"Install Suite","description":"Install a benchmark suite for the authenticated user.","operationId":"install_suite_api_v1_marketplace_suites__suite_id__install_post","parameters":[{"name":"suite_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Suite Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BenchmarkSuiteWithTasks"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/marketplace/installed":{"get":{"tags":["marketplace"],"summary":"List Installed Suites","description":"List all suites installed by the authenticated user.","operationId":"list_installed_suites_api_v1_marketplace_installed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BenchmarkSuiteRead"},"type":"array","title":"Response List Installed Suites Api V1 Marketplace Installed Get"}}}}}}},"/api/v1/marketplace/suites/{suite_id}/uninstall":{"delete":{"tags":["marketplace"],"summary":"Uninstall Suite","description":"Remove a suite installation for the authenticated user.","operationId":"uninstall_suite_api_v1_marketplace_suites__suite_id__uninstall_delete","parameters":[{"name":"suite_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Suite Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/og/leaderboard.png":{"get":{"tags":["og"],"summary":"Og Leaderboard","description":"OG image for the leaderboard. Includes live agent count.","operationId":"og_leaderboard_api_v1_og_leaderboard_png_get","parameters":[{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`png` (default) | `svg`","title":"Format"},"description":"`png` (default) | `svg`"}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/og/home.png":{"get":{"tags":["og"],"summary":"Og Home","operationId":"og_home_api_v1_og_home_png_get","parameters":[{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`png` (default) | `svg`","title":"Format"},"description":"`png` (default) | `svg`"}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/og/agent/{agent_id}.png":{"get":{"tags":["og"],"summary":"Og Agent","description":"OG image for an agent profile. Shows composite + rank + sparkline.","operationId":"og_agent_api_v1_og_agent__agent_id__png_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"w","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"PRD-010 FR-12 — compact 5-tuple weight override matching the frontend URL-hash format, e.g. `40,30,10,10,10`. Order: correctness, latency, cost, tool, robustness. When supplied and the v2 flag is on, the rendered composite score reflects these weights and a `WEIGHTS` pill appears on the card.","title":"W"},"description":"PRD-010 FR-12 — compact 5-tuple weight override matching the frontend URL-hash format, e.g. `40,30,10,10,10`. Order: correctness, latency, cost, tool, robustness. When supplied and the v2 flag is on, the rendered composite score reflects these weights and a `WEIGHTS` pill appears on the card."},{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`png` (default) | `svg`","title":"Format"},"description":"`png` (default) | `svg`"}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/og/run/{run_id}.png":{"get":{"tags":["og"],"summary":"Og Run","description":"OG image for a single run. Respects agent.is_public — private runs\nfall back to a generic card so we don't leak their existence via a\nrich social preview.","operationId":"og_run_api_v1_og_run__run_id__png_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}},{"name":"w","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"PRD-010 FR-12 — compact weight tuple `40,30,10,10,10`. When set and the v2 flag is on, the card's score reflects the weighted composite for the agent (the per-task `Score` row is left alone — we recompute on the fly).","title":"W"},"description":"PRD-010 FR-12 — compact weight tuple `40,30,10,10,10`. When set and the v2 flag is on, the card's score reflects the weighted composite for the agent (the per-task `Score` row is left alone — we recompute on the fly)."},{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`png` (default) | `svg`","title":"Format"},"description":"`png` (default) | `svg`"}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/digest/send-weekly":{"post":{"tags":["digest"],"summary":"Send Weekly Digests","description":"Cron-targeted weekly digest fan-out.\n\nAuth: shared-secret header (X-Internal-Key == settings.SECRET_KEY).\nThis is the contract the existing cron job ships with — do not\nchange it without bumping the cron config in deploy.","operationId":"send_weekly_digests_api_v1_digest_send_weekly_post","parameters":[{"name":"X-Internal-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Internal-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Send Weekly Digests Api V1 Digest Send Weekly Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/digest/send/{user_id}":{"post":{"tags":["digest"],"summary":"Send Digest To One User","description":"Admin one-shot: send this user's digest immediately.\n\nHonors the user's notify_weekly_digest opt-out — admins should not\nhave a back-door past consent. If the user has no activity in the\nwindow we still skip (matches the cron behavior).","operationId":"send_digest_to_one_user_api_v1_digest_send__user_id__post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Send Digest To One User Api V1 Digest Send  User Id  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/digest/preview/{user_id}":{"get":{"tags":["digest"],"summary":"Preview Digest For User","description":"Compute what next Monday's digest would say without sending.\n\nReturns the rendered stats dict + flags so admins can pre-review\ntemplate output during a copy change. No email is dispatched —\nuse POST /digest/send/{user_id} for that.","operationId":"preview_digest_for_user_api_v1_digest_preview__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Preview Digest For User Api V1 Digest Preview  User Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/fitness":{"get":{"tags":["insights"],"summary":"Get Agent Fitness","description":"5-axis fitness snapshot for the agent. PRD-004 FR-01 + PRD-010 FR-01..FR-03.\n\nEach axis returns 0-100 (higher = better) or null when not computable.\n`composite_score` is the weighted average — defaults to equal weights\n(PRD-004 v1) unless `weights=` or `preset_id=` is supplied (PRD-010).\nRaw underlying values are also returned for tooltip display.","operationId":"get_agent_fitness_api_v1_agents__agent_id__fitness_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"weights","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional 5-axis weight override (PRD-010). Format: `correctness:30,latency:25,cost:15,tool:10,robustness:20`. Sum must be 99..101. Mutually exclusive with `preset_id`.","title":"Weights"},"description":"Optional 5-axis weight override (PRD-010). Format: `correctness:30,latency:25,cost:15,tool:10,robustness:20`. Sum must be 99..101. Mutually exclusive with `preset_id`."},{"name":"preset_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Optional preset id to apply (PRD-010). Caller must own the preset; otherwise 404. Mutually exclusive with `weights`.","title":"Preset Id"},"description":"Optional preset id to apply (PRD-010). Caller must own the preset; otherwise 404. Mutually exclusive with `weights`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Agent Fitness Api V1 Agents  Agent Id  Fitness Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/drift":{"get":{"tags":["insights"],"summary":"Get Agent Drift","description":"Daily-bucketed pass-rate / latency / cost trajectory. PRD-005 FR-01.","operationId":"get_agent_drift_api_v1_agents__agent_id__drift_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}},{"name":"window","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Window in days","default":30,"title":"Window"},"description":"Window in days"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Agent Drift Api V1 Agents  Agent Id  Drift Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/failures":{"get":{"tags":["insights"],"summary":"Get Agent Failures","description":"Top failure clusters for the agent's last 100 runs. PRD-006 FR-04.\n\nReturns up to 5 clusters sorted by count desc. Each cluster includes a\nrepresentative run id (the most recent failed run in that cluster) and\na sample reason snippet for the UI.","operationId":"get_agent_failures_api_v1_agents__agent_id__failures_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Agent Failures Api V1 Agents  Agent Id  Failures Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/setup/frameworks":{"get":{"tags":["integrations"],"summary":"List Frameworks","description":"List all supported frameworks with basic info.","operationId":"list_frameworks_api_v1_integrations_setup_frameworks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/FrameworkListItem"},"type":"array","title":"Response List Frameworks Api V1 Integrations Setup Frameworks Get"}}}}}}},"/api/v1/integrations/setup/{framework}":{"get":{"tags":["integrations"],"summary":"Get Setup Guide","description":"Get the complete setup guide for a specific framework.","operationId":"get_setup_guide_api_v1_integrations_setup__framework__get","parameters":[{"name":"framework","in":"path","required":true,"schema":{"type":"string","title":"Framework"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrameworkSetup"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/agent-test-ping":{"post":{"tags":["integrations"],"summary":"Test Agent Ping","description":"BRIEF-001 §6 IN-2 — canary request against a candidate agent endpoint.\n\nPosts one synthetic payload (shape: ``payload.payload_schema``) to the\nURL the customer typed into the connect form. Returns request + verbatim\nresponse + typed result class. The customer reads the response inline\nto fix auth / shape mismatches BEFORE committing to a full benchmark\nrun.\n\nAuth-required: prosumers wire this against their own infrastructure,\nnot the public internet from an anonymous caller. The SSRF gate is\nthe same `resolve_public_url` + `pinned_request_kwargs` pattern used\nby `/test-connection` and `arena._call_agent_endpoint` so a malicious\nendpoint string can't reach 169.254.169.254 or 127.0.0.1.","operationId":"test_agent_ping_api_v1_integrations_agent_test_ping_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestPingRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestPingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/test-connection":{"post":{"tags":["integrations"],"summary":"Test Connection","description":"Test connection to an agent endpoint by POSTing the same canary shape\nreal screening dispatch uses, and verify it responds with valid JSON.\n\nPROD-DEFECT-1 — the probe now mirrors `arena._call_agent_endpoint`\nexactly: same HTTP method (POST), same SSRF-pinned dispatch, same\nbadge_native wire shape. A customer who followed the docs and built a\nPOST-only handler no longer gets a false-negative 405 here.","operationId":"test_connection_api_v1_integrations_test_connection_post","parameters":[{"name":"endpoint","in":"query","required":true,"schema":{"type":"string","description":"The endpoint URL to test","title":"Endpoint"},"description":"The endpoint URL to test"},{"name":"framework","in":"query","required":false,"schema":{"type":"string","description":"The framework type. One of the known frameworks (langchain, crewai, …) or a generic label (custom/generic/http/endpoint) for a framework-agnostic endpoint test.","default":"custom","title":"Framework"},"description":"The framework type. One of the known frameworks (langchain, crewai, …) or a generic label (custom/generic/http/endpoint) for a framework-agnostic endpoint test."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Test Connection Api V1 Integrations Test Connection Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations":{"get":{"tags":["integrations"],"summary":"List Integrations","description":"List all integrations configured by the current user.","operationId":"list_integrations_api_v1_integrations_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/IntegrationRead"},"type":"array","title":"Response List Integrations Api V1 Integrations Get"}}}}}},"post":{"tags":["integrations"],"summary":"Create Integration","description":"Create a new integration configuration for the current user.","operationId":"create_integration_api_v1_integrations_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/{integration_id}":{"get":{"tags":["integrations"],"summary":"Get Integration","description":"Get a single integration by ID (must be owned by current user).","operationId":"get_integration_api_v1_integrations__integration_id__get","parameters":[{"name":"integration_id","in":"path","required":true,"schema":{"type":"string","title":"Integration Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["integrations"],"summary":"Update Integration","description":"Update an integration configuration.","operationId":"update_integration_api_v1_integrations__integration_id__patch","parameters":[{"name":"integration_id","in":"path","required":true,"schema":{"type":"string","title":"Integration Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["integrations"],"summary":"Delete Integration","description":"Delete an integration configuration.","operationId":"delete_integration_api_v1_integrations__integration_id__delete","parameters":[{"name":"integration_id","in":"path","required":true,"schema":{"type":"string","title":"Integration Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integrations/{integration_id}/test":{"post":{"tags":["integrations"],"summary":"Test Integration Connection","description":"Test the connection for an integration.\n\nAttempts to ping the webhook URL or perform a framework-specific health check.","operationId":"test_integration_connection_api_v1_integrations__integration_id__test_post","parameters":[{"name":"integration_id","in":"path","required":true,"schema":{"type":"string","title":"Integration Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/IntegrationTestRequest"},{"type":"null"}],"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationTestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/models/pricing":{"get":{"tags":["pricing"],"summary":"List Model Pricing","description":"List all model pricing entries, optionally filtered by provider.","operationId":"list_model_pricing_api_v1_models_pricing_get","parameters":[{"name":"provider","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by provider","title":"Provider"},"description":"Filter by provider"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ModelPricingRead"},"title":"Response List Model Pricing Api V1 Models Pricing Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/models/pricing/{model_name}":{"get":{"tags":["pricing"],"summary":"Get Model Pricing","description":"Get pricing for a specific model.","operationId":"get_model_pricing_api_v1_models_pricing__model_name__get","parameters":[{"name":"model_name","in":"path","required":true,"schema":{"type":"string","title":"Model Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelPricingRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/profiles/{username}":{"get":{"tags":["profiles"],"summary":"Get Public Profile","description":"Return a public profile page payload for `username` (case-insensitive).\n\n404 if the user doesn't exist, is inactive, or has no username set.","operationId":"get_public_profile_api_v1_profiles__username__get","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProfile"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/seo/sitemap-data":{"get":{"tags":["seo"],"summary":"Get Sitemap Data","description":"Full sitemap payload for the Next.js ``app/sitemap.ts`` generator.\n\nStays 200 regardless of the flag so the frontend's sitemap route never\nsees a 5xx — it just renders the static stub when feature_enabled=False.","operationId":"get_sitemap_data_api_v1_seo_sitemap_data_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SitemapDataResponse"}}}}}}},"/api/v1/seo/talent-pool":{"get":{"tags":["seo"],"summary":"Talent Pool Root","description":"Top-N public agents across all domains. Always indexable (FR-01).","operationId":"talent_pool_root_api_v1_seo_talent_pool_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TalentPoolPageData"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/seo/talent-pool/family/{family}":{"get":{"tags":["seo"],"summary":"Talent Pool By Model Family","description":"Top-N public agents in a model-family segment (RES-014-B). Flag-gated.","operationId":"talent_pool_by_model_family_api_v1_seo_talent_pool_family__family__get","parameters":[{"name":"family","in":"path","required":true,"schema":{"type":"string","title":"Family"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AxisSegmentPageData"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/seo/talent-pool/cost/{tier}":{"get":{"tags":["seo"],"summary":"Talent Pool By Cost Tier","description":"Top-N public agents in a cost-tier segment (RES-014-B). Flag-gated.","operationId":"talent_pool_by_cost_tier_api_v1_seo_talent_pool_cost__tier__get","parameters":[{"name":"tier","in":"path","required":true,"schema":{"type":"string","title":"Tier"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AxisSegmentPageData"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/seo/talent-pool/{domain_slug}":{"get":{"tags":["seo"],"summary":"Talent Pool By Domain","operationId":"talent_pool_by_domain_api_v1_seo_talent_pool__domain_slug__get","parameters":[{"name":"domain_slug","in":"path","required":true,"schema":{"type":"string","title":"Domain Slug"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TalentPoolPageData"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/seo/talent-pool/{domain_slug}/{difficulty_slug}":{"get":{"tags":["seo"],"summary":"Talent Pool By Domain Difficulty","operationId":"talent_pool_by_domain_difficulty_api_v1_seo_talent_pool__domain_slug___difficulty_slug__get","parameters":[{"name":"domain_slug","in":"path","required":true,"schema":{"type":"string","title":"Domain Slug"}},{"name":"difficulty_slug","in":"path","required":true,"schema":{"type":"string","title":"Difficulty Slug"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TalentPoolPageData"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/seo/compare/{slug}":{"get":{"tags":["seo"],"summary":"Compare Pair","description":"Resolve a ``<a>-vs-<b>`` slug into both agents' SEO payloads.\n\nIf the requested ordering isn't canonical (alphabetical-first), the\nresponse includes ``redirect_to`` so the Next.js page returns a 301\ninstead of indexing two URLs (FR-10).","operationId":"compare_pair_api_v1_seo_compare__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComparePageData"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/seo/agents/{agent_id}/jsonld":{"get":{"tags":["seo"],"summary":"Agent Jsonld","description":"Schema.org SoftwareApplication payload for one indexable agent.","operationId":"agent_jsonld_api_v1_seo_agents__agent_id__jsonld_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentJsonLd"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/seo/robots-config":{"get":{"tags":["seo"],"summary":"Robots Config","description":"Single source of truth for the robots.txt allow/disallow lists.\n\nThe Next.js ``app/robots.ts`` route fetches this and serialises. Keeping\nthe rules server-side means we can flip them without a frontend deploy.","operationId":"robots_config_api_v1_seo_robots_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/me/radar-weights":{"get":{"tags":["radar-weights"],"summary":"List my radar weight presets","operationId":"list_presets_api_v1_me_radar_weights_get","parameters":[{"name":"scope","in":"query","required":false,"schema":{"enum":["user","workspace","all"],"type":"string","description":"Filter by ownership scope. 'user' returns only the caller's personal presets (PRD-010 default). 'workspace' requires team_id and returns the team-shared shelf. 'all' returns personal + every workspace-shared preset visible to the caller.","default":"user","title":"Scope"},"description":"Filter by ownership scope. 'user' returns only the caller's personal presets (PRD-010 default). 'workspace' requires team_id and returns the team-shared shelf. 'all' returns personal + every workspace-shared preset visible to the caller."},{"name":"team_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Presets Api V1 Me Radar Weights Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["radar-weights"],"summary":"Create a preset","operationId":"create_preset_api_v1_me_radar_weights_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresetCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Preset Api V1 Me Radar Weights Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/radar-weights/{preset_id}":{"patch":{"tags":["radar-weights"],"summary":"Update a preset","operationId":"update_preset_api_v1_me_radar_weights__preset_id__patch","parameters":[{"name":"preset_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Preset Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresetUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Preset Api V1 Me Radar Weights  Preset Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["radar-weights"],"summary":"Delete a preset","operationId":"delete_preset_api_v1_me_radar_weights__preset_id__delete","parameters":[{"name":"preset_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Preset Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/radar-weights/{preset_id}/promote-default":{"post":{"tags":["radar-weights"],"summary":"Promote a preset to be the user's default","operationId":"promote_default_api_v1_me_radar_weights__preset_id__promote_default_post","parameters":[{"name":"preset_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Preset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Promote Default Api V1 Me Radar Weights  Preset Id  Promote Default Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/observability/healthz":{"get":{"tags":["observability"],"summary":"Admin-only diagnostic for observability wiring (PostHog + Sentry)","description":"Report PostHog + Sentry wiring status for post-deploy verification.\n\nReturns:\n    ``{\"posthog\": {\"initialized\": bool, \"host\": str, \"key_prefix\": str | None,\n                   \"last_capture_ts\": str | None, \"last_capture_event\": str | None},\n       \"sentry\": {\"dsn_set\": bool}}``\n\nAuthorization: requires the caller's email to appear in ``ADMIN_EMAILS``.\n401 for unauthenticated, 403 for authenticated non-admin.\n\nThe ``last_capture_*`` fields are process-local — they reflect the most\nrecent successful enqueue in *this* worker. In a multi-worker prod\npod, expect them to lag and vary between requests; that's fine for\n\"is anything firing at all?\" verification.","operationId":"observability_healthz_api_v1_observability_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Observability Healthz Api V1 Observability Healthz Get"}}}}}}},"/api/v1/observability/funnel-baseline":{"get":{"tags":["observability"],"summary":"Admin-only diagnostic for the signup funnel (BRIEF-LP-000)","description":"Report 24h signup-funnel counts for post-deploy verification.\n\nBRIEF-LP-000 §6.5 / AC-LP0-03 — answers the question \"is the\nsignup_started → signup_completed wiring live in this process?\"\nwithout requiring a PostHog API key at runtime.\n\nReturns:\n    ``{\"signup_started_24h\": int,\n       \"signup_completed_24h\": int,\n       \"ratio\": float | None,\n       \"events_fully_instrumented\": bool}``\n\nAuthorization: requires the caller's email to appear in ``ADMIN_EMAILS``.\n401 for unauthenticated, 403 for authenticated non-admin.\n\nTrade-off (BRIEF §6.5 OQ #1): this endpoint reads a PER-WORKER,\nPER-PROCESS in-memory counter. Counts RESET on container restart and\ndo NOT aggregate across worker pods. For wiring verification (\"did the\ncode path fire at all in this process in the last 24h?\") that's the\nright signal. For precise PostHog-truth windowing, swap to a HogQL\nbackend in a follow-up — see BRIEF-LP-000 §6 \"Deferred to dev\" and\nOQ #1 in §9.","operationId":"funnel_baseline_api_v1_observability_funnel_baseline_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Funnel Baseline Api V1 Observability Funnel Baseline Get"}}}}}}},"/api/v1/admin/tasks":{"post":{"tags":["admin"],"summary":"PRD-023A — idempotent, audited admin catalog-task creation","description":"Create one catalog task without duplicate or unaudited writes.\n\nA response-lost retry presents the same idempotency UUID and receives the\nexisting metadata-only response. The task row and ADMIN_TASK_CREATED audit\nrow flush and commit in one transaction. Audit failure raises before the\ncommit, so request-session teardown rolls the task back.\n\nNeither response nor audit detail contains description, prompt, or grading\nanswer. Anonymous → 401, non-admin → 403, dashboard flag off → 404.","operationId":"admin_create_task_api_v1_admin_tasks_post","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"description":"One UUID per deliberate create attempt.","title":"Idempotency-Key"},"description":"One UUID per deliberate create attempt."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTaskCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTaskCreateResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/kpis":{"get":{"tags":["admin"],"summary":"Admin KPI dashboard — operator KPIs for observability (BRIEF-ADMIN-001)","description":"Return the operator KPI payload.\n\nArgs:\n    force_refresh: When ``true``, bypass the 5-minute in-process\n        cache and recompute every tile against live data. Used\n        sparingly — repeated force_refresh hits hurt warm-cache\n        latency for everyone.\n\nAuthorization:\n    - Anonymous → 401 (handled by the auth dep)\n    - Authenticated non-admin → 403 (handled by `require_admin`)\n    - Admin → 200\n\nPrivacy (CV §10 / AC-ADMIN-07):\n    Aggregates and counts ONLY. No customer email, agent name,\n    user-id, or per-user drill-down. The Sentry tile is a count\n    with a link-out; no rendered issue titles or stack traces.\n    Per-user filter parameters are NOT accepted and the route\n    does NOT expose them in OpenAPI.\n\nFlag gate (rule #4):\n    When ``ADMIN_DASHBOARD_ENABLED`` is false (prod default), the\n    endpoint returns 404. Independent of `ADMIN_EMAILS` — the\n    flag controls *existence*, the email list controls *access*.\n\nResponse shape:\n    {\n      \"computed_at\": \"<ISO8601 UTC>\",\n      \"ttl_seconds\": 300,\n      \"cached\": bool,\n      \"kpis\": [\n        {\"id\": \"total_users\", \"label\": \"Total users\",\n         \"available\": true, \"value\": 42, \"unit\": \"count\"},\n        ...\n      ]\n    }","operationId":"admin_kpis_api_v1_admin_kpis_get","parameters":[{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force Refresh"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Kpis Api V1 Admin Kpis Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/stripe-webhook-diagnostic":{"get":{"tags":["admin"],"summary":"#914/#871 — read-only LIVE webhook config check (Pillar 3 decisive gate)","description":"Report whether the Stripe webhook config can actually promote a payer.\n\nRead-only: one ``GET /v1/webhook_endpoints``; no mutation, no secret\nmaterial returned. Covers founder checks 1+2 from #871 (endpoint\nexists/enabled at the Badge path; both promotion events subscribed).\nChecks 3 (signing-secret match) and 4 (customer receipt email) are not\nAPI-readable and remain the manual dashboard checklist.\n\nAuthorization:\n    - Anonymous → 401 (auth dep) · non-admin → 403 (``require_admin``)\n    - Dashboard flag off → 404 (same posture as the other admin tiles)","operationId":"admin_stripe_webhook_diagnostic_api_v1_admin_stripe_webhook_diagnostic_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Stripe Webhook Diagnostic Api V1 Admin Stripe Webhook Diagnostic Get"}}}}}}},"/api/v1/admin/runtime-memory":{"get":{"tags":["admin"],"summary":"#1231 — backend container memory cgroup, OOM-kill count and per-process RSS","description":"Report the backend container's memory headroom without SSH.\n\nRead-only: reads ``/sys/fs/cgroup/memory.{current,max,events}`` and each\nprocess's ``/proc/<pid>/status`` (inside the container's PID namespace).\n``oom_kill_count`` is cumulative for the container's lifetime, so a rising\nvalue between two calls means the kernel is killing workers. Numbers,\nprocess names and pids only — no command lines or environment.\n\nAuthorization:\n    - Anonymous → 401 (auth dep) · non-admin → 403 (``require_admin``)\n    - Dashboard flag off → 404 (same posture as the other admin tiles)","operationId":"admin_runtime_memory_api_v1_admin_runtime_memory_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Runtime Memory Api V1 Admin Runtime Memory Get"}}}}}}},"/api/v1/admin/systems":{"get":{"tags":["admin"],"summary":"ADMIN-OPS-002 — systems registry: every external/infra dependency + honest status","description":"Return the curated systems registry with live-computed status.\n\nADMIN-OPS-002. The operator's \"is everything wired?\" answer on one\nscreen: backend API, database, redis, cert-signing, backups, Sentry,\nPostHog, email, Stripe, Hetzner, GitHub, DNS, support mailbox.\n\nRead-only — no mutation, no audit row (nothing changes). Reuses the same\nlive probes as GET /health/dependencies (DB SELECT 1, Redis PING) rather\nthan inventing a second health path.\n\nHONESTY (the point of this surface):\n    - \"ok\" only when we actually probed it live this request (backend,\n      DB, Redis).\n    - \"configured\" reflects safe configuration presence or current\n      declarative proof for services we can't ping (Sentry, PostHog,\n      Resend, Stripe, WireGuard); \"not_configured\" means the required\n      configuration/posture declaration is absent.\n    - \"unknown\" for posture this API cannot independently verify\n      (Hetzner, GitHub, DNS, the GH-Actions-scoped backup workflow, the\n      support mailbox, the frontend web app, and declaration-only controls\n      such as the WireGuard deployment plane).\n\nSECRET SAFETY: the response contains ONLY booleans + public labels. No\nDSN / API key / connection string value is ever emitted (see\n`services/admin_systems.py`).\n\nAuthorization:\n    - Anonymous → 401 (auth dep on ``require_admin``).\n    - Authenticated non-admin → 403 (``require_admin``).\n    - Admin (email in ``ADMIN_EMAILS``) → 200.\n\nFlag gate (rule #4): 404 when ``ADMIN_DASHBOARD_ENABLED`` is off, so the\nwhole ``/admin/*`` surface stays uniformly gated.\n\nResponse shape:\n    {\n      \"computed_at\": \"<ISO8601 UTC>\",\n      \"environment\": \"<env>\",\n      \"version\": \"<app version>\",\n      \"categories\": [\"frontend\", \"backend\", \"data\", ...],\n      \"systems\": [\n        {\"id\": \"database\", \"name\": \"Database\", \"category\": \"data\",\n         \"provider\": \"Neon serverless Postgres (EU · Frankfurt)\",\n         \"status\": \"ok\", \"status_detail\": \"...\",\n         \"metrics\": [{\"label\": \"Reachable\", \"value\": \"yes\"}, ...],\n         \"dashboard_url\": \"https://console.neon.tech\",\n         \"runbook_url\": \"https://github.com/.../RUNBOOK-postgres.md\",\n         \"description\": \"...\"},\n        ...\n      ]\n    }","operationId":"admin_systems_api_v1_admin_systems_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Systems Api V1 Admin Systems Get"}}}}}}},"/api/v1/admin/bpp-policing":{"get":{"tags":["admin"],"summary":"BPP-001 W5-T2 — price-performance anomaly worklist (admin-only advisory surface)","description":"Return the price-performance anomaly worklist.\n\nADVISORY ONLY (RES-017 §3.5 GhostPrint caveat — \"triage, not verdicts\").\nAn anomaly here never failed, hid, revoked, or downgraded anything; it is\nsurfaced for an OPERATOR to investigate, not auto-enforced. NOT shown on\nthe public Talent Pool board in this wave (admin-only, per the brief).\n\nRead-only — no mutation, no audit row (nothing changes).\n\nAuthorization:\n    - Anonymous → 401 (auth dep on ``require_admin``).\n    - Authenticated non-admin → 403 (``require_admin``).\n    - Admin → 200.\n\nFlag gate (rule #4): 404 when ``ADMIN_DASHBOARD_ENABLED`` is off.\n\nResponse shape:\n    {\"anomalies\": [{\"run_id\": \"...\", \"agent_id\": \"...\", \"z\": 3.42,\n                     \"declared_tier\": \"budget\",\n                     \"detected_at\": \"<ISO8601 UTC>\"}, ...]}","operationId":"admin_bpp_policing_api_v1_admin_bpp_policing_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Bpp Policing Api V1 Admin Bpp Policing Get"}}}}}}},"/api/v1/admin/overview":{"get":{"tags":["admin"],"summary":"BRIEF-ADMIN-004 — cockpit overview: status rollup + attention worklist + hero metrics","description":"Return the cockpit overview: a health status rollup, an actionable\nattention worklist, and 4 hero metrics with prior-period deltas + a\nsparkline. 60s in-process TTL cache; ``force_refresh`` busts it.\n\nRead-only, aggregate-first. The status rollup trips ``critical`` only on a\nreal fault (DB unreachable / a live probe degraded) — link-only ``unknown``\nsystems never trip it. No secret value is emitted.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.","operationId":"admin_overview_api_v1_admin_overview_get","parameters":[{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force Refresh"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Overview Api V1 Admin Overview Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/revenue":{"get":{"tags":["admin"],"summary":"BRIEF-ADMIN-004 — revenue: MRR/ARR proxy, active paid subs, trials (admin-gated)","description":"Return revenue detail: MRR/ARR (list-price proxy), active paid subs by\nplan, ARPU, trialing count, trials expiring within 7d, and the Stripe\nlive/test mode (inferred from the key PREFIX only — never the key value).\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.","operationId":"admin_revenue_api_v1_admin_revenue_get","parameters":[{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force Refresh"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Revenue Api V1 Admin Revenue Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/cost":{"get":{"tags":["admin"],"summary":"BRIEF-ADMIN-004 — cost: real spend windows + top spenders vs cap (admin-gated)","description":"Return spend detail: real (non-simulated) spend over 24h/7d/30d/MTD and\nthe top-spending accounts + teams. There is no cap percentage: the Cost Cap\nfeature was removed 2026-07-27 because Badge bills a flat subscription and\nmeters no customer LLM spend, so there is no customer limit to report\nagainst. Excludes simulated/mock runs.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.","operationId":"admin_cost_api_v1_admin_cost_get","parameters":[{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force Refresh"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Cost Api V1 Admin Cost Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/waitlists":{"get":{"tags":["admin"],"summary":"BIZ-007 §7 — enterprise + pro waitlist visibility (read-only, admin-gated)","description":"Return both capture lists, newest-first, paged, with exact counts.\n\n``{enterprise: {count, matching, offset, limit, has_more,\n                entries:[{id,email,created_at,contacted_at}]},\n   pro:        {... same envelope, entries carry notified_at}}``\n\n``count`` is the exact table total (never affected by paging or ``q``);\n``matching`` is what ``q`` matched; ``has_more`` says whether more pages\nexist. The enterprise emails ARE returned — that is the point of the surface\n(inbound sales leads), so a successful read commits a PII-free access receipt\nbefore returning. No password/token/secret is ever in these tables.\n\n**Paging and search are load-bearing for the PR #599 notification ceiling.**\nThat ceiling is only safe because a suppressed lead is still reachable here;\nwith the previous bare ``LIMIT 200`` and no offset, ~204 unauthenticated\nPOSTs pushed a genuine lead past the last returned row and no HTTP surface\ncould reach it (PR #599 review finding 1). Do not remove either parameter\nwithout re-opening that hole.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404 (rule #4).","operationId":"admin_waitlists_api_v1_admin_waitlists_get","parameters":[{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Rows to skip (newest-first ordering).","default":0,"title":"Offset"},"description":"Rows to skip (newest-first ordering)."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Rows per page (rule #9 cap).","default":100,"title":"Page Size"},"description":"Rows per page (rule #9 cap)."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"description":"Case-insensitive email substring filter. RFC 5321 max address length.","title":"Q"},"description":"Case-insensitive email substring filter. RFC 5321 max address length."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Waitlists Api V1 Admin Waitlists Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/waitlists/enterprise/{entry_id}":{"patch":{"tags":["admin"],"summary":"BIZ-007 §7 — flip an enterprise lead's contact status (audited, admin-gated)","description":"Set or clear ``contacted_at`` on one enterprise-waitlist entry.\n\n``{\"contacted\": true}`` stamps ``contacted_at`` with the SERVER clock;\n``{\"contacted\": false}`` clears it (undo). The client never supplies a\ntimestamp — a forged/skewed client clock can't land in the row.\n\nNon-destructive → a plain toggle, no confirm contract. But it IS a mutation\non the operator surface, so it writes an ``auth_audit_log`` row via the\nfail-closed ``_audit_or_500`` wrapper (ADMIN-OPS-001 pattern): actor =\nadmin (user_id + email), and ``detail`` carries the target id + the new\nboolean state ONLY — never the prospect's email (lead PII stays out of the\ntrail). Idempotent: flipping to the current state still returns 200 (with\n``changed=false``) and still audits the deliberate action.\n\nPro waitlist is intentionally NOT mutable here — its ``notified_at`` has\nlaunch-notify semantics driven by a one-shot script, a different lifecycle.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404 (rule #4).\nUnknown id → 404.","operationId":"admin_flag_enterprise_contact_api_v1_admin_waitlists_enterprise__entry_id__patch","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Entry Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminWaitlistContactPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Flag Enterprise Contact Api V1 Admin Waitlists Enterprise  Entry Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/support":{"get":{"tags":["admin"],"summary":"BRIEF-SUPPORT-001 — list synced support messages (admin-gated)","description":"List synced support messages, newest first (by received-at, then sync-at).\n\nReturns the feature `enabled` / `configured` booleans so the UI can show the\nactivation state, plus a global `unread_total`. Body text is NOT included in\nthe list (it's on the per-message detail read). Pagination caps at 100 (rule\n#9). Auth: anon→401, non-admin→403, admin→200; ADMIN_DASHBOARD off→404.","operationId":"admin_list_support_api_v1_admin_support_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"description":"Sender / subject substring.","title":"Search"},"description":"Sender / subject substring."},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(open|resolved)$"},{"type":"null"}],"description":"Filter by triage status.","title":"Status"},"description":"Filter by triage status."},{"name":"unread_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only unread messages.","default":false,"title":"Unread Only"},"description":"Only unread messages."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin List Support Api V1 Admin Support Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/support/sync":{"post":{"tags":["admin"],"summary":"BRIEF-SUPPORT-001 — pull recent support mail via read-only IMAP (admin-gated)","description":"Trigger a read-only IMAP pull of recent support mail into the DB.\n\nIdempotent (dedup by Message-ID). Manual (operator click) or cron-able. When\n``SUPPORT_INBOX_ENABLED`` is off returns ``enabled=false`` and does nothing\n(rerun-nudge precedent). When enabled but no IMAP credential is set, 503\n\"Support inbox not configured\" (Sentry-allowlisted). A live IMAP failure is\na 502 with a credential-free message.\n\nAudited (counts only — never a sender/subject/body). Auth: anon→401,\nnon-admin→403, admin→200; ADMIN_DASHBOARD off→404.","operationId":"admin_support_sync_api_v1_admin_support_sync_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Support Sync Api V1 Admin Support Sync Post"}}}}}}},"/api/v1/admin/support/erasure":{"post":{"tags":["admin"],"summary":"PRD-025 — preview or execute source-purge-first support-message erasure","description":"Preview or erase local support rows for one normalized sender email.\n\nDry-run is the default.  Execute mode is schema-gated on three independent\noperator confirmations: the source mailbox was already purged, the email\nwas repeated exactly after normalization, and the expected local row count\nmatches at execution time.  Sync and erasure share a PostgreSQL transaction\nlock, closing the in-flight-sync re-import race.\n\nThe audit row is fail-closed and atomic with deletion.  It identifies the\nadmin by ``user_id`` but deliberately omits every email, message id, subject,\nand body; detail contains action/counts only.  The response is counts-only.\nThis endpoint remains available when SUPPORT_INBOX_ENABLED is off so a\nprivacy request is never blocked by an ingestion feature flag.","operationId":"admin_erase_support_by_sender_api_v1_admin_support_erasure_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSupportErasureRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"boolean"}]},"type":"object","title":"Response Admin Erase Support By Sender Api V1 Admin Support Erasure Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/support/{support_id}":{"get":{"tags":["admin"],"summary":"BRIEF-SUPPORT-001 — one support message incl. body (admin-gated)","description":"Full detail of one support message, including the plain-text body.\n\nThe body is stored HTML-stripped (services/support_inbox.py), so the client\nrenders it as text — no active content. Auth: anon→401, non-admin→403,\nadmin→200; ADMIN_DASHBOARD off→404; unknown id→404.","operationId":"admin_get_support_api_v1_admin_support__support_id__get","parameters":[{"name":"support_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Support Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Get Support Api V1 Admin Support  Support Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"BRIEF-SUPPORT-001 — mark a support message read / resolved (admin-gated)","description":"Update operator triage state (`is_read`, `status`) on one message.\n\nThis is OUR state — it never touches the mail on the server. `exclude_unset`\nso an omitted field is untouched. Audited (target-id + field NAMES only).\nAuth: anon→401, non-admin→403, admin→200; ADMIN_DASHBOARD off→404;\nunknown id→404.","operationId":"admin_update_support_api_v1_admin_support__support_id__patch","parameters":[{"name":"support_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Support Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSupportMessagePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Update Support Api V1 Admin Support  Support Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/support/{support_id}/reply":{"post":{"tags":["admin"],"summary":"EPIC-SUPPORT-002 — send one idempotent threaded support reply","description":"Reply from support@badgeia.com and retain a replay-safe outbound row.\n\nThe existing global write limiter applies before this admin-only handler.\nSync, erasure, and reply share the same database operation lock so a reply\ncannot reintroduce a just-erased recipient row. The provider call is\nbounded and uses the durable row key as Resend's Idempotency-Key.","operationId":"admin_reply_to_support_api_v1_admin_support__support_id__reply_post","parameters":[{"name":"support_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Support Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSupportReplyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Reply To Support Api V1 Admin Support  Support Id  Reply Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/lead-capture-budget":{"get":{"tags":["admin"],"summary":"Parsed Enterprise-lead capture bounds + source-IP resolution proof","description":"Expose the parsed capture-side bounds and prove source-IP resolution works.\n\nBoth settings here traverse three CD env-render hops, and the per-source\nnotification allowance has a genuinely SILENT failure mode: it buckets on\nthe trusted-XFF client IP, so if ``TRUSTED_PROXIES`` ever drifts away from\nCaddy's container address, every caller collapses into ONE bucket and\nreal-time lead notices go quiet after the daily allowance. Leads are still\ncaptured and still listed in /admin — but the alerting this exists to\nprotect would be dead with no error anywhere. Rule #13 forbids the SSH that\nwould otherwise diagnose it, so the check has to be an HTTP surface.\n\n``xff_honored`` is the load-bearing field: it must be true in prod. False\nbehind Caddy means TRUSTED_PROXIES is wrong and every lead shares a bucket.\n\n``source_ip`` is the CALLER's own address (the authenticated admin's), so\nthis discloses nothing the caller doesn't already know.\n\nShape:\n    {\n      \"notify_max_per_source_per_day\": 5,\n      \"waitlist_retention_days\": 365,\n      \"retention_scheduler_enabled\": false,\n      \"source_ip\": \"203.0.113.9\",\n      \"xff_honored\": true,\n      \"peer_ip\": \"172.30.10.2\"\n    }","operationId":"admin_lead_capture_budget_api_v1_admin_lead_capture_budget_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Lead Capture Budget Api V1 Admin Lead Capture Budget Get"}}}}}}},"/api/v1/admin/rate-limit-latency":{"get":{"tags":["admin"],"summary":"Rate-limiter latency p50/p95/p99 per category (v0.1.37 Redis RCA diagnostic)","description":"Return a snapshot of Redis-check latency per category.\n\nPer-category ring buffers hold the last 500 successful check\nlatencies. Failed checks (TimeoutError → fail-open) are NOT\nincluded — they're tracked separately via the Sentry counter.\n\nOperator use:\n    - Verify the 100ms wait_for budget is sufficient. p99 should\n      sit well under 100ms; if p99 creeps toward the ceiling,\n      time for another tuning pass.\n    - Spot a regression after a Redis/Hetzner config change.\n\nShape:\n    {\n      \"auth\": {\"count\": 423, \"p50_ms\": 1.2, \"p95_ms\": 4.8, \"p99_ms\": 12.3, \"max_ms\": 41.0},\n      \"read\": {...},\n      \"write\": {...},\n      \"daemon\": {...},\n    }\n    Returns an empty dict when no checks have run yet.","operationId":"admin_rate_limit_latency_api_v1_admin_rate_limit_latency_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Rate Limit Latency Api V1 Admin Rate Limit Latency Get"}}}}}}},"/api/v1/admin/notification-budget":{"get":{"tags":["admin"],"summary":"Ops-notification hourly ceiling — parsed limit + current window usage","description":"Return the live state of every global ops-notification ceiling.\n\nDiagnostic for the PR #519 finding-2 ceilings. The limits are env-tunable\nand prod has no shell access, so without an HTTP view of the *parsed* values\na missed CD env-render hop would be invisible until a flood either went\nthrough or silently didn't. Also reports which backend is in play:\n``redis`` means the ceilings are genuinely global; ``memory`` means Redis is\nunreachable and they have degraded to per-worker.\n\nCounts only — no lead addresses, nothing PII-bearing. Read-only: calling\nthis never charges the budget.\n\nShape:\n    {\n      \"enterprise_lead\": {\n        \"channel\": \"enterprise_lead\", \"backend\": \"redis\",\n        \"windows\": {\n          \"hour\": {\"limit\": 10, \"window_seconds\": 3600, \"used\": 3,\n                   \"remaining\": 7, \"reset_seconds\": 1840,\n                   \"digest_sent\": false},\n          \"day\":  {\"limit\": 20, \"window_seconds\": 86400, ...}\n        }\n      }\n    }","operationId":"admin_notification_budget_api_v1_admin_notification_budget_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Notification Budget Api V1 Admin Notification Budget Get"}}}}}}},"/api/v1/admin/auth-events":{"get":{"tags":["admin"],"summary":"Auth-event audit log — newest-first, paginated (SEC-AUTH-014)","description":"Return the auth-event audit log, newest first.\n\nSEC-AUTH-014. Backs an operator's account-takeover / brute-force\ninvestigation: \"what IPs hit this email, when, and did any succeed?\"\n\nAuthorization:\n    - Anonymous → 401 (handled by the auth dep on `require_admin`).\n    - Authenticated non-admin → 403 (handled by `require_admin`).\n    - Admin (email in `ADMIN_EMAILS`) → 200.\n\nPagination (CLAUDE.md rule #9): `page_size` caps at 100 — `page_size=200`\nreturns 422 via the `le=100` Query bound, matching every other paginated\nendpoint. `page` is 1-based.\n\nFilters (both optional, exact match, AND-combined):\n    - `event_type` — e.g. `login_failure`.\n    - `email` — the email the caller presented at auth time.\n\nResponse shape:\n    {\n      \"items\": [\n        {\"id\": \"<uuid>\", \"event_type\": \"login_failure\", \"user_id\": \"<uuid|null>\",\n         \"email\": \"a@b.com\", \"ip_address\": \"1.2.3.4\", \"user_agent\": \"...\",\n         \"success\": false, \"detail\": \"bad_password\",\n         \"created_at\": \"<ISO8601 UTC>\"},\n        ...\n      ],\n      \"total\": <int>, \"page\": <int>, \"page_size\": <int>, \"pages\": <int>\n    }\n\nPrivacy: this surface intentionally DOES expose per-event IP / email /\nuser-agent — that's the security purpose of the table (unlike the\naggregate-only `/admin/kpis`). It is admin-gated for exactly that\nreason. No password / token / secret is ever stored, so none can leak.\n\nFlag gate (rule #4): 404 when ``ADMIN_DASHBOARD_ENABLED`` is off, so the whole\n``/admin/*`` surface — including this SEC-AUTH-014 audit log now surfaced by\nthe BRIEF-ADMIN-004 Activity tab — stays uniformly gated.","operationId":"admin_auth_events_api_v1_admin_auth_events_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to a single event_type (exact match).","title":"Event Type"},"description":"Filter to a single event_type (exact match)."},{"name":"email","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to a single presented email (exact match).","title":"Email"},"description":"Filter to a single presented email (exact match)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Auth Events Api V1 Admin Auth Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/prune-auth-data":{"post":{"tags":["admin"],"summary":"Prune aged auth, token, and support rows (GDPR retention)","description":"Bound retention on auth personal/security data. Returns rows deleted.\n\nGDPR follow-up to SEC-AUTH-014 (`auth_audit_log` stores client IPs —\npersonal data, Art. 6(1)(f) legitimate-interest basis) and SEC-AUTH-013/\n012 (single-use `password_reset_tokens` / `email_verification_tokens`\naccumulate spent rows). Runs both pruners from\n`services/auth_retention_service.py`:\n\n  - deletes `auth_audit_log` rows older than\n    ``settings.AUTH_AUDIT_RETENTION_DAYS`` (default 90d);\n  - deletes spent (used OR expired) reset/verification tokens older than\n    ``settings.AUTH_TOKEN_GRACE_DAYS`` (default 7d). Live tokens are\n    never pruned.\n  - deletes inbound and outbound support rows older than\n    ``settings.SUPPORT_MESSAGE_RETENTION_DAYS`` (default 365d), including\n    outbound provider replay HTML on the enclosing row.\n\nThe production lifespan worker runs the same aggregate once per day behind\na cross-worker Redis lease. This endpoint remains the authenticated manual\npath, and ``python -m scripts.prune_auth_data`` is the dry-run-first\nstandalone path. See docs/RUNBOOK-data-retention.md.\n\nAuthorization:\n    - Anonymous → 401 (handled by the auth dep on `require_admin`).\n    - Authenticated non-admin → 403 (handled by `require_admin`).\n    - Admin (email in `ADMIN_EMAILS`) → 200.\n\nResponse shape:\n    {\n      \"pruned\": {\n        \"auth_audit_log\": <int>,\n        \"password_reset_tokens\": <int>,\n        \"email_verification_tokens\": <int>,\n        \"support_messages\": <int>,\n        \"enterprise_waitlist\": <int>\n      },\n      \"retention_days\": <int>,\n      \"grace_days\": <int>,\n      \"support_retention_days\": <int>,\n      \"enterprise_waitlist_retention_days\": <int>\n    }","operationId":"admin_prune_auth_data_api_v1_admin_prune_auth_data_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Prune Auth Data Api V1 Admin Prune Auth Data Post"}}}}}}},"/api/v1/admin/retention/preview":{"get":{"tags":["admin"],"summary":"Counts-only retention preview — same numbers as ops-retention-preview.yml, on demand","description":"Report prunable-row counts + age distribution without dispatching a workflow.\n\n`.github/workflows/ops-retention-preview.yml` (#652) gives an operator the\nsame numbers, but it can only be dispatched from a `v*` release tag — the\nproduction GitHub Environment's deployment-branch policy allows nothing\nelse, so it is correct as a pre-flip gate but heavyweight for routine\nchecking. This endpoint is the same read, on demand, no workflow dispatch\nrequired.\n\nProvably read-only: the only service calls are `count_prunable` and\n`count_row_age_histogram`, both pure ``SELECT count(*) ...`` statements.\nNeither touches `delete()`, `prune_all`, or `db.commit()` — this handler\nmust never import or call either. The handler itself issues no writes, so\n`get_db`'s exit-time `await session.commit()` (`database.py`, run on every\nsuccessful request regardless of handler) is a no-op here — nothing in the\nsession is ever dirtied. That safety property lives in the dependency, not\nin this function; if a future edit adds a `db.add(...)` here, that commit\nstops being a no-op even though this docstring still says \"read-only\" —\nkeep the two in sync.\n\nResponse mirrors the standalone pruner's dry-run receipt\n(`python -m scripts.prune_auth_data`, the same output\n`preview-retention-counts.sh` copies into the workflow's Actions log) so\nthe two are directly comparable:\n\n    {\n      \"retention_scheduler_enabled\": <bool>,\n      \"prunable\": {\n        \"auth_audit_log\": <int>,\n        \"password_reset_tokens\": <int>,\n        \"email_verification_tokens\": <int>,\n        \"support_messages\": <int>,\n        \"enterprise_waitlist\": <int>\n      },\n      \"age_histogram\": {\n        \"auth_audit_log\": {\"<=7d\": <int>, \"8-30d\": <int>, \"31-90d\": <int>,\n                            \"91-180d\": <int>, \"181-365d\": <int>,\n                            \">365d\": <int>, \"total\": <int>},\n        ... (one row per table above)\n      },\n      \"windows\": {\n        \"auth_audit_log\": {\"retention_days\": <int>},\n        \"password_reset_tokens\": {\"grace_days\": <int>},\n        \"email_verification_tokens\": {\"grace_days\": <int>},\n        \"support_messages\": {\"retention_days\": <int>},\n        \"enterprise_waitlist\": {\"retention_days\": <int>}\n      }\n    }\n\n`windows` always reflects the currently configured values, even when a\nwindow is misconfigured (see below) — it is built before either service\ncall so a bad value is never swallowed by the exception it causes.\n\nIf a configured window fails `count_prunable`'s validation (e.g.\n`AUTH_AUDIT_RETENTION_DAYS` set below the 7-day safety floor —\nunlike `SUPPORT_MESSAGE_RETENTION_DAYS` / `ENTERPRISE_WAITLIST_RETENTION_DAYS`,\nit has no startup validator, so a bad value boots fine and only surfaces\nhere), the response is still 200 with `prunable` and `age_histogram`\nomitted and an `error` string added (config names and integers only, no\nPII, admin-only audience) — the exact multi-hop-env misconfiguration this\nendpoint exists to diagnose must never collapse into an opaque 500.\n\nCounts and configuration only. `age_histogram` buckets ALL rows by age at\nday-7-or-coarser granularity (see `count_row_age_histogram`'s docstring for\nwhy buckets, not dates) — it never returns a row's content, email, IP, or\nexact timestamp.\n\nAuthorization:\n    - Anonymous → 401 (auth dep on `require_admin`).\n    - Authenticated non-admin → 403 (`require_admin`).\n    - Admin → 200 (or 200 + `error`, see above).\n\nFlag gate (rule #4): 404 when `ADMIN_DASHBOARD_ENABLED` is off, matching\nevery other handler in this router. This does NOT hide the route's\nexistence — `main.py` serves `/openapi.json` unauthenticated, so the path\nand schema are public regardless of flag state (same property already\ncorrected once on `_require_custody_notice_enabled` above; matching that\nlanguage here rather than repeating the mistake). What IS true: FastAPI\nresolves `require_admin` before this body runs, so anonymous still gets\n401 and a non-admin caller still gets 403 no matter the flag — only an\nalready-authenticated admin can distinguish 404 from 200, so flag state\nis never disclosed below the admin trust level this route already\nrequires.","operationId":"admin_retention_preview_api_v1_admin_retention_preview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Retention Preview Api V1 Admin Retention Preview Get"}}}}}}},"/api/v1/admin/rerun-nudge/scan":{"post":{"tags":["admin"],"summary":"Admin Rerun Nudge Scan","description":"RES-014-B — operator trigger for the re-run nudge scan/dispatch pass.\n\nThe nudge is built but DISABLED by default (``RERUN_NUDGE_ENABLED`` OFF —\npopulation/retention-gated). This admin-gated endpoint lets the operator\nrun a scan once the flag is flipped (and to dry-run reach beforehand —\n``dry_run=True`` is the default so a stray click sends nothing).\n\nReturns the scan summary, including ``fenced_out_non_customer_key`` (the\nAC-06 cost fence in action) so the operator can confirm Badge-paid-fallback\nagents are excluded before any live send.\n\n404 when ``ADMIN_DASHBOARD_ENABLED`` is off (rule #4 — fail explicit), so\nthe admin surface stays uniformly gated. When ``RERUN_NUDGE_ENABLED`` is\noff the scan returns ``enabled=false`` and does nothing.","operationId":"admin_rerun_nudge_scan_api_v1_admin_rerun_nudge_scan_post","parameters":[{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","description":"Preview reach without sending (default).","default":true,"title":"Dry Run"},"description":"Preview reach without sending (default)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Rerun Nudge Scan Api V1 Admin Rerun Nudge Scan Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/billing/reconcile-stripe-customers":{"post":{"tags":["admin"],"summary":"One-off: NULL stale stripe_customer_id rows that don't exist under the current key","description":"Bulk-clean ``stripe_customer_id`` rows orphaned by the test→live key flip.\n\nROAD-002 §WP-A task 4. When the prod Stripe key flipped from test to live,\nevery ``stripe_customer_id`` minted under the test key became \"No such\ncustomer\" under the live key — a 400→503 on that user's next checkout. The\ncheckout handler now self-heals lazily (null + recreate + retry once), so\nthis endpoint is the *proactive* counterpart: verify each stored customer\nagainst the current key and NULL the ones Stripe no longer knows.\n\nOnly rows Stripe positively reports as GONE (404) are cleared. Any\nindeterminate signal (network error, rate-limit, unexpected status) leaves\nthe row untouched — we never destroy a mapping on an ambiguous answer.\n\nAuthorization:\n    - Anonymous → 401 (auth dep on ``require_admin``).\n    - Authenticated non-admin → 403 (``require_admin``).\n    - Admin (email in ``ADMIN_EMAILS``) → 200.\n\nFlag gate (rule #4): 404 when ``ADMIN_DASHBOARD_ENABLED`` is off, so the\nwhole ``/admin/*`` surface stays uniformly gated.\n\n503 \"Stripe not configured\" (Sentry-allowlisted) when no key is set.\n\nResponse (counts only — never an email or a customer id):\n    {\"dry_run\": bool, \"scanned\": int, \"stale\": int, \"cleared\": int,\n     \"indeterminate\": int}","operationId":"admin_reconcile_stripe_customers_api_v1_admin_billing_reconcile_stripe_customers_post","parameters":[{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","description":"Preview counts without writing (default).","default":true,"title":"Dry Run"},"description":"Preview counts without writing (default)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Reconcile Stripe Customers Api V1 Admin Billing Reconcile Stripe Customers Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/accounts":{"get":{"tags":["admin"],"summary":"ADMIN-OPS-001 — paginated account list with search (admin-gated)","description":"List platform accounts, newest first, with per-account activity counts.\n\nPer row: id, email, plan, is_paid (stripe_subscription_id present),\nis_active, email_verified, agent_count, run_count, created_at, last_active\n(best-effort — max of the account's last run and last successful login).\n\nN+1 avoidance: the agent counts, run counts, last-run and last-login\ntimestamps are each computed in ONE grouped query over the page's user-id\nset, not per-row.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404\n(rule #4). Pagination caps at 100 (rule #9).\n\nPrivacy: password hashes / stripe ids / tokens are NEVER serialized — see\n`_account_row`.","operationId":"admin_list_accounts_api_v1_admin_accounts_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"description":"Case-insensitive email substring filter.","title":"Search"},"description":"Case-insensitive email substring filter."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin List Accounts Api V1 Admin Accounts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/accounts/{user_id}/disable":{"post":{"tags":["admin"],"summary":"ADMIN-OPS-001 — soft-disable an account (blocks login + hides their agents)","description":"Soft-disable an account: set `is_active=False` and hide their public agents.\n\nEnforcement of the disabled state is ALREADY wired in `routers/auth.py`:\na disabled account's password login is rejected (403 \"inactive\") AND their\nexisting session is rejected on the next request (`get_current_user` → 401),\nso no token needs to be individually revoked here.\n\nSide effect: every one of the account's currently-public agents is flipped\nto `is_public=False` so a disabled user's work leaves the public Talent\nPool / Compare / Registry immediately. Enable does NOT auto-republish them\n(see the enable endpoint) — re-publishing is a deliberate per-agent choice.\n\nIdempotent: re-disabling an already-disabled account returns 200 with\n`changed=false` (and still re-hides any agents that drifted public).\n\nGuard: an admin cannot disable THEMSELVES (400) — that would lock the\noperator out of the very surface they're using.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.","operationId":"admin_disable_account_api_v1_admin_accounts__user_id__disable_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Disable Account Api V1 Admin Accounts  User Id  Disable Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/accounts/{user_id}/cancel-deletion":{"post":{"tags":["admin"],"summary":"PRD-027 — cancel a pending account deletion on the owner's behalf","description":"Cancel a scheduled erasure. The recovery path for a hijacked account.\n\nSelf-service cancel-by-login is the normal reversal, and it is enough right\nup until the operator has to suspend the account — which is exactly what\nhappens when a stolen session requests deletion and the real owner mails\nsupport. Suspension freezes the attacker AND removes the owner's ability to\nsign in and cancel, so without this endpoint the recovery action and the\nonly reversal are mutually exclusive.\n\nDeliberately separate from `/enable`. Re-enabling an account is not consent\nto cancel an erasure its owner genuinely asked for, and conflating them\nwould let a routine un-suspension silently revoke a real deletion request.\nAn operator resolving a takeover calls both; an operator lifting an\nunrelated suspension calls one.\n\nLeaves `suspended_at` alone: whether the account should also be\nun-suspended is a separate judgement, made with `/enable`.\n\nIdempotent: an account with no pending deletion returns 200 `changed=false`.\n\n**Deliberately NOT gated on `ACCOUNT_DELETION_ENABLED`** — the one place in\nthis feature that ignores the flag. Rule #4 says a flag-off surface fails\nexplicit, and the reasoning holds for every endpoint that *starts* an\nerasure. This one only ever stops one. The state it exists to clear can\noutlive the flag: an operator flipping the flag off mid-grace leaves\naccounts pending-and-frozen forever, and gating the unstick behind the\nsame flag would make the emergency stop unrecoverable. Admin-only, and it\ncannot destroy anything. `test_admin_cancel_works_while_the_flag_is_off`\npins this as a decision rather than an oversight.","operationId":"admin_cancel_account_deletion_api_v1_admin_accounts__user_id__cancel_deletion_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Cancel Account Deletion Api V1 Admin Accounts  User Id  Cancel Deletion Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/accounts/{user_id}/enable":{"post":{"tags":["admin"],"summary":"ADMIN-OPS-001 — re-enable a soft-disabled account (does NOT republish agents)","description":"Re-enable a soft-disabled account: set `is_active=True`.\n\nDeliberately does NOT auto-republish the agents that `disable` hid — a\nre-enabled user's agents stay private until they (or an admin) flip them\nback on purpose. Re-publishing on enable would silently re-expose work the\noperator may have disabled the account specifically to take down.\n\nIdempotent: enabling an already-active account returns 200 with\n`changed=false`.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.","operationId":"admin_enable_account_api_v1_admin_accounts__user_id__enable_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Enable Account Api V1 Admin Accounts  User Id  Enable Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agents":{"get":{"tags":["admin"],"summary":"ADMIN-OPS-001 — search ALL agents incl. private/inactive (admin-gated)","description":"List every agent — including private (is_public=False) and soft-deleted\n(is_active=False) rows the public list can't reach.\n\nPer row: id, name, owner_email, is_public, is_active, connection_mode,\ncomposite_score (latest overall score, may be null), registry_status,\nverified_at, description. Owner emails + latest scores are batched (no N+1).\n\nFilters (all optional, AND-combined): `search` (name substring),\n`owner_email` (exact personal-owner email, case-insensitive), and `team_id`\n(exact workspace UUID).\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.\nPagination caps at 100 (rule #9).","operationId":"admin_list_agents_api_v1_admin_agents_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"description":"Case-insensitive name substring filter.","title":"Search"},"description":"Case-insensitive name substring filter."},{"name":"owner_email","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"description":"Filter to agents owned by this exact email (case-insensitive). Backs the Accounts tab's 'view this account's agents' row action.","title":"Owner Email"},"description":"Filter to agents owned by this exact email (case-insensitive). Backs the Accounts tab's 'view this account's agents' row action."},{"name":"team_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter to agents owned by this exact workspace UUID.","title":"Team Id"},"description":"Filter to agents owned by this exact workspace UUID."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin List Agents Api V1 Admin Agents Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/playbooks":{"get":{"tags":["admin"],"summary":"ADMIN-OPS-001 — discover ALL playbooks incl. private/inactive (admin-gated)","description":"List operational metadata for every playbook, including private and inactive rows.\n\nThe response intentionally excludes prompts, examples, tool configuration,\nmodel settings, notes, agent endpoints, and other execution data. Filters are\noptional and AND-combined. Owner email applies only to personal agents;\nworkspace ownership is represented by ``team_id``/``team_name``.\n\nAuth: anonymous → 401, non-admin → 403, flag-off → 404. Pagination caps at\n100 and search metacharacters are matched literally on Postgres and SQLite.","operationId":"admin_list_playbooks_api_v1_admin_playbooks_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"description":"Case-insensitive literal substring filter over playbook or agent name.","title":"Search"},"description":"Case-insensitive literal substring filter over playbook or agent name."},{"name":"owner_email","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"description":"Filter by exact personal-owner email (case-insensitive).","title":"Owner Email"},"description":"Filter by exact personal-owner email (case-insensitive)."},{"name":"team_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter by exact workspace UUID.","title":"Team Id"},"description":"Filter by exact workspace UUID."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin List Playbooks Api V1 Admin Playbooks Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agents/{agent_id}":{"patch":{"tags":["admin"],"summary":"ADMIN-OPS-001 — edit any agent's description / visibility (admin-gated)","description":"Admin edit of ANY agent — regardless of owner.\n\nv1 fields: `description` and `is_public`. Uses `exclude_unset` so an\nomitted field is untouched while an explicit null clears the description.\nThis is how the operator fixes reference-agent copy without owning the row.\n\nAudit `detail` records only the NAMES of the fields changed (never the new\ndescription text) so the trail stays small + content-free.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.\n404 when the agent doesn't exist.","operationId":"admin_edit_agent_api_v1_admin_agents__agent_id__patch","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAgentPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Edit Agent Api V1 Admin Agents  Agent Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"ADMIN-OPS-001 — soft-delete any agent (admin-gated)","description":"Soft-delete ANY agent (mirrors the owner path: `is_active=False`).\n\nReturns a JSON summary (not 204) so the operator UI can show the result.\nIdempotent: re-deleting an already-inactive agent returns `changed=false`.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.\n404 when the agent doesn't exist.","operationId":"admin_delete_agent_api_v1_admin_agents__agent_id__delete","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Delete Agent Api V1 Admin Agents  Agent Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/agents/scrub-descriptions":{"post":{"tags":["admin"],"summary":"ADMIN-OPS-001 — bulk find/replace across agent descriptions (dry-run by default)","description":"Bulk substring find/replace across all agent descriptions.\n\nBuilt to fix the 60 reference agents carrying the\n\"(PRD-016 FR-11 demo frontier)\" marker in one shot\n(find=\"(PRD-016 FR-11 demo frontier)\", replace=\"\").\n\n`dry_run=True` (the default) returns the match count + a small before/after\nsample WITHOUT writing. `dry_run=False` applies the replace and commits.\nThe match set is capped at `_SCRUB_MATCH_CAP` rows per call to bound the\ntransaction + audit blast-radius; `capped=true` in the response signals the\noperator to run again to catch the remainder.\n\nThe SQL filter is a case-sensitive substring match (mirrors the Python\n`str.replace`, which is case-sensitive). We only count/write a row whose\ndescription ACTUALLY changes, so a dialect that matches case-insensitively\n(SQLite LIKE) can't cause a phantom no-op write.\n\nAudit `detail` is COUNT-ONLY (never the find/replace strings' content nor a\ndescription body).\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.","operationId":"admin_scrub_descriptions_api_v1_admin_agents_scrub_descriptions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminScrubDescriptionsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Scrub Descriptions Api V1 Admin Agents Scrub Descriptions Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/playbooks/{playbook_id}":{"delete":{"tags":["admin"],"summary":"ADMIN-OPS-001 — soft-delete/unpublish any playbook regardless of owner (admin-gated)","description":"Soft-delete ANY playbook — regardless of owner.\n\nMirrors the owner path (`is_active=False` + `is_default=False`), but reaches\nplaybooks the owner-only delete at `playbooks.py` can't (e.g. test leftovers\non a founder-owned reference agent). Idempotent.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.\n404 when the playbook doesn't exist.","operationId":"admin_delete_playbook_api_v1_admin_playbooks__playbook_id__delete","parameters":[{"name":"playbook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Playbook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Delete Playbook Api V1 Admin Playbooks  Playbook Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/teams":{"get":{"tags":["admin"],"summary":"Admin team management — paginated workspace list with search (admin-gated)","description":"List every workspace, newest first, with per-team activity counts.\n\nPer row: id, name, plan, owner (id + email + plan), workspace_active,\nmember_count, pending_invitations, seats_reserved vs max_seats, agent_count,\nrun_count, created_at, last_activity.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404\n(rule #4). Pagination caps at 100 (rule #9).","operationId":"admin_list_teams_api_v1_admin_teams_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"description":"Case-insensitive substring filter over team name AND owner email.","title":"Search"},"description":"Case-insensitive substring filter over team name AND owner email."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin List Teams Api V1 Admin Teams Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/teams/{team_id}":{"get":{"tags":["admin"],"summary":"Admin team management — one workspace: roster, invitations, agents, stats","description":"Full operator view of one workspace.\n\nCounts and aggregates plus the member roster — never run payloads, prompts,\noutputs, or agent endpoint URLs. See `services/admin_teams.team_detail` for\nwhy each statistic is here.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.\n404 when the team doesn't exist.","operationId":"admin_get_team_api_v1_admin_teams__team_id__get","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Get Team Api V1 Admin Teams  Team Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Admin team management — rename a workspace (audit-logged)","description":"Rename a workspace. Idempotent: renaming to the current name is a no-op.\n\nOnly the name is editable — plan / seats / ownership each have their own\nenforcement path and are not reachable from here (see `AdminTeamRename`).\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.\n404 when the team doesn't exist. 409 when the name is already taken\n(`teams.name` is UNIQUE).","operationId":"admin_rename_team_api_v1_admin_teams__team_id__patch","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTeamRename"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Rename Team Api V1 Admin Teams  Team Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/teams/{team_id}/deletion":{"post":{"tags":["admin"],"summary":"Admin team management — preview or execute a workspace teardown (audit-logged)","description":"Preview (default) or execute a workspace teardown.\n\nPOST, not DELETE, for the same reason as `POST /admin/support/erasure`: the\nceremony needs a request body, and the safe default — a dry run that\ncomputes what WOULD happen — must not be spelled with a destructive verb.\n\nDry run (default) returns the counts-only inventory: how many agents get\nreassigned to the owner, how many of those hold provider credentials that\nwill be cleared, how many memberships and invitations are dropped, how many\nworkspace radar presets die, and how many historical runs are left with a\ndangling `team_id`.\n\nExecute reassigns the workspace agents to the OWNER's personal scope,\nrevokes their workspace machine credentials, clears their provider\ncredentials, and deletes the team with its memberships, invitations, and\npresets — all in one transaction with the audit row.\n\n**Member user accounts are never deleted.** Removing a workspace removes\naccess, not people.\n\nAuth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404.\n404 when the team doesn't exist.\n409 when a confirmation no longer matches the live workspace, or when the\nteam has no resolvable owner to reassign its agents to.\n422 when the execute body is incomplete (see `AdminTeamDeletionRequest`).","operationId":"admin_delete_team_api_v1_admin_teams__team_id__deletion_post","parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Team Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTeamDeletionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Delete Team Api V1 Admin Teams  Team Id  Deletion Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/endpoint-url-policy":{"get":{"tags":["admin"],"summary":"Counts-only pre-deploy gate for the EPIC-KEYS-001A T1 URL policy","description":"Count stored agent URLs that the T1 credential-carrier policy rejects.\n\nEPIC-KEYS-001A T1 refuses userinfo, query strings, and fragments on every\npersisted customer-supplied URL. Rows written *before* that guard can still\ncarry one, and such a row now reads back as ``null`` and fails dispatch —\nso the affected count is a release gate, not a curiosity: a non-zero\n``endpoint`` count means real agents stop screening the moment this\ndeploys.\n\nThis exists because host access is forbidden (CLAUDE.md rule #13 / the\ndiagnostic-endpoint convention): without an HTTP path there is no way to\ntake this measurement on staging or production at all.\n\nCounts only. It never selects, returns, hashes, logs, or serializes a URL\nvalue, and it touches no credential column — the expressions below are\nboolean aggregates, and the response carries integers exclusively.","operationId":"endpoint_url_policy_counts_api_v1_admin_endpoint_url_policy_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Endpoint Url Policy Counts Api V1 Admin Endpoint Url Policy Get"}}}}}}},"/api/v1/admin/provider-custody-notice/preview":{"get":{"tags":["admin"],"summary":"EPIC-KEYS-001A T2 — counts-only preview of the custody-notice cohort","description":"Report how many owners the custody notice would reach. Counts ONLY.\n\nEvery value in this response is an integer, a boolean, or the notice's\ncontent hash. No email address, user id, agent id, team id, or any value\nderived from credential material can appear here — that is the presence-only\ncontract the T1 security review's D1 finding requires (an ungated bit that\ndistinguished this exact cohort was treated as a credential-presence oracle;\nan admin JSON body listing them would be the same oracle behind a thinner\nwall).\n\n``retired_agent_count`` is the notice cohort: holds stored provider\nciphertext AND had execution frozen by T1.\n``credential_presence_agent_count`` is the superset that merely holds\nciphertext — the difference is endpoint-rescued rows whose owner still has a\ncredential to revoke but whose runs were never suspended. They are out of\nscope for this notice (the copy leads with \"execution is suspended\") and\nbelong to the T5 inventory lane; the delta is reported so the operator sees\nthe gap rather than assuming full coverage.\n\n``delivery_configured`` is the diagnostic that keeps the multi-hop env\npipeline debuggable without SSH: flag on but no Resend key means the POST\nwill 503, and the operator learns it here rather than from a failed send.\n\nAuthorization:\n    - Anonymous → 401 (auth dep on ``require_admin``).\n    - Authenticated non-admin → 403 (``require_admin``).\n    - Admin → 200.\n\nFlag gates (rule #4): 404 when ``ADMIN_DASHBOARD_ENABLED`` is off, 404 when\n``PROVIDER_CUSTODY_NOTICE_ENABLED`` is off.","operationId":"admin_preview_custody_notice_api_v1_admin_provider_custody_notice_preview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Preview Custody Notice Api V1 Admin Provider Custody Notice Preview Get"}}}}}}},"/api/v1/admin/badge-funded-ceiling":{"get":{"tags":["admin"],"summary":"Badge-funded spend interlock: parsed flag/ceiling state + month-to-date","description":"Echo the PARSED state of the Badge-funded spend interlock.\n\nThis exists because ``BADGE_FUNDED_MONTHLY_CEILING_USD`` crosses the\nthree-hop CD env pipeline (cd.yml env block -> render() -> compose mapping)\nand host access is forbidden (CLAUDE.md rule #13 / the diagnostic-endpoint\nconvention). Without an HTTP path, an operator who sets the GH Variable has\nno way to tell \"the ceiling is live\" from \"a hop is missing and the value\nsilently defaulted to 0\" -- and 0 means REFUSE, so that failure presents as\na permanent 503 with no explanation. The pressured response to that is to\ndelete the interlock, which is the outcome it exists to prevent.\n\n``effective_state`` is the point: it reports what the running process will\nactually DO, not what an env var contains.\n\nAdmin-gated. The client-facing 503 is deliberately generic and names none\nof this -- the specifics live here and in ``logger.error``.","operationId":"admin_badge_funded_ceiling_api_v1_admin_badge_funded_ceiling_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Badge Funded Ceiling Api V1 Admin Badge Funded Ceiling Get"}}}}}}},"/api/v1/admin/provider-custody-notice/authorize-delivery":{"post":{"tags":["admin"],"summary":"EPIC-KEYS-001A T2 — operator-authorized one-shot custody-notice delivery","description":"Send the reviewed custody notice to the pending cohort, once each.\n\nThis is the operator action itself. Flipping\n``PROVIDER_CUSTODY_NOTICE_ENABLED`` makes the endpoint exist; calling it with\na body that transcribes the previewed cohort size and copy hash is what\nauthorizes the send. Neither alone sends anything.\n\nThe copy is ``services/provider_custody_notice.render_...()`` UNCHANGED —\nthis handler never templates, personalizes, or interpolates anything into it,\nwhich is what keeps the reviewed identity-free copy module identity-free.\n\nResponses:\n    200 — counts-only delivery result (see the service dataclass).\n    400 — the gate flipped off between the request and the service call.\n    409 — the confirmed recipient count or notice version no longer matches\n          the live cohort. A stale preview never sends.\n    422 — ``confirm_delivery`` was not explicitly true.\n    503 — flag on, no Resend key (Sentry-allowlisted; see observability).\n\nAuthorization / flag gates identical to the preview endpoint.\n\nDurability note: the per-recipient record of what was sent is the\n``provider_custody_notice_deliveries`` ledger, committed per recipient as\ndelivery proceeds. The audit row below is the operator-attribution record for\nthe batch and is written after the batch completes, so a process death\nmid-batch leaves the ledger authoritative and the batch un-audited — the next\npreview shows the ledger state, and re-authorizing is safe because\nalready-sent recipients are skipped.","operationId":"admin_authorize_custody_notice_delivery_api_v1_admin_provider_custody_notice_authorize_delivery_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProviderCustodyNoticeAuthorization"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Authorize Custody Notice Delivery Api V1 Admin Provider Custody Notice Authorize Delivery Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/daemon/jobs":{"get":{"tags":["daemon"],"summary":"Claim Next Job","description":"Long-poll for the next job assigned to this daemon's agent.\n\n`wait` (0..DAEMON_POLL_MAX_WAIT_SECONDS) is the maximum time the\nhandler holds the connection waiting for work. Returns:\n\n  * 200 + `DaemonJobOut` once a job has been claimed.\n  * 204 No Content if no job arrives within `wait` seconds.\n\nConcurrency rule (AC-CONNECT-Q5): if an in-flight unresolved claim\nalready exists for this agent, returns 409 Conflict.\n\nVisibility timeout (AC-CONNECT-Q2): if `claimed_at` is older than\n`DAEMON_VISIBILITY_TIMEOUT_SECONDS`, the job is re-eligible. We\nissue a NEW `claim_token` on re-claim — a result POST with the\nstale token from the previous claim will 401, which is correct\nbehaviour (the previous owner is presumed dead).","operationId":"claim_next_job_api_v1_daemon_jobs_get","parameters":[{"name":"wait","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Wait"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DaemonJobOut"},{"type":"null"}],"title":"Response Claim Next Job Api V1 Daemon Jobs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/daemon/jobs/{job_id}/result":{"post":{"tags":["daemon"],"summary":"Submit Job Result","description":"Submit the result for a claimed job.\n\nIdempotent on `(job_id, claim_token)`. A duplicate POST returns the\nsame shape (200 + `{\"status\":\"already_recorded\"}`) so a daemon that\nretried after a network blip doesn't double-count.\n\nFailure responses:\n  * 401 — bearer token doesn't resolve to the job's agent, or\n          `claim_token` doesn't match.\n  * 404 — job_id doesn't exist or isn't this daemon's.\n  * 409 — job already completed with a DIFFERENT claim_token\n          (i.e. visibility-timeout re-claimed it; the original\n          daemon must drop its result).","operationId":"submit_job_result_api_v1_daemon_jobs__job_id__result_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DaemonJobResult"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Submit Job Result Api V1 Daemon Jobs  Job Id  Result Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/daemon/diagnostic":{"get":{"tags":["daemon"],"summary":"Daemon Diagnostic","description":"Admin-gated diagnostic — pairs with the diagnostic-endpoints memo.\n\nReturns parsed state for the daemon-pull + openai_assistant\nsubstrate so the operator can confirm without SSH whether:\n\n  * daemon tokens were minted at all (token_hash_count),\n  * any jobs are currently in-flight (in_flight_jobs),\n  * any daemons have gone dark (dead_daemons_24h),\n  * BADGE_FIELD_ENCRYPTION_KEY survived the CD env-render\n    (field_encryption_configured).","operationId":"daemon_diagnostic_api_v1_daemon_diagnostic_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DaemonDiagnostic"}}}}}}},"/health":{"get":{"tags":["system"],"summary":"Health check","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/database":{"get":{"tags":["system"],"summary":"Recent database connection failures (does not query the database)","description":"503 while a database connection failure was recorded in the last 15 min.\n\nBuilt for an external uptime monitor. It reads a Redis marker instead of\nconnecting to Postgres, so polling it never keeps Neon's compute awake.\nSee ``app.services.database_health``.","operationId":"health_database_health_database_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/dependencies":{"get":{"tags":["system"],"summary":"Probe configured external dependencies (Redis, etc.)","description":"Return per-dependency status for monitoring + post-deploy verification.\n\nCurrently probes Redis (rate-limiter backend). The endpoint is always 200\nso dashboards can read individual statuses without losing the full\npicture to a single failed dep — mirror the boot-log behaviour where\nRedis errors fail-open rather than crash the app.\n\nResponse shape (additive — new deps appended over time):\n  {\n    \"redis\": {\n      \"configured\": bool,        # is REDIS_URL set?\n      \"reachable\": bool | null,  # null when not configured\n      \"latency_ms\": float | null,\n      \"error\": str | null,       # categorical; never raw exception text\n    }\n  }","operationId":"health_dependencies_health_dependencies_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"tags":["system"],"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AdminAgentPatch":{"properties":{"description":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Description"},"is_public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public"}},"type":"object","title":"AdminAgentPatch","description":"Body for PATCH /admin/agents/{agent_id}.\n\nBoth fields are optional so a partial edit only touches what it names.\nWe use ``model_dump(exclude_unset=True)`` in the handler to distinguish\n\"field omitted\" from \"field set to null\" — so a caller CAN clear a\ndescription by sending ``{\"description\": null}`` explicitly, while a\ncaller who only flips visibility leaves the description untouched.\n\n``description`` is capped at 4000 chars — generous for the reference-agent\ncopy this is built to fix, but bounded so an admin PATCH can't write an\nunbounded blob into the Text column."},"AdminProviderCustodyNoticeAuthorization":{"properties":{"expected_recipient_count":{"type":"integer","maximum":100000.0,"minimum":0.0,"title":"Expected Recipient Count"},"expected_notice_version":{"type":"string","maxLength":64,"minLength":8,"pattern":"^[0-9a-f]+$","title":"Expected Notice Version"},"confirm_delivery":{"type":"boolean","title":"Confirm Delivery","default":false}},"type":"object","required":["expected_recipient_count","expected_notice_version"],"title":"AdminProviderCustodyNoticeAuthorization","description":"Body for POST /admin/provider-custody-notice/authorize-delivery.\n\nEPIC-KEYS-001A T2. This is the only request in the codebase whose success\nsends unsolicited mail to customers, so the body is an attestation, not a\ntrigger — every field must be transcribed from a preview the operator just\nread, and there is no default that makes an empty POST meaningful.\n\n``expected_recipient_count`` and ``expected_notice_version`` are checked\nagainst a freshly derived cohort in the handler and 409 on drift (see\n``services/provider_custody_notice_cohort.deliver_custody_notice``). That is\nwhat stops a stale preview from authorizing a batch the operator never saw:\na cohort that grew since the preview, or copy that changed under them, is\nrefused rather than silently sent.\n\nNothing here is or can become a recipient identity — an integer, a content\nhash, and a boolean."},"AdminScrubDescriptionsRequest":{"properties":{"find":{"type":"string","maxLength":500,"minLength":1,"title":"Find"},"replace":{"type":"string","maxLength":500,"title":"Replace","default":""},"dry_run":{"type":"boolean","title":"Dry Run","default":true}},"type":"object","required":["find"],"title":"AdminScrubDescriptionsRequest","description":"Body for POST /admin/agents/scrub-descriptions.\n\nBulk substring find/replace across every agent whose description contains\n``find``. ``find`` is required and non-empty (an empty needle would match\nevery row — a foot-gun we refuse at the schema boundary). ``replace``\ndefaults to \"\" (the delete-a-substring case, e.g. stripping the\n\"(PRD-016 FR-11 demo frontier)\" marker off the 60 reference agents).\n``dry_run`` defaults to True so a stray call previews without writing."},"AdminSupportErasureRequest":{"properties":{"sender_email":{"type":"string","format":"email","title":"Sender Email"},"confirm_sender_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Confirm Sender Email"},"source_mailbox_purged":{"type":"boolean","title":"Source Mailbox Purged","default":false},"expected_row_count":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":0.0},{"type":"null"}],"title":"Expected Row Count"},"dry_run":{"type":"boolean","title":"Dry Run","default":true}},"type":"object","required":["sender_email"],"title":"AdminSupportErasureRequest","description":"Source-purge-first targeted support-message erasure (PRD-025).\n\nA preview is the safe default and needs only a valid sender email.  Execute\nmode is intentionally verbose: the operator must attest that the source\nmailbox was purged, repeat the normalized email, and confirm the exact row\ncount observed in the preview.  The endpoint never returns either email."},"AdminSupportMessagePatch":{"properties":{"is_read":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Read"},"status":{"anyOf":[{"type":"string","pattern":"^(open|resolved)$"},{"type":"null"}],"title":"Status"}},"type":"object","title":"AdminSupportMessagePatch","description":"Body for PATCH /admin/support/{id} (BRIEF-SUPPORT-001).\n\nBoth fields optional so a partial edit only touches what it names\n(``exclude_unset`` in the handler). ``status`` is a closed set — open or\nresolved — validated here so a bad value 422s at the boundary rather than\nwriting an unknown state."},"AdminSupportReplyRequest":{"properties":{"body_text":{"type":"string","maxLength":20000,"minLength":1,"title":"Body Text"},"idempotency_key":{"type":"string","format":"uuid","title":"Idempotency Key"}},"type":"object","required":["body_text","idempotency_key"],"title":"AdminSupportReplyRequest","description":"One idempotent, plain-text reply from the admin Support detail."},"AdminTaskCreate":{"properties":{"title":{"type":"string","maxLength":255,"minLength":1,"title":"Title"},"description":{"type":"string","minLength":1,"title":"Description"},"domain":{"$ref":"#/components/schemas/TaskDomain","default":"code_generation"},"difficulty":{"$ref":"#/components/schemas/TaskDifficulty","default":"medium"},"prompt":{"type":"string","minLength":1,"title":"Prompt"},"max_tokens_hint":{"type":"integer","maximum":32768.0,"minimum":64.0,"title":"Max Tokens Hint","default":2048},"expected_output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Output"},"is_secret":{"type":"boolean","title":"Is Secret","default":true},"suite_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Suite Id"},"suite_version":{"type":"integer","minimum":1.0,"title":"Suite Version","default":1}},"type":"object","required":["title","description","prompt"],"title":"AdminTaskCreate","description":"Secret-safe body for POST /admin/tasks.\n\nThe legacy global task endpoint remains backward compatible. This stricter\nadmin surface trims every text field before validation, defaults holdout\nprotection on, and refuses a malformed secret suite row at the server\nboundary even if a client bypasses the browser form."},"AdminTaskCreateResult":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"title":{"type":"string","title":"Title"},"domain":{"$ref":"#/components/schemas/TaskDomain"},"difficulty":{"$ref":"#/components/schemas/TaskDifficulty"},"is_secret":{"type":"boolean","title":"Is Secret"},"suite_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suite Id"},"suite_version":{"type":"integer","title":"Suite Version"}},"type":"object","required":["id","title","domain","difficulty","is_secret","suite_id","suite_version"],"title":"AdminTaskCreateResult","description":"Metadata-only create response. Never echoes authored task contents."},"AdminTeamDeletionRequest":{"properties":{"dry_run":{"type":"boolean","title":"Dry Run","default":true},"confirm_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Confirm Name"},"expected_member_count":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":0.0},{"type":"null"}],"title":"Expected Member Count"},"expected_agent_count":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":0.0},{"type":"null"}],"title":"Expected Agent Count"},"acknowledge_agent_reassignment":{"type":"boolean","title":"Acknowledge Agent Reassignment","default":false}},"type":"object","title":"AdminTeamDeletionRequest","description":"Body for POST /admin/teams/{team_id}/deletion.\n\nDeleting a team reassigns its workspace agents to the owner's personal\nscope and removes every membership, so the body is an attestation, not a\ntrigger — the PRD-025 contract (`AdminSupportErasureRequest`) applied to a\ndestructive tenant operation:\n\n  • `dry_run` defaults to TRUE. An empty POST previews and never deletes.\n  • Execute requires the team's name typed back exactly. A name is a\n    deliberate act to reproduce; a button is a reflex.\n  • Execute requires the member and agent counts the operator just read.\n    A stale preview — a member accepted an invitation in the meantime —\n    409s instead of silently deleting something larger than was reviewed.\n  • `acknowledge_agent_reassignment` states the surprising consequence in\n    words, mirroring `source_mailbox_purged`, so a half-built or replayed\n    request body cannot delete.\n\n`confirm_name` is compared to the live team name in the handler and is\nnever echoed back, logged, or written to the audit `detail`."},"AdminTeamRename":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"AdminTeamRename","description":"Body for PATCH /admin/teams/{team_id}.\n\nRename only. Plan, seats, and ownership are deliberately NOT editable here:\neach is an entitlement with its own enforcement path (`plan_limits`,\n`ensure_seat_available`, `create_team`), and letting an operator poke them\nfrom a console would route around every one of those checks. A name is the\none field with no downstream semantics — nothing authorizes on it.\n\n`teams.name` is UNIQUE, so the handler converts an IntegrityError into a\n409 rather than surfacing a driver error."},"AdminWaitlistContactPatch":{"properties":{"contacted":{"type":"boolean","title":"Contacted"}},"type":"object","required":["contacted"],"title":"AdminWaitlistContactPatch","description":"Body for PATCH /admin/waitlists/enterprise/{id} (BIZ-007 §7 tracking).\n\nA single required boolean. ``contacted=true`` stamps ``contacted_at`` with\nthe SERVER's clock; ``contacted=false`` clears it (undo). The client never\nsupplies a timestamp — the handler owns it — so a skewed or forged client\nclock can't land in the row. Not-destructive → a plain toggle, no confirm\ncontract (unlike the erasure request above)."},"AffectedAgent":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"}},"type":"object","required":["agent_id","agent_name"],"title":"AffectedAgent"},"AgentBulkCreate":{"properties":{"agents":{"items":{"$ref":"#/components/schemas/AgentCreate"},"type":"array","maxItems":100,"minItems":1,"title":"Agents"}},"type":"object","required":["agents"],"title":"AgentBulkCreate","description":"Bulk-create payload for the /agents/bulk endpoint (RES-009 §X #13).\n\nCaps the batch at 100 to keep a single request bounded — past that the\nuser should split into multiple POSTs so a partial failure is\ndiagnosable. The response surfaces per-row results so the caller can\nshow line-numbered errors."},"AgentBulkResult":{"properties":{"created_count":{"type":"integer","title":"Created Count"},"skipped_count":{"type":"integer","title":"Skipped Count"},"error_count":{"type":"integer","title":"Error Count"},"rows":{"items":{"$ref":"#/components/schemas/AgentBulkResultRow"},"type":"array","title":"Rows"}},"type":"object","required":["created_count","skipped_count","error_count","rows"],"title":"AgentBulkResult"},"AgentBulkResultRow":{"properties":{"index":{"type":"integer","title":"Index"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"agent_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent Id"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["index","name","status"],"title":"AgentBulkResultRow"},"AgentCapabilityRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"capability_type":{"type":"string","title":"Capability Type"},"name":{"type":"string","title":"Name"},"proficiency_score":{"type":"number","title":"Proficiency Score"},"evidence_run_count":{"type":"integer","title":"Evidence Run Count"},"last_assessed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Assessed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","agent_id","capability_type","name","proficiency_score","evidence_run_count","last_assessed_at","created_at","updated_at"],"title":"AgentCapabilityRead","description":"Read a capability."},"AgentCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name","examples":["GPT-4o-agent"]},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"},"endpoint":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Endpoint","examples":["https://api.example.com/agent"]},"team_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Team Id","description":"Create directly as a workspace-owned agent."},"manifest_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Manifest Url"},"provider_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Provider Name"},"provider_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Provider Url"},"model_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Model Name"},"model_provider":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Model Provider"},"architecture":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Architecture"},"agent_version":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Agent Version"},"domains":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Domains","description":"Comma-separated domain list"},"tags":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Tags","description":"Comma-separated tags"},"payload_schema":{"type":"string","enum":["badge_native","openai_chat","anthropic_messages"],"title":"Payload Schema","description":"Outbound request body shape — see arena._build_request_payload.","default":"badge_native"},"connection_mode":{"type":"string","enum":["http_endpoint","daemon_pull"],"title":"Connection Mode","description":"Supported connectivity mode. 'http_endpoint' dispatches to a customer-controlled HTTPS endpoint; 'daemon_pull' uses the customer-side daemon when enabled.","default":"http_endpoint"}},"type":"object","required":["name"],"title":"AgentCreate"},"AgentJsonLd":{"properties":{"@context":{"type":"string","title":"@Context","default":"https://schema.org"},"@type":{"type":"string","title":"@Type","default":"SoftwareApplication"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"applicationCategory":{"type":"string","title":"Applicationcategory","default":"Productivity"},"operatingSystem":{"type":"string","title":"Operatingsystem","default":"Any"},"url":{"type":"string","title":"Url"},"aggregateRating":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Aggregaterating"},"creator":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Creator"}},"type":"object","required":["name","url"],"title":"AgentJsonLd","description":"JSON-LD ``SoftwareApplication`` payload for an agent profile (FR-12).\n\nThe shape is the actual Schema.org payload — frontend dumps it\nverbatim into a ``<script type=\"application/ld+json\">`` tag."},"AgentListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AgentRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"},"visibility_counts":{"$ref":"#/components/schemas/AgentVisibilityCounts"}},"type":"object","required":["items","total","page","page_size","pages","visibility_counts"],"title":"AgentListResponse","description":"Paginated agent rows plus totals that are independent of page size."},"AgentManifest":{"properties":{"schema_version":{"type":"string","maxLength":20,"title":"Schema Version","default":"2.0"},"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name","examples":["Explorer-Llama"]},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"},"version":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Version","examples":["1.2.0"]},"provider":{"anyOf":[{"$ref":"#/components/schemas/ManifestProvider"},{"type":"null"}]},"endpoint":{"anyOf":[{"$ref":"#/components/schemas/ManifestEndpoint"},{"type":"null"}]},"capabilities":{"anyOf":[{"$ref":"#/components/schemas/ManifestCapabilities"},{"type":"null"}]},"model":{"anyOf":[{"$ref":"#/components/schemas/ManifestModel"},{"type":"null"}]},"auth":{"anyOf":[{"$ref":"#/components/schemas/ManifestAuth"},{"type":"null"}]},"evaluation":{"anyOf":[{"$ref":"#/components/schemas/ManifestEvaluation"},{"type":"null"}]},"schemas":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Schemas","description":"JSON Schema definitions for input/output contracts"},"benchmarks":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Benchmarks","description":"Self-reported benchmark scores (e.g. {humaneval: 0.82})"},"meta":{"anyOf":[{"$ref":"#/components/schemas/ManifestMeta"},{"type":"null"}]},"ml_bom":{"anyOf":[{"$ref":"#/components/schemas/ManifestMLBom"},{"type":"null"}]},"provenance_public_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provenance Public Key","description":"JWK JSON string (Ed25519 OKP only in W1)"},"signatures":{"anyOf":[{"items":{"$ref":"#/components/schemas/ManifestSignature"},"type":"array"},{"type":"null"}],"title":"Signatures"}},"type":"object","required":["name"],"title":"Badge Agent Manifest v2 (ARP)","description":"The full agent manifest served at /.well-known/agent.json — ARP v2"},"AgentOtlpTokenResponse":{"properties":{"otlp_ingest_token":{"type":"string","title":"Otlp Ingest Token"},"otlp_endpoint":{"type":"string","title":"Otlp Endpoint"},"action":{"type":"string","enum":["created","rotated"],"title":"Action"}},"type":"object","required":["otlp_ingest_token","otlp_endpoint","action"],"title":"AgentOtlpTokenResponse","description":"Single-reveal agent-scoped OTLP credential response."},"AgentRead":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name","examples":["GPT-4o-agent"]},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"},"endpoint":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Endpoint","examples":["https://api.example.com/agent"]},"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"ownership_scope":{"type":"string","enum":["personal","workspace","system"],"title":"Ownership Scope","default":"system"},"team_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Team Id"},"can_edit":{"type":"boolean","title":"Can Edit","default":false},"can_run_configured":{"type":"boolean","title":"Can Run Configured","default":false},"credential_reconnect_required":{"type":"boolean","title":"Credential Reconnect Required","default":false},"architecture_staleness":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Architecture Staleness"},"connection_retired":{"type":"boolean","title":"Connection Retired","default":false},"has_endpoint":{"type":"boolean","title":"Has Endpoint","default":false},"workspace_role":{"anyOf":[{"type":"string","enum":["owner","admin","member","viewer"]},{"type":"null"}],"title":"Workspace Role"},"has_otlp_ingest_token":{"type":"boolean","title":"Has Otlp Ingest Token","default":false},"is_active":{"type":"boolean","title":"Is Active"},"is_public":{"type":"boolean","title":"Is Public","default":true},"is_reference":{"type":"boolean","title":"Is Reference","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"connection_mode":{"anyOf":[{"type":"string","enum":["http_endpoint","daemon_pull","openai_assistant","customer_llm"]},{"type":"null"}],"title":"Connection Mode"},"daemon_last_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Daemon Last Seen At"},"customer_llm_provider":{"anyOf":[{"type":"string","enum":["gemini","openai_compat"]},{"type":"null"}],"title":"Customer Llm Provider"},"customer_llm_key_last4":{"anyOf":[{"type":"string","maxLength":4},{"type":"null"}],"title":"Customer Llm Key Last4"},"manifest_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manifest Url"},"provider_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Name"},"provider_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Url"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"model_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Provider"},"architecture":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Architecture"},"schema_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema Version"},"agent_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Version"},"domains":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domains"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Verified At"},"registry_status":{"type":"string","title":"Registry Status","default":"unverified"},"variant_of":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Variant Of"},"payload_schema":{"type":"string","enum":["badge_native","openai_chat","anthropic_messages"],"title":"Payload Schema","default":"badge_native"},"created_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By User Id","description":"UUID of the workspace member who registered this agent (null for transferred/legacy rows whose creator was never recorded, or whose creator account was deleted — the FK is ON DELETE SET NULL). Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission (Owner/Admin); null on every other path and for members and viewers. The raw id only — no name, no email."},"composite_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Composite Score","description":"Cross-task overall composite score, ALREADY on a 0-100 scale — never multiply or divide it (CLAUDE.md rule 2). Null when the agent has no cross-task Score row yet. Agent-level and NOT workspace-scoped: it is derived from every run the agent ever completed, including any from before a transfer, and is the same number a public agent shows on the Talent Pool. Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission; null on every other path."},"total_runs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Runs","description":"Count of COMPLETED runs this agent performed FOR THIS WORKSPACE. Runs from before a transfer are personal-scoped and are excluded, so a freshly transferred agent reports 0 here while its composite score still reflects them. 0 (not null) when there are none. Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission; null on every other path."},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At","description":"When this agent last started a completed run FOR THIS WORKSPACE. Derived from the run START (SEC-RUNS-009), not its completion. Null when there are no completed workspace runs — pre-transfer personal runs never surface here. Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission; null on every other path."},"verified_state":{"anyOf":[{"type":"string","enum":["verified","simulated","unverified"]},{"type":"null"}],"title":"Verified State","description":"Execution provenance for this agent's signed WORKSPACE runs: 'verified' (has a signed real-execution workspace run), 'simulated' (signed workspace runs, all mock), or 'unverified' (no signed workspace run at all — the value, not null, when the field is populated). A pre-transfer personal run cannot light this, so it may read 'unverified' while the public board shows a ✓ for the same agent. Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission; null on every other path."},"has_openai_credentials":{"type":"boolean","title":"Has Openai Credentials","readOnly":true},"has_customer_llm_key":{"type":"boolean","title":"Has Customer Llm Key","readOnly":true},"ml_bom":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ml Bom","readOnly":true},"provenance_public_key_set":{"type":"boolean","title":"Provenance Public Key Set","readOnly":true}},"type":"object","required":["name","id","is_active","created_at","updated_at","has_openai_credentials","has_customer_llm_key","ml_bom","provenance_public_key_set"],"title":"AgentRead"},"AgentReadinessRead":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"connection_mode":{"type":"string","title":"Connection Mode"},"endpoint":{"$ref":"#/components/schemas/EndpointReadinessRead"},"telemetry":{"$ref":"#/components/schemas/TelemetryReadinessRead"},"stale_token_failures":{"anyOf":[{"$ref":"#/components/schemas/OtlpStaleTokenFailureRead"},{"type":"null"}]},"execution_ready":{"type":"boolean","title":"Execution Ready"},"recovery":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recovery"}},"type":"object","required":["agent_id","connection_mode","endpoint","telemetry","execution_ready","recovery"],"title":"AgentReadinessRead"},"AgentRegisterResponse":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name","examples":["GPT-4o-agent"]},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"},"endpoint":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Endpoint","examples":["https://api.example.com/agent"]},"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"ownership_scope":{"type":"string","enum":["personal","workspace","system"],"title":"Ownership Scope","default":"system"},"team_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Team Id"},"can_edit":{"type":"boolean","title":"Can Edit","default":false},"can_run_configured":{"type":"boolean","title":"Can Run Configured","default":false},"credential_reconnect_required":{"type":"boolean","title":"Credential Reconnect Required","default":false},"architecture_staleness":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Architecture Staleness"},"connection_retired":{"type":"boolean","title":"Connection Retired","default":false},"has_endpoint":{"type":"boolean","title":"Has Endpoint","default":false},"workspace_role":{"anyOf":[{"type":"string","enum":["owner","admin","member","viewer"]},{"type":"null"}],"title":"Workspace Role"},"has_otlp_ingest_token":{"type":"boolean","title":"Has Otlp Ingest Token","default":false},"is_active":{"type":"boolean","title":"Is Active"},"is_public":{"type":"boolean","title":"Is Public","default":true},"is_reference":{"type":"boolean","title":"Is Reference","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"connection_mode":{"anyOf":[{"type":"string","enum":["http_endpoint","daemon_pull","openai_assistant","customer_llm"]},{"type":"null"}],"title":"Connection Mode"},"daemon_last_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Daemon Last Seen At"},"customer_llm_provider":{"anyOf":[{"type":"string","enum":["gemini","openai_compat"]},{"type":"null"}],"title":"Customer Llm Provider"},"customer_llm_key_last4":{"anyOf":[{"type":"string","maxLength":4},{"type":"null"}],"title":"Customer Llm Key Last4"},"manifest_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manifest Url"},"provider_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Name"},"provider_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Url"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"model_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Provider"},"architecture":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Architecture"},"schema_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schema Version"},"agent_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Version"},"domains":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domains"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Verified At"},"registry_status":{"type":"string","title":"Registry Status","default":"unverified"},"variant_of":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Variant Of"},"payload_schema":{"type":"string","enum":["badge_native","openai_chat","anthropic_messages"],"title":"Payload Schema","default":"badge_native"},"created_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By User Id","description":"UUID of the workspace member who registered this agent (null for transferred/legacy rows whose creator was never recorded, or whose creator account was deleted — the FK is ON DELETE SET NULL). Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission (Owner/Admin); null on every other path and for members and viewers. The raw id only — no name, no email."},"composite_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Composite Score","description":"Cross-task overall composite score, ALREADY on a 0-100 scale — never multiply or divide it (CLAUDE.md rule 2). Null when the agent has no cross-task Score row yet. Agent-level and NOT workspace-scoped: it is derived from every run the agent ever completed, including any from before a transfer, and is the same number a public agent shows on the Talent Pool. Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission; null on every other path."},"total_runs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Runs","description":"Count of COMPLETED runs this agent performed FOR THIS WORKSPACE. Runs from before a transfer are personal-scoped and are excluded, so a freshly transferred agent reports 0 here while its composite score still reflects them. 0 (not null) when there are none. Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission; null on every other path."},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At","description":"When this agent last started a completed run FOR THIS WORKSPACE. Derived from the run START (SEC-RUNS-009), not its completion. Null when there are no completed workspace runs — pre-transfer personal runs never surface here. Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission; null on every other path."},"verified_state":{"anyOf":[{"type":"string","enum":["verified","simulated","unverified"]},{"type":"null"}],"title":"Verified State","description":"Execution provenance for this agent's signed WORKSPACE runs: 'verified' (has a signed real-execution workspace run), 'simulated' (signed workspace runs, all mock), or 'unverified' (no signed workspace run at all — the value, not null, when the field is populated). A pre-transfer personal run cannot light this, so it may read 'unverified' while the public board shows a ✓ for the same agent. Populated ONLY on GET /agents?team_id=... for a caller with workspace-analytics permission; null on every other path."},"daemon_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Daemon Token","description":"Plaintext bearer token for the badgeia-cli daemon. ONLY returned on agent registration; cannot be recovered. Set to None for non-daemon modes."},"has_openai_credentials":{"type":"boolean","title":"Has Openai Credentials","readOnly":true},"has_customer_llm_key":{"type":"boolean","title":"Has Customer Llm Key","readOnly":true},"ml_bom":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ml Bom","readOnly":true},"provenance_public_key_set":{"type":"boolean","title":"Provenance Public Key Set","readOnly":true}},"type":"object","required":["name","id","is_active","created_at","updated_at","has_openai_credentials","has_customer_llm_key","ml_bom","provenance_public_key_set"],"title":"AgentRegisterResponse","description":"Response shape for POST /api/v1/agents — extended for CONNECT-001.\n\nBackward compatible with the pre-CONNECT-001 `AgentRead` contract:\ncallers reading `id`, `name`, `endpoint`, `is_public`, etc. continue\nto work unchanged. We add one field — `daemon_token` — which carries\nthe plaintext bearer token for `connection_mode='daemon_pull'` and\nis `None` for every other mode.\n\n**`daemon_token` is the only time the token is ever exposed.**\nSubsequent reads return only `daemon_last_seen_at` and the\n`has_openai_credentials` presence flag — no secret material.\n\nThe frontend Register Agent wizard surfaces the token with a\n\"copy and save it; it cannot be shown again\" callout before\nnavigating away from the success page."},"AgentStatsResponse":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"total_runs":{"type":"integer","title":"Total Runs"},"successful_runs":{"type":"integer","title":"Successful Runs"},"failed_runs":{"type":"integer","title":"Failed Runs"},"avg_latency_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Latency Ms"},"avg_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Cost Usd"},"reliability_score":{"type":"number","title":"Reliability Score"},"completion_rate":{"type":"number","title":"Completion Rate","default":0.0},"cost_score":{"type":"number","title":"Cost Score","default":0.0},"composite_score":{"type":"number","title":"Composite Score","default":0.0},"best_task":{"anyOf":[{"$ref":"#/components/schemas/TaskStats"},{"type":"null"}]},"worst_task":{"anyOf":[{"$ref":"#/components/schemas/TaskStats"},{"type":"null"}]},"recent_runs":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Recent Runs"},"verified_state":{"type":"string","title":"Verified State","default":"unverified"},"cost_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost Basis"}},"type":"object","required":["agent_id","total_runs","successful_runs","failed_runs","avg_latency_ms","avg_cost_usd","reliability_score","best_task","worst_task","recent_runs"],"title":"AgentStatsResponse"},"AgentTransferToWorkspace":{"properties":{"team_id":{"type":"string","format":"uuid","title":"Team Id"},"confirm":{"type":"boolean","title":"Confirm","description":"Explicitly confirm permanent workspace ownership."}},"type":"object","required":["team_id","confirm"],"title":"AgentTransferToWorkspace"},"AgentUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"is_public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public","description":"Agent visibility. Flipping to False requires a paid plan."},"manifest_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manifest Url"},"provider_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Name"},"provider_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Url"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"model_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Provider"},"architecture":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Architecture"},"agent_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Version"},"domains":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domains"},"tags":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"},"payload_schema":{"anyOf":[{"type":"string","enum":["badge_native","openai_chat","anthropic_messages"]},{"type":"null"}],"title":"Payload Schema"},"connection_mode":{"type":"string","enum":["http_endpoint","daemon_pull"],"title":"Connection Mode","description":"Supported connectivity mode. 'http_endpoint' dispatches to a customer-controlled HTTPS endpoint; 'daemon_pull' uses the customer-side daemon when enabled."},"clear_customer_llm_key":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Clear Customer Llm Key","description":"When true, removes the attached LLM key (NULLs key + provider)."},"variant_of":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Variant Of"}},"type":"object","title":"AgentUpdate"},"AgentVisibilityCounts":{"properties":{"public":{"type":"integer","title":"Public"},"workspace_only":{"type":"integer","title":"Workspace Only"}},"type":"object","required":["public","workspace_only"],"title":"AgentVisibilityCounts","description":"Visibility facets for the complete access-filtered agent result set."},"ApiKeyBulkRevoke":{"properties":{"ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":200,"title":"Ids"},"all":{"type":"boolean","title":"All","default":false}},"type":"object","title":"ApiKeyBulkRevoke","description":"Bulk-revoke specific keys by ID, or every active key (`all=true`).\n\nEither `ids` or `all` must be provided. `all=true` ignores `ids`. Revoke\nis soft (sets `is_active=False`) — same as DELETE /api-keys/{id}."},"ApiKeyBulkRevokeResult":{"properties":{"revoked_count":{"type":"integer","title":"Revoked Count"},"revoked_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Revoked Ids"}},"type":"object","required":["revoked_count","revoked_ids"],"title":"ApiKeyBulkRevokeResult"},"ApiKeyCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"scopes":{"type":"string","maxLength":200,"title":"Scopes","default":"read,write"},"rate_limit_per_minute":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Rate Limit Per Minute","default":60},"rate_limit_per_day":{"type":"integer","maximum":1000000.0,"minimum":1.0,"title":"Rate Limit Per Day","default":10000}},"type":"object","required":["name"],"title":"ApiKeyCreate"},"ApiKeyCreated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"scopes":{"type":"string","title":"Scopes"},"rate_limit_per_minute":{"type":"integer","title":"Rate Limit Per Minute"},"rate_limit_per_day":{"type":"integer","title":"Rate Limit Per Day"},"total_requests":{"type":"integer","title":"Total Requests"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"is_active":{"type":"boolean","title":"Is Active"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"full_key":{"type":"string","title":"Full Key"}},"type":"object","required":["id","name","key_prefix","scopes","rate_limit_per_minute","rate_limit_per_day","total_requests","last_used_at","is_active","expires_at","created_at","full_key"],"title":"ApiKeyCreated","description":"Returned only on creation — includes the full key (shown once)."},"ApiKeyRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"scopes":{"type":"string","title":"Scopes"},"rate_limit_per_minute":{"type":"integer","title":"Rate Limit Per Minute"},"rate_limit_per_day":{"type":"integer","title":"Rate Limit Per Day"},"total_requests":{"type":"integer","title":"Total Requests"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"is_active":{"type":"boolean","title":"Is Active"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","key_prefix","scopes","rate_limit_per_minute","rate_limit_per_day","total_requests","last_used_at","is_active","expires_at","created_at"],"title":"ApiKeyRead"},"ApiKeyRotated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"scopes":{"type":"string","title":"Scopes"},"rate_limit_per_minute":{"type":"integer","title":"Rate Limit Per Minute"},"rate_limit_per_day":{"type":"integer","title":"Rate Limit Per Day"},"total_requests":{"type":"integer","title":"Total Requests"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"is_active":{"type":"boolean","title":"Is Active"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"full_key":{"type":"string","title":"Full Key"},"rotated_from_id":{"type":"string","format":"uuid","title":"Rotated From Id"},"new_id":{"type":"string","format":"uuid","title":"New Id"}},"type":"object","required":["id","name","key_prefix","scopes","rate_limit_per_minute","rate_limit_per_day","total_requests","last_used_at","is_active","expires_at","created_at","full_key","rotated_from_id","new_id"],"title":"ApiKeyRotated","description":"Returned by POST /api-keys/{id}/rotate.\n\n`id` is the OLD key's id, kept for the client to map UI rows. The new key\nhas its own id, prefix, key_hash; the old key is soft-revoked. Includes the\nnew full key — shown once."},"ApiKeyUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"scopes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scopes"},"rate_limit_per_minute":{"anyOf":[{"type":"integer","maximum":1000.0,"minimum":1.0},{"type":"null"}],"title":"Rate Limit Per Minute"},"rate_limit_per_day":{"anyOf":[{"type":"integer","maximum":1000000.0,"minimum":1.0},{"type":"null"}],"title":"Rate Limit Per Day"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"ApiKeyUpdate"},"ApiKeyUsage":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"total_requests":{"type":"integer","title":"Total Requests"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"days_since_last_use":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days Since Last Use","description":"Days since last_used_at, or None if never used."},"days_since_created":{"type":"integer","title":"Days Since Created","description":"Days since the key was created."},"avg_requests_per_day":{"type":"number","title":"Avg Requests Per Day","description":"total_requests / max(days_since_created, 1)."},"rate_limit_per_minute":{"type":"integer","title":"Rate Limit Per Minute"},"rate_limit_per_day":{"type":"integer","title":"Rate Limit Per Day"},"is_active":{"type":"boolean","title":"Is Active"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["id","total_requests","last_used_at","days_since_created","avg_requests_per_day","rate_limit_per_minute","rate_limit_per_day","is_active","expires_at"],"title":"ApiKeyUsage","description":"Per-key usage summary derived from existing fields. No new event log."},"ApprovalAccess":{"properties":{"can_view_queue":{"type":"boolean","title":"Can View Queue"},"can_approve":{"type":"boolean","title":"Can Approve"},"can_edit_policy":{"type":"boolean","title":"Can Edit Policy"},"can_request":{"type":"boolean","title":"Can Request"},"plan_lapsed":{"type":"boolean","title":"Plan Lapsed"}},"type":"object","required":["can_view_queue","can_approve","can_edit_policy","can_request","plan_lapsed"],"title":"ApprovalAccess","description":"What this caller may do in the workspace's approvals, derived server-side."},"ApprovalList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ApprovalRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"ApprovalList"},"ApprovalPolicyRead":{"properties":{"team_id":{"type":"string","format":"uuid","title":"Team Id"},"configured":{"type":"boolean","title":"Configured"},"required_suite_ids":{"items":{"type":"string"},"type":"array","title":"Required Suite Ids"},"min_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Score"},"min_pass_k":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Min Pass K"},"max_measured_cost_per_run":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Measured Cost Per Run"},"require_sbom":{"type":"boolean","title":"Require Sbom"},"approver_roles":{"items":{"type":"string"},"type":"array","title":"Approver Roles"},"min_approvers":{"type":"integer","title":"Min Approvers"},"expiry_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expiry Days"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["team_id","configured","required_suite_ids","min_score","min_pass_k","max_measured_cost_per_run","require_sbom","approver_roles","min_approvers","expiry_days","updated_at"],"title":"ApprovalPolicyRead"},"ApprovalPolicySaved":{"properties":{"team_id":{"type":"string","format":"uuid","title":"Team Id"},"configured":{"type":"boolean","title":"Configured"},"required_suite_ids":{"items":{"type":"string"},"type":"array","title":"Required Suite Ids"},"min_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Score"},"min_pass_k":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Min Pass K"},"max_measured_cost_per_run":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Measured Cost Per Run"},"require_sbom":{"type":"boolean","title":"Require Sbom"},"approver_roles":{"items":{"type":"string"},"type":"array","title":"Approver Roles"},"min_approvers":{"type":"integer","title":"Min Approvers"},"expiry_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expiry Days"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"revoked_count":{"type":"integer","title":"Revoked Count","default":0},"affected":{"items":{"$ref":"#/components/schemas/AffectedAgent"},"type":"array","title":"Affected"}},"type":"object","required":["team_id","configured","required_suite_ids","min_score","min_pass_k","max_measured_cost_per_run","require_sbom","approver_roles","min_approvers","expiry_days","updated_at"],"title":"ApprovalPolicySaved","description":"The saved policy plus what the change ended (revoked or expired approvals)."},"ApprovalPolicyWrite":{"properties":{"required_suite_ids":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Required Suite Ids"},"min_score":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Min Score"},"min_pass_k":{"anyOf":[{"$ref":"#/components/schemas/PassKRequirement"},{"type":"null"}]},"max_measured_cost_per_run":{"anyOf":[{"type":"number","maximum":999999.0,"minimum":0.0},{"type":"null"}],"title":"Max Measured Cost Per Run"},"require_sbom":{"type":"boolean","title":"Require Sbom","default":false},"approver_roles":{"items":{"type":"string","enum":["owner","admin","member"]},"type":"array","title":"Approver Roles"},"min_approvers":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Min Approvers","default":1},"expiry_days":{"anyOf":[{"type":"integer","maximum":3650.0,"minimum":1.0},{"type":"null"}],"title":"Expiry Days"}},"additionalProperties":false,"type":"object","title":"ApprovalPolicyWrite","description":"Full replace: every omitted field returns to its default."},"ApprovalRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"team_id":{"type":"string","format":"uuid","title":"Team Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name"},"status":{"type":"string","enum":["candidate","approved","rejected","revoked","expired"],"title":"Status"},"blueprint_version_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Blueprint Version Id"},"requested_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Requested By"},"requested_by_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested By Label"},"evidence_snapshot":{"additionalProperties":true,"type":"object","title":"Evidence Snapshot"},"gates":{"items":{"$ref":"#/components/schemas/GateResult"},"type":"array","title":"Gates"},"decided_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Decided At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revoked Reason"},"revoke_comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revoke Comment"},"revoked_by_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revoked By Label"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"approvals_count":{"type":"integer","title":"Approvals Count"},"approvals_required":{"type":"integer","title":"Approvals Required"},"decisions":{"items":{"$ref":"#/components/schemas/DecisionRead"},"type":"array","title":"Decisions"}},"type":"object","required":["id","team_id","agent_id","agent_name","status","blueprint_version_id","requested_by","requested_by_label","evidence_snapshot","gates","decided_at","expires_at","revoked_reason","revoke_comment","revoked_by_label","revoked_at","created_at","approvals_count","approvals_required","decisions"],"title":"ApprovalRead"},"AuditCheckpointRead":{"properties":{"seq":{"type":"integer","title":"Seq"},"head_hash":{"type":"string","title":"Head Hash"},"signed_at":{"type":"string","title":"Signed At"},"key_id":{"type":"string","title":"Key Id"},"signature":{"type":"string","title":"Signature"},"format":{"type":"string","title":"Format"},"signature_status":{"type":"string","enum":["valid","invalid","key_rotated"],"title":"Signature Status"},"signature_valid":{"type":"boolean","title":"Signature Valid"}},"type":"object","required":["seq","head_hash","signed_at","key_id","signature","format","signature_status","signature_valid"],"title":"AuditCheckpointRead","description":"A signed checkpoint receipt.\n\nSigned bytes: ``b\"badge-audit-checkpoint-v1\\0\"`` followed by\n``canonical_json({team_id, seq, head_hash, signed_at})`` (sorted keys, no\nspaces), Ed25519 under the key named by ``key_id``."},"AuditEventRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"seq":{"type":"integer","title":"Seq"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"actor_type":{"type":"string","title":"Actor Type"},"actor_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor User Id"},"actor_ref_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Ref Hash"},"actor_label":{"type":"string","title":"Actor Label"},"actor_display_hash":{"type":"string","title":"Actor Display Hash"},"action":{"type":"string","title":"Action"},"target_type":{"type":"string","title":"Target Type"},"target_id":{"type":"string","title":"Target Id"},"target_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Label"},"target_label_hash":{"type":"string","title":"Target Label Hash"},"before_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Before Hash"},"after_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"After Hash"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"metadata_hash":{"type":"string","title":"Metadata Hash"},"redacted":{"type":"boolean","title":"Redacted"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"prev_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prev Hash"},"hash":{"type":"string","title":"Hash"}},"type":"object","required":["id","seq","created_at","actor_type","actor_user_id","actor_ref_hash","actor_label","actor_display_hash","action","target_type","target_id","target_label","target_label_hash","before_hash","after_hash","metadata","metadata_hash","redacted","request_id","ip_address","prev_hash","hash"],"title":"AuditEventRead"},"AuditVerifyRead":{"properties":{"valid":{"type":"boolean","title":"Valid"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"checked":{"type":"integer","title":"Checked"},"first_invalid_seq":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"First Invalid Seq"},"head_seq":{"type":"integer","title":"Head Seq"},"head_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Head Hash"},"checkpoints_checked":{"type":"integer","title":"Checkpoints Checked"},"checkpoints_expected":{"type":"integer","title":"Checkpoints Expected"},"last_checkpoint":{"anyOf":[{"$ref":"#/components/schemas/AuditCheckpointRead"},{"type":"null"}]}},"type":"object","required":["valid","reason","checked","first_invalid_seq","head_seq","head_hash","checkpoints_checked","checkpoints_expected","last_checkpoint"],"title":"AuditVerifyRead"},"AxisSegmentPageData":{"properties":{"axis":{"type":"string","title":"Axis"},"value":{"type":"string","title":"Value"},"label":{"type":"string","title":"Label"},"total_agents":{"type":"integer","title":"Total Agents"},"is_indexable":{"type":"boolean","title":"Is Indexable","description":"False when count < MIN_AGENTS_PER_SEGMENT — render noindex."},"agents":{"items":{"$ref":"#/components/schemas/PublicAgentSEO"},"type":"array","title":"Agents"},"canonical_path":{"type":"string","title":"Canonical Path","description":"Self-referential canonical URL for <link rel=canonical>."}},"type":"object","required":["axis","value","label","total_agents","is_indexable","agents","canonical_path"],"title":"AxisSegmentPageData","description":"Server-side payload for the RES-014-B model-family / cost-tier pages.\n\n``/talent-pool/family/<family>`` and ``/talent-pool/cost/<tier>``. Mirrors\n``TalentPoolPageData`` but for the single-level KOM axes. ``axis`` is\n\"model_family\" | \"cost_tier\"; ``value`` the bounded enum member; ``label``\nthe human-readable axis label for the page heading."},"AxisSegmentSEO":{"properties":{"axis":{"type":"string","title":"Axis"},"value":{"type":"string","title":"Value"},"agent_count":{"type":"integer","title":"Agent Count"}},"type":"object","required":["axis","value","agent_count"],"title":"AxisSegmentSEO","description":"RES-014-B — a model-family or cost-tier sitemap segment.\n\n``axis`` ∈ {\"model_family\", \"cost_tier\"}; ``value`` is the bounded enum\nmember. Emitted only when the segments flag is ON (dark phase suppresses\nthese so no axis URLs enter the sitemap pre-launch)."},"BatchRunCreate":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"suite_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Suite Id"},"entry_point":{"anyOf":[{"type":"string","enum":["suite_detail","marketplace_card","screen_deep_link","screen_selector"]},{"type":"null"}],"title":"Entry Point"},"task_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":200},{"type":"null"}],"title":"Task Ids"},"repeats":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Repeats","default":1},"trigger_source":{"anyOf":[{"type":"string","const":"staleness_chip"},{"type":"null"}],"title":"Trigger Source"}},"type":"object","required":["agent_id"],"title":"BatchRunCreate"},"BenchmarkSuiteCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"description":{"type":"string","minLength":0,"title":"Description","default":""},"author":{"type":"string","maxLength":255,"title":"Author","default":"Badge"},"domain":{"$ref":"#/components/schemas/TaskDomain","default":"custom"},"difficulty":{"type":"string","maxLength":20,"title":"Difficulty","default":"mixed"},"is_featured":{"type":"boolean","title":"Is Featured","default":false},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"List of tags","default":[]},"task_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Task Ids","description":"Task IDs to include in suite","default":[]}},"type":"object","required":["name"],"title":"BenchmarkSuiteCreate"},"BenchmarkSuiteRead":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"description":{"type":"string","minLength":0,"title":"Description","default":""},"author":{"type":"string","maxLength":255,"title":"Author","default":"Badge"},"domain":{"$ref":"#/components/schemas/TaskDomain","default":"custom"},"difficulty":{"type":"string","maxLength":20,"title":"Difficulty","default":"mixed"},"is_featured":{"type":"boolean","title":"Is Featured","default":false},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"List of tags","default":[]},"id":{"type":"string","format":"uuid","title":"Id"},"downloads":{"type":"integer","title":"Downloads"},"rating":{"type":"number","title":"Rating"},"is_active":{"type":"boolean","title":"Is Active"},"task_count":{"type":"integer","title":"Task Count","description":"Number of tasks in suite","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["name","id","downloads","rating","is_active","created_at","updated_at"],"title":"BenchmarkSuiteRead"},"BenchmarkSuiteWithTasks":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"description":{"type":"string","minLength":0,"title":"Description","default":""},"author":{"type":"string","maxLength":255,"title":"Author","default":"Badge"},"domain":{"$ref":"#/components/schemas/TaskDomain","default":"custom"},"difficulty":{"type":"string","maxLength":20,"title":"Difficulty","default":"mixed"},"is_featured":{"type":"boolean","title":"Is Featured","default":false},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"List of tags","default":[]},"id":{"type":"string","format":"uuid","title":"Id"},"downloads":{"type":"integer","title":"Downloads"},"rating":{"type":"number","title":"Rating"},"is_active":{"type":"boolean","title":"Is Active"},"task_count":{"type":"integer","title":"Task Count","description":"Number of tasks in suite","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"task_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Task Ids","description":"List of task IDs in suite","default":[]}},"type":"object","required":["name","id","downloads","rating","is_active","created_at","updated_at"],"title":"BenchmarkSuiteWithTasks"},"BillingStatusResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"checkout_ready":{"type":"boolean","title":"Checkout Ready","default":false},"annual_checkout_ready":{"type":"boolean","title":"Annual Checkout Ready","default":false},"team_checkout_ready":{"type":"boolean","title":"Team Checkout Ready","default":false},"mode":{"anyOf":[{"type":"string","enum":["live","test"]},{"type":"null"}],"title":"Mode"}},"type":"object","required":["enabled"],"title":"BillingStatusResponse","description":"Public flag surface — drives the /pricing + /settings UI branch.\n\nUnauthenticated by design. The flag is not user data; exposing it lets\nthe marketing/pricing page (which serves anonymous visitors) make the\nsame UI decision the authenticated dashboard does without two code\npaths. SWR on the frontend caches with `revalidateOnFocus` so a flag\nflip is picked up within seconds without a forced reload."},"BlueprintEdge":{"properties":{"source":{"type":"string","title":"Source"},"target":{"type":"string","title":"Target"},"call_count":{"type":"integer","minimum":1.0,"title":"Call Count"},"run_coverage":{"type":"integer","minimum":0.0,"title":"Run Coverage"}},"type":"object","required":["source","target","call_count","run_coverage"],"title":"BlueprintEdge"},"BlueprintNode":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","enum":["agent","llm_call","tool","retrieval"],"title":"Type"},"label":{"type":"string","title":"Label"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"call_count":{"type":"integer","minimum":0.0,"title":"Call Count"},"run_coverage":{"type":"integer","minimum":0.0,"title":"Run Coverage"},"input_tokens":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Output Tokens"},"latency_p50_ms":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Latency P50 Ms"},"latency_p95_ms":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Latency P95 Ms"},"cost_usd":{"anyOf":[{"type":"string","pattern":"^\\d+(?:\\.\\d+)?$"},{"type":"null"}],"title":"Cost Usd"},"cost_source":{"type":"string","enum":["self_reported","estimated","mixed","unpriced"],"title":"Cost Source"},"cost_is_partial":{"type":"boolean","title":"Cost Is Partial"},"unpriced_call_count":{"type":"integer","minimum":0.0,"title":"Unpriced Call Count"}},"type":"object","required":["id","type","label","call_count","run_coverage","cost_source","cost_is_partial","unpriced_call_count"],"title":"BlueprintNode"},"BlueprintRead":{"properties":{"schema_version":{"type":"integer","const":1,"title":"Schema Version"},"projection":{"type":"string","enum":["public","owner"],"title":"Projection"},"scope":{"type":"string","enum":["run","agent"],"title":"Scope"},"run_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Run Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"run_count":{"type":"integer","minimum":0.0,"title":"Run Count"},"source_span_count":{"type":"integer","minimum":0.0,"title":"Source Span Count"},"evidence_label":{"type":"string","const":"self-reported telemetry — consistent with claims, not proof","title":"Evidence Label"},"nodes":{"items":{"$ref":"#/components/schemas/BlueprintNode"},"type":"array","title":"Nodes"},"edges":{"items":{"$ref":"#/components/schemas/BlueprintEdge"},"type":"array","title":"Edges"},"sequence":{"items":{"$ref":"#/components/schemas/BlueprintSequenceEntry"},"type":"array","title":"Sequence"},"truncation":{"$ref":"#/components/schemas/BlueprintTruncation"},"blueprint_version":{"anyOf":[{"$ref":"#/components/schemas/BlueprintVersionRef"},{"type":"null"}]},"declared_match":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Declared Match"},"architecture_binding_partial":{"type":"boolean","title":"Architecture Binding Partial","default":false}},"type":"object","required":["schema_version","projection","scope","run_id","agent_id","run_count","source_span_count","evidence_label","nodes","edges","sequence","truncation"],"title":"BlueprintRead"},"BlueprintSequenceEntry":{"properties":{"position":{"type":"integer","minimum":1.0,"title":"Position"},"node_id":{"type":"string","title":"Node Id"},"parent_node_id":{"type":"string","title":"Parent Node Id"},"type":{"type":"string","enum":["agent","llm_call","tool","retrieval"],"title":"Type"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool"},"input_tokens":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Output Tokens"},"latency_ms":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Latency Ms"},"cost_usd":{"anyOf":[{"type":"string","pattern":"^\\d+(?:\\.\\d+)?$"},{"type":"null"}],"title":"Cost Usd"},"cost_source":{"type":"string","enum":["self_reported","estimated","mixed","unpriced"],"title":"Cost Source"}},"type":"object","required":["position","node_id","parent_node_id","type","cost_source"],"title":"BlueprintSequenceEntry"},"BlueprintTimelineEntry":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"version_number":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Version Number"},"canonicalization_version":{"type":"integer","minimum":1.0,"title":"Canonicalization Version"},"node_count":{"type":"integer","minimum":0.0,"title":"Node Count"},"edge_count":{"type":"integer","minimum":0.0,"title":"Edge Count"},"first_seen_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Seen At"},"last_seen_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Seen At"},"run_count":{"type":"integer","minimum":0.0,"title":"Run Count"},"confirmed_run_count":{"type":"integer","minimum":0.0,"title":"Confirmed Run Count"},"partial_run_count":{"type":"integer","minimum":0.0,"title":"Partial Run Count"},"latest_signed_binding_partial":{"type":"boolean","title":"Latest Signed Binding Partial","default":false},"parent_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Parent Ids"},"diff":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Diff"},"is_current":{"type":"boolean","title":"Is Current","default":false}},"type":"object","required":["id","canonicalization_version","node_count","edge_count","run_count","confirmed_run_count","partial_run_count"],"title":"BlueprintTimelineEntry","description":"One row of the Evidence version timeline (OTEL-002d, ADR-018 D6).\n\nTier rules baked into the serializer, not the route: ``version_number``\nis owner-tier only (D3 — it counts private-run architectures);\n``diff`` is the FULL structured diff for owners and the counts-only\n``public_diff_projection`` for everyone else (the node tuples carry the\nopaque identity projections the anonymous Blueprint tier replaces with\nordinals). Anonymous order is conveyed by array position alone."},"BlueprintTimelineRead":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"projection":{"type":"string","enum":["public","owner"],"title":"Projection"},"evidence_label":{"type":"string","const":"self-reported telemetry — consistent with claims, not proof","title":"Evidence Label"},"entries":{"items":{"$ref":"#/components/schemas/BlueprintTimelineEntry"},"type":"array","title":"Entries"},"has_more":{"type":"boolean","title":"Has More","default":false},"latest_signed_binding_partial":{"type":"boolean","title":"Latest Signed Binding Partial","default":false}},"type":"object","required":["agent_id","projection","evidence_label","entries"],"title":"BlueprintTimelineRead"},"BlueprintTruncation":{"properties":{"truncated":{"type":"boolean","title":"Truncated"},"dropped_nodes":{"type":"integer","minimum":0.0,"title":"Dropped Nodes"},"dropped_sequence_entries":{"type":"integer","minimum":0.0,"title":"Dropped Sequence Entries"}},"type":"object","required":["truncated","dropped_nodes","dropped_sequence_entries"],"title":"BlueprintTruncation"},"BlueprintVersionRef":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"version_number":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Version Number"},"canonicalization_version":{"type":"integer","minimum":1.0,"title":"Canonicalization Version"}},"type":"object","required":["id","canonicalization_version"],"title":"BlueprintVersionRef","description":"OTEL-002c (#927, ADR-018 D3) — the citable architecture identity.\n\nThe content hash never appears on any response tier: it is a hash of\ncustomer-chosen identity projections, so publishing it would hand\nanonymous readers a whole-graph confirmation oracle. The UUID is random\n(zero content bits) and safe at every tier.\n\n``version_number`` is OWNER/EDITOR-TIER ONLY (security review of PR\n#938, finding 1): the counter is minted across the agent's whole run\nhistory including PRIVATE runs, so serving it anonymously publishes the\nowner's private architecture-iteration count — the exact disclosure\ncohort the 086 comparison path refuses to cross. Anonymous readers get\nthe UUID (identity and change-detection, which is the product story)\nwith ``version_number: null``."},"CapabilityConstraints":{"properties":{"max_concurrent_requests":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Concurrent Requests"},"max_tokens_per_request":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Tokens Per Request"},"requires_auth":{"type":"boolean","title":"Requires Auth","default":false},"rate_limit_rpm":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Limit Rpm","description":"Requests per minute limit"}},"type":"object","title":"CapabilityConstraints","description":"Operational constraints for the agent."},"CapabilityTool":{"properties":{"name":{"type":"string","maxLength":100,"title":"Name","examples":["web_search"]},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Description"},"type":{"type":"string","maxLength":50,"title":"Type","default":"function"}},"type":"object","required":["name"],"title":"CapabilityTool","description":"A tool the agent has access to."},"CertificationManifestProjection":{"properties":{"certification_id":{"type":"string","format":"uuid","title":"Certification Id"},"version":{"type":"string","title":"Version"},"state":{"type":"string","title":"State"},"valid":{"type":"boolean","title":"Valid"},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason"},"coverage_complete":{"type":"boolean","title":"Coverage Complete"},"run_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Run Count"},"task_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Task Count"},"successful_run_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Successful Run Count"},"answer_exposed_run_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Answer Exposed Run Count"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"calculated_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Calculated Cost Usd"},"cost_per_success_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Per Success Usd"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"},"requested_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested Model"},"returned_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Returned Model"},"pricing_snapshots":{"items":{"$ref":"#/components/schemas/ManifestPricingSnapshot"},"type":"array","title":"Pricing Snapshots"},"runs_digest":{"type":"string","title":"Runs Digest"},"manifest_hash":{"type":"string","title":"Manifest Hash"},"signature":{"type":"string","title":"Signature"},"signed_at":{"type":"string","title":"Signed At"},"key_id":{"type":"string","title":"Key Id"}},"type":"object","required":["certification_id","version","state","valid","failure_reason","coverage_complete","run_count","task_count","successful_run_count","input_tokens","output_tokens","calculated_cost_usd","cost_per_success_usd","provider","requested_model","returned_model","pricing_snapshots","runs_digest","manifest_hash","signature","signed_at","key_id"],"title":"CertificationManifestProjection"},"CertifyCheckoutRequest":{"properties":{"agent_id":{"type":"string","title":"Agent Id"},"accept_immediate_performance":{"type":"boolean","title":"Accept Immediate Performance","default":false},"trigger_reason":{"anyOf":[{"type":"string","enum":["architecture_staleness","suite_rotation"]},{"type":"null"}],"title":"Trigger Reason"}},"type":"object","required":["agent_id"],"title":"CertifyCheckoutRequest"},"CertifyCheckoutResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url"},"certification_id":{"type":"string","title":"Certification Id"}},"type":"object","required":["checkout_url","certification_id"],"title":"CertifyCheckoutResponse"},"CertifyDevGrantResponse":{"properties":{"dev_mode":{"type":"boolean","title":"Dev Mode","default":true},"certification_id":{"type":"string","title":"Certification Id"},"status":{"type":"string","title":"Status"}},"type":"object","required":["certification_id","status"],"title":"CertifyDevGrantResponse"},"CertifyDiagnostic":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"price_usd":{"type":"integer","title":"Price Usd"},"repeats_per_task":{"type":"integer","title":"Repeats Per Task"},"min_task_count":{"type":"integer","title":"Min Task Count"},"required_task_count":{"type":"integer","title":"Required Task Count"},"selected_task_count":{"type":"integer","title":"Selected Task Count"},"catalog_ready":{"type":"boolean","title":"Catalog Ready"},"gemini_31_min_interval_seconds":{"type":"number","title":"Gemini 31 Min Interval Seconds"},"quota_max_pauses":{"type":"integer","title":"Quota Max Pauses"},"price_id_configured":{"type":"boolean","title":"Price Id Configured"},"stripe_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Mode"}},"type":"object","required":["enabled","price_usd","repeats_per_task","min_task_count","required_task_count","selected_task_count","catalog_ready","gemini_31_min_interval_seconds","quota_max_pauses","price_id_configured","stripe_mode"],"title":"CertifyDiagnostic","description":"Ungated flag-state surface (no secrets) — the diagnostic-endpoint memo."},"CertifyEligibility":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"eligible":{"type":"boolean","title":"Eligible"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"has_live_capability":{"type":"boolean","title":"Has Live Capability"},"is_recert":{"type":"boolean","title":"Is Recert"},"price_usd":{"type":"integer","title":"Price Usd"},"current_suite_version":{"type":"integer","title":"Current Suite Version"},"certified_suite_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Certified Suite Version"},"free_pass_k_populated":{"type":"boolean","title":"Free Pass K Populated","default":false},"model_cost_eligible":{"type":"boolean","title":"Model Cost Eligible","default":false},"model_cost_eligibility_reason":{"type":"string","title":"Model Cost Eligibility Reason","default":"non_authoritative_path"},"model_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Provider"},"requested_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested Model"},"model_input_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Model Input Cost Per Million"},"model_output_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Model Output Cost Per Million"}},"type":"object","required":["enabled","eligible","has_live_capability","is_recert","price_usd","current_suite_version"],"title":"CertifyEligibility"},"CertifyStatusResponse":{"properties":{"certification_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Certification Id"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"completed_run_count":{"type":"integer","title":"Completed Run Count","default":0},"expected_run_count":{"type":"integer","title":"Expected Run Count","default":0},"quota_resume_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Quota Resume At"},"requested_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested Model"}},"type":"object","title":"CertifyStatusResponse"},"ChallengeCreate":{"properties":{"title":{"type":"string","maxLength":255,"minLength":1,"title":"Title"},"description":{"type":"string","title":"Description"},"domain":{"type":"string","title":"Domain"},"task_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Task Ids"},"starts_at":{"type":"string","format":"date-time","title":"Starts At"},"ends_at":{"type":"string","format":"date-time","title":"Ends At"}},"type":"object","required":["title","description","domain","task_ids","starts_at","ends_at"],"title":"ChallengeCreate"},"ChallengeRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"domain":{"type":"string","title":"Domain"},"task_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Task Ids"},"starts_at":{"type":"string","format":"date-time","title":"Starts At"},"ends_at":{"type":"string","format":"date-time","title":"Ends At"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","title","description","domain","task_ids","starts_at","ends_at","is_active","created_at"],"title":"ChallengeRead"},"CheckoutRequest":{"properties":{"price_id":{"type":"string","maxLength":255,"pattern":"^[A-Za-z0-9_]*$","title":"Price Id","default":""},"annual":{"type":"boolean","title":"Annual","default":false},"plan":{"anyOf":[{"type":"string","enum":["pro","team"]},{"type":"null"}],"title":"Plan"}},"type":"object","title":"CheckoutRequest"},"CheckoutResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url"}},"type":"object","required":["checkout_url"],"title":"CheckoutResponse"},"ComparePageData":{"properties":{"canonical_slug":{"type":"string","title":"Canonical Slug"},"redirect_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect To","description":"If the requested slug isn't in canonical (alphabetical-first) order, the router returns this for the frontend to 301."},"left":{"$ref":"#/components/schemas/PublicAgentSEO"},"right":{"$ref":"#/components/schemas/PublicAgentSEO"},"shared_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shared Domain"},"is_indexable":{"type":"boolean","title":"Is Indexable"}},"type":"object","required":["canonical_slug","left","right","shared_domain","is_indexable"],"title":"ComparePageData","description":"Server-side payload for /compare/<canonical-slug> pages."},"ComparePairSEO":{"properties":{"left_slug":{"type":"string","title":"Left Slug"},"right_slug":{"type":"string","title":"Right Slug"},"canonical_slug":{"type":"string","title":"Canonical Slug"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"last_updated":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Updated"}},"type":"object","required":["left_slug","right_slug","canonical_slug"],"title":"ComparePairSEO"},"ConfirmationLinkRequest":{"properties":{},"type":"object","title":"ConfirmationLinkRequest","description":"Ask for the emailed second factor (OAuth-only accounts)."},"ConnectOnboardResponse":{"properties":{"onboarding_url":{"type":"string","title":"Onboarding Url"}},"type":"object","required":["onboarding_url"],"title":"ConnectOnboardResponse","description":"Body for POST /playbooks/my/connect/onboard."},"ConnectStatusResponse":{"properties":{"connected":{"type":"boolean","title":"Connected"},"charges_enabled":{"type":"boolean","title":"Charges Enabled"},"payouts_enabled":{"type":"boolean","title":"Payouts Enabled"},"details_submitted":{"type":"boolean","title":"Details Submitted"}},"type":"object","required":["connected","charges_enabled","payouts_enabled","details_submitted"],"title":"ConnectStatusResponse","description":"Body for GET /playbooks/my/connect/status — mirrors the Stripe account's\ncapability flags. `connected` is True once an Express account exists for the\ncaller (regardless of whether onboarding is complete)."},"CustomBenchmarkCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":2,"title":"Name"},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"}},"type":"object","required":["name"],"title":"CustomBenchmarkCreate"},"CustomBenchmarkDetailRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"owner_user_id":{"type":"string","format":"uuid","title":"Owner User Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_public":{"type":"boolean","title":"Is Public"},"task_count":{"type":"integer","title":"Task Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"tasks":{"items":{"$ref":"#/components/schemas/CustomBenchmarkTaskRead"},"type":"array","title":"Tasks","default":[]}},"type":"object","required":["id","owner_user_id","name","description","is_public","task_count","created_at","updated_at"],"title":"CustomBenchmarkDetailRead","description":"Includes the actual task rows. Used by GET /custom-benchmarks/{id}."},"CustomBenchmarkRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"owner_user_id":{"type":"string","format":"uuid","title":"Owner User Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_public":{"type":"boolean","title":"Is Public"},"task_count":{"type":"integer","title":"Task Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","owner_user_id","name","description","is_public","task_count","created_at","updated_at"],"title":"CustomBenchmarkRead"},"CustomBenchmarkTaskCreate":{"properties":{"title":{"type":"string","maxLength":255,"minLength":2,"title":"Title"},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"},"domain":{"$ref":"#/components/schemas/TaskDomain","default":"custom"},"difficulty":{"$ref":"#/components/schemas/TaskDifficulty","default":"medium"},"prompt":{"type":"string","maxLength":20000,"minLength":2,"title":"Prompt"},"expected_output":{"anyOf":[{"type":"string","maxLength":20000},{"type":"null"}],"title":"Expected Output"},"max_tokens_hint":{"type":"integer","maximum":32000.0,"minimum":128.0,"title":"Max Tokens Hint","default":2048}},"type":"object","required":["title","prompt"],"title":"CustomBenchmarkTaskCreate","description":"Shape of one task inside an upload payload. Same fields as the\npublic Task — keeps validation logic consistent between curated tasks\nand user uploads."},"CustomBenchmarkTaskRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"benchmark_id":{"type":"string","format":"uuid","title":"Benchmark Id"},"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"domain":{"type":"string","title":"Domain"},"difficulty":{"type":"string","title":"Difficulty"},"prompt":{"type":"string","title":"Prompt"},"expected_output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Output"},"max_tokens_hint":{"type":"integer","title":"Max Tokens Hint"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","benchmark_id","title","description","domain","difficulty","prompt","expected_output","max_tokens_hint","created_at"],"title":"CustomBenchmarkTaskRead"},"CustomBenchmarkUpload":{"properties":{"tasks":{"items":{"$ref":"#/components/schemas/CustomBenchmarkTaskCreate"},"type":"array","maxItems":500,"minItems":1,"title":"Tasks"}},"type":"object","required":["tasks"],"title":"CustomBenchmarkUpload","description":"Bulk-add tasks to an existing benchmark. Capped at 500 tasks per\nrequest to keep memory + insert-batch bounded."},"DaemonDiagnostic":{"properties":{"token_hash_count":{"type":"integer","title":"Token Hash Count"},"in_flight_jobs":{"type":"integer","title":"In Flight Jobs"},"dead_daemons_24h":{"type":"integer","title":"Dead Daemons 24H"},"field_encryption_configured":{"type":"boolean","title":"Field Encryption Configured"}},"type":"object","required":["token_hash_count","in_flight_jobs","dead_daemons_24h","field_encryption_configured"],"title":"DaemonDiagnostic","description":"Admin-gated parsed state — pairs with the diagnostic-endpoints memo.\n\nLets an operator confirm without SSH:\n  * how many agents have a token hash configured,\n  * how many in-flight jobs are claimed-but-unresolved,\n  * how many daemons are dead (no heartbeat in the last 24h)."},"DaemonJobOut":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"run_id":{"type":"string","format":"uuid","title":"Run Id"},"payload":{"additionalProperties":true,"type":"object","title":"Payload"},"claim_token":{"type":"string","title":"Claim Token","description":"Opaque token the daemon must echo back on the result POST. Equivalent to a 'do you still own this claim?' check."}},"type":"object","required":["job_id","agent_id","run_id","payload","claim_token"],"title":"DaemonJobOut"},"DaemonJobResult":{"properties":{"claim_token":{"type":"string","title":"Claim Token","description":"The claim_token returned at claim time."},"success":{"type":"boolean","title":"Success"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms","description":"Round-trip latency the daemon measured against the local agent. None for synchronous failure (e.g. agent refused)."},"input_tokens":{"type":"integer","title":"Input Tokens","default":0},"output_tokens":{"type":"integer","title":"Output Tokens","default":0},"total_cost_usd":{"type":"number","title":"Total Cost Usd","default":0.0},"output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"retry_count":{"type":"integer","title":"Retry Count","default":0},"error_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Class"},"response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Status"},"error_body_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Body Excerpt"},"response_payload":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Response Payload"}},"type":"object","required":["claim_token","success"],"title":"DaemonJobResult","description":"Result POST body — canonical metrics shape matching arena.execute_run."},"DecisionComment":{"properties":{"comment":{"type":"string","maxLength":2000,"title":"Comment","default":""}},"additionalProperties":false,"type":"object","title":"DecisionComment"},"DecisionRead":{"properties":{"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"user_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Label"},"decision":{"type":"string","enum":["approve","reject"],"title":"Decision"},"comment":{"type":"string","title":"Comment"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["user_id","user_label","decision","comment","created_at"],"title":"DecisionRead"},"DeclaredConfigurationCollection":{"properties":{"items":{"items":{"$ref":"#/components/schemas/DeclaredConfigurationRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["items","total"],"title":"DeclaredConfigurationCollection"},"DeclaredConfigurationRead":{"properties":{"version":{"type":"integer","title":"Version"},"is_active":{"type":"boolean","title":"Is Active"},"is_default":{"type":"boolean","title":"Is Default"},"playbook_type":{"type":"string","title":"Playbook Type"},"model":{"type":"string","title":"Model"},"temperature":{"type":"number","title":"Temperature"},"max_tokens":{"type":"integer","title":"Max Tokens"},"top_p":{"type":"number","title":"Top P"},"last_updated_at":{"type":"string","format":"date-time","title":"Last Updated At"}},"type":"object","required":["version","is_active","is_default","playbook_type","model","temperature","max_tokens","top_p","last_updated_at"],"title":"DeclaredConfigurationRead","description":"Allowlisted historical declaration shown beside Blueprint.\n\nThis projection intentionally has no prompt, few-shot examples, tool\nconfiguration, notes, description, pricing, marketplace aggregate, or\npublic visibility fields. It is returned only after current agent edit\nauthority has been resolved."},"DeletionRequest":{"properties":{"confirmation_phrase":{"type":"string","maxLength":200,"title":"Confirmation Phrase"},"password":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Password"},"confirmation_token":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Confirmation Token"}},"type":"object","required":["confirmation_phrase"],"title":"DeletionRequest","description":"The ceremony payload. Both factors travel together; no cookie-only path."},"DevUpgradeResponse":{"properties":{"dev_mode":{"type":"boolean","title":"Dev Mode","default":true},"plan":{"type":"string","title":"Plan"},"user":{"$ref":"#/components/schemas/UserRead"}},"type":"object","required":["plan","user"],"title":"DevUpgradeResponse"},"DriftAlertList":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"scope":{"type":"string","enum":["owner","public"],"title":"Scope"},"items":{"anyOf":[{"items":{"$ref":"#/components/schemas/DriftAlertRead"},"type":"array"},{"items":{"$ref":"#/components/schemas/DriftAlertPublicRead"},"type":"array"}],"title":"Items"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["agent_id","scope","items","total"],"title":"DriftAlertList"},"DriftAlertPublicRead":{"properties":{"metric":{"type":"string","enum":["score","pass_rate","cost","latency"],"title":"Metric"},"bucket_date":{"type":"string","format":"date","title":"Bucket Date"},"direction":{"type":"string","enum":["up","down"],"title":"Direction"}},"type":"object","required":["metric","bucket_date","direction"],"title":"DriftAlertPublicRead"},"DriftAlertRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"metric":{"type":"string","enum":["score","pass_rate","cost","latency"],"title":"Metric"},"event":{"type":"string","title":"Event"},"direction":{"type":"string","enum":["up","down"],"title":"Direction"},"bucket_date":{"type":"string","format":"date","title":"Bucket Date"},"window_buckets":{"type":"integer","title":"Window Buckets"},"baseline_mean":{"type":"number","title":"Baseline Mean"},"baseline_std":{"type":"number","title":"Baseline Std"},"observed":{"type":"number","title":"Observed"},"z":{"type":"number","title":"Z"},"delta":{"type":"number","title":"Delta"},"run_ids":{"items":{"type":"string"},"type":"array","title":"Run Ids"},"blueprint_version_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Blueprint Version Id"},"blueprint_version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Blueprint Version Number"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"notified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Notified At"},"acknowledged_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Acknowledged At"}},"type":"object","required":["id","agent_id","metric","event","direction","bucket_date","window_buckets","baseline_mean","baseline_std","observed","z","delta","run_ids","blueprint_version_id","blueprint_version_number","created_at","notified_at","acknowledged_at"],"title":"DriftAlertRead"},"DriftEvaluateResult":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"alerts_created":{"type":"integer","title":"Alerts Created"},"alerts":{"items":{"$ref":"#/components/schemas/DriftAlertRead"},"type":"array","title":"Alerts"}},"type":"object","required":["agent_id","alerts_created","alerts"],"title":"DriftEvaluateResult"},"DriftMetricOverride":{"properties":{"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"min_delta":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Min Delta"},"floor":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Floor"}},"additionalProperties":false,"type":"object","title":"DriftMetricOverride"},"DriftMetricOverrides":{"properties":{"score":{"anyOf":[{"$ref":"#/components/schemas/DriftMetricOverride"},{"type":"null"}]},"pass_rate":{"anyOf":[{"$ref":"#/components/schemas/DriftMetricOverride"},{"type":"null"}]},"cost":{"anyOf":[{"$ref":"#/components/schemas/DriftMetricOverride"},{"type":"null"}]},"latency":{"anyOf":[{"$ref":"#/components/schemas/DriftMetricOverride"},{"type":"null"}]}},"additionalProperties":false,"type":"object","title":"DriftMetricOverrides"},"DriftMetricSettingsRead":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"min_delta":{"type":"number","title":"Min Delta"},"floor":{"type":"number","title":"Floor"},"direction":{"type":"string","enum":["up","down"],"title":"Direction"},"relative":{"type":"boolean","title":"Relative"},"min_delta_abs":{"type":"number","title":"Min Delta Abs"}},"type":"object","required":["enabled","min_delta","floor","direction","relative","min_delta_abs"],"title":"DriftMetricSettingsRead"},"DriftSettingsRead":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"is_default":{"type":"boolean","title":"Is Default"},"enabled":{"type":"boolean","title":"Enabled"},"threshold":{"type":"number","title":"Threshold"},"window_buckets":{"type":"integer","title":"Window Buckets"},"min_buckets":{"type":"integer","title":"Min Buckets"},"cooldown_hours":{"type":"integer","title":"Cooldown Hours"},"metrics":{"additionalProperties":{"$ref":"#/components/schemas/DriftMetricSettingsRead"},"type":"object","title":"Metrics"}},"type":"object","required":["agent_id","is_default","enabled","threshold","window_buckets","min_buckets","cooldown_hours","metrics"],"title":"DriftSettingsRead"},"DriftSettingsUpdate":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"threshold":{"type":"number","maximum":10.0,"minimum":1.5,"title":"Threshold","default":2.5},"window_buckets":{"type":"integer","maximum":60.0,"minimum":5.0,"title":"Window Buckets","default":14},"metrics":{"$ref":"#/components/schemas/DriftMetricOverrides"}},"additionalProperties":false,"type":"object","title":"DriftSettingsUpdate","description":"PUT body. Full replace: an omitted field resets to its default."},"EarningsByPlaybook":{"properties":{"playbook_id":{"type":"string","format":"uuid","title":"Playbook Id"},"playbook_name":{"type":"string","title":"Playbook Name"},"price_usd_cents":{"type":"integer","title":"Price Usd Cents"},"total_clones":{"type":"integer","title":"Total Clones"},"total_revenue_usd_cents":{"type":"integer","title":"Total Revenue Usd Cents"},"creator_earnings_usd_cents":{"type":"integer","title":"Creator Earnings Usd Cents"}},"type":"object","required":["playbook_id","playbook_name","price_usd_cents","total_clones","total_revenue_usd_cents","creator_earnings_usd_cents"],"title":"EarningsByPlaybook"},"EarningsSummary":{"properties":{"total_earnings_usd_cents":{"type":"integer","title":"Total Earnings Usd Cents","description":"Lifetime net earnings (after platform fee)."},"total_purchases":{"type":"integer","title":"Total Purchases","description":"Lifetime completed hires across all your playbooks."},"total_refunds":{"type":"integer","title":"Total Refunds","description":"Lifetime refunded purchases.","default":0},"last_30_days_earnings_usd_cents":{"type":"integer","title":"Last 30 Days Earnings Usd Cents","default":0},"pending_earnings_usd_cents":{"type":"integer","title":"Pending Earnings Usd Cents","description":"Net earnings from PENDING (unsettled) hires — not yet paid out.","default":0},"pending_purchases":{"type":"integer","title":"Pending Purchases","description":"Count of PENDING (unsettled) hires.","default":0},"by_playbook":{"items":{"$ref":"#/components/schemas/EarningsByPlaybook"},"type":"array","title":"By Playbook"}},"type":"object","required":["total_earnings_usd_cents","total_purchases"],"title":"EarningsSummary","description":"Aggregate creator-side payout view for `/playbooks/my/earnings`."},"EndpointReadinessRead":{"properties":{"status":{"type":"string","enum":["unknown","stale","reachable","unreachable","not_applicable"],"title":"Status"},"checked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Checked At"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"result":{"anyOf":[{"type":"string","enum":["success","non_2xx","bad_response_shape","connection_refused","timeout","ssrf_blocked","endpoint_url_unsupported"]},{"type":"null"}],"title":"Result"}},"type":"object","required":["status","checked_at","latency_ms","result"],"title":"EndpointReadinessRead"},"EnterpriseWaitlistRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"EnterpriseWaitlistRequest"},"EnterpriseWaitlistResponse":{"properties":{"queued":{"type":"boolean","title":"Queued"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["queued"],"title":"EnterpriseWaitlistResponse"},"ExecutionStepRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"run_id":{"type":"string","format":"uuid","title":"Run Id"},"step_number":{"type":"integer","title":"Step Number"},"step_type":{"type":"string","title":"Step Type"},"model_used":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Used"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"},"input_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Text"},"output_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output Text"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","run_id","step_number","step_type","model_used","provider","input_text","output_text","input_tokens","output_tokens","cost_usd","latency_ms","started_at","completed_at","created_at"],"title":"ExecutionStepRead","description":"Read an execution step record."},"ExperimentStatus":{"type":"string","enum":["running","completed","cancelled"],"title":"ExperimentStatus","description":"Status of a lab experiment."},"ExperimentVariant":{"properties":{"label":{"type":"string","maxLength":50,"minLength":1,"title":"Label","examples":["A"]},"price_cents":{"type":"integer","maximum":10000000.0,"minimum":0.0,"title":"Price Cents"},"traffic_pct":{"type":"integer","maximum":99.0,"minimum":1.0,"title":"Traffic Pct"}},"type":"object","required":["label","price_cents","traffic_pct"],"title":"ExperimentVariant","description":"One arm of an A/B price experiment.\n\n`traffic_pct` is whole percent [1, 99] per variant; the array must sum to\nexactly 100 (validated at the experiment-create endpoint, not here, because\na single-variant view of the array can't enforce a cross-row invariant).\n\n`price_cents` shares `PRICE_USD_CENTS_MAX` with the listing schema and is\nnot free to drift from it (#728): concluding an experiment writes the\nwinning variant straight into `playbooks.price_usd_cents`, so a looser bound\nhere is simply a way around the tighter bound there."},"FitnessAxes":{"properties":{"correctness":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Correctness"},"latency":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Latency"},"cost":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Cost"},"tool_efficiency":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Tool Efficiency"},"robustness":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Robustness"}},"type":"object","title":"FitnessAxes","description":"The five normalised 0-100 fitness axes (PRD-004 §3, PRD-010 FR-09).\n\nSurfaced inside ``PublicAgentSEO`` only when the talent-pool endpoints\npopulate them — the sitemap-data response leaves ``fitness=None`` since\nit would balloon the payload without a use-case.\n\nNulls mean \"no signal\" (zero runs, missing latency etc.) — the frontend\nre-rank logic must drop these axes and renormalise weights to match the\nbackend behaviour in ``fitness_service.apply_weights``."},"ForgotPasswordRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"ForgotPasswordRequest","description":"Body for POST /auth/forgot-password. Only the email — the response is\ndeliberately generic (no enumeration) regardless of whether it resolves."},"FrameworkListItem":{"properties":{"framework":{"type":"string","title":"Framework"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"icon_hint":{"type":"string","title":"Icon Hint"}},"type":"object","required":["framework","name","description","icon_hint"],"title":"FrameworkListItem","description":"Framework item in list endpoint."},"FrameworkSetup":{"properties":{"framework":{"type":"string","title":"Framework"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"icon_hint":{"type":"string","title":"Icon Hint"},"requirements":{"items":{"type":"string"},"type":"array","title":"Requirements"},"steps":{"items":{"$ref":"#/components/schemas/SetupStep"},"type":"array","title":"Steps"}},"type":"object","required":["framework","name","description","icon_hint","requirements","steps"],"title":"FrameworkSetup","description":"Complete setup guide for a framework."},"FrontierRead":{"properties":{"root_agent_id":{"type":"string","format":"uuid","title":"Root Agent Id"},"variants":{"items":{"$ref":"#/components/schemas/FrontierVariant"},"type":"array","title":"Variants"}},"type":"object","required":["root_agent_id","variants"],"title":"FrontierRead","description":"The variant group for an agent's Hiring Frontier chart (FR-3)."},"FrontierVariant":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"run_count":{"type":"integer","title":"Run Count"},"pass_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pass Rate"},"pass_k":{"anyOf":[{"additionalProperties":{"type":"number"},"type":"object"},{"type":"null"}],"title":"Pass K"},"mean_cost_per_task_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mean Cost Per Task Usd"},"provenance":{"type":"string","title":"Provenance"},"provenance_counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Provenance Counts"},"cost_basis":{"type":"string","title":"Cost Basis","default":"unavailable"},"cost_basis_counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Cost Basis Counts","default":{}},"scored_cost_per_run_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Scored Cost Per Run Usd"},"is_public":{"type":"boolean","title":"Is Public"}},"type":"object","required":["agent_id","agent_name","run_count","provenance","provenance_counts","is_public"],"title":"FrontierVariant","description":"One agent (root or variant) in a variant group, with its aggregates.\n\nDeliberately carries NO owner-only fields (no user_id, no key material) —\nthe frontier is anonymous-readable for public agents (rule #3 leak\ndiscipline). All aggregates are computed from runs already in the DB."},"GateResult":{"properties":{"gate":{"type":"string","title":"Gate"},"required":{"title":"Required"},"observed":{"title":"Observed"},"passed":{"type":"boolean","title":"Passed"}},"type":"object","required":["gate","required","observed","passed"],"title":"GateResult"},"GoogleConfigIn":{"properties":{"allowed_domains":{"items":{"type":"string"},"type":"array","maxItems":10,"minItems":1,"title":"Allowed Domains"}},"additionalProperties":false,"type":"object","required":["allowed_domains"],"title":"GoogleConfigIn"},"GoogleConfigRead":{"properties":{"allowed_domains":{"items":{"type":"string"},"type":"array","title":"Allowed Domains"}},"type":"object","required":["allowed_domains"],"title":"GoogleConfigRead"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IndexableAgentSEO":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"}},"type":"object","required":["agent_id","agent_name","updated_at"],"title":"IndexableAgentSEO","description":"PII-free sitemap row for a direct, public agent detail page."},"IntegrationCreate":{"properties":{"framework":{"type":"string","enum":["langchain","crewai","autogen","openai_assistants","anthropic","llamaindex"],"title":"Framework"},"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url"}},"type":"object","required":["framework"],"title":"IntegrationCreate"},"IntegrationRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"framework":{"type":"string","enum":["langchain","crewai","autogen","openai_assistants","anthropic","llamaindex"],"title":"Framework"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"is_active":{"type":"boolean","title":"Is Active"},"last_tested_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Tested At"},"test_status":{"anyOf":[{"type":"string","enum":["success","failed"]},{"type":"null"}],"title":"Test Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","user_id","framework","webhook_url","is_active","last_tested_at","test_status","created_at","updated_at"],"title":"IntegrationRead"},"IntegrationTestRequest":{"properties":{"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url"}},"type":"object","title":"IntegrationTestRequest","description":"Request body for testing an integration connection."},"IntegrationTestResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"tested_at":{"type":"string","format":"date-time","title":"Tested At"}},"type":"object","required":["success","message","tested_at"],"title":"IntegrationTestResponse","description":"Response from testing an integration."},"IntegrationUpdate":{"properties":{"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"IntegrationUpdate"},"LabExperimentCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Description"}},"type":"object","required":["name"],"title":"LabExperimentCreate","description":"Create a lab experiment."},"LabExperimentRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","user_id","name","description","status","created_at","completed_at"],"title":"LabExperimentRead","description":"Read a lab experiment."},"LabExperimentUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Description"},"status":{"anyOf":[{"$ref":"#/components/schemas/ExperimentStatus"},{"type":"null"}]}},"type":"object","title":"LabExperimentUpdate","description":"Update a lab experiment."},"LabRunBatchCreate":{"properties":{"playbook_ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":5,"minItems":1,"title":"Playbook Ids"},"task_ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":20,"minItems":1,"title":"Task Ids"},"experiment_id":{"type":"string","format":"uuid","title":"Experiment Id"}},"type":"object","required":["playbook_ids","task_ids","experiment_id"],"title":"LabRunBatchCreate","description":"Execute multiple lab runs at once — for side-by-side comparison."},"LabRunRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"experiment_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Experiment Id"},"playbook_id":{"type":"string","format":"uuid","title":"Playbook Id"},"task_id":{"type":"string","format":"uuid","title":"Task Id"},"status":{"type":"string","title":"Status"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"success":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Success"},"output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"total_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Usd"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","experiment_id","playbook_id","task_id","status","started_at","completed_at","latency_ms","success","output","error_message","input_tokens","output_tokens","total_cost_usd","created_at"],"title":"LabRunRead"},"LeaderboardEntry":{"properties":{"rank":{"type":"integer","title":"Rank"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"},"composite_score":{"type":"number","title":"Composite Score"},"success_rate":{"type":"number","title":"Success Rate"},"reliability_score":{"type":"number","title":"Reliability Score"},"cost_score":{"type":"number","title":"Cost Score"},"avg_latency_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Latency Ms"},"avg_cost_usd":{"type":"number","title":"Avg Cost Usd"},"total_runs":{"type":"integer","title":"Total Runs"},"elo_rating":{"type":"integer","title":"Elo Rating"},"computed_at":{"type":"string","format":"date-time","title":"Computed At"},"trending":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trending"},"verified_state":{"type":"string","title":"Verified State","default":"unverified"},"is_reference":{"type":"boolean","title":"Is Reference","default":false},"repeatability_tasks":{"type":"integer","title":"Repeatability Tasks","default":0},"cost_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost Basis"},"measured_run_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Measured Run Count"},"counted_run_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Counted Run Count"}},"type":"object","required":["rank","agent_id","agent_name","composite_score","success_rate","reliability_score","cost_score","avg_latency_ms","avg_cost_usd","total_runs","elo_rating","computed_at"],"title":"LeaderboardEntry","description":"Flattened view for the public leaderboard."},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","minLength":1,"title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"MLBomModel":{"properties":{"id":{"type":"string","maxLength":255,"title":"Id","examples":["gpt-4o-mini"]},"provider":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Provider","examples":["openai"]},"role":{"type":"string","maxLength":50,"title":"Role","default":"primary","examples":["primary","fallback","router"]}},"type":"object","required":["id"],"title":"MLBomModel","description":"One model an agent self-declares it uses (BPP-1 ML-BOM)."},"MLBomTool":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name","examples":["web_search"]},"kind":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Kind","examples":["retrieval"]}},"type":"object","required":["name"],"title":"MLBomTool","description":"One tool an agent self-declares it may invoke (BPP-1 ML-BOM)."},"ManifestAuth":{"properties":{"type":{"type":"string","maxLength":50,"title":"Type","default":"bearer"},"header":{"type":"string","maxLength":100,"title":"Header","default":"Authorization"},"docs_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Docs Url"}},"type":"object","title":"ManifestAuth","description":"Authentication requirements for calling the agent."},"ManifestCapabilities":{"properties":{"domains":{"items":{"type":"string"},"type":"array","title":"Domains","examples":[["code_generation","tool_use"]]},"modalities":{"items":{"type":"string"},"type":"array","title":"Modalities"},"max_context_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Context Tokens","examples":[128000]},"supports_streaming":{"type":"boolean","title":"Supports Streaming","default":false},"supports_tools":{"type":"boolean","title":"Supports Tools","default":false},"tools":{"anyOf":[{"items":{"$ref":"#/components/schemas/CapabilityTool"},"type":"array"},{"type":"null"}],"title":"Tools","description":"List of tools/functions the agent can invoke"},"skills":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Skills","description":"High-level skills (e.g. 'code_review', 'data_analysis')","examples":[["code_review","debugging","api_design"]]},"languages":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Languages","description":"Programming languages supported","examples":[["python","typescript","go"]]},"constraints":{"anyOf":[{"$ref":"#/components/schemas/CapabilityConstraints"},{"type":"null"}]}},"type":"object","title":"ManifestCapabilities"},"ManifestDiscoverRequest":{"properties":{"url":{"type":"string","maxLength":500,"title":"Url","description":"Base URL of the agent (manifest fetched from {url}/.well-known/agent.json)","examples":["https://agents.acme.ai/explorer-llama"]}},"type":"object","required":["url"],"title":"ManifestDiscoverRequest","description":"Request to discover an agent from a URL."},"ManifestDiscoverResponse":{"properties":{"manifest":{"$ref":"#/components/schemas/AgentManifest"},"health_ok":{"type":"boolean","title":"Health Ok","default":false},"health_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Health Latency Ms"},"source_url":{"type":"string","title":"Source Url"}},"type":"object","required":["manifest","source_url"],"title":"ManifestDiscoverResponse","description":"Response from manifest discovery — the parsed manifest + health status."},"ManifestEndpoint":{"properties":{"base_url":{"type":"string","maxLength":500,"title":"Base Url","examples":["https://agents.acme.ai/explorer"]},"execute":{"type":"string","maxLength":200,"title":"Execute","default":"/execute"},"health":{"type":"string","maxLength":200,"title":"Health","default":"/health"},"protocol":{"type":"string","maxLength":20,"title":"Protocol","default":"http"}},"type":"object","required":["base_url"],"title":"ManifestEndpoint"},"ManifestEvaluation":{"properties":{"preferred_tasks":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Preferred Tasks","description":"Task domains the agent is optimized for"},"warm_up_runs":{"type":"integer","minimum":0.0,"title":"Warm Up Runs","description":"Recommended warm-up runs before scoring","default":0},"timeout_seconds":{"type":"integer","maximum":300.0,"minimum":5.0,"title":"Timeout Seconds","default":60}},"type":"object","title":"ManifestEvaluation","description":"Agent's evaluation preferences."},"ManifestMLBom":{"properties":{"models":{"items":{"$ref":"#/components/schemas/MLBomModel"},"type":"array","title":"Models"},"tools":{"items":{"$ref":"#/components/schemas/MLBomTool"},"type":"array","title":"Tools"},"routing_policy":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Routing Policy","examples":["single-model"]}},"type":"object","title":"ManifestMLBom","description":"ARP v2 ML bill-of-materials — models/tools the agent DECLARES it runs.\n\nPurely self-reported at this stage (BPP-1 ``declared`` level); later BPP\nwaves (OTel-traced spans, metering, reconciliation) corroborate or\ncontradict these claims — see ``app.services.provenance``. Additive and\noptional so a legacy manifest with no ``ml_bom`` keeps validating\nbyte-identically."},"ManifestMeta":{"properties":{"tags":{"items":{"type":"string"},"type":"array","title":"Tags","examples":[["react","tool-use"]]},"license":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"License"},"source_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Source Url"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","title":"ManifestMeta"},"ManifestModel":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name","examples":["llama-3.2-70b"]},"provider":{"type":"string","maxLength":255,"title":"Provider","examples":["meta"]},"architecture":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Architecture","examples":["react"]}},"type":"object","required":["name","provider"],"title":"ManifestModel"},"ManifestPricingSnapshot":{"properties":{"pricing_id":{"type":"string","format":"uuid","title":"Pricing Id"},"model":{"type":"string","title":"Model"},"provider":{"type":"string","title":"Provider"},"input_cost_per_million":{"type":"number","title":"Input Cost Per Million"},"output_cost_per_million":{"type":"number","title":"Output Cost Per Million"},"effective_date":{"type":"string","format":"date","title":"Effective Date"},"run_count":{"type":"integer","title":"Run Count"}},"type":"object","required":["pricing_id","model","provider","input_cost_per_million","output_cost_per_million","effective_date","run_count"],"title":"ManifestPricingSnapshot"},"ManifestProvider":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name","examples":["Acme AI Labs"]},"url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Url","examples":["https://acme-ai.dev"]}},"type":"object","required":["name"],"title":"ManifestProvider"},"ManifestSignature":{"properties":{"alg":{"type":"string","maxLength":20,"title":"Alg","examples":["EdDSA"]},"jws":{"type":"string","title":"Jws","description":"Detached compact JWS: 'header..signature', or full compact 'header.payload.signature' where payload must match the independently-canonicalized manifest bytes."}},"type":"object","required":["alg","jws"],"title":"ManifestSignature","description":"A detached-JWS signature over the JCS-canonical manifest.\n\nW1 supports exactly one algorithm: EdDSA (Ed25519), verified by\n``app.services.bpp_manifest.verify_manifest``. An unsupported ``alg`` is\nrejected at VERIFICATION time with ``reason=\"alg_unsupported\"`` — never\nat schema-parse time, since a manifest declaring one must still be\naccepted at discover/register (progressive-never-a-gate, BPP-001 §0.2)."},"MintMeteringKeyRequest":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"}},"type":"object","required":["agent_id"],"title":"MintMeteringKeyRequest"},"MintMeteringKeyResponse":{"properties":{"virtual_key":{"type":"string","title":"Virtual Key"},"virtual_key_last4":{"type":"string","title":"Virtual Key Last4"},"created":{"type":"boolean","title":"Created"}},"type":"object","required":["virtual_key","virtual_key_last4","created"],"title":"MintMeteringKeyResponse"},"ModelPricingRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"model_name":{"type":"string","title":"Model Name"},"provider":{"type":"string","title":"Provider"},"input_cost_per_million":{"type":"number","title":"Input Cost Per Million"},"output_cost_per_million":{"type":"number","title":"Output Cost Per Million"},"effective_date":{"type":"string","format":"date","title":"Effective Date"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","model_name","provider","input_cost_per_million","output_cost_per_million","effective_date","notes","created_at"],"title":"ModelPricingRead","description":"Read model pricing."},"NoCurrentApproval":{"properties":{"status":{"type":"string","const":"none","title":"Status","default":"none"}},"type":"object","title":"NoCurrentApproval","description":"Workspace members' answer when the agent has no live approval (200, not 404)."},"NotifyMeRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"NotifyMeRequest"},"NotifyMeResponse":{"properties":{"queued":{"type":"boolean","title":"Queued"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["queued"],"title":"NotifyMeResponse"},"OtlpIngestReceiptRead":{"properties":{"projected_spans":{"type":"integer","maximum":999.0,"minimum":0.0,"title":"Projected Spans"},"newly_stored":{"type":"integer","maximum":999.0,"minimum":0.0,"title":"Newly Stored"},"replayed":{"type":"integer","maximum":999.0,"minimum":0.0,"title":"Replayed"},"cap_dropped":{"type":"integer","maximum":999.0,"minimum":0.0,"title":"Cap Dropped"},"count_saturated":{"type":"boolean","title":"Count Saturated"},"last_disposition":{"anyOf":[{"type":"string","enum":["stored_new","replay_only","stored_with_replay","cap_dropped"]},{"type":"null"}],"title":"Last Disposition"},"last_received_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Received At"},"semconv":{"anyOf":[{"type":"string","enum":["genai","openinference","openllmetry"]},{"type":"null"}],"title":"Semconv"}},"type":"object","required":["projected_spans","newly_stored","replayed","cap_dropped","count_saturated","last_disposition","last_received_at"],"title":"OtlpIngestReceiptRead","description":"Strict owner/admin view of Badge's bounded per-run ingest receipt."},"OtlpStaleTokenFailureRead":{"properties":{"request_count":{"type":"integer","maximum":999.0,"minimum":1.0,"title":"Request Count"},"count_saturated":{"type":"boolean","title":"Count Saturated"},"last_rejected_at":{"type":"string","format":"date-time","title":"Last Rejected At"},"state":{"type":"string","enum":["active","recovered"],"title":"State"}},"type":"object","required":["request_count","count_saturated","last_rejected_at","state"],"title":"OtlpStaleTokenFailureRead"},"OwnedPromoCodeRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"playbook_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Playbook Id"},"creator_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Creator User Id"},"code":{"type":"string","title":"Code"},"discount_type":{"type":"string","title":"Discount Type"},"discount_value":{"type":"integer","title":"Discount Value"},"max_redemptions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Redemptions"},"current_redemptions":{"type":"integer","title":"Current Redemptions"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"min_buyer_account_age_days":{"type":"integer","title":"Min Buyer Account Age Days"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"playbook_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Playbook Name"}},"type":"object","required":["id","playbook_id","creator_user_id","code","discount_type","discount_value","max_redemptions","current_redemptions","expires_at","min_buyer_account_age_days","created_at","revoked_at"],"title":"OwnedPromoCodeRead","description":"Same as PromoCodeRead but with the parent playbook's name pre-joined.\n\nUsed by the creator's cross-playbook codes index (`GET /playbooks/promo-codes`,\nPRD-008 FR-15). Avoids an N+1 round-trip from the frontend just to render\na \"for: <playbook>\" column."},"PMFResponseCreate":{"properties":{"response":{"type":"string","pattern":"^(very_disappointed|somewhat_disappointed|not_disappointed)$","title":"Response"}},"type":"object","required":["response"],"title":"PMFResponseCreate"},"PMFResponseRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"response":{"type":"string","title":"Response"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","response","created_at"],"title":"PMFResponseRead"},"PMFResultsRead":{"properties":{"total_responses":{"type":"integer","title":"Total Responses"},"very_disappointed":{"type":"integer","title":"Very Disappointed"},"somewhat_disappointed":{"type":"integer","title":"Somewhat Disappointed"},"not_disappointed":{"type":"integer","title":"Not Disappointed"},"nps_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Nps Score"}},"type":"object","required":["total_responses","very_disappointed","somewhat_disappointed","not_disappointed"],"title":"PMFResultsRead"},"PaginatedResponse_AgentCapabilityRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AgentCapabilityRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[AgentCapabilityRead]"},"PaginatedResponse_AgentRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AgentRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[AgentRead]"},"PaginatedResponse_ApiKeyRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ApiKeyRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[ApiKeyRead]"},"PaginatedResponse_AuditEventRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AuditEventRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[AuditEventRead]"},"PaginatedResponse_BenchmarkSuiteRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/BenchmarkSuiteRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[BenchmarkSuiteRead]"},"PaginatedResponse_ChallengeRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ChallengeRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[ChallengeRead]"},"PaginatedResponse_CustomBenchmarkRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/CustomBenchmarkRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[CustomBenchmarkRead]"},"PaginatedResponse_ExecutionStepRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ExecutionStepRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[ExecutionStepRead]"},"PaginatedResponse_LabExperimentRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/LabExperimentRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[LabExperimentRead]"},"PaginatedResponse_LabRunRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/LabRunRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[LabRunRead]"},"PaginatedResponse_LeaderboardEntry_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/LeaderboardEntry"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[LeaderboardEntry]"},"PaginatedResponse_PlaybookPublicRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/PlaybookPublicRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[PlaybookPublicRead]"},"PaginatedResponse_PlaybookRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/PlaybookRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[PlaybookRead]"},"PaginatedResponse_RegressionAlertRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RegressionAlertRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[RegressionAlertRead]"},"PaginatedResponse_RunLogRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RunLogRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[RunLogRead]"},"PaginatedResponse_RunRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RunRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[RunRead]"},"PaginatedResponse_ScheduleHistoryItem_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ScheduleHistoryItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[ScheduleHistoryItem]"},"PaginatedResponse_ScreeningSessionRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ScreeningSessionRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[ScreeningSessionRead]"},"PaginatedResponse_TaskRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TaskRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[TaskRead]"},"PaginatedResponse_TaskSubmissionRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TaskSubmissionRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[TaskSubmissionRead]"},"PaginatedResponse_TeamRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TeamRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[TeamRead]"},"PaginatedResponse_WebhookDeliveryRead_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/WebhookDeliveryRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","page_size","pages"],"title":"PaginatedResponse[WebhookDeliveryRead]"},"PassKRequirement":{"properties":{"k":{"type":"integer","title":"K"},"threshold":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Threshold"}},"additionalProperties":false,"type":"object","required":["k","threshold"],"title":"PassKRequirement"},"PayoutEmailRead":{"properties":{"payout_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payout Email"}},"type":"object","title":"PayoutEmailRead"},"PayoutEmailUpdate":{"properties":{"payout_email":{"type":"string","format":"email","title":"Payout Email"}},"type":"object","required":["payout_email"],"title":"PayoutEmailUpdate","description":"Body for PUT /playbooks/my/payout-email."},"PendingPaymentResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"payment_pending":{"type":"boolean","title":"Payment Pending","default":false},"payment_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Url"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["user_id"],"title":"PendingPaymentResponse","description":"Authenticated recovery state for one already-requested plan change.\n\nThis deliberately lives outside ``BillingStatusResponse``: billing status\nis public deployment configuration, whereas an open hosted invoice is\ncustomer payment data. The endpoint below is the only browser-readable\nprojection and returns no Stripe/customer/subscription identifiers. The\nauthenticated Badge user id binds this response to the browser's SWR cache\nkey; it is not a Stripe identifier and is never used for authorization."},"PerformanceHistoryResponse":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"},"history":{"items":{"$ref":"#/components/schemas/PerformancePoint"},"type":"array","title":"History"},"regression_detected":{"type":"boolean","title":"Regression Detected"},"regression_details":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Regression Details"}},"type":"object","required":["agent_id","agent_name","history","regression_detected","regression_details"],"title":"PerformanceHistoryResponse"},"PerformancePoint":{"properties":{"date":{"type":"string","title":"Date"},"success_rate":{"type":"number","title":"Success Rate"},"avg_latency_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Latency Ms"},"avg_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Cost Usd"},"run_count":{"type":"integer","title":"Run Count"},"composite_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Composite Score"}},"type":"object","required":["date","success_rate","avg_latency_ms","avg_cost_usd","run_count","composite_score"],"title":"PerformancePoint","description":"A data point in the performance history timeline."},"PlanChangeResponse":{"properties":{"plan_changed":{"type":"boolean","title":"Plan Changed","default":true},"dev_mode":{"type":"boolean","title":"Dev Mode","default":false},"payment_pending":{"type":"boolean","title":"Payment Pending","default":false},"payment_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Url"},"plan":{"type":"string","title":"Plan"},"interval":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Interval"},"previous_plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Plan"},"user":{"$ref":"#/components/schemas/UserRead"}},"type":"object","required":["plan","user"],"title":"PlanChangeResponse","description":"Returned when an existing paid subscription was MODIFIED, not replaced.\n\nA customer who already pays us and picks a different tier or cadence never\nreaches Stripe Checkout — there is no session and no redirect, because\nCheckout can only create a second subscription. The change is applied to\nthe subscription they already have and this response reports the result.\n\n``plan_changed`` is the frontend's branch signal, deliberately a distinct\nfield rather than a reuse of ``dev_mode``: this is a real, live, money-\nmoving change and labelling it \"dev mode\" would be a lie that some future\nreader acts on. ``lib/billing.ts`` treats it the way it treats ``dev_mode``\n— no redirect, refresh the user — so both /pricing and /settings already do\nthe right thing with it."},"PlaybookCheckoutRead":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url","description":"Stripe-hosted Checkout Session URL to redirect to."},"purchase_id":{"type":"string","format":"uuid","title":"Purchase Id","description":"The AWAITING_PAYMENT purchase row id."},"status":{"type":"string","title":"Status","description":"Always 'awaiting_payment' on this path.","default":"awaiting_payment"}},"type":"object","required":["checkout_url","purchase_id"],"title":"PlaybookCheckoutRead","description":"Response for the LIVE charge path of POST /playbooks/{id}/purchase.\n\nCharge-first / deliver-on-confirm (F-01 Increment 2): no clone exists yet, so\nthis deliberately carries NO clone field — the frontend redirects the buyer to\n`checkout_url` and the clone is minted by the webhook on payment confirmation.\nReturned with HTTP 200 (vs the lean-v1 fallback's 201 + PlaybookPurchaseRead),\nso the frontend branches on the response shape, not just the status code."},"PlaybookCloneCreate":{"properties":{"target_agent_id":{"type":"string","format":"uuid","title":"Target Agent Id","description":"Agent in the caller's roster to receive the cloned playbook."}},"type":"object","required":["target_agent_id"],"title":"PlaybookCloneCreate","description":"Clone (\"Hire\") a public playbook to one of the caller's agents.\n\nTyped so a malformed `target_agent_id` is a clean 422 (Pydantic) rather than\na 500 from raw `uuid.UUID(...)` parsing. Body carries only the target — the\nsource playbook is the path param and price/ownership are server-side."},"PlaybookCreate":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name","examples":["CoT-v1"]},"playbook_type":{"$ref":"#/components/schemas/PlaybookType","default":"zero_shot"},"system_prompt":{"anyOf":[{"type":"string","maxLength":50000},{"type":"null"}],"title":"System Prompt"},"model":{"type":"string","maxLength":100,"title":"Model","default":"gpt-4o"},"temperature":{"type":"number","maximum":2.0,"minimum":0.0,"title":"Temperature","default":0.7},"max_tokens":{"type":"integer","maximum":128000.0,"minimum":1.0,"title":"Max Tokens","default":4096},"top_p":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Top P","default":1.0},"few_shot_examples":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Few Shot Examples"},"tools_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tools Config"},"notes":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Notes"},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Description","description":"Public listing blurb shown on marketplace cards. REQUIRED (non-empty) when is_public=True — see routers/playbooks.py."},"is_public":{"type":"boolean","title":"Is Public","default":false},"pricing_model":{"$ref":"#/components/schemas/PricingModel","default":"free"},"price_usd_cents":{"type":"integer","maximum":10000000.0,"minimum":0.0,"title":"Price Usd Cents","description":"Hire price in USD cents. 0 == free. Max $100k. Integer only — money is NEVER Float.","default":0}},"type":"object","required":["agent_id","name"],"title":"PlaybookCreate","description":"Create a new playbook for an agent."},"PlaybookPublicRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"name":{"type":"string","title":"Name"},"version":{"type":"integer","title":"Version"},"parent_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Id"},"is_active":{"type":"boolean","title":"Is Active"},"is_default":{"type":"boolean","title":"Is Default"},"is_public":{"type":"boolean","title":"Is Public"},"playbook_type":{"type":"string","title":"Playbook Type"},"system_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature"},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens"},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P"},"few_shot_examples":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Few Shot Examples"},"tools_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tools Config"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"pricing_model":{"type":"string","title":"Pricing Model","default":"free"},"price_usd_cents":{"type":"integer","title":"Price Usd Cents","default":0},"total_clones":{"type":"integer","title":"Total Clones","default":0},"total_revenue_usd_cents":{"type":"integer","title":"Total Revenue Usd Cents","default":0},"already_hired":{"type":"boolean","title":"Already Hired","default":false},"configuration_available":{"type":"boolean","title":"Configuration Available","default":false}},"type":"object","required":["id","agent_id","name","version","parent_id","is_active","is_default","is_public","playbook_type","created_at"],"title":"PlaybookPublicRead","description":"Marketplace-safe view of a public playbook.\n\nPaid execution configuration is nullable because it is disclosed only to\nthe creator or a buyer with a provider-confirmed COMPLETED purchase. Safe\ncatalog metadata remains available for discovery."},"PlaybookPurchaseCreate":{"properties":{"target_agent_id":{"type":"string","format":"uuid","title":"Target Agent Id","description":"Agent in the buyer's roster to receive the cloned playbook."}},"type":"object","required":["target_agent_id"],"title":"PlaybookPurchaseCreate","description":"Purchase (\"hire\") a paid public playbook.\n\nThe buyer is the authenticated user; `target_agent_id` is the agent in the\nbuyer's roster that should receive the cloned playbook. In sandbox mode\n(MARKETPLACE_ENABLED=true, no Stripe), the purchase is recorded synchronously\nand the cloned playbook is minted in the same transaction."},"PlaybookRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"name":{"type":"string","title":"Name"},"version":{"type":"integer","title":"Version"},"parent_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Id"},"is_active":{"type":"boolean","title":"Is Active"},"is_default":{"type":"boolean","title":"Is Default"},"is_public":{"type":"boolean","title":"Is Public"},"playbook_type":{"type":"string","title":"Playbook Type"},"system_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt"},"model":{"type":"string","title":"Model"},"temperature":{"type":"number","title":"Temperature"},"max_tokens":{"type":"integer","title":"Max Tokens"},"top_p":{"type":"number","title":"Top P"},"few_shot_examples":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Few Shot Examples"},"tools_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tools Config"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"pricing_model":{"type":"string","title":"Pricing Model","default":"free"},"price_usd_cents":{"type":"integer","title":"Price Usd Cents","default":0},"total_clones":{"type":"integer","title":"Total Clones","default":0},"total_revenue_usd_cents":{"type":"integer","title":"Total Revenue Usd Cents","default":0},"already_hired":{"type":"boolean","title":"Already Hired","default":false}},"type":"object","required":["id","agent_id","name","version","parent_id","is_active","is_default","is_public","playbook_type","system_prompt","model","temperature","max_tokens","top_p","few_shot_examples","tools_config","notes","created_at"],"title":"PlaybookRead"},"PlaybookType":{"type":"string","enum":["zero_shot","few_shot","chain_of_thought","react","custom"],"title":"PlaybookType","description":"Playbook archetypes for agent configuration."},"PlaybookUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"playbook_type":{"anyOf":[{"$ref":"#/components/schemas/PlaybookType"},{"type":"null"}]},"system_prompt":{"anyOf":[{"type":"string","maxLength":50000},{"type":"null"}],"title":"System Prompt"},"model":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Model"},"temperature":{"anyOf":[{"type":"number","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Temperature"},"max_tokens":{"anyOf":[{"type":"integer","maximum":128000.0,"minimum":1.0},{"type":"null"}],"title":"Max Tokens"},"top_p":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Top P"},"few_shot_examples":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Few Shot Examples"},"tools_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tools Config"},"notes":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Notes"},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Description"},"is_public":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public"},"pricing_model":{"anyOf":[{"$ref":"#/components/schemas/PricingModel"},{"type":"null"}]},"price_usd_cents":{"anyOf":[{"type":"integer","maximum":10000000.0,"minimum":0.0},{"type":"null"}],"title":"Price Usd Cents"}},"type":"object","title":"PlaybookUpdate","description":"Update a playbook — creates a new version under the hood.\nOnly fields provided will be changed; others carry over from current version."},"PolicyDryRun":{"properties":{"would_revoke":{"type":"integer","title":"Would Revoke"},"affected":{"items":{"$ref":"#/components/schemas/AffectedAgent"},"type":"array","title":"Affected"}},"type":"object","required":["would_revoke","affected"],"title":"PolicyDryRun","description":"``PUT ...?dry_run=true``: what the new policy would end, with nothing written."},"PortalResponse":{"properties":{"portal_url":{"type":"string","title":"Portal Url"}},"type":"object","required":["portal_url"],"title":"PortalResponse"},"PresetCreate":{"properties":{"name":{"type":"string","maxLength":64,"minLength":1,"title":"Name"},"weights":{"$ref":"#/components/schemas/_WeightsTuple"},"is_default":{"type":"boolean","title":"Is Default","default":false},"scope":{"type":"string","enum":["user","workspace"],"title":"Scope","default":"user"},"team_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Team Id"}},"type":"object","required":["name","weights"],"title":"PresetCreate"},"PresetUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":1},{"type":"null"}],"title":"Name"},"weights":{"anyOf":[{"$ref":"#/components/schemas/_WeightsTuple"},{"type":"null"}]}},"type":"object","title":"PresetUpdate"},"PriceExperimentConcludeRequest":{"properties":{"winner_variant_label":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Winner Variant Label"}},"type":"object","title":"PriceExperimentConcludeRequest","description":"Manual-conclude payload. `winner_variant_label` is optional — when null,\nthe service auto-picks the highest-converting variant (FR-07)."},"PriceExperimentCreate":{"properties":{"variants":{"items":{"$ref":"#/components/schemas/ExperimentVariant"},"type":"array","maxItems":4,"minItems":2,"title":"Variants"},"min_sample_per_variant":{"type":"integer","maximum":500.0,"minimum":50.0,"title":"Min Sample Per Variant","default":100},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"}},"type":"object","required":["variants"],"title":"PriceExperimentCreate","description":"Creator-side: create a new draft price experiment.\n\nVariants must:\n  - have between 2 and 4 entries (PRD-008 FR-06).\n  - have unique labels.\n  - have traffic_pct summing to exactly 100.\n  - span ≤ 5x range (PRD-008 FR-06; service helper does the math).\n\nValidation that depends on referenced rows (intro-pricing overlap, single-\nrunning-experiment-per-playbook) lives in the endpoint where it has DB\naccess."},"PriceExperimentRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"playbook_id":{"type":"string","format":"uuid","title":"Playbook Id"},"creator_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Creator User Id"},"variants_json":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Variants Json"},"status":{"type":"string","title":"Status"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"ends_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ends At"},"min_sample_per_variant":{"type":"integer","title":"Min Sample Per Variant"},"winner_variant_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Winner Variant Label"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"concluded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Concluded At"}},"type":"object","required":["id","playbook_id","creator_user_id","variants_json","status","started_at","ends_at","min_sample_per_variant","winner_variant_label","notes","created_at","concluded_at"],"title":"PriceExperimentRead","description":"Full experiment row + computed-on-read fields."},"PriceExperimentResults":{"properties":{"experiment":{"$ref":"#/components/schemas/PriceExperimentRead"},"variants":{"items":{"$ref":"#/components/schemas/VariantStatsRead"},"type":"array","title":"Variants"},"sample_met":{"type":"boolean","title":"Sample Met"}},"type":"object","required":["experiment","variants","sample_met"],"title":"PriceExperimentResults","description":"Composite response for the dashboard: experiment + per-variant stats.\n\nVisible only to the playbook's creator (the GET endpoint enforces ownership)."},"PriceQuoteResponse":{"properties":{"playbook_id":{"type":"string","format":"uuid","title":"Playbook Id"},"list_price_cents":{"type":"integer","title":"List Price Cents"},"price_cents":{"type":"integer","title":"Price Cents"},"is_experiment_variant":{"type":"boolean","title":"Is Experiment Variant"},"experiment_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Experiment Id"},"variant_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Label"},"anchor_was_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Anchor Was Cents"},"anchor_valid_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Anchor Valid Until"},"promo_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Promo Code"},"discount_cents":{"type":"integer","title":"Discount Cents","default":0},"effective_price_cents":{"type":"integer","title":"Effective Price Cents"}},"type":"object","required":["playbook_id","list_price_cents","price_cents","is_experiment_variant","experiment_id","variant_label","effective_price_cents"],"title":"PriceQuoteResponse","description":"Computed price for a viewer of /playbooks/{id}.\n\nIncludes the variant assignment (if any), the anchor \"was/now\" pair (if\nvalid per FR-11), and the platform fee that would be deducted from the\ncreator's payout (so creator-side dashboards can show net economics).\n\n`is_experiment_variant` lets the UI show a transparent \"Test price\"\nindicator (PRD-008 FR-05 & R-02 cohort guardrail)."},"PricingModel":{"type":"string","enum":["free","one_time"],"title":"PricingModel","description":"How a Playbook is monetized in the Recruiting marketplace."},"ProInterestRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"interest":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Interest"}},"type":"object","required":["email"],"title":"ProInterestRequest"},"ProInterestResponse":{"properties":{"queued":{"type":"boolean","title":"Queued"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["queued"],"title":"ProInterestResponse"},"PromoCodeCreate":{"properties":{"code":{"type":"string","maxLength":50,"minLength":3,"title":"Code","examples":["LAUNCH20"]},"discount_type":{"type":"string","enum":["percent","fixed"],"title":"Discount Type"},"discount_value":{"type":"integer","minimum":1.0,"title":"Discount Value"},"max_redemptions":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Redemptions"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"min_buyer_account_age_days":{"type":"integer","maximum":365.0,"minimum":0.0,"title":"Min Buyer Account Age Days","default":0}},"type":"object","required":["code","discount_type","discount_value"],"title":"PromoCodeCreate","description":"Creator creates a discount code for one of their playbooks.\n\nCode is normalised to uppercase server-side before persistence + uniqueness\ncheck (PRD-008 FR-09)."},"PromoCodeRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"playbook_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Playbook Id"},"creator_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Creator User Id"},"code":{"type":"string","title":"Code"},"discount_type":{"type":"string","title":"Discount Type"},"discount_value":{"type":"integer","title":"Discount Value"},"max_redemptions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Redemptions"},"current_redemptions":{"type":"integer","title":"Current Redemptions"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"min_buyer_account_age_days":{"type":"integer","title":"Min Buyer Account Age Days"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"}},"type":"object","required":["id","playbook_id","creator_user_id","code","discount_type","discount_value","max_redemptions","current_redemptions","expires_at","min_buyer_account_age_days","created_at","revoked_at"],"title":"PromoCodeRead","description":"Creator-facing read shape — includes all fields including revoked_at."},"PromoValidateRequest":{"properties":{"code":{"type":"string","maxLength":50,"minLength":1,"title":"Code"}},"type":"object","required":["code"],"title":"PromoValidateRequest","description":"Buyer-side: 'is this code valid for me on this playbook?'"},"PromoValidateResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"discount_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Discount Type"},"discount_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Discount Value"},"discounted_price_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Discounted Price Cents"},"list_price_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"List Price Cents"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["valid"],"title":"PromoValidateResponse","description":"Buyer-side validation result. Never reveals seller-only fields like\nmax_redemptions or per-buyer eligibility logic — only enough for the UI to\nsay \"code applied: $X off\"."},"PublicAgentSEO":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"},"agent_slug":{"type":"string","title":"Agent Slug","description":"handle-prefixed canonical slug"},"handle":{"type":"string","title":"Handle"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"composite_score":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Composite Score"},"total_runs":{"type":"integer","title":"Total Runs","default":0},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"fitness":{"anyOf":[{"$ref":"#/components/schemas/FitnessAxes"},{"type":"null"}]},"verified_state":{"type":"string","title":"Verified State","default":"unverified"},"model_family":{"type":"string","title":"Model Family","default":"other"},"cost_tier":{"type":"string","title":"Cost Tier","default":"unknown"}},"type":"object","required":["agent_id","agent_name","agent_slug","handle","domain","updated_at"],"title":"PublicAgentSEO","description":"One row in ``GET /seo/sitemap-data`` ``public_agents``.\n\nUsed for sitemap emission, /talent-pool tile rendering, and the JSON-LD\n``SoftwareApplication`` payload."},"PublicApproval":{"properties":{"status":{"type":"string","const":"approved","title":"Status"},"workspace":{"type":"string","title":"Workspace"},"decided_at":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Decided At"},"blueprint_version_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Blueprint Version Id"}},"type":"object","required":["status","workspace","decided_at","blueprint_version_id"],"title":"PublicApproval","description":"The ONLY approval fields an anonymous reader ever sees."},"PublicProfile":{"properties":{"username":{"type":"string","title":"Username"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"plan":{"type":"string","title":"Plan"},"joined_at":{"type":"string","format":"date-time","title":"Joined At"},"public_agent_count":{"type":"integer","title":"Public Agent Count"},"total_public_runs":{"type":"integer","title":"Total Public Runs"},"best_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best Score"},"agents":{"items":{"$ref":"#/components/schemas/PublicProfileAgent"},"type":"array","title":"Agents","default":[]}},"type":"object","required":["username","plan","joined_at","public_agent_count","total_public_runs"],"title":"PublicProfile","description":"Public-facing profile payload for GET /profiles/{username}.\n\nStrictly PII-free: no email, no internal ids beyond the stable username,\nno notification prefs, no plan-expiry dates. Returns aggregated stats\nand the user's public agents only (is_public=True)."},"PublicProfileAgent":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"provider_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Name"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"run_count":{"type":"integer","title":"Run Count","default":0},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"}},"type":"object","required":["id","name"],"title":"PublicProfileAgent"},"RecommendedPriceResponse":{"properties":{"p25_cents":{"type":"integer","title":"P25 Cents"},"p50_cents":{"type":"integer","title":"P50 Cents"},"p75_cents":{"type":"integer","title":"P75 Cents"},"num_comparables":{"type":"integer","title":"Num Comparables"},"confidence":{"type":"string","enum":["low","medium","high"],"title":"Confidence"}},"type":"object","required":["p25_cents","p50_cents","p75_cents","num_comparables","confidence"],"title":"RecommendedPriceResponse","description":"Output of the recommended-price endpoint (FR-10)."},"ReconciliationAuditRecord":{"properties":{"certification_id":{"type":"string","format":"uuid","title":"Certification Id"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"},"verdict":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verdict"},"delta_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Delta Pct"},"cost_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost Scope"}},"type":"object","required":["certification_id","provider","verdict","delta_pct","cost_scope"],"title":"ReconciliationAuditRecord"},"ReconciliationAuditRequest":{"properties":{"k":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"K","default":5}},"type":"object","title":"ReconciliationAuditRequest"},"ReconciliationAuditResponse":{"properties":{"selected_count":{"type":"integer","title":"Selected Count"},"records":{"items":{"$ref":"#/components/schemas/ReconciliationAuditRecord"},"type":"array","title":"Records"}},"type":"object","required":["selected_count","records"],"title":"ReconciliationAuditResponse"},"RegressionAlertRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"drop_percent":{"type":"number","title":"Drop Percent"},"architecture_changed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Architecture Changed"},"architecture_node_delta":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Architecture Node Delta"},"architecture_edge_delta":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Architecture Edge Delta"},"detected_at":{"type":"string","format":"date-time","title":"Detected At"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"}},"type":"object","required":["id","agent_id","user_id","drop_percent","detected_at","resolved_at"],"title":"RegressionAlertRead","description":"Response schema for RegressionAlert."},"ReportBodyVerifyResponse":{"properties":{"valid":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Valid"},"status":{"type":"string","enum":["valid","invalid","unverifiable"],"title":"Status"},"agent_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent Id"},"generated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Generated At"},"payload_sha256":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payload Sha256"},"key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"canonical_form":{"anyOf":[{"type":"string","enum":["current","legacy"]},{"type":"null"}],"title":"Canonical Form"}},"type":"object","required":["valid","status"],"title":"ReportBodyVerifyResponse","description":"Result of checking a downloaded report file (POST /verify/report)."},"ReportHeadline":{"properties":{"baseline_agent_name":{"type":"string","title":"Baseline Agent Name"},"cheapest_agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cheapest Agent Name"},"baseline_measured_cost_per_run_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Baseline Measured Cost Per Run Usd"},"cheapest_measured_cost_per_run_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cheapest Measured Cost Per Run Usd"},"projected_monthly_saving_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Projected Monthly Saving Usd"},"observed_monthly_runs":{"type":"number","title":"Observed Monthly Runs"},"window_days":{"type":"integer","title":"Window Days"},"pass_rate_tolerance":{"type":"number","title":"Pass Rate Tolerance"},"k":{"type":"integer","title":"K"},"pass_k_gate":{"type":"string","title":"Pass K Gate"}},"type":"object","required":["baseline_agent_name","observed_monthly_runs","window_days","pass_rate_tolerance","k","pass_k_gate"],"title":"ReportHeadline","description":"Signed headline facts, at PUBLIC precision, for a PUBLIC agent only."},"ReportVerifyResponse":{"properties":{"valid":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Valid"},"status":{"type":"string","enum":["valid","invalid","unverifiable"],"title":"Status"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"payload_sha256":{"type":"string","title":"Payload Sha256"},"key_id":{"type":"string","title":"Key Id"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"headline":{"anyOf":[{"$ref":"#/components/schemas/ReportHeadline"},{"type":"null"}]},"canonical_form":{"anyOf":[{"type":"string","enum":["current","legacy"]},{"type":"null"}],"title":"Canonical Form"}},"type":"object","required":["valid","status","agent_id","generated_at","payload_sha256","key_id"],"title":"ReportVerifyResponse"},"RequiredComment":{"properties":{"comment":{"type":"string","maxLength":2000,"minLength":1,"title":"Comment"}},"additionalProperties":false,"type":"object","required":["comment"],"title":"RequiredComment"},"ResetPasswordRequest":{"properties":{"token":{"type":"string","maxLength":512,"minLength":1,"title":"Token"},"new_password":{"type":"string","maxLength":255,"minLength":8,"title":"New Password"}},"type":"object","required":["token","new_password"],"title":"ResetPasswordRequest","description":"Body for POST /auth/reset-password.\n\n`new_password` reuses the signup strength policy via\npassword_service.validate_password_strength so a reset can never set a\nweaker password than signup allows. A weak password → 422 (Pydantic\nsurfaces the ValueError message). The token itself is validated in the\nhandler (existence / expiry / single-use), not here."},"RevokeBody":{"properties":{"reason":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Reason"},"comment":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Comment"}},"additionalProperties":false,"type":"object","title":"RevokeBody","description":"``reason`` is the contract; ``comment`` is accepted as an alias."},"RunCreate":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"task_id":{"type":"string","format":"uuid","title":"Task Id"}},"type":"object","required":["agent_id","task_id"],"title":"RunCreate"},"RunCreateRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Display Name"},"agent_identity_state":{"anyOf":[{"type":"string","enum":["active","deactivated","unavailable"]},{"type":"null"}],"title":"Agent Identity State"},"task_id":{"type":"string","format":"uuid","title":"Task Id"},"status":{"$ref":"#/components/schemas/RunStatus"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"success":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Success"},"output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output"},"output_withheld":{"type":"boolean","title":"Output Withheld","default":false},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"total_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Usd"},"evidence_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Evidence Cost Usd"},"evidence_cost_source":{"type":"string","title":"Evidence Cost Source","default":"unavailable"},"evidence_cost_partial":{"type":"boolean","title":"Evidence Cost Partial","default":false},"evidence_priced_call_count":{"type":"integer","title":"Evidence Priced Call Count","default":0},"evidence_unpriced_call_count":{"type":"integer","title":"Evidence Unpriced Call Count","default":0},"evidence_total_call_count":{"type":"integer","title":"Evidence Total Call Count","default":0},"retry_count":{"type":"integer","title":"Retry Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"answer_exposed":{"type":"boolean","title":"Answer Exposed","default":false},"provider_cost_authority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Cost Authority"},"screening_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Screening Session Id"},"repeat_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Repeat Index"},"repeat_total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Repeat Total"},"architecture_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Architecture Hash"},"previous_architecture_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Architecture Hash"},"architecture_changed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Architecture Changed"},"architecture_comparable":{"type":"boolean","title":"Architecture Comparable","default":false},"architecture_change_summary":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Architecture Change Summary"},"architecture_span_count":{"type":"integer","title":"Architecture Span Count","default":0},"certification_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Certification Id"},"certification_sequence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Certification Sequence"},"requested_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested Model"},"returned_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Returned Model"},"llm_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Provider"},"usage_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Usage Source"},"model_pricing_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Model Pricing Id"},"pricing_input_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pricing Input Cost Per Million"},"pricing_output_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pricing Output Cost Per Million"},"pricing_effective_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Pricing Effective Date"},"error_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Class"},"response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Status"},"error_body_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Body Excerpt"},"execution_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Execution Mode"},"verification_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Hash"},"signed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Signed At"},"key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"},"public_certificate_state":{"type":"string","enum":["verified","simulated","unsigned","invalid"],"title":"Public Certificate State","default":"unsigned"},"suite_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suite Id"},"suite_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Suite Version"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"cost_provenance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost Provenance"},"cost_basis":{"anyOf":[{"type":"string","enum":["metered","traced","traced_partial","self_reported","unavailable"]},{"type":"null"}],"title":"Cost Basis"},"scored_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Scored Cost Usd"},"provenance_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provenance Level"},"manifest_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manifest Hash"},"otlp_ingest_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Otlp Ingest Token"},"otlp_endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Otlp Endpoint"},"provenance_flags":{"items":{"type":"string"},"type":"array","title":"Provenance Flags","readOnly":true}},"type":"object","required":["id","agent_id","task_id","status","started_at","completed_at","latency_ms","success","output","error_message","input_tokens","output_tokens","total_cost_usd","retry_count","created_at","provenance_flags"],"title":"RunCreateRead","description":"``POST /runs``-only response surface — BPP-001 W2-T1 per-run OTLP\ntoken mint.\n\n``otlp_ingest_token`` is the RAW bearer token, revealed exactly once\nhere (auth_token_service pattern — only its sha256 hash lands on\n``run.otlp_token_hash``). Deliberately declared on THIS subclass, never\non ``RunRead`` itself, so no GET (including ``GET /runs/{id}``) can ever\nleak it.\n\nBoth fields are populated only when ``BPP_ENABLED`` is on AND the agent\nis ``http_endpoint``-mode; otherwise they stay unset and — because the\nroute below serializes with ``response_model_exclude_unset=True`` — are\nfully ABSENT from the JSON body (not merely null), matching the\nBPP-001 zero-delta contract for flag-off / non-http_endpoint agents."},"RunLogRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"run_id":{"type":"string","format":"uuid","title":"Run Id"},"level":{"type":"string","title":"Level"},"source":{"type":"string","title":"Source"},"message":{"type":"string","title":"Message"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"}},"type":"object","required":["id","run_id","level","source","message","timestamp"],"title":"RunLogRead","description":"Read a run log entry."},"RunPhaseEventRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"run_id":{"type":"string","format":"uuid","title":"Run Id"},"sequence":{"type":"integer","title":"Sequence"},"phase":{"type":"string","title":"Phase"},"state":{"type":"string","enum":["started","succeeded","failed","unavailable","not_applicable"],"title":"State"},"occurred_at":{"type":"string","format":"date-time","title":"Occurred At"},"duration_since_previous_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Since Previous Ms"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["id","run_id","sequence","phase","state","occurred_at","duration_since_previous_ms","metadata"],"title":"RunPhaseEventRead"},"RunRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Display Name"},"agent_identity_state":{"anyOf":[{"type":"string","enum":["active","deactivated","unavailable"]},{"type":"null"}],"title":"Agent Identity State"},"task_id":{"type":"string","format":"uuid","title":"Task Id"},"status":{"$ref":"#/components/schemas/RunStatus"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"success":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Success"},"output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output"},"output_withheld":{"type":"boolean","title":"Output Withheld","default":false},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"total_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Usd"},"evidence_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Evidence Cost Usd"},"evidence_cost_source":{"type":"string","title":"Evidence Cost Source","default":"unavailable"},"evidence_cost_partial":{"type":"boolean","title":"Evidence Cost Partial","default":false},"evidence_priced_call_count":{"type":"integer","title":"Evidence Priced Call Count","default":0},"evidence_unpriced_call_count":{"type":"integer","title":"Evidence Unpriced Call Count","default":0},"evidence_total_call_count":{"type":"integer","title":"Evidence Total Call Count","default":0},"retry_count":{"type":"integer","title":"Retry Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"answer_exposed":{"type":"boolean","title":"Answer Exposed","default":false},"provider_cost_authority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Cost Authority"},"screening_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Screening Session Id"},"repeat_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Repeat Index"},"repeat_total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Repeat Total"},"architecture_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Architecture Hash"},"previous_architecture_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Architecture Hash"},"architecture_changed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Architecture Changed"},"architecture_comparable":{"type":"boolean","title":"Architecture Comparable","default":false},"architecture_change_summary":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Architecture Change Summary"},"architecture_span_count":{"type":"integer","title":"Architecture Span Count","default":0},"certification_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Certification Id"},"certification_sequence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Certification Sequence"},"requested_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested Model"},"returned_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Returned Model"},"llm_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Provider"},"usage_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Usage Source"},"model_pricing_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Model Pricing Id"},"pricing_input_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pricing Input Cost Per Million"},"pricing_output_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pricing Output Cost Per Million"},"pricing_effective_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Pricing Effective Date"},"error_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Class"},"response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Status"},"error_body_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Body Excerpt"},"execution_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Execution Mode"},"verification_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Hash"},"signed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Signed At"},"key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"},"public_certificate_state":{"type":"string","enum":["verified","simulated","unsigned","invalid"],"title":"Public Certificate State","default":"unsigned"},"suite_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suite Id"},"suite_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Suite Version"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"cost_provenance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost Provenance"},"cost_basis":{"anyOf":[{"type":"string","enum":["metered","traced","traced_partial","self_reported","unavailable"]},{"type":"null"}],"title":"Cost Basis"},"scored_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Scored Cost Usd"},"provenance_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provenance Level"},"manifest_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manifest Hash"},"provenance_flags":{"items":{"type":"string"},"type":"array","title":"Provenance Flags","readOnly":true}},"type":"object","required":["id","agent_id","task_id","status","started_at","completed_at","latency_ms","success","output","error_message","input_tokens","output_tokens","total_cost_usd","retry_count","created_at","provenance_flags"],"title":"RunRead"},"RunStatus":{"type":"string","enum":["pending","running","completed","failed","timeout"],"title":"RunStatus"},"RunStatusUpdate":{"properties":{"status":{"$ref":"#/components/schemas/RunStatus"},"success":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Success"},"output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"total_cost_usd":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Total Cost Usd"},"retry_count":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Retry Count"},"model":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Model"},"unit_cost_override_usd":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Unit Cost Override Usd","description":"Per-task TOTAL cost for the run in USD. Sanity-capped at 100."}},"type":"object","required":["status"],"title":"RunStatusUpdate"},"RunTraceRead":{"properties":{"run_id":{"type":"string","format":"uuid","title":"Run Id"},"task_id":{"type":"string","format":"uuid","title":"Task Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"request_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Url"},"has_request_url":{"type":"boolean","title":"Has Request Url","default":false},"request_method":{"type":"string","title":"Request Method","default":"POST"},"request_headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Request Headers"},"request_body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"string"},{"type":"null"}],"title":"Request Body"},"response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Status"},"response_body":{"title":"Response Body"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"retry_count":{"type":"integer","title":"Retry Count","default":0},"error_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Class"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"parsed_output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parsed Output"},"expected_output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Output"},"success":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Success"},"answer_exposed":{"type":"boolean","title":"Answer Exposed","default":false},"task_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Name"},"task_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Prompt"},"prompt_available":{"type":"boolean","title":"Prompt Available","default":false},"evaluation_method":{"type":"string","title":"Evaluation Method","default":"fuzzy_text_match_v1"},"expected_output_shape":{"type":"string","enum":["reference_text","non_empty_text"],"title":"Expected Output Shape","default":"non_empty_text"},"evaluation_result":{"type":"string","enum":["passed","failed","pending"],"title":"Evaluation Result","default":"pending"},"evaluation_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evaluation Reason"}},"type":"object","required":["run_id","task_id","agent_id"],"title":"RunTraceRead","description":"Per-task request/response trace surface — BRIEF-001 §6 IN-5.\n\nReturned from GET /runs/{id}/trace and rendered inline on the\nrun-detail page so the customer can verify the score is real\n(Customer Voice §1 quote: \"I told you it's a RAG bot and you ran\nFizzBuzz on it\"). Headers are redacted server-side — the caller\nnever sees the bearer token they configured on the agent.\n\nFree tier sees this exact shape. Pro adds export — handled at the\npaywall layer in a follow-up brief (§4 trace-as-Pro wedge), not\nhere. The minimum-viable trace is non-negotiable per §6 IN-5."},"SamlConfigIn":{"properties":{"idp_entity_id":{"type":"string","maxLength":1024,"minLength":1,"title":"Idp Entity Id"},"sso_url":{"type":"string","maxLength":2048,"minLength":1,"title":"Sso Url"},"slo_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Slo Url"},"x509_certs":{"items":{"type":"string"},"type":"array","maxItems":2,"minItems":1,"title":"X509 Certs"},"name_id_format":{"type":"string","enum":["urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress","urn:oasis:names:tc:SAML:2.0:nameid-format:persistent","urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"],"title":"Name Id Format","default":"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"},"want_assertions_signed":{"type":"boolean","const":true,"title":"Want Assertions Signed","default":true}},"additionalProperties":false,"type":"object","required":["idp_entity_id","sso_url","x509_certs"],"title":"SamlConfigIn"},"SamlConfigRead":{"properties":{"idp_entity_id":{"type":"string","title":"Idp Entity Id"},"sso_url":{"type":"string","title":"Sso Url"},"slo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slo Url"},"x509_certs":{"items":{"type":"string"},"type":"array","title":"X509 Certs"},"certificates":{"items":{"$ref":"#/components/schemas/SsoCertificateRead"},"type":"array","title":"Certificates"},"name_id_format":{"type":"string","enum":["urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress","urn:oasis:names:tc:SAML:2.0:nameid-format:persistent","urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"],"title":"Name Id Format"},"want_assertions_signed":{"type":"boolean","title":"Want Assertions Signed","default":true}},"type":"object","required":["idp_entity_id","sso_url","slo_url","x509_certs","certificates","name_id_format"],"title":"SamlConfigRead"},"SavingsBaseline":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"}},"type":"object","required":["agent_id","agent_name"],"title":"SavingsBaseline"},"SavingsCheapest":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"},"measured_cost_per_run_usd":{"type":"number","title":"Measured Cost Per Run Usd"}},"type":"object","required":["agent_id","agent_name","measured_cost_per_run_usd"],"title":"SavingsCheapest"},"SavingsExcluded":{"properties":{"ineligible_runs":{"type":"integer","title":"Ineligible Runs"},"simulated_runs":{"type":"integer","title":"Simulated Runs"}},"type":"object","required":["ineligible_runs","simulated_runs"],"title":"SavingsExcluded"},"SavingsReportCreated":{"properties":{"report_id":{"type":"string","format":"uuid","title":"Report Id"},"payload":{"$ref":"#/components/schemas/SavingsReportPayload"},"signature":{"type":"string","title":"Signature"},"key_id":{"type":"string","title":"Key Id"}},"type":"object","required":["report_id","payload","signature","key_id"],"title":"SavingsReportCreated"},"SavingsReportGenerateRequest":{"properties":{"window_days":{"type":"integer","maximum":365.0,"minimum":1.0,"title":"Window Days","default":30},"pass_rate_tolerance":{"type":"number","maximum":0.25,"minimum":0.0,"title":"Pass Rate Tolerance","default":0.0},"k":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"K","default":3}},"type":"object","title":"SavingsReportGenerateRequest"},"SavingsReportPayload":{"properties":{"report_version":{"type":"integer","const":1,"title":"Report Version","default":1},"report_id":{"type":"string","format":"uuid","title":"Report Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"root_agent_id":{"type":"string","format":"uuid","title":"Root Agent Id"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"window_days":{"type":"integer","title":"Window Days"},"pass_rate_tolerance":{"type":"number","title":"Pass Rate Tolerance"},"k":{"type":"integer","title":"K"},"projection":{"type":"string","enum":["owner","public"],"title":"Projection"},"pass_k_gate":{"type":"string","enum":["applied","unavailable"],"title":"Pass K Gate"},"basis":{"type":"string","title":"Basis"},"baseline":{"$ref":"#/components/schemas/SavingsBaseline"},"variants":{"items":{"$ref":"#/components/schemas/SavingsVariant"},"type":"array","title":"Variants"},"cheapest_passing":{"anyOf":[{"$ref":"#/components/schemas/SavingsCheapest"},{"type":"null"}]},"observed_monthly_runs":{"type":"number","title":"Observed Monthly Runs"},"projected_monthly_saving_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Projected Monthly Saving Usd"},"excluded":{"$ref":"#/components/schemas/SavingsExcluded"}},"type":"object","required":["report_id","agent_id","root_agent_id","generated_at","window_days","pass_rate_tolerance","k","projection","pass_k_gate","basis","baseline","variants","observed_monthly_runs","excluded"],"title":"SavingsReportPayload","description":"The signed document. Everything here is covered by the signature."},"SavingsVariant":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"run_count":{"type":"integer","title":"Run Count"},"pass_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pass Rate"},"pass_k":{"anyOf":[{"additionalProperties":{"type":"number"},"type":"object"},{"type":"null"}],"title":"Pass K"},"latency_p50_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency P50 Ms"},"latency_p95_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency P95 Ms"},"measured_cost_per_run_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Measured Cost Per Run Usd"},"measured_run_count":{"type":"integer","title":"Measured Run Count","default":0},"claimed_cost_per_run_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Claimed Cost Per Run Usd"},"cost_basis":{"type":"string","title":"Cost Basis","default":"unavailable"},"ineligible_run_count":{"type":"integer","title":"Ineligible Run Count","default":0},"simulated_run_count":{"type":"integer","title":"Simulated Run Count","default":0}},"type":"object","required":["agent_id","agent_name","run_count"],"title":"SavingsVariant"},"SbomVerifyResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"},"agent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Id"},"signed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed At"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["valid"],"title":"SbomVerifyResponse"},"ScheduleCreate":{"properties":{"run_request":{"$ref":"#/components/schemas/ScheduleRunRequest","default":{}},"cadence":{"type":"string","enum":["daily","weekly","on_blueprint_change"],"title":"Cadence"},"hour_utc":{"type":"integer","maximum":23.0,"minimum":0.0,"title":"Hour Utc","default":0},"weekday":{"anyOf":[{"type":"integer","maximum":6.0,"minimum":0.0},{"type":"null"}],"title":"Weekday","description":"0=Monday; weekly only"},"window_minutes":{"type":"integer","maximum":1440.0,"minimum":15.0,"title":"Window Minutes","default":120},"run_count_k":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Run Count K","default":1},"budget_cap_usd_per_run":{"anyOf":[{"type":"number","maximum":100000.0,"exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Budget Cap Usd Per Run"},"budget_cap_usd_per_month":{"anyOf":[{"type":"number","maximum":1000000.0,"exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Budget Cap Usd Per Month"}},"additionalProperties":false,"type":"object","required":["cadence"],"title":"ScheduleCreate"},"ScheduleHistoryItem":{"properties":{"session_id":{"type":"string","format":"uuid","title":"Session Id"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"status":{"type":"string","title":"Status"},"run_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Run Ids"},"run_count":{"type":"integer","title":"Run Count"},"passed_count":{"type":"integer","title":"Passed Count"},"failed_count":{"type":"integer","title":"Failed Count"},"cost_usd":{"type":"number","title":"Cost Usd"}},"type":"object","required":["session_id","started_at","status","run_ids","run_count","passed_count","failed_count","cost_usd"],"title":"ScheduleHistoryItem"},"ScheduleRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"team_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Team Id"},"run_request":{"additionalProperties":true,"type":"object","title":"Run Request"},"cadence":{"type":"string","enum":["daily","weekly","on_blueprint_change"],"title":"Cadence"},"hour_utc":{"type":"integer","title":"Hour Utc"},"weekday":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Weekday"},"window_minutes":{"type":"integer","title":"Window Minutes"},"run_count_k":{"type":"integer","title":"Run Count K"},"budget_cap_usd_per_run":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Budget Cap Usd Per Run"},"budget_cap_usd_per_month":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Budget Cap Usd Per Month"},"spent_usd_month":{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$","title":"Spent Usd Month"},"consecutive_failures":{"type":"integer","title":"Consecutive Failures"},"paused_reason":{"anyOf":[{"type":"string","enum":["budget","endpoint_failures","owner","access_lost","plan","config"]},{"type":"null"}],"title":"Paused Reason"},"is_active":{"type":"boolean","title":"Is Active"},"next_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Run At"},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"},"last_screening_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Last Screening Session Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","agent_id","team_id","run_request","cadence","hour_utc","weekday","window_minutes","run_count_k","budget_cap_usd_per_run","budget_cap_usd_per_month","spent_usd_month","consecutive_failures","paused_reason","is_active","next_run_at","last_run_at","last_screening_session_id","created_at"],"title":"ScheduleRead"},"ScheduleRunRequest":{"properties":{"suite_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Suite Id"},"task_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":200},{"type":"null"}],"title":"Task Ids"}},"additionalProperties":false,"type":"object","title":"ScheduleRunRequest","description":"What each occurrence screens. ``agent_id`` is never accepted here."},"ScheduleUpdate":{"properties":{"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"cadence":{"anyOf":[{"type":"string","enum":["daily","weekly","on_blueprint_change"]},{"type":"null"}],"title":"Cadence"},"hour_utc":{"anyOf":[{"type":"integer","maximum":23.0,"minimum":0.0},{"type":"null"}],"title":"Hour Utc"},"weekday":{"anyOf":[{"type":"integer","maximum":6.0,"minimum":0.0},{"type":"null"}],"title":"Weekday"},"window_minutes":{"anyOf":[{"type":"integer","maximum":1440.0,"minimum":15.0},{"type":"null"}],"title":"Window Minutes"},"run_count_k":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Run Count K"},"budget_cap_usd_per_run":{"anyOf":[{"type":"number","maximum":100000.0,"exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Budget Cap Usd Per Run"},"budget_cap_usd_per_month":{"anyOf":[{"type":"number","maximum":1000000.0,"exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Budget Cap Usd Per Month"},"run_request":{"anyOf":[{"$ref":"#/components/schemas/ScheduleRunRequest"},{"type":"null"}]}},"additionalProperties":false,"type":"object","title":"ScheduleUpdate","description":"PATCH: only the fields present are changed."},"ScreeningPreflightRead":{"properties":{"timeout_seconds":{"type":"integer","title":"Timeout Seconds"},"max_attempts":{"type":"integer","title":"Max Attempts"},"retry_backoff_seconds":{"type":"integer","title":"Retry Backoff Seconds"},"maximum_task_duration_seconds":{"type":"integer","title":"Maximum Task Duration Seconds"},"tasks_execute_sequentially":{"type":"boolean","title":"Tasks Execute Sequentially"}},"type":"object","required":["timeout_seconds","max_attempts","retry_backoff_seconds","maximum_task_duration_seconds","tasks_execute_sequentially"],"title":"ScreeningPreflightRead"},"ScreeningSessionDetailRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"selection_mode":{"type":"string","enum":["suite","custom","catalogue"],"title":"Selection Mode"},"suite_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Suite Id"},"label":{"type":"string","title":"Label"},"trigger":{"type":"string","enum":["user","api_key","schedule","system"],"title":"Trigger"},"trigger_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trigger Label"},"repeats":{"type":"integer","title":"Repeats"},"task_count":{"type":"integer","title":"Task Count"},"run_count":{"type":"integer","title":"Run Count"},"status":{"type":"string","enum":["pending","running","completed","partial_failed","failed"],"title":"Status"},"passed_count":{"type":"integer","title":"Passed Count"},"failed_count":{"type":"integer","title":"Failed Count"},"total_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Usd"},"latency_p50_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency P50 Ms"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"task_plan":{"items":{"$ref":"#/components/schemas/ScreeningTaskPlanRead"},"type":"array","title":"Task Plan"},"runs":{"items":{"$ref":"#/components/schemas/ScreeningSessionRunRead"},"type":"array","title":"Runs"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms","readOnly":true}},"type":"object","required":["id","agent_id","selection_mode","suite_id","label","trigger","trigger_label","repeats","task_count","run_count","status","passed_count","failed_count","created_at","started_at","completed_at","task_plan","duration_ms"],"title":"ScreeningSessionDetailRead"},"ScreeningSessionRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"selection_mode":{"type":"string","enum":["suite","custom","catalogue"],"title":"Selection Mode"},"suite_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Suite Id"},"label":{"type":"string","title":"Label"},"trigger":{"type":"string","enum":["user","api_key","schedule","system"],"title":"Trigger"},"trigger_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trigger Label"},"repeats":{"type":"integer","title":"Repeats"},"task_count":{"type":"integer","title":"Task Count"},"run_count":{"type":"integer","title":"Run Count"},"status":{"type":"string","enum":["pending","running","completed","partial_failed","failed"],"title":"Status"},"passed_count":{"type":"integer","title":"Passed Count"},"failed_count":{"type":"integer","title":"Failed Count"},"total_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Usd"},"latency_p50_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency P50 Ms"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"task_plan":{"items":{"$ref":"#/components/schemas/ScreeningTaskPlanRead"},"type":"array","title":"Task Plan"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms","readOnly":true}},"type":"object","required":["id","agent_id","selection_mode","suite_id","label","trigger","trigger_label","repeats","task_count","run_count","status","passed_count","failed_count","created_at","started_at","completed_at","task_plan","duration_ms"],"title":"ScreeningSessionRead"},"ScreeningSessionRunRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Display Name"},"agent_identity_state":{"anyOf":[{"type":"string","enum":["active","deactivated","unavailable"]},{"type":"null"}],"title":"Agent Identity State"},"task_id":{"type":"string","format":"uuid","title":"Task Id"},"status":{"$ref":"#/components/schemas/RunStatus"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"success":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Success"},"output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Output"},"output_withheld":{"type":"boolean","title":"Output Withheld","default":false},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"total_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Usd"},"evidence_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Evidence Cost Usd"},"evidence_cost_source":{"type":"string","title":"Evidence Cost Source","default":"unavailable"},"evidence_cost_partial":{"type":"boolean","title":"Evidence Cost Partial","default":false},"evidence_priced_call_count":{"type":"integer","title":"Evidence Priced Call Count","default":0},"evidence_unpriced_call_count":{"type":"integer","title":"Evidence Unpriced Call Count","default":0},"evidence_total_call_count":{"type":"integer","title":"Evidence Total Call Count","default":0},"retry_count":{"type":"integer","title":"Retry Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"answer_exposed":{"type":"boolean","title":"Answer Exposed","default":false},"provider_cost_authority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Cost Authority"},"screening_session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Screening Session Id"},"repeat_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Repeat Index"},"repeat_total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Repeat Total"},"architecture_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Architecture Hash"},"previous_architecture_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Architecture Hash"},"architecture_changed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Architecture Changed"},"architecture_comparable":{"type":"boolean","title":"Architecture Comparable","default":false},"architecture_change_summary":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Architecture Change Summary"},"architecture_span_count":{"type":"integer","title":"Architecture Span Count","default":0},"certification_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Certification Id"},"certification_sequence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Certification Sequence"},"requested_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested Model"},"returned_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Returned Model"},"llm_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Provider"},"usage_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Usage Source"},"model_pricing_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Model Pricing Id"},"pricing_input_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pricing Input Cost Per Million"},"pricing_output_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pricing Output Cost Per Million"},"pricing_effective_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Pricing Effective Date"},"error_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Class"},"response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Status"},"error_body_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Body Excerpt"},"execution_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Execution Mode"},"verification_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Hash"},"signed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Signed At"},"key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"},"public_certificate_state":{"type":"string","enum":["verified","simulated","unsigned","invalid"],"title":"Public Certificate State","default":"unsigned"},"suite_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suite Id"},"suite_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Suite Version"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"cost_provenance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost Provenance"},"cost_basis":{"anyOf":[{"type":"string","enum":["metered","traced","traced_partial","self_reported","unavailable"]},{"type":"null"}],"title":"Cost Basis"},"scored_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Scored Cost Usd"},"provenance_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provenance Level"},"manifest_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manifest Hash"},"task_title":{"type":"string","title":"Task Title"},"phases":{"items":{"$ref":"#/components/schemas/RunPhaseEventRead"},"type":"array","title":"Phases"},"provenance_flags":{"items":{"type":"string"},"type":"array","title":"Provenance Flags","readOnly":true}},"type":"object","required":["id","agent_id","task_id","status","started_at","completed_at","latency_ms","success","output","error_message","input_tokens","output_tokens","total_cost_usd","retry_count","created_at","task_title","provenance_flags"],"title":"ScreeningSessionRunRead"},"ScreeningTaskPlanRead":{"properties":{"task_id":{"type":"string","format":"uuid","title":"Task Id"},"title":{"type":"string","title":"Title"},"domain":{"type":"string","title":"Domain"},"difficulty":{"type":"string","title":"Difficulty"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt"},"prompt_available":{"type":"boolean","title":"Prompt Available"},"evaluator_id":{"type":"string","title":"Evaluator Id"},"expected_output_shape":{"type":"string","enum":["reference_text","non_empty_text"],"title":"Expected Output Shape"},"timeout_seconds":{"type":"integer","minimum":1.0,"title":"Timeout Seconds"}},"type":"object","required":["task_id","title","domain","difficulty","prompt_available","evaluator_id","expected_output_shape","timeout_seconds"],"title":"ScreeningTaskPlanRead"},"SecretSuiteDiagnostic":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"suites":{"items":{"$ref":"#/components/schemas/SecretSuiteSummary"},"type":"array","title":"Suites"}},"type":"object","required":["enabled","suites"],"title":"SecretSuiteDiagnostic","description":"Operator diagnostic — parsed flag state + per-suite counts.\n\nPairs with the diagnostic-endpoints memo: an env/flag-driven feature must\nship an HTTP surface that exposes its parsed state so a multi-hop CD\nenv-render failure is diagnosable without SSH."},"SecretSuiteRotateRequest":{"properties":{"suite_id":{"type":"string","maxLength":64,"minLength":1,"title":"Suite Id"}},"type":"object","required":["suite_id"],"title":"SecretSuiteRotateRequest"},"SecretSuiteRotateResult":{"properties":{"suite_id":{"type":"string","title":"Suite Id"},"previous_version":{"type":"integer","title":"Previous Version"},"new_version":{"type":"integer","title":"New Version"},"tasks_rotated":{"type":"integer","title":"Tasks Rotated"}},"type":"object","required":["suite_id","previous_version","new_version","tasks_rotated"],"title":"SecretSuiteRotateResult"},"SecretSuiteSummary":{"properties":{"suite_id":{"type":"string","title":"Suite Id"},"version":{"type":"integer","title":"Version"},"task_count":{"type":"integer","title":"Task Count"},"active_task_count":{"type":"integer","title":"Active Task Count"}},"type":"object","required":["suite_id","version","task_count","active_task_count"],"title":"SecretSuiteSummary","description":"Counts-only view of one secret suite. NEVER carries an answer key."},"SetupStep":{"properties":{"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"code_snippet":{"type":"string","title":"Code Snippet"},"language":{"type":"string","title":"Language","default":"python"}},"type":"object","required":["title","description","code_snippet"],"title":"SetupStep","description":"A single step in the setup guide."},"SitemapDataResponse":{"properties":{"public_agents":{"items":{"$ref":"#/components/schemas/PublicAgentSEO"},"type":"array","title":"Public Agents"},"domains":{"items":{"type":"string"},"type":"array","title":"Domains"},"talent_pool_segments":{"items":{"$ref":"#/components/schemas/TalentPoolSegmentSEO"},"type":"array","title":"Talent Pool Segments"},"compare_pairs":{"items":{"$ref":"#/components/schemas/ComparePairSEO"},"type":"array","title":"Compare Pairs"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"feature_enabled":{"type":"boolean","title":"Feature Enabled","description":"False when SEO_TALENT_POOL_ENABLED is off — Next.js renders stub."},"axis_segments":{"items":{"$ref":"#/components/schemas/AxisSegmentSEO"},"type":"array","title":"Axis Segments"},"indexable_agents":{"items":{"$ref":"#/components/schemas/IndexableAgentSEO"},"type":"array","title":"Indexable Agents"}},"type":"object","required":["public_agents","domains","talent_pool_segments","compare_pairs","generated_at","feature_enabled"],"title":"SitemapDataResponse","description":"Full response payload of ``GET /seo/sitemap-data`` (FR-06).\n\nCached 1h by the gateway; the underlying generator is cheap on small\ncatalogues but fans out at the compare-pair level."},"SsoCertificateRead":{"properties":{"fingerprint_sha256":{"type":"string","title":"Fingerprint Sha256"},"subject":{"type":"string","title":"Subject"},"not_after":{"type":"string","format":"date-time","title":"Not After"}},"type":"object","required":["fingerprint_sha256","subject","not_after"],"title":"SsoCertificateRead"},"SsoConfigRead":{"properties":{"team_id":{"type":"string","format":"uuid","title":"Team Id"},"configured":{"type":"boolean","title":"Configured"},"provider":{"anyOf":[{"type":"string","enum":["saml","google"]},{"type":"null"}],"title":"Provider"},"saml":{"anyOf":[{"$ref":"#/components/schemas/SamlConfigRead"},{"type":"null"}]},"google":{"anyOf":[{"$ref":"#/components/schemas/GoogleConfigRead"},{"type":"null"}]},"sso_only":{"type":"boolean","title":"Sso Only","default":false},"default_role":{"type":"string","enum":["member","viewer"],"title":"Default Role","default":"member"},"domains":{"items":{"$ref":"#/components/schemas/SsoDomainRead"},"type":"array","title":"Domains"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"members_without_password":{"type":"integer","title":"Members Without Password","default":0},"service_provider":{"$ref":"#/components/schemas/SsoServiceProviderRead"},"plan_allows_sso":{"type":"boolean","title":"Plan Allows Sso"}},"type":"object","required":["team_id","configured","service_provider","plan_allows_sso"],"title":"SsoConfigRead"},"SsoConfigUpdate":{"properties":{"provider":{"type":"string","enum":["saml","google"],"title":"Provider"},"saml":{"anyOf":[{"$ref":"#/components/schemas/SamlConfigIn"},{"type":"null"}]},"google":{"anyOf":[{"$ref":"#/components/schemas/GoogleConfigIn"},{"type":"null"}]},"domains":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":10,"minItems":1},{"type":"null"}],"title":"Domains"},"sso_only":{"type":"boolean","title":"Sso Only","default":false},"default_role":{"type":"string","enum":["member","viewer"],"title":"Default Role","default":"member"}},"additionalProperties":false,"type":"object","required":["provider"],"title":"SsoConfigUpdate","description":"Body of ``PUT /teams/{team_id}/sso``. Replaces the whole configuration."},"SsoDiscoverRead":{"properties":{"team_id":{"type":"string","format":"uuid","title":"Team Id"},"provider":{"type":"string","enum":["saml","google"],"title":"Provider"},"login_url":{"type":"string","title":"Login Url"}},"type":"object","required":["team_id","provider","login_url"],"title":"SsoDiscoverRead"},"SsoDomainRead":{"properties":{"domain":{"type":"string","title":"Domain"},"verified":{"type":"boolean","title":"Verified"},"verification":{"$ref":"#/components/schemas/SsoDomainVerificationRead"}},"type":"object","required":["domain","verified","verification"],"title":"SsoDomainRead"},"SsoDomainVerificationRead":{"properties":{"record_name":{"type":"string","title":"Record Name"},"record_type":{"type":"string","const":"TXT","title":"Record Type","default":"TXT"},"record_value":{"type":"string","title":"Record Value"}},"type":"object","required":["record_name","record_value"],"title":"SsoDomainVerificationRead","description":"The DNS record that proves the domain (security F1)."},"SsoPendingCancel":{"properties":{"csrf":{"type":"string","maxLength":128,"minLength":1,"title":"Csrf"}},"type":"object","required":["csrf"],"title":"SsoPendingCancel"},"SsoPendingConfirm":{"properties":{"csrf":{"type":"string","maxLength":128,"minLength":1,"title":"Csrf"},"password":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Password"}},"type":"object","required":["csrf"],"title":"SsoPendingConfirm"},"SsoPendingRead":{"properties":{"kind":{"type":"string","enum":["link","switch"],"title":"Kind"},"workspace_name":{"type":"string","title":"Workspace Name"},"provider":{"type":"string","enum":["saml","google"],"title":"Provider"},"email":{"type":"string","title":"Email"},"signed_in_as":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed In As"},"github":{"type":"boolean","title":"Github","default":false},"joins_as_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Joins As Role"},"is_owner":{"type":"boolean","title":"Is Owner","default":false},"sso_only_after_confirm":{"type":"boolean","title":"Sso Only After Confirm","default":false},"csrf":{"type":"string","title":"Csrf"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["kind","workspace_name","provider","email","csrf","expires_at"],"title":"SsoPendingRead","description":"What the SPA's /auth/sso-continue page shows for a pending SSO hand-off (#1393).\n\nAnswered only to the browser holding the pending cookie, i.e. the browser\nthat just completed the IdP sign-in for ``email``."},"SsoServiceProviderRead":{"properties":{"entity_id":{"type":"string","title":"Entity Id"},"acs_url":{"type":"string","title":"Acs Url"},"metadata_url":{"type":"string","title":"Metadata Url"},"google_redirect_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Google Redirect Uri"}},"type":"object","required":["entity_id","acs_url","metadata_url","google_redirect_uri"],"title":"SsoServiceProviderRead","description":"What the IdP administrator copies into their IdP."},"SsoStatusRead":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"saml":{"type":"boolean","title":"Saml"},"google":{"type":"boolean","title":"Google"}},"type":"object","required":["enabled","saml","google"],"title":"SsoStatusRead","description":"Always-200 runtime probe so the SPA can gate its SSO UI without a 404."},"SuiteOption":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"runs":{"type":"integer","title":"Runs"}},"type":"object","required":["id","label","runs"],"title":"SuiteOption"},"TalentPoolPageData":{"properties":{"domain_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain Slug"},"difficulty_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Difficulty Slug"},"total_agents":{"type":"integer","title":"Total Agents"},"is_indexable":{"type":"boolean","title":"Is Indexable","description":"False when count < MIN_AGENTS_PER_SEGMENT — render noindex."},"agents":{"items":{"$ref":"#/components/schemas/PublicAgentSEO"},"type":"array","title":"Agents"},"canonical_path":{"type":"string","title":"Canonical Path","description":"Self-referential canonical URL for <link rel=canonical>."}},"type":"object","required":["total_agents","is_indexable","agents","canonical_path"],"title":"TalentPoolPageData","description":"Server-side payload for /talent-pool[/<domain>[/<difficulty>]] pages."},"TalentPoolSegmentSEO":{"properties":{"domain_slug":{"type":"string","title":"Domain Slug"},"difficulty_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Difficulty Slug"},"agent_count":{"type":"integer","title":"Agent Count"},"last_updated":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Updated"}},"type":"object","required":["domain_slug","agent_count"],"title":"TalentPoolSegmentSEO"},"TaskAdminRead":{"properties":{"title":{"type":"string","maxLength":255,"minLength":1,"title":"Title"},"description":{"type":"string","minLength":1,"title":"Description"},"domain":{"$ref":"#/components/schemas/TaskDomain","default":"code_generation"},"difficulty":{"$ref":"#/components/schemas/TaskDifficulty","default":"medium"},"prompt":{"type":"string","minLength":1,"title":"Prompt"},"max_tokens_hint":{"type":"integer","maximum":32768.0,"minimum":64.0,"title":"Max Tokens Hint","default":2048},"id":{"type":"string","format":"uuid","title":"Id"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_secret":{"type":"boolean","title":"Is Secret","default":false},"suite_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suite Id"},"suite_version":{"type":"integer","title":"Suite Version","default":1},"has_expected_output":{"type":"boolean","title":"Has Expected Output","default":false},"expected_output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Output"}},"type":"object","required":["title","description","prompt","id","is_active","created_at"],"title":"TaskAdminRead","description":"Operator echo of a task just authored (``POST /tasks``, admin only).\n\nThe caller posted the answer; echoing it back lets the authoring UI confirm\nwhat was stored. A secret task's answer is still withheld (AC-C1-1): once a\ntask is marked secret the key never leaves the server, on any surface,\nregardless of ``SECRET_SUITES_ENABLED``."},"TaskCreate":{"properties":{"title":{"type":"string","maxLength":255,"minLength":1,"title":"Title"},"description":{"type":"string","minLength":1,"title":"Description"},"domain":{"$ref":"#/components/schemas/TaskDomain","default":"code_generation"},"difficulty":{"$ref":"#/components/schemas/TaskDifficulty","default":"medium"},"prompt":{"type":"string","minLength":1,"title":"Prompt"},"max_tokens_hint":{"type":"integer","maximum":32768.0,"minimum":64.0,"title":"Max Tokens Hint","default":2048},"expected_output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Output"},"is_secret":{"type":"boolean","title":"Is Secret","default":false},"suite_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Suite Id"},"suite_version":{"type":"integer","minimum":1.0,"title":"Suite Version","default":1}},"type":"object","required":["title","description","prompt"],"title":"TaskCreate"},"TaskDifficulty":{"type":"string","enum":["easy","medium","hard"],"title":"TaskDifficulty"},"TaskDomain":{"type":"string","enum":["code_generation","data_extraction","tool_use","customer_support","rag","research","writing","reasoning","custom"],"title":"TaskDomain"},"TaskRead":{"properties":{"title":{"type":"string","maxLength":255,"minLength":1,"title":"Title"},"description":{"type":"string","minLength":1,"title":"Description"},"domain":{"$ref":"#/components/schemas/TaskDomain","default":"code_generation"},"difficulty":{"$ref":"#/components/schemas/TaskDifficulty","default":"medium"},"prompt":{"type":"string","minLength":1,"title":"Prompt"},"max_tokens_hint":{"type":"integer","maximum":32768.0,"minimum":64.0,"title":"Max Tokens Hint","default":2048},"id":{"type":"string","format":"uuid","title":"Id"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_secret":{"type":"boolean","title":"Is Secret","default":false},"suite_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suite Id"},"suite_version":{"type":"integer","title":"Suite Version","default":1},"has_expected_output":{"type":"boolean","title":"Has Expected Output","default":false}},"type":"object","required":["title","description","prompt","id","is_active","created_at"],"title":"TaskRead","description":"One catalog task as every caller may see it.\n\n#1263 — this schema deliberately has NO ``expected_output`` field, for any\ntask, secret or not. #1222/#1261 stopped the arena from *sending* the\nanswer key, but every request still carries ``task_id`` and the anonymous\n``GET /tasks`` / ``GET /tasks/{id}`` returned the key for every non-secret\ntask, so an endpoint could look it up mid-run (confirmed on production,\n2026-10-16). Removing the field — rather than nulling it per caller — is\nthe same shape of guarantee ``RunRead`` carries: no present or future read\nsurface that reuses this schema can leak it. The only echo is\n``TaskAdminRead`` on the admin-only create endpoint.\n\n``has_expected_output`` tells the UI whether grading compares against a\nreference text or only requires a non-empty response (the same fact the\nrun trace exposes as ``expected_output_shape``). It never carries the text.\n\nRES-014-C1 — ``is_secret``/``suite_id``/``suite_version`` are surfaced so\ncallers know a task is a holdout (the marker is public; only the ANSWER is\nsecret)."},"TaskRetireResult":{"properties":{"task_id":{"type":"string","format":"uuid","title":"Task Id"},"title":{"type":"string","title":"Title"},"was_active":{"type":"boolean","title":"Was Active"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["task_id","title","was_active","is_active"],"title":"TaskRetireResult","description":"Result of the one-way admin retire (UX-AUDIT A3). ``was_active`` lets an\noperator distinguish a fresh retire from an idempotent replay."},"TaskStats":{"properties":{"task_id":{"type":"string","format":"uuid","title":"Task Id"},"task_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Title"},"success_rate":{"type":"number","title":"Success Rate"},"total_runs":{"type":"integer","title":"Total Runs"},"successful_runs":{"type":"integer","title":"Successful Runs"}},"type":"object","required":["task_id","task_title","success_rate","total_runs","successful_runs"],"title":"TaskStats"},"TaskSubmissionApprove":{"properties":{},"type":"object","title":"TaskSubmissionApprove","description":"Admin payload for approving a submission. The task is minted from\nthe submission's fields verbatim — no editing here. If the admin wants\nto tweak the task, they reject with a reason and the submitter\nre-submits."},"TaskSubmissionCreate":{"properties":{"title":{"type":"string","maxLength":255,"minLength":4,"title":"Title"},"description":{"type":"string","maxLength":5000,"minLength":10,"title":"Description"},"domain":{"$ref":"#/components/schemas/TaskDomain"},"difficulty":{"$ref":"#/components/schemas/TaskDifficulty","default":"medium"},"prompt":{"type":"string","maxLength":20000,"minLength":10,"title":"Prompt"},"expected_output":{"anyOf":[{"type":"string","maxLength":20000},{"type":"null"}],"title":"Expected Output"},"max_tokens_hint":{"type":"integer","maximum":32000.0,"minimum":128.0,"title":"Max Tokens Hint","default":2048},"submission_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Submission Notes","description":"Optional context for the reviewer — e.g. why this task is useful, where you saw it fail in production."}},"type":"object","required":["title","description","domain","prompt"],"title":"TaskSubmissionCreate","description":"Submitter payload — same shape as TaskCreate plus optional notes."},"TaskSubmissionRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"submitter_user_id":{"type":"string","format":"uuid","title":"Submitter User Id"},"status":{"type":"string","title":"Status"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"domain":{"type":"string","title":"Domain"},"difficulty":{"type":"string","title":"Difficulty"},"prompt":{"type":"string","title":"Prompt"},"expected_output":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Output"},"max_tokens_hint":{"type":"integer","title":"Max Tokens Hint"},"submission_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submission Notes"},"reviewer_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Reviewer User Id"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"rejection_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rejection Reason"},"approved_task_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Approved Task Id"},"is_flagged":{"type":"boolean","title":"Is Flagged"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","submitter_user_id","status","title","description","domain","difficulty","prompt","expected_output","max_tokens_hint","submission_notes","reviewer_user_id","reviewed_at","rejection_reason","approved_task_id","is_flagged","created_at","updated_at"],"title":"TaskSubmissionRead"},"TaskSubmissionReject":{"properties":{"rejection_reason":{"type":"string","maxLength":2000,"minLength":4,"title":"Rejection Reason"}},"type":"object","required":["rejection_reason"],"title":"TaskSubmissionReject","description":"Admin payload for rejecting a submission."},"TeamAnalyticsRead":{"properties":{"team_id":{"type":"string","format":"uuid","title":"Team Id"},"plan":{"type":"string","title":"Plan"},"seats_used":{"type":"integer","title":"Seats Used"},"max_seats":{"type":"integer","title":"Max Seats"},"monthly_run_count":{"type":"integer","title":"Monthly Run Count"},"monthly_run_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Monthly Run Cap"},"total_runs_initiated":{"type":"integer","title":"Total Runs Initiated"},"total_workspace_agents":{"type":"integer","title":"Total Workspace Agents"},"total_scorecards_published":{"type":"integer","title":"Total Scorecards Published"},"provenance":{"$ref":"#/components/schemas/TeamProvenanceSummaryRead"},"runs_window_days":{"type":"integer","title":"Runs Window Days"},"runs_per_day":{"items":{"$ref":"#/components/schemas/TeamRunsPerDayPointRead"},"type":"array","title":"Runs Per Day"},"members":{"items":{"$ref":"#/components/schemas/TeamMemberContributionRead"},"type":"array","title":"Members"},"shared_agents":{"items":{"$ref":"#/components/schemas/TeamSharedAgentRead"},"type":"array","title":"Shared Agents"}},"type":"object","required":["team_id","plan","seats_used","max_seats","monthly_run_count","total_runs_initiated","total_workspace_agents","total_scorecards_published","provenance","runs_window_days"],"title":"TeamAnalyticsRead"},"TeamClaimedInvitationRead":{"properties":{"workspace_name":{"type":"string","title":"Workspace Name"},"role":{"type":"string","title":"Role"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"id":{"type":"string","format":"uuid","title":"Id"},"team_id":{"type":"string","format":"uuid","title":"Team Id"},"refusal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refusal"}},"type":"object","required":["workspace_name","role","expires_at","id","team_id"],"title":"TeamClaimedInvitationRead","description":"The answer to a claim: the pending shape, plus why joining is refused, if it is.\n\n``refusal`` is the machine-readable cause the accept route would answer with\n(today only ``sso_plan_required``, #1420), so the page can say so before the\nJoin click. The claimant presented the token, so they already hold every field\n``/invitations/preview`` returns for it; this adds the cause and no data."},"TeamCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["name"],"title":"TeamCreate"},"TeamInvitationAccept":{"properties":{"token":{"type":"string","maxLength":512,"minLength":32,"title":"Token"}},"type":"object","required":["token"],"title":"TeamInvitationAccept","description":"Raw-token request body — used by preview and claim."},"TeamInvitationCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"display_name":{"type":"string","maxLength":255,"minLength":1,"title":"Display Name"},"role":{"type":"string","pattern":"^(admin|member|viewer)$","title":"Role","default":"member"}},"type":"object","required":["email","display_name"],"title":"TeamInvitationCreate"},"TeamInvitationIssuedRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"team_id":{"type":"string","format":"uuid","title":"Team Id"},"email":{"type":"string","title":"Email"},"display_name":{"type":"string","title":"Display Name"},"role":{"type":"string","title":"Role"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"cancelled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Cancelled At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"delivery_status":{"type":"string","enum":["sent","delivered","bounced","suppressed","unavailable"],"title":"Delivery Status"},"accept_url":{"type":"string","title":"Accept Url"}},"type":"object","required":["id","team_id","email","display_name","role","expires_at","accepted_at","cancelled_at","created_at","delivery_status","accept_url"],"title":"TeamInvitationIssuedRead","description":"One-time secret material returned only when an invite token is issued."},"TeamInvitationPreview":{"properties":{"workspace_name":{"type":"string","title":"Workspace Name"},"role":{"type":"string","title":"Role"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["workspace_name","role","expires_at"],"title":"TeamInvitationPreview"},"TeamInvitationRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"team_id":{"type":"string","format":"uuid","title":"Team Id"},"email":{"type":"string","title":"Email"},"display_name":{"type":"string","title":"Display Name"},"role":{"type":"string","title":"Role"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"cancelled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Cancelled At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"delivery_status":{"type":"string","enum":["sent","delivered","bounced","suppressed","unavailable"],"title":"Delivery Status"}},"type":"object","required":["id","team_id","email","display_name","role","expires_at","accepted_at","cancelled_at","created_at","delivery_status"],"title":"TeamInvitationRead"},"TeamInvitationRedeem":{"properties":{"token":{"anyOf":[{"type":"string","maxLength":512,"minLength":32},{"type":"null"}],"title":"Token"},"invitation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Invitation Id"}},"type":"object","title":"TeamInvitationRedeem","description":"Accept credential: the raw token, or an invitation this user claimed.\n\nExactly one, never both. `invitation_id` is a SELECTOR, not a credential —\nit is authorized solely by `TeamInvitation.claimed_by_user_id ==\ncurrent_user.id`, which only a prior successful raw-token presentation can\nset. Anyone tempted to widen this into an id-only accept has to remove that\nbinding first, and should not."},"TeamMemberContributionRead":{"properties":{"member_id":{"type":"string","format":"uuid","title":"Member Id"},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"display_name":{"type":"string","title":"Display Name"},"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role"},"runs_initiated":{"type":"integer","title":"Runs Initiated"},"real_runs_initiated":{"type":"integer","title":"Real Runs Initiated"},"simulated_runs_initiated":{"type":"integer","title":"Simulated Runs Initiated"},"agents_registered":{"type":"integer","title":"Agents Registered"},"scorecards_published":{"type":"integer","title":"Scorecards Published"}},"type":"object","required":["member_id","display_name","email","role","runs_initiated","real_runs_initiated","simulated_runs_initiated","agents_registered","scorecards_published"],"title":"TeamMemberContributionRead","description":"Per-member contribution over the workspace (grouped receipts)."},"TeamMemberRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"team_id":{"type":"string","format":"uuid","title":"Team Id"},"email":{"type":"string","title":"Email"},"display_name":{"type":"string","title":"Display Name"},"role":{"type":"string","title":"Role"},"invited_at":{"type":"string","format":"date-time","title":"Invited At"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"}},"type":"object","required":["id","team_id","email","display_name","role","invited_at","accepted_at"],"title":"TeamMemberRead"},"TeamMemberRoleUpdate":{"properties":{"role":{"type":"string","pattern":"^(admin|member|viewer)$","title":"Role"}},"type":"object","required":["role"],"title":"TeamMemberRoleUpdate"},"TeamPendingInvitationList":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TeamPendingInvitationRead"},"type":"array","title":"Items"},"blocked_by_sso_plan":{"items":{"$ref":"#/components/schemas/TeamPendingInvitationRead"},"type":"array","title":"Blocked By Sso Plan"}},"type":"object","title":"TeamPendingInvitationList"},"TeamPendingInvitationRead":{"properties":{"workspace_name":{"type":"string","title":"Workspace Name"},"role":{"type":"string","title":"Role"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"id":{"type":"string","format":"uuid","title":"Id"},"team_id":{"type":"string","format":"uuid","title":"Team Id"}},"type":"object","required":["workspace_name","role","expires_at","id","team_id"],"title":"TeamPendingInvitationRead","description":"A claimed, still-joinable invitation, listed back to its claimant.\n\nDeliberately a superset of `TeamInvitationPreview` and nothing more. The\nunauthenticated `/invitations/preview` route already hands `workspace_name`\n+ `role` + `expires_at` to any anonymous holder of the token, so returning\nthem to the authenticated account that presented that same token discloses\nstrictly less than what already ships. `email`, `invited_by_user_id` and\n`delivery_status` are NOT here and must not be added — the invitee has no\nuse for them and they describe other people."},"TeamProvenanceSummaryRead":{"properties":{"real_runs":{"type":"integer","title":"Real Runs"},"simulated_runs":{"type":"integer","title":"Simulated Runs"},"total_runs":{"type":"integer","title":"Total Runs"}},"type":"object","required":["real_runs","simulated_runs","total_runs"],"title":"TeamProvenanceSummaryRead","description":"Workspace-wide real-vs-simulated run counts (§6 provenance honesty).\n\n``real_runs`` = runs whose ``execution_mode`` is a positively-confirmed\nlive execution (``real_llm`` / ``live_endpoint``); everything else — mock\ndice-rolls and legacy NULLs — is simulated (the conservative default,\nmirroring ``verification.normalize_execution_mode``). The UI must label a\nworkspace whose runs are simulated-only with a provenance chip."},"TeamRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"plan":{"type":"string","title":"Plan"},"max_seats":{"type":"integer","title":"Max Seats"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"audit_retention_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Audit Retention Days"}},"type":"object","required":["id","name","description","plan","max_seats","created_at"],"title":"TeamRead"},"TeamRunsPerDayPointRead":{"properties":{"date":{"type":"string","title":"Date"},"real":{"type":"integer","title":"Real"},"simulated":{"type":"integer","title":"Simulated"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["date","real","simulated","total"],"title":"TeamRunsPerDayPointRead","description":"One densified daily bucket in the runs/day series (zero-filled)."},"TeamSharedAgentRead":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"name":{"type":"string","title":"Name"},"ownership_scope":{"type":"string","title":"Ownership Scope"},"run_count":{"type":"integer","title":"Run Count"},"real_run_count":{"type":"integer","title":"Real Run Count"},"simulated_run_count":{"type":"integer","title":"Simulated Run Count"}},"type":"object","required":["agent_id","name","ownership_scope","run_count","real_run_count","simulated_run_count"],"title":"TeamSharedAgentRead","description":"A workspace-owned agent and its workspace run count."},"TeamUpdate":{"properties":{"audit_retention_days":{"anyOf":[{"type":"integer","maximum":3650.0,"minimum":1.0},{"type":"null"}],"title":"Audit Retention Days"}},"type":"object","title":"TeamUpdate","description":"PATCH /teams/{id}. Only the audit-log retention setting today.\n\nExplicit ``null`` means \"keep forever\"; an omitted field is left unchanged\n(the router reads ``model_fields_set``)."},"TeamWithMembers":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"plan":{"type":"string","title":"Plan"},"max_seats":{"type":"integer","title":"Max Seats"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"audit_retention_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Audit Retention Days"},"members":{"items":{"$ref":"#/components/schemas/TeamMemberRead"},"type":"array","title":"Members"},"invitations":{"items":{"$ref":"#/components/schemas/TeamInvitationRead"},"type":"array","title":"Invitations"},"current_role":{"type":"string","title":"Current Role"},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions"},"invitations_blocked_by_sso":{"type":"boolean","title":"Invitations Blocked By Sso","default":false}},"type":"object","required":["id","name","description","plan","max_seats","created_at","current_role"],"title":"TeamWithMembers"},"TelemetryReadinessRead":{"properties":{"status":{"type":"string","enum":["traced","none"],"title":"Status"},"last_received_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Received At"},"blueprint_run_count":{"type":"integer","minimum":0.0,"title":"Blueprint Run Count","default":0}},"type":"object","required":["status","last_received_at"],"title":"TelemetryReadinessRead"},"TestPingRequest":{"properties":{"endpoint":{"type":"string","maxLength":500,"minLength":1,"title":"Endpoint"},"payload_schema":{"type":"string","enum":["badge_native","openai_chat","anthropic_messages"],"title":"Payload Schema","default":"badge_native"},"auth_type":{"type":"string","title":"Auth Type","default":"none"},"auth_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auth Token"},"prompt":{"anyOf":[{"type":"string","maxLength":4096},{"type":"null"}],"title":"Prompt"}},"type":"object","required":["endpoint"],"title":"TestPingRequest","description":"Connect-step canary request — BRIEF-001 §6 IN-2 / AC-04.\n\nDrives the *Test ping* button. The customer hasn't created an Agent row\nyet (this is pre-registration), so we accept the URL + schema as a request\nbody and synthesize one canned task to send. Legacy authentication fields\nremain parseable only so stale clients receive the stable T1 retirement\nresponse instead of a generic 422."},"TestPingResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"result":{"type":"string","enum":["success","non_2xx","bad_response_shape","connection_refused","timeout","ssrf_blocked","response_too_large","endpoint_url_unsupported"],"title":"Result"},"payload_schema":{"type":"string","title":"Payload Schema"},"request_body":{"additionalProperties":true,"type":"object","title":"Request Body"},"response_body_preview":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Body Preview"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","status_code","latency_ms","result","payload_schema","request_body","response_body_preview","message"],"title":"TestPingResponse","description":"Full verbatim ping result — see TestPingRequest docstring.\n\n`result` is the typed outcome class for funnel analytics\n(BRIEF-001 §5 `benchmark_test_ping_clicked.result`). The body\npreview is the customer-facing surface — \"tell me what my endpoint\nactually said\" — capped at 500 chars to bound payload size."},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"user":{"$ref":"#/components/schemas/UserRead"}},"type":"object","required":["access_token","user"],"title":"TokenResponse"},"UploadResult":{"properties":{"benchmark_id":{"type":"string","format":"uuid","title":"Benchmark Id"},"tasks_added":{"type":"integer","title":"Tasks Added"},"new_task_count":{"type":"integer","title":"New Task Count"}},"type":"object","required":["benchmark_id","tasks_added","new_task_count"],"title":"UploadResult","description":"Returned by the bulk-upload endpoint."},"UserCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email","examples":["user@example.com"]},"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Avatar Url"},"password":{"type":"string","maxLength":255,"minLength":8,"title":"Password"}},"type":"object","required":["email","password"],"title":"UserCreate"},"UserRead":{"properties":{"email":{"type":"string","format":"email","title":"Email","examples":["user@example.com"]},"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Avatar Url"},"id":{"type":"string","format":"uuid","title":"Id"},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"auth_provider":{"type":"string","title":"Auth Provider"},"plan":{"type":"string","title":"Plan"},"has_billing_account":{"type":"boolean","title":"Has Billing Account","default":false},"plan_interval":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Interval"},"email_verified":{"type":"boolean","title":"Email Verified","default":true},"trial_ends_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Trial Ends At"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"notify_run_complete":{"type":"boolean","title":"Notify Run Complete"},"notify_score_change":{"type":"boolean","title":"Notify Score Change"},"notify_rank_change":{"type":"boolean","title":"Notify Rank Change"},"notify_weekly_digest":{"type":"boolean","title":"Notify Weekly Digest"},"notify_lifecycle_email":{"type":"boolean","title":"Notify Lifecycle Email","default":true},"notify_regression":{"type":"boolean","title":"Notify Regression","default":true},"pmf_survey_last_shown":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Pmf Survey Last Shown"},"marketplace_payout_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marketplace Payout Email"},"is_admin":{"type":"boolean","title":"Is Admin","default":false},"deletion_requested_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deletion Requested At"},"deletion_due_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deletion Due At"},"arena_run_count":{"type":"integer","title":"Arena Run Count","default":0},"monthly_run_count":{"type":"integer","title":"Monthly Run Count","default":0},"agent_count":{"type":"integer","title":"Agent Count","default":0},"team_count":{"type":"integer","title":"Team Count","default":0}},"type":"object","required":["email","id","auth_provider","plan","is_active","created_at","updated_at","notify_run_complete","notify_score_change","notify_rank_change","notify_weekly_digest"],"title":"UserRead"},"UserUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Avatar Url"},"notify_run_complete":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify Run Complete"},"notify_score_change":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify Score Change"},"notify_rank_change":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify Rank Change"},"notify_weekly_digest":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify Weekly Digest"},"notify_lifecycle_email":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify Lifecycle Email"},"notify_regression":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notify Regression"}},"type":"object","title":"UserUpdate"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VariantStatsRead":{"properties":{"label":{"type":"string","title":"Label"},"price_cents":{"type":"integer","title":"Price Cents"},"traffic_pct":{"type":"integer","title":"Traffic Pct"},"views":{"type":"integer","title":"Views"},"purchases":{"type":"integer","title":"Purchases"},"revenue_cents":{"type":"integer","title":"Revenue Cents"},"conversion_pct":{"type":"number","title":"Conversion Pct"},"lift_vs_control_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lift Vs Control Pct"},"p_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P Value"},"badge":{"type":"string","title":"Badge"}},"type":"object","required":["label","price_cents","traffic_pct","views","purchases","revenue_cents","conversion_pct","lift_vs_control_pct","p_value","badge"],"title":"VariantStatsRead","description":"Per-variant aggregate stats returned by the results endpoint."},"VerifyEmailRequest":{"properties":{"token":{"type":"string","maxLength":512,"minLength":1,"title":"Token"}},"type":"object","required":["token"],"title":"VerifyEmailRequest","description":"Body for POST /auth/verify-email. The token rides the emailed link."},"VerifyResponse":{"properties":{"run_id":{"type":"string","format":"uuid","title":"Run Id"},"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"state":{"type":"string","title":"State"},"valid":{"type":"boolean","title":"Valid"},"execution_mode":{"type":"string","title":"Execution Mode"},"is_simulated":{"type":"boolean","title":"Is Simulated"},"verification_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Hash"},"signature":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signature"},"signed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed At"},"key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"},"task_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Title"},"task_difficulty":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Difficulty"},"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name"},"honesty_statement":{"type":"string","title":"Honesty Statement"},"state_statement":{"type":"string","title":"State Statement"},"reliability_pass_k":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"number"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Reliability Pass K"},"reliability_n_runs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reliability N Runs"},"reliability_plain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reliability Plain"},"is_certified":{"type":"boolean","title":"Is Certified","default":false},"certified_suite_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Certified Suite Version"},"current_suite_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Suite Version"},"manifest":{"anyOf":[{"$ref":"#/components/schemas/CertificationManifestProjection"},{"type":"null"}]},"architecture_version_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Architecture Version Id"},"fingerprint_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fingerprint Version"},"architecture_binding_partial":{"type":"boolean","title":"Architecture Binding Partial","default":false},"cost_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost Basis"},"answer_exposed":{"type":"boolean","title":"Answer Exposed","default":false},"approval":{"anyOf":[{"$ref":"#/components/schemas/PublicApproval"},{"type":"null"}]}},"type":"object","required":["run_id","agent_id","state","valid","execution_mode","is_simulated","verification_hash","signature","signed_at","key_id","task_title","task_difficulty","agent_name","honesty_statement","state_statement"],"title":"VerifyResponse"},"WebhookCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"url":{"type":"string","maxLength":500,"minLength":1,"title":"Url"},"secret":{"anyOf":[{"type":"string","maxLength":96,"minLength":32},{"type":"null"}],"title":"Secret"},"events":{"type":"string","maxLength":500,"title":"Events","default":"run.completed,run.failed,agent.score_updated,regression.detected,agent.drift.score,agent.drift.cost,agent.drift.latency,agent.approved,agent.revoked"},"format":{"type":"string","pattern":"^(json|slack|teams|discord)$","title":"Format","default":"json"}},"type":"object","required":["name","url"],"title":"WebhookCreate"},"WebhookDeliveryRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"webhook_id":{"type":"string","format":"uuid","title":"Webhook Id"},"event_type":{"type":"string","title":"Event Type"},"delivery_id":{"type":"string","title":"Delivery Id"},"request_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Body"},"response_status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Status Code"},"response_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Body"},"response_time_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Time Ms"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"response_preview_omitted":{"type":"boolean","title":"Response Preview Omitted"},"attempt_number":{"type":"integer","title":"Attempt Number"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","webhook_id","event_type","delivery_id","request_body","response_status_code","response_body","response_time_ms","error_message","response_preview_omitted","attempt_number","created_at"],"title":"WebhookDeliveryRead","description":"A single row in the per-webhook delivery log."},"WebhookListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/WebhookRead"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"pages":{"type":"integer","title":"Pages"},"active_count":{"type":"integer","title":"Active Count"},"max_active":{"type":"integer","title":"Max Active","default":5}},"type":"object","required":["items","total","page","page_size","pages","active_count"],"title":"WebhookListResponse"},"WebhookRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"url":{"type":"string","title":"Url"},"events":{"type":"string","title":"Events"},"format":{"type":"string","title":"Format"},"has_secret":{"type":"boolean","title":"Has Secret"},"is_active":{"type":"boolean","title":"Is Active"},"total_deliveries":{"type":"integer","title":"Total Deliveries"},"failed_deliveries":{"type":"integer","title":"Failed Deliveries"},"last_delivery_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Delivery At"},"last_status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Status Code"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","url","events","format","has_secret","is_active","total_deliveries","failed_deliveries","last_delivery_at","last_status_code","created_at"],"title":"WebhookRead"},"WebhookTestResult":{"properties":{"success":{"type":"boolean","title":"Success"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"},"response_time_ms":{"type":"integer","title":"Response Time Ms"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"response_preview_omitted":{"type":"boolean","title":"Response Preview Omitted","default":false}},"type":"object","required":["success","status_code","response_time_ms"],"title":"WebhookTestResult"},"WebhookUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"url":{"anyOf":[{"type":"string","maxLength":500,"minLength":1},{"type":"null"}],"title":"Url"},"secret":{"anyOf":[{"type":"string","maxLength":96,"minLength":32},{"type":"null"}],"title":"Secret"},"events":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Events"},"format":{"anyOf":[{"type":"string","pattern":"^(json|slack|teams|discord)$"},{"type":"null"}],"title":"Format"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"WebhookUpdate"},"WorkspaceSavingsAgent":{"properties":{"agent_id":{"type":"string","format":"uuid","title":"Agent Id"},"agent_name":{"type":"string","title":"Agent Name"},"projected_monthly_saving_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Projected Monthly Saving Usd"}},"type":"object","required":["agent_id","agent_name"],"title":"WorkspaceSavingsAgent"},"WorkspaceSavingsReport":{"properties":{"team_id":{"type":"string","format":"uuid","title":"Team Id"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"window_days":{"type":"integer","title":"Window Days"},"agents":{"items":{"$ref":"#/components/schemas/WorkspaceSavingsAgent"},"type":"array","title":"Agents"},"projected_monthly_saving_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Projected Monthly Saving Usd"},"agents_without_figure":{"type":"integer","title":"Agents Without Figure"}},"type":"object","required":["team_id","generated_at","window_days","agents","agents_without_figure"],"title":"WorkspaceSavingsReport"},"_WeightsTuple":{"properties":{"correctness":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Correctness"},"latency":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Latency"},"cost":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Cost"},"tool":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Tool"},"robustness":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Robustness"}},"type":"object","required":["correctness","latency","cost","tool","robustness"],"title":"_WeightsTuple","description":"Five integer weights summing to 99..101 (slack for slider rounding)."}}}}