{"components":{"schemas":{"AcceptInvitationRequest":{"additionalProperties":false,"properties":{"token":{"type":"string"}},"required":["token"],"type":"object"},"ApiError":{"description":"The universal failure envelope. Every non-2xx response from every route has this shape. Branch on `error.code` — a stable, machine-readable string — never on `error.message`, which is human-facing and may change.","properties":{"error":{"properties":{"code":{"description":"Stable machine-readable code, e.g. `auth.missing_scope`, `request.invalid`, `upstream.rate_limited`.","type":"string"},"details":{"description":"Optional structured context — the offending parameter, the unsupported fields, the upstream's own error code."},"message":{"description":"Human-facing explanation.","type":"string"},"request_id":{"description":"UUIDv7 for this request; quote it in support requests.","type":"string"},"trace_id":{"description":"W3C trace id, for correlating across services.","type":"string"}},"required":["code","message"],"type":"object"}},"required":["error"],"title":"ApiError","type":"object"},"AuditEntryId":{"description":"One row in api.audit_log.","format":"uuid","type":"string"},"AuditEntryPublic":{"properties":{"action":{"type":"string"},"actor_id":{"format":"uuid","type":["string","null"]},"actor_kind":{"type":"string"},"id":{"$ref":"#/components/schemas/AuditEntryId"},"ip":{"type":["string","null"]},"method":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"path":{"type":"string"},"request_id":{"type":"string"},"resource_id":{"type":["string","null"]},"resource_type":{"type":["string","null"]},"status_code":{"format":"int32","type":"integer"},"tenant_id":{"anyOf":[{"$ref":"#/components/schemas/TenantId"},{"type":"null"}]},"trace_id":{"type":["string","null"]},"user_agent":{"type":["string","null"]}},"required":["id","occurred_at","actor_kind","action","request_id","method","path","status_code"],"type":"object"},"AuthSession":{"description":"Successful login / refresh response. Carries both an access JWT\n(short-lived; ~15min) and a refresh token (long-lived; ~30 days).\n\nOn the dashboard surface the same values are set as HttpOnly cookies;\nthe body form is here for SDK callers and for the test harness.","properties":{"access_expires_at":{"format":"date-time","type":"string"},"access_token":{"type":"string"},"refresh_expires_at":{"format":"date-time","type":"string"},"refresh_token":{"type":"string"},"user":{"$ref":"#/components/schemas/UserPublic"}},"required":["access_token","access_expires_at","refresh_token","refresh_expires_at","user"],"type":"object"},"BootstrapTenantRequest":{"additionalProperties":false,"properties":{"name":{"description":"Display name for the tenant — your company, or whatever you call the\nbilling boundary. The slug is derived from it unless you supply one.","type":"string"},"organization_name":{"default":null,"description":"First organization's name. Defaults to the tenant name — the common\ncase is one company, one organization, and asking twice for the same\nanswer is a worse first experience than assuming it.","type":["string","null"]},"project_environment":{"anyOf":[{"$ref":"#/components/schemas/ProjectEnvironment"},{"type":"null"}],"default":null,"description":"First project's environment. Defaults to production: a first project is\noverwhelmingly where real traffic goes, and a caller who wanted staging\nwill say so."},"project_name":{"default":null,"description":"First project's name. Defaults to `default`.","type":["string","null"]},"slug":{"anyOf":[{"$ref":"#/components/schemas/Slug"},{"type":"null"}],"default":null,"description":"Optional explicit slug. Supply it when the derived one would be ugly,\nor when the name has no derivable slug at all (all punctuation, all\nemoji). Collisions are resolved automatically with a random suffix."}},"required":["name"],"type":"object"},"BootstrapTenantResponse":{"properties":{"organization":{"$ref":"#/components/schemas/OrganizationPublic"},"project":{"$ref":"#/components/schemas/ProjectPublic"},"tenant":{"$ref":"#/components/schemas/TenantPublic"}},"required":["tenant","organization","project"],"type":"object"},"BudgetWindow":{"description":"The window a spend cap applies over.\n\nThe serde spelling is the stored spelling, which [`Self::as_str`] and\n[`Self::parse`] also use, so the wire, the column and the enum cannot\ndrift; a test pins the three together.","enum":["daily","monthly","lifetime"],"type":"string"},"CatalogModel":{"properties":{"active":{"type":"boolean"},"bound":{"description":"Whether the caller can call this model right now: a global active\nbinding, or a binding in the caller's own tenant. Unlike `active`\n(any tenant's binding counts) and `deployability.status == callable`\n(same), this is answered for the caller who asked.","type":"boolean"},"capabilities":{"items":{"type":"string"},"type":"array"},"context_window":{"format":"int32","type":["integer","null"]},"created_at":{"format":"date-time","type":"string"},"deployability":{"$ref":"#/components/schemas/Deployability","description":"How (and whether) this model can be served — see [`Deployability`]."},"display_name":{"type":"string"},"family":{"type":"string"},"hf_repo":{"type":["string","null"]},"id":{"type":"string"},"kind":{"description":"The binding kind — which inference surface serves it (`openai_chat`,\n`openai_embed`, `openai_transcription`, `openai_image`, …); `null`\nwhen `bound` is false.","type":["string","null"]},"license":{"type":["string","null"]},"max_output_tokens":{"description":"The most tokens one reply may carry, as the provider states it.\n`None` ⇒ unpublished; a consumer must not guess it.","format":"int32","type":["integer","null"]},"modality":{"type":"string"},"params_total_b":{"format":"double","type":["number","null"]},"pricing":{"$ref":"#/components/schemas/Pricing"},"provider":{"description":"The upstream provider the caller's resolving binding routes to;\n`null` when `bound` is false.","type":["string","null"]},"updated_at":{"format":"date-time","type":"string"},"upstream_model":{"description":"The model id on that provider's wire; `null` when `bound` is false.","type":["string","null"]},"wire_capabilities":{"anyOf":[{"$ref":"#/components/schemas/WireCapabilities"},{"type":"null"}],"description":"The parameter support the router enforces for the caller's resolving\nbinding — the same booleans `GET /v1/models/{id}/capabilities`\nanswers, computed the same way (wire family, narrowed by the provider\nrow, the model's own profile and the binding kind). `null` when\n`bound` is false: there is no binding to answer for. Distinct from\n`capabilities`, which is the curated tag list a discovered model\ncarries before any binding exists."}},"required":["id","family","display_name","modality","capabilities","pricing","active","created_at","updated_at","deployability","bound"],"type":"object"},"ChangePasswordRequest":{"additionalProperties":false,"description":"`POST /v1/me/password` body — change password while authenticated.","properties":{"current_password":{"$ref":"#/components/schemas/PlaintextPassword"},"new_password":{"$ref":"#/components/schemas/PlaintextPassword"}},"required":["current_password","new_password"],"type":"object"},"ChangePlanRequest":{"additionalProperties":false,"properties":{"plan_id":{"type":"string"}},"required":["plan_id"],"type":"object"},"Channel":{"enum":["slack","email","apns","web_push","customer_webhook"],"type":"string"},"CheckStatus":{"enum":["ok","degraded","error"],"type":"string"},"CheckoutRequest":{"additionalProperties":false,"properties":{"cancel_url":{"type":"string"},"plan_id":{"type":"string"},"success_url":{"type":"string"}},"required":["plan_id","success_url","cancel_url"],"type":"object"},"CheckoutResponse":{"properties":{"session_url":{"type":"string"}},"required":["session_url"],"type":"object"},"CostEntryPublic":{"properties":{"cached_tokens":{"format":"int64","type":["integer","null"]},"completion_tokens":{"format":"int64","type":["integer","null"]},"cost_cents":{"description":"Whole cents, rounded once at the edge. Kept because it shipped;\na typical inference call is well under one cent and reads `0`\nhere, so reconcile on `cost_micro_cents`.","format":"int64","type":"integer"},"cost_micro_cents":{"description":"The exact figure — the same integer the `X-Nozzle-Cost-Micro-Cents`\nresponse header carried for `request_id`.","format":"int64","type":"integer"},"currency":{"type":"string"},"id":{"format":"uuid","type":"string"},"kind":{"type":"string"},"occurred_at":{"format":"date-time","type":"string"},"project_id":{"anyOf":[{"$ref":"#/components/schemas/ProjectId"},{"type":"null"}]},"prompt_tokens":{"format":"int64","type":["integer","null"]},"ref_id":{"type":["string","null"]},"ref_type":{"type":["string","null"]},"request_id":{"description":"The `X-Request-Id` of the call that produced this row; `null` on\nrows that are not one call (a GPU-hour tick).","type":["string","null"]},"tenant_id":{"$ref":"#/components/schemas/TenantId"}},"required":["id","tenant_id","cost_cents","cost_micro_cents","currency","kind","occurred_at"],"type":"object"},"CreateCredentialRequest":{"additionalProperties":false,"description":"NO Debug derive — the struct carries a plaintext key; a derived Debug is\nexactly the accidental-log leak this module's discipline forbids.","properties":{"api_key":{"description":"The customer's plaintext provider key. Sealed immediately; never\nstored, logged, or echoed.","type":"string"},"base_url_override":{"default":null,"type":["string","null"]},"provider":{"description":"`models.upstream_providers.name` — a typo fails the FK at INSERT.","type":"string"}},"required":["provider","api_key"],"type":"object"},"CreateInvitationRequest":{"additionalProperties":false,"properties":{"email":{"$ref":"#/components/schemas/EmailAddress"},"role":{"$ref":"#/components/schemas/Role"}},"required":["email","role"],"type":"object"},"CreateOrganizationRequest":{"additionalProperties":false,"properties":{"name":{"type":"string"},"slug":{"$ref":"#/components/schemas/Slug"}},"required":["slug","name"],"type":"object"},"CreateProjectRequest":{"additionalProperties":false,"properties":{"environment":{"$ref":"#/components/schemas/ProjectEnvironment"},"name":{"type":"string"},"slug":{"$ref":"#/components/schemas/Slug"}},"required":["slug","name","environment"],"type":"object"},"CreateServiceAccountRequest":{"additionalProperties":false,"description":"`POST /v1/organizations/{organization_id}/service-accounts` body.","properties":{"description":{"default":null,"type":["string","null"]},"max_scopes":{"description":"The scope ceiling for every key this account mints.","items":{"$ref":"#/components/schemas/Scope"},"type":"array"},"name":{"type":"string"}},"required":["name","max_scopes"],"type":"object"},"CreateSubscriptionRequest":{"additionalProperties":false,"description":"`POST /v1/projects/{project_id}/webhooks` body.","properties":{"description":{"default":null,"type":["string","null"]},"event_types":{"description":"Customer-namespace event types only — System events are refused.","items":{"type":"string"},"type":"array"},"url":{"type":"string"}},"required":["url","event_types"],"type":"object"},"CreateVirtualKeyRequest":{"additionalProperties":false,"description":"`POST /v1/projects/{project_id}/keys` body.","properties":{"environment":{"$ref":"#/components/schemas/KeyEnvironment"},"expires_at":{"default":null,"description":"Optional absolute expiry. When `None`, the key never expires\n(revocation is the only way to disable it).","format":"date-time","type":["string","null"]},"name":{"type":"string"},"rate_limit_rpm":{"default":null,"description":"Optional per-key override of the project's default rate limit.\nBounded at the gateway-level configured maximum.","format":"uint32","minimum":0,"type":["integer","null"]},"scopes":{"items":{"$ref":"#/components/schemas/Scope"},"type":"array"}},"required":["name","environment","scopes"],"type":"object"},"CredentialPublic":{"description":"Public listing shape — NEVER carries key material beyond last4.","properties":{"base_url_override":{"type":["string","null"]},"created_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"key_last4":{"type":"string"},"last_verified_at":{"format":"date-time","type":["string","null"]},"provider":{"type":"string"},"status":{"type":"string"},"tenant_id":{"anyOf":[{"$ref":"#/components/schemas/TenantId"},{"type":"null"}]},"updated_at":{"format":"date-time","type":"string"}},"required":["id","provider","key_last4","status","created_at","updated_at"],"type":"object"},"CreditBalance":{"properties":{"balance_cents":{"format":"int64","type":"integer"},"currency":{"type":"string"},"tenant_id":{"$ref":"#/components/schemas/TenantId"}},"required":["tenant_id","balance_cents","currency"],"type":"object"},"CreditEntryPublic":{"properties":{"currency":{"type":"string"},"delta_cents":{"format":"int64","type":"integer"},"id":{"format":"uuid","type":"string"},"occurred_at":{"format":"date-time","type":"string"},"reason":{"type":"string"},"ref_id":{"type":["string","null"]},"ref_type":{"type":["string","null"]},"tenant_id":{"$ref":"#/components/schemas/TenantId"}},"required":["id","tenant_id","delta_cents","currency","reason","occurred_at"],"type":"object"},"DeliveryPublic":{"description":"Read-shape for a delivery (history + replay listing).","properties":{"attempt":{"format":"uint32","minimum":0,"type":"integer"},"created_at":{"format":"date-time","type":"string"},"delivered_at":{"format":"date-time","type":["string","null"]},"event_id":{"$ref":"#/components/schemas/WebhookEventId"},"event_type":{"type":"string"},"id":{"$ref":"#/components/schemas/WebhookDeliveryId"},"last_error":{"type":["string","null"]},"last_status_code":{"format":"int32","type":["integer","null"]},"max_attempts":{"format":"uint32","minimum":0,"type":"integer"},"next_attempt_at":{"format":"date-time","type":"string"},"state":{"$ref":"#/components/schemas/DeliveryState"},"subscription_id":{"$ref":"#/components/schemas/WebhookSubscriptionId"}},"required":["id","subscription_id","event_id","event_type","state","attempt","max_attempts","next_attempt_at","created_at"],"type":"object"},"DeliveryState":{"description":"The lifecycle state of one delivery attempt-chain.","enum":["pending","in_flight","succeeded","failed","dead_lettered"],"type":"string"},"DependencyCheck":{"properties":{"error":{"type":["string","null"]},"latency_ms":{"format":"uint64","minimum":0,"type":"integer"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/CheckStatus"}},"required":["name","status","latency_ms"],"type":"object"},"Deployability":{"description":"The deployability classification for one catalog model — the answer to\n\"can I use this, and if not, what's missing?\". Joins four facts:\nan active binding (callable), a matching Blueprint (a launch recipe),\na priced GPU offering (somewhere to run it), and nothing at all.","properties":{"blueprints":{"description":"Names of the Blueprints that can launch this model's family.","items":{"type":"string"},"type":"array"},"est_hourly_cents":{"description":"Floor hourly cost of a self-hosted launch, integer cents. Present\nonly when a Blueprint AND a priced GPU both exist.","format":"int64","type":["integer","null"]},"gpu_required":{"description":"Whether serving this model needs a GPU launch (i.e. it has a\nBlueprint) versus being callable through an existing binding.","type":"boolean"},"status":{"$ref":"#/components/schemas/DeployabilityStatus"}},"required":["status","blueprints","gpu_required"],"type":"object"},"DeployabilityStatus":{"description":"Deployability tiers, in descending readiness. The wire strings are the\n`?deployability=` filter values.","oneOf":[{"const":"callable","description":"An active binding exists — callable through inference right now.","type":"string"},{"const":"launchable","description":"A Blueprint exists and a priced GPU is available — a launch would\nsucceed.","type":"string"},{"const":"blueprint_no_gpu","description":"A Blueprint exists but no priced GPU offering does — recipe ready,\nnowhere to run it.","type":"string"},{"const":"no_blueprint","description":"In the catalog but with no Blueprint — the work-queue for authoring\none.","type":"string"}]},"DisplayName":{"description":"A display name. Trimmed on receipt; 1–128 characters; control characters are refused.","maxLength":128,"minLength":1,"type":"string"},"EmailAddress":{"description":"An email address, normalized to lowercase and trimmed. Must contain exactly one `@`, a non-empty local part, and a domain containing a dot. Max 320 bytes (RFC 5321).","format":"email","maxLength":320,"type":"string"},"EmailVerificationConfirm":{"additionalProperties":false,"description":"`POST /v1/auth/email/verify` body.","properties":{"token":{"type":"string"}},"required":["token"],"type":"object"},"EntitlementView":{"properties":{"custom_overrides":true,"plan":{"$ref":"#/components/schemas/Plan"},"tenant_id":{"$ref":"#/components/schemas/TenantId"},"valid_from":{"format":"date-time","type":"string"},"valid_to":{"format":"date-time","type":["string","null"]}},"required":["tenant_id","plan","custom_overrides","valid_from"],"type":"object"},"EventTypeInfo":{"description":"One entry in the `GET /v1/webhooks/event-types` catalog.","properties":{"event_type":{"type":"string"},"namespace":{"type":"string"}},"required":["event_type","namespace"],"type":"object"},"InvitationPublic":{"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"invited_by":{"$ref":"#/components/schemas/UserId"},"organization_id":{"$ref":"#/components/schemas/OrganizationId"},"role":{"$ref":"#/components/schemas/Role"},"status":{"$ref":"#/components/schemas/InvitationStatus"}},"required":["id","organization_id","email","role","invited_by","created_at","expires_at","status"],"type":"object"},"InvitationStatus":{"enum":["pending","accepted","expired","revoked"],"type":"string"},"KeyEnvironment":{"enum":["live","test"],"type":"string"},"KeyStatus":{"enum":["active","expired","revoked"],"type":"string"},"LivenessResponse":{"description":"`GET /v1/health/liveness` response.","properties":{"service":{"type":"string"},"status":{"type":"string"},"uptime_seconds":{"format":"uint64","minimum":0,"type":"integer"},"version":{"type":"string"}},"required":["status","service","version","uptime_seconds"],"type":"object"},"LoginRequest":{"additionalProperties":false,"description":"`POST /v1/auth/login` body. Either password or oauth-callback path.","properties":{"email":{"$ref":"#/components/schemas/EmailAddress"},"mfa_code":{"anyOf":[{"$ref":"#/components/schemas/MfaCode"},{"type":"null"}]},"password":{"$ref":"#/components/schemas/PlaintextPassword"}},"required":["email","password"],"type":"object"},"MembershipPublic":{"properties":{"joined_at":{"format":"date-time","type":"string"},"organization_id":{"$ref":"#/components/schemas/OrganizationId"},"role":{"$ref":"#/components/schemas/Role"},"user_id":{"$ref":"#/components/schemas/UserId"}},"required":["organization_id","user_id","role","joined_at"],"type":"object"},"MfaCode":{"description":"A second-factor code: either a 6-digit TOTP code or a recovery code. Trimmed on receipt.","maxLength":64,"minLength":1,"type":"string","writeOnly":true},"MintedVirtualKey":{"description":"The response from a mint: includes the plaintext token *exactly once*.\nSubsequent reads return [`VirtualKeyPublic`] without the token field.","properties":{"key":{"$ref":"#/components/schemas/VirtualKeyPublic"},"token":{"description":"Full plaintext token. Display once; never returned again.","type":"string"}},"required":["key","token"],"type":"object"},"ModelHealth":{"description":"The customer-facing answer for one model.","properties":{"binding_id":{"format":"uuid","type":"string"},"consecutive_failures":{"format":"int32","type":"integer"},"kind":{"type":"string"},"last_failure_at":{"format":"date-time","type":["string","null"]},"last_failure_code":{"type":["string","null"]},"last_failure_status":{"format":"int16","maximum":32767,"minimum":-32768,"type":["integer","null"]},"last_success_at":{"format":"date-time","type":["string","null"]},"model":{"type":"string"},"provider":{"type":["string","null"]},"status":{"type":"string"}},"required":["model","binding_id","kind","status","consecutive_failures"],"type":"object"},"MyOrganizationEntry":{"properties":{"organization":{"$ref":"#/components/schemas/OrganizationPublic"},"role":{"$ref":"#/components/schemas/Role"}},"required":["organization","role"],"type":"object"},"OpenAiModel":{"properties":{"created":{"format":"int64","type":"integer"},"id":{"type":"string"},"object":{"type":"string"},"owned_by":{"type":"string"}},"required":["id","object","created","owned_by"],"type":"object"},"OpenAiModelList":{"description":"`GET /v1/models` OpenAI-compatible response.","properties":{"data":{"items":{"$ref":"#/components/schemas/OpenAiModel"},"type":"array"},"object":{"type":"string"}},"required":["object","data"],"type":"object"},"OrganizationId":{"description":"Organization within a tenant.","format":"uuid","type":"string"},"OrganizationPublic":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"$ref":"#/components/schemas/OrganizationId"},"name":{"type":"string"},"owner_user_id":{"$ref":"#/components/schemas/UserId"},"slug":{"$ref":"#/components/schemas/Slug"},"tenant_id":{"$ref":"#/components/schemas/TenantId"}},"required":["id","tenant_id","slug","name","owner_user_id","created_at"],"type":"object"},"PageOfAuditEntryPublic":{"description":"The envelope every list endpoint returns. Generic over the item type.\n\nThe `rename` is load-bearing for the published spec: without it schemars\nnames each instantiation `Page`, `Page2`, `Page3`… by order of discovery,\nwhich produces meaningless SDK type names that also reshuffle whenever a\nroute is added. `PageOfAuditEntryPublic` is stable and self-describing.","properties":{"has_more":{"type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/AuditEntryPublic"},"type":"array"},"next_cursor":{"type":["string","null"]}},"required":["items","has_more"],"type":"object"},"PageOfCreditEntryPublic":{"description":"The envelope every list endpoint returns. Generic over the item type.\n\nThe `rename` is load-bearing for the published spec: without it schemars\nnames each instantiation `Page`, `Page2`, `Page3`… by order of discovery,\nwhich produces meaningless SDK type names that also reshuffle whenever a\nroute is added. `PageOfAuditEntryPublic` is stable and self-describing.","properties":{"has_more":{"type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/CreditEntryPublic"},"type":"array"},"next_cursor":{"type":["string","null"]}},"required":["items","has_more"],"type":"object"},"PasswordResetConfirm":{"additionalProperties":false,"description":"`POST /v1/auth/password/reset-confirm` body.","properties":{"new_password":{"$ref":"#/components/schemas/PlaintextPassword"},"token":{"type":"string"}},"required":["token","new_password"],"type":"object"},"PasswordResetRequest":{"additionalProperties":false,"description":"`POST /v1/auth/password/reset-request` body.","properties":{"email":{"$ref":"#/components/schemas/EmailAddress"}},"required":["email"],"type":"object"},"PlaintextPassword":{"description":"A plaintext password. Accepted on request bodies only — never present in any response. Held in memory as a zeroizing secret and dropped once hashed or verified.","format":"password","type":"string","writeOnly":true},"Plan":{"properties":{"active":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"currency":{"type":"string"},"features":true,"id":{"type":"string"},"max_concurrent_instances":{"format":"int32","type":"integer"},"max_model_params_b":{"format":"double","type":"number"},"monthly_credits_cents":{"format":"int64","type":"integer"},"name":{"type":"string"},"per_day_limit":{"format":"int32","type":["integer","null"]},"per_minute_limit":{"description":"G13 — burst protection ceilings. `None` means \"unlimited\" (the\n`effective_ceiling` short-circuit returns Some(v) from the\ncustom_override JSON before falling through to these, so the\noperator can still tighten an enterprise tenant via override).\nStock plans seed values per tier in migration 0014b.","format":"int32","type":["integer","null"]},"price_cents_monthly":{"format":"int64","type":"integer"}},"required":["id","name","monthly_credits_cents","max_concurrent_instances","max_model_params_b","features","price_cents_monthly","currency","active","created_at"],"type":"object"},"PortalRequest":{"additionalProperties":false,"properties":{"return_url":{"type":"string"}},"required":["return_url"],"type":"object"},"PortalResponse":{"properties":{"portal_url":{"type":"string"}},"required":["portal_url"],"type":"object"},"Pricing":{"description":"The list price, every dimension the cost writer bills on. The three cache\nrates are published so a consumer that mirrors this catalog and estimates\nits own spend (Lighthouse does) prices a cache read and a cache write with\nthe SAME numbers the ledger uses, instead of guessing a multiplier and\ndrifting from the bill. Absent when the model has no such rate.","properties":{"cache_creation_1hr_cents_per_mtok":{"format":"double","type":["number","null"]},"cache_creation_cents_per_mtok":{"format":"double","type":["number","null"]},"cached_input_cents_per_mtok":{"format":"double","type":["number","null"]},"currency":{"type":"string"},"input_cents_per_mtok":{"format":"double","type":["number","null"]},"output_cents_per_mtok":{"format":"double","type":["number","null"]}},"required":["currency"],"type":"object"},"ProjectEnvironment":{"enum":["production","staging","development"],"type":"string"},"ProjectId":{"description":"Project within an organization — the unit virtual keys belong to.","format":"uuid","type":"string"},"ProjectPublic":{"properties":{"created_at":{"format":"date-time","type":"string"},"environment":{"$ref":"#/components/schemas/ProjectEnvironment"},"id":{"$ref":"#/components/schemas/ProjectId"},"name":{"type":"string"},"organization_id":{"$ref":"#/components/schemas/OrganizationId"},"slug":{"$ref":"#/components/schemas/Slug"}},"required":["id","organization_id","slug","name","environment","created_at"],"type":"object"},"ProviderSummary":{"properties":{"credential":{"description":"`\"platform\"` when Nozzle holds the credential and bills you for\ntokens; `\"byok\"` when you must supply your own via\n`POST /v1/byok/credentials`; `\"self_hosted\"` for pods we run.","type":"string"},"name":{"type":"string"},"wire_family":{"type":"string"}},"required":["name","credential","wire_family"],"type":"object"},"QuotaDigest":{"description":"The full quota digest for a tenant — one slot per `QuotaKind`, always.","properties":{"plan_id":{"type":"string"},"slots":{"items":{"$ref":"#/components/schemas/QuotaSlot"},"type":"array"},"tenant_id":{"format":"uuid","type":"string"}},"required":["tenant_id","plan_id","slots"],"type":"object"},"QuotaMeasure":{"description":"What `value` measures. A spend is summed from the ledger, a gauge is\ncounted live, a counter is incremented per event, and `ceiling_only` says\nthe kind bounds a request property rather than accumulating anything —\nits `value` is always zero and is not a measurement.","enum":["spend","gauge","counter","ceiling_only"],"type":"string"},"QuotaSlot":{"description":"Public view of a quota slot's current usage and ceiling.\n\nAdditive since the counter-backed shape: `kind`, `period_key`, `value`,\n`ceiling` and `updated_at` keep their names and types. The new fields make\nthe slot self-describing so a consumer never has to know which table a\nkind lives in.","properties":{"ceiling":{"description":"The ceiling in `unit`. `null` when — and only when — `unlimited`.","format":"int64","type":["integer","null"]},"enforced":{"description":"`true` when at least one declared operation enforces this kind. A kind\nno route declares is reported, not hidden, and this says it is inert.","type":"boolean"},"kind":{"type":"string"},"measure":{"$ref":"#/components/schemas/QuotaMeasure"},"period_key":{"type":"string"},"source":{"description":"The table or gauge `value` is read from — the same one the enforcer\nreads, by construction.","type":"string"},"unit":{"$ref":"#/components/schemas/QuotaUnit"},"unlimited":{"description":"`true` when no ceiling applies (plan column NULL or an explicit\n`null` override). Stated rather than left to be inferred from a null\n`ceiling`, so \"unlimited\" and \"unknown\" can never be confused.","type":"boolean"},"updated_at":{"format":"date-time","type":"string"},"value":{"description":"Current usage in `unit`. Zero and not a measurement when `measure` is\n`ceiling_only`.","format":"int64","type":"integer"}},"required":["kind","period_key","value","updated_at","unit","measure","unlimited","source","enforced"],"type":"object"},"QuotaUnit":{"description":"The unit a slot's `value` and `ceiling` are BOTH denominated in.\n\nStated on the wire because the 2026-09-19 digest compared a request count\nagainst a cents ceiling inside one slot; a reader could not tell. A slot\nnow carries one unit and both numbers are in it.","enum":["micro_cents","instances","requests","params_b"],"type":"string"},"ReadinessResponse":{"description":"`GET /v1/health/readiness` response.","properties":{"checks":{"items":{"$ref":"#/components/schemas/DependencyCheck"},"type":"array"},"status":{"$ref":"#/components/schemas/ReadinessStatus"}},"required":["status","checks"],"type":"object"},"ReadinessStatus":{"enum":["ready","degraded","notready"],"type":"string"},"RecoveryCodesResponse":{"description":"`POST /v1/me/mfa/recovery-codes/generate` response.","properties":{"codes":{"description":"Plaintext codes. Display once; never recoverable.","items":{"type":"string"},"type":"array"},"factor_id":{"format":"uuid","type":"string"}},"required":["factor_id","codes"],"type":"object"},"RefreshRequest":{"additionalProperties":false,"description":"`POST /v1/auth/refresh` body.\n\n`refresh_token` is optional because the console never holds it: the\nbrowser sends the `nozzle_refresh` cookie instead (see `cookies.rs`).\nSDK callers keep passing it in the body. A body naming it wins over the\ncookie so a script can rotate a specific session deliberately.","properties":{"refresh_token":{"default":null,"type":["string","null"]}},"type":"object"},"RegisterModelRequest":{"additionalProperties":false,"properties":{"cents_per_audio_minute":{"default":null,"description":"Cost per minute of audio, in cents — the unit an audio model bills in.\nRequired for `modality: \"audio\"` unless the catalog already prices it.","format":"double","type":["number","null"]},"input_cents_per_mtok":{"default":null,"description":"Cost per million input tokens, in cents. Required only when the\ncatalog does not already price this model under this provider, and only\nfor a token-billed modality.","format":"double","type":["number","null"]},"modality":{"default":null,"description":"What the model serves, and therefore which surface it answers on:\n`text` (the default) for `/v1/chat/completions`, `embedding` for\n`/v1/embeddings`, `audio` for `/v1/audio/transcriptions`. The binding\nkind is derived from it by the same mapping a self-hosted pod uses, so\nthere is one vocabulary for \"what is this model\", not two.\n\nOne of `text`, `embedding`, `audio`. Sent as a string because the\nvocabulary belongs to the registry crate, which has no business\nderiving a JSON schema; an unknown value is refused by name.","type":["string","null"]},"name":{"description":"The name you will send in `{\"model\": \"...\"}`. Any string you like —\nan alias you invent, or an existing catalog name you are re-pointing\nat your own provider account.","type":"string"},"output_cents_per_mtok":{"default":null,"description":"Cost per million output tokens, in cents.","format":"double","type":["number","null"]},"provider":{"description":"Which upstream serves it. Must be enabled; `GET /v1/providers` lists\nthe ones available to you.","type":"string"},"upstream_model":{"description":"The provider's own name for the model. Routinely differs from `name`\n(`Qwen/Qwen3.8-27B` at DeepInfra vs `qwen3.8-27b` at Groq), which is\nexactly why both exist.","type":"string"}},"required":["name","provider","upstream_model"],"type":"object"},"RegisteredModel":{"properties":{"id":{"type":"string"},"modality":{"description":"What it serves, echoed back so a client can see which surface to call.","type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"scope":{"description":"Always `\"tenant\"`. Stated rather than implied so a client can tell a\nmodel it registered from one the platform published.","type":"string"},"upstream_model":{"type":"string"}},"required":["id","name","provider","upstream_model","scope","modality"],"type":"object"},"RevokedSessions":{"properties":{"revoked_count":{"format":"uint64","minimum":0,"type":"integer"}},"required":["revoked_count"],"type":"object"},"Role":{"description":"Organization member role. Ordered by privilege: `Owner` ≥ `Admin` ≥\n`Developer` ≥ `Viewer`. The ordering is what enables checks like\n`role >= Role::Admin`.","enum":["viewer","developer","admin","owner"],"type":"string"},"RotateCredentialRequest":{"additionalProperties":false,"description":"NO derived Debug — same plaintext-key discipline as create.","properties":{"api_key":{"description":"The replacement plaintext key. Same discipline as create.","type":"string"}},"required":["api_key"],"type":"object"},"RotateKeyRequest":{"additionalProperties":false,"description":"`POST /v1/keys/{key_id}/rotate` body — optional grace window.","properties":{"grace_period_seconds":{"default":0,"description":"Seconds during which the *old* token remains valid after rotation.\nDefaults to 0 (immediate cutover). Bounded by `MAX_ROTATION_GRACE_SECS`.","format":"uint32","minimum":0,"type":"integer"}},"type":"object"},"RotatedSecret":{"description":"`POST /v1/webhooks/{id}/rotate-secret` response.","properties":{"id":{"$ref":"#/components/schemas/WebhookSubscriptionId"},"signing_secret":{"type":"string"}},"required":["id","signing_secret"],"type":"object"},"RotatedVirtualKey":{"properties":{"grace_expires_at":{"description":"When the previous token stops accepting requests.","format":"date-time","type":"string"},"key":{"$ref":"#/components/schemas/VirtualKeyPublic"},"token":{"description":"The new plaintext token. Display once.","type":"string"}},"required":["key","token","grace_expires_at"],"type":"object"},"Scope":{"description":"A permission in the closed catalog, spelled `<domain>:<action>`. The `internal:*` namespace is operator-only and is refused on a customer bearer. A key can only be granted scopes its minter already holds.","enum":["catalog:read","instances:read","training:read","usage:read","audit:read","webhooks:read","keys:read","billing:read","identity:read","inference:call","catalog:write","instances:write","training:write","webhooks:write","keys:write","billing:write","tenancy:write","identity:write","arena:write","admin:tenants:manage","admin:keys:mint","admin:billing:manage","admin:audit:export","internal:logs:read","internal:db:query","internal:traces:read","internal:forensics:read","internal:deploy:manage","internal:health:read","internal:agent:impersonate","internal:blueprints:author","internal:credentials:reseal"],"title":"Scope","type":"string"},"ServiceAccountPublic":{"properties":{"active":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"created_by":{"anyOf":[{"$ref":"#/components/schemas/UserId"},{"type":"null"}]},"description":{"type":["string","null"]},"disabled_at":{"format":"date-time","type":["string","null"]},"id":{"format":"uuid","type":"string"},"max_scopes":{"items":{"$ref":"#/components/schemas/Scope"},"type":"array"},"name":{"type":"string"},"organization_id":{"$ref":"#/components/schemas/OrganizationId"},"tenant_id":{"$ref":"#/components/schemas/TenantId"}},"required":["id","tenant_id","organization_id","name","max_scopes","created_at","active"],"type":"object"},"SessionId":{"description":"A browser session.","format":"uuid","type":"string"},"SessionPublic":{"description":"`GET /v1/me/sessions` response item.","properties":{"created_at":{"format":"date-time","type":"string"},"current":{"type":"boolean"},"expires_at":{"format":"date-time","type":"string"},"id":{"$ref":"#/components/schemas/SessionId"},"ip":{"type":["string","null"]},"last_seen_at":{"format":"date-time","type":"string"},"user_agent":{"type":["string","null"]}},"required":["id","created_at","last_seen_at","expires_at","current"],"type":"object"},"SignupRequest":{"additionalProperties":false,"description":"`POST /v1/auth/signup` body.","properties":{"display_name":{"$ref":"#/components/schemas/DisplayName"},"email":{"$ref":"#/components/schemas/EmailAddress"},"password":{"$ref":"#/components/schemas/PlaintextPassword"}},"required":["email","password","display_name"],"type":"object"},"Slug":{"description":"A URL-safe identifier: lowercase alphanumerics and single dashes, 1–64 characters, no leading/trailing dash and no double dash. A small set of reserved words is additionally refused at runtime.","maxLength":64,"minLength":1,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","type":"string"},"SpendCap":{"additionalProperties":false,"description":"A key's configured cap. Both fields are set or neither is — the DB\n`virtual_keys_budget_coherent` CHECK in `0023` makes a half-configured row\nunrepresentable, so this type mirrors that invariant rather than carrying\ntwo independent `Option`s that could disagree.","properties":{"budget_window":{"$ref":"#/components/schemas/BudgetWindow"},"max_budget_micro_cents":{"description":"The ceiling in MICRO-cents (1 cent = `1_000_000`), the unit the ledger\nstores, so a sub-cent charge is never rounded away on the way to a cap.","format":"int64","type":"integer"}},"required":["max_budget_micro_cents","budget_window"],"type":"object"},"Subscription":{"properties":{"active":{"type":"boolean"},"channel":{"$ref":"#/components/schemas/Channel"},"created_at":{"format":"date-time","type":"string"},"event_type":{"type":"string"},"id":{"format":"uuid","type":"string"},"last_delivery_at":{"format":"date-time","type":["string","null"]},"project_id":{"format":"uuid","type":["string","null"]},"target":true,"tenant_id":{"format":"uuid","type":"string"},"updated_at":{"format":"date-time","type":"string"}},"required":["id","tenant_id","channel","event_type","target","active","created_at","updated_at"],"type":"object"},"SubscriptionPublic":{"description":"Read-shape: the signing secret is intentionally absent.","properties":{"active":{"type":"boolean"},"created_at":{"format":"date-time","type":"string"},"description":{"type":["string","null"]},"disabled_at":{"format":"date-time","type":["string","null"]},"event_types":{"items":{"type":"string"},"type":"array"},"id":{"$ref":"#/components/schemas/WebhookSubscriptionId"},"project_id":{"$ref":"#/components/schemas/ProjectId"},"tenant_id":{"$ref":"#/components/schemas/TenantId"},"updated_at":{"format":"date-time","type":"string"},"url":{"type":"string"}},"required":["id","project_id","tenant_id","url","event_types","active","created_at","updated_at"],"type":"object"},"TenantId":{"description":"Top-level tenancy: an organization / customer.","format":"uuid","type":"string"},"TenantPublic":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"$ref":"#/components/schemas/TenantId"},"name":{"type":"string"},"region":{"type":"string"},"slug":{"$ref":"#/components/schemas/Slug"},"status":{"$ref":"#/components/schemas/TenantStatus"}},"required":["id","slug","name","status","region","created_at"],"type":"object"},"TenantStatus":{"oneOf":[{"const":"active","description":"Healthy; everything works.","type":"string"},{"const":"suspended","description":"Read-only; reads succeed, writes refuse.","type":"string"},{"const":"frozen","description":"Cold-storage; both reads and writes refuse. Recoverable.","type":"string"},{"const":"closed","description":"Soft-closed; pending hard-delete after retention window.","type":"string"}]},"TenantUsageResponse":{"properties":{"all_time_cents":{"format":"int64","type":"integer"},"last_24h_cents":{"format":"int64","type":"integer"},"last_30d_by_kind":{"items":{"$ref":"#/components/schemas/UsageByKind"},"type":"array"},"last_30d_cents":{"format":"int64","type":"integer"},"last_7d_cents":{"format":"int64","type":"integer"},"tenant_id":{"format":"uuid","type":"string"}},"required":["tenant_id","last_24h_cents","last_7d_cents","last_30d_cents","all_time_cents","last_30d_by_kind"],"type":"object"},"TotpConfirmRequest":{"additionalProperties":false,"description":"`POST /v1/me/mfa/totp/confirm` body.","properties":{"code":{"$ref":"#/components/schemas/MfaCode"},"factor_id":{"format":"uuid","type":"string"}},"required":["factor_id","code"],"type":"object"},"TotpEnrollmentResponse":{"description":"`POST /v1/me/mfa/totp/enroll` response — the QR-encodable secret.","properties":{"factor_id":{"format":"uuid","type":"string"},"otpauth_uri":{"description":"`otpauth://...` URI for the user's authenticator app QR code.","type":"string"},"secret":{"description":"The Base32-encoded TOTP secret. Display once; never again.","type":"string"}},"required":["factor_id","secret","otpauth_uri"],"type":"object"},"UpdateMemberRoleRequest":{"additionalProperties":false,"properties":{"role":{"$ref":"#/components/schemas/Role"}},"required":["role"],"type":"object"},"UpdateSubscriptionRequest":{"additionalProperties":false,"description":"`PATCH /v1/webhooks/{id}` body. All fields optional.","properties":{"active":{"default":null,"type":["boolean","null"]},"description":{"default":null,"type":["string","null"]},"event_types":{"default":null,"items":{"type":"string"},"type":["array","null"]},"url":{"default":null,"type":["string","null"]}},"type":"object"},"UpdateVirtualKeyRequest":{"additionalProperties":false,"description":"`PATCH /v1/keys/{key_id}` — partial update for fields that are safe\nto change in place (no rotation, no scope expansion).","properties":{"expires_at":{"description":"Setting to `None` clears the expiry (no-op for never-expiring keys).","format":"date-time","type":["string","null"]},"name":{"default":null,"type":["string","null"]},"rate_limit_rpm":{"default":null,"format":"uint32","minimum":0,"type":["integer","null"]},"scopes":{"default":null,"description":"Reducing the scope set is allowed; expanding requires a remint.","items":{"$ref":"#/components/schemas/Scope"},"type":["array","null"]},"spend_cap":{"anyOf":[{"$ref":"#/components/schemas/SpendCap"},{"type":"null"}],"default":null,"description":"The most this key may spend, over which window. Both halves arrive\ntogether because the type carries both: a ceiling with no window never\nenforces and a window with no ceiling means nothing, which is what the\n`virtual_keys_budget_coherent` CHECK says in the database.\n\nOmitting it leaves the existing cap alone, as every other field here\ndoes. Removing a cap is deliberately not expressible for the same\nreason clearing an expiry is not: one PATCH body cannot distinguish\n\"absent\" from \"set to nothing\" without a second nesting level, and a\nsilent uncapping is the wrong thing to guess."}},"type":"object"},"UsageByKind":{"properties":{"cost_cents":{"format":"int64","type":"integer"},"kind":{"type":"string"},"row_count":{"format":"int64","type":"integer"}},"required":["kind","row_count","cost_cents"],"type":"object"},"UserId":{"description":"End-user identifier (dashboard login).","format":"uuid","type":"string"},"UserPublic":{"description":"The non-secret view of a User. This is what every endpoint that\nreturns user info emits — `email_verified` instead of `email_verified_at`,\nno audit timestamps, no `mfa_required` flag (it's a security signal).","properties":{"created_at":{"format":"date-time","type":"string"},"display_name":{"$ref":"#/components/schemas/DisplayName"},"email":{"$ref":"#/components/schemas/EmailAddress"},"email_verified":{"type":"boolean"},"id":{"$ref":"#/components/schemas/UserId"},"status":{"$ref":"#/components/schemas/UserStatus"}},"required":["id","email","email_verified","display_name","status","created_at"],"type":"object"},"UserStatus":{"enum":["active","suspended","disabled"],"type":"string"},"VirtualKeyId":{"description":"A customer-facing programmatic key (pk_live_* / pk_test_*).","format":"uuid","type":"string"},"VirtualKeyPublic":{"properties":{"created_at":{"format":"date-time","type":"string"},"created_by":{"anyOf":[{"$ref":"#/components/schemas/UserId"},{"type":"null"}]},"environment":{"$ref":"#/components/schemas/KeyEnvironment"},"expires_at":{"format":"date-time","type":["string","null"]},"id":{"$ref":"#/components/schemas/VirtualKeyId"},"last_used_at":{"format":"date-time","type":["string","null"]},"name":{"type":"string"},"preview":{"description":"Suffix of the token (e.g. `…aB3xQ`) for UI identification.","type":"string"},"project_id":{"$ref":"#/components/schemas/ProjectId"},"rate_limit_rpm":{"format":"uint32","minimum":0,"type":"integer"},"revoked_at":{"format":"date-time","type":["string","null"]},"scopes":{"items":{"$ref":"#/components/schemas/Scope"},"type":"array"},"spend_cap":{"anyOf":[{"$ref":"#/components/schemas/SpendCap"},{"type":"null"}],"description":"The spend ceiling this key carries, or `null` when it is uncapped.\nReadable because it is settable: a cap you cannot see is a cap you\ncannot audit."},"status":{"$ref":"#/components/schemas/KeyStatus"},"tenant_id":{"$ref":"#/components/schemas/TenantId"}},"required":["id","project_id","tenant_id","environment","name","preview","scopes","rate_limit_rpm","created_at","status"],"type":"object"},"WebhookDeliveryId":{"description":"One (event, subscription) delivery attempt-chain.","format":"uuid","type":"string"},"WebhookEventId":{"description":"One fired event in api.webhook_event_log.","format":"uuid","type":"string"},"WebhookSubscriptionId":{"description":"A tenant's outbound-webhook subscription.","format":"uuid","type":"string"},"WireCapabilities":{"description":"What a wire grammar can honor. Field names are the wire strings the\ncapabilities endpoint serializes — stable, snake_case, additive-only.","properties":{"audio_in":{"type":"boolean"},"audio_out":{"type":"boolean"},"cache_control":{"type":"boolean"},"json_object":{"type":"boolean"},"json_schema":{"type":"boolean"},"logit_bias":{"type":"boolean"},"logprobs":{"type":"boolean"},"n_gt_1":{"type":"boolean"},"parallel_tool_calls":{"type":"boolean"},"pdf_in":{"type":"boolean"},"penalties":{"type":"boolean"},"reasoning":{"type":"boolean"},"responses":{"description":"Whether the upstream serves the `OpenAI` Responses API\n(`POST /v1/responses`) natively, so a Responses-shaped request can\nbe forwarded to it verbatim.\n\nA DIALECT of the upstream's API generation, not a property of the\nwire grammar: every `openai_chat_completions` provider speaks chat\ncompletions, but only `OpenAI` itself (and the shims that chose to)\nserves `/responses`. So the baseline here is `false` for every wire\nand the truth is derived per provider row by\n[`responses_native_default`] plus the row's own `responses` override —\nthe same two inputs the router registers on.","type":"boolean"},"seed":{"type":"boolean"},"streaming":{"type":"boolean"},"timestamps":{"description":"Whether the model can time a transcript: `verbose_json` with segments\nand word timings, and the `srt`/`vtt` renderings built from them.\n`OpenAI`'s `gpt-4o-transcribe` family cannot; a `models.model_params`\nrow says so and the router refuses those containers by name.","type":"boolean"},"tool_choice_named":{"type":"boolean"},"tools":{"type":"boolean"},"translation":{"description":"Whether the model serves `/v1/audio/translations`.","type":"boolean"},"vision":{"type":"boolean"}},"required":["tools","parallel_tool_calls","tool_choice_named","json_object","json_schema","vision","audio_in","audio_out","pdf_in","cache_control","reasoning","responses","timestamps","translation","streaming","n_gt_1","logprobs","seed","penalties","logit_bias"],"type":"object"}},"securitySchemes":{"SessionJwtBearer":{"bearerFormat":"JWT","description":"HS256 JWT minted by signup or login. Used for dashboard / browser session calls; refused on /internal/v1/*.","scheme":"bearer","type":"http"},"VirtualKeyBearer":{"description":"Customer programmatic key. `pk_live_*` calls billable operations normally. `pk_test_*` is a SANDBOX key: it authenticates, carries scopes, and reads your own data exactly like a live key, but any operation that spends real money upstream — inference on any modality, and launching a compute instance — is refused with 403. Use it to wire up and test integrations without spend. Both are refused on /internal/v1/*.","scheme":"bearer","type":"http"}}},"info":{"contact":{"url":"https://github.com/Sapelo-AI/nozzle"},"description":"Programmable substrate for AI infrastructure — inference, GPU lifecycle, training, observability.","title":"Nozzle API","version":"0.1.0"},"openapi":"3.1.0","paths":{"/anthropic/v1/messages":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"sdk_compat.anthropic.messages","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Accepts the Anthropic Messages API request shape unchanged and answers in the Anthropic response shape, including its streaming event vocabulary. Point an Anthropic SDK at this path with no other change.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Accepts the Anthropic Messages API request shape unchanged and answers in the Anthropic response shape, including its streaming event vocabulary. Point an Anthropic SDK at this path with no other change.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"Anthropic Messages API drop-in — translated to the one chat pipeline.","x-required-scopes":["inference:call"]}},"/v1/analytics/cost":{"get":{"description":"**Authorization:** requires `usage:read`.","operationId":"analytics.cost_per_day_mine","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"One row per UTC day, newest first, capped at 400 days: `{day, inference_cents, instance_cents, training_cents, margin_cents}`. Read from the pre-materialized rollup, so the most recent day trails live spend by up to one scheduler tick — use `GET /v1/tenants/{tenant_id}/usage` for up-to-the-second totals. Optional `from` / `to` are inclusive `YYYY-MM-DD` bounds. The shape is owned by analytics-service and is not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["usage:read"]}],"summary":"Your own cost per day.","x-required-scopes":["usage:read"]}},"/v1/analytics/instances":{"get":{"description":"**Authorization:** requires `usage:read`.","operationId":"analytics.instance_lifetimes_mine","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"One row per compute Instance, newest first: `{instance_id, blueprint_name, provider, gpu_sku, started_at, stopped_at, total_seconds, total_cents, total_tokens_in, total_tokens_out}`. `stopped_at` and `total_seconds` are null while an Instance is still running. Optional `limit` (1-1000, default 100). The shape is owned by analytics-service and is not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["usage:read"]}],"summary":"Your own instance lifetime rollups.","x-required-scopes":["usage:read"]}},"/v1/analytics/margin":{"get":{"description":"**Authorization:** requires `usage:read`.","operationId":"analytics.margin_per_day_mine","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"`{days: [{day, inference_cents, instance_cents, margin_cents}], total_inference_cents, total_instance_cents, total_margin_cents, markup_note}`. Margin is inference spend minus compute spend; at today's 0% markup that is a cost-versus-cost comparison, not profit, and `markup_note` says so on every response. Negative totals are the honest answer on days a GPU sat idle. The shape is owned by analytics-service and is not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["usage:read"]}],"summary":"Your own margin per day.","x-required-scopes":["usage:read"]}},"/v1/audio/speech":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.speech","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible text-to-speech. Audio bytes out; bills by estimated duration.","x-required-scopes":["inference:call"]}},"/v1/audio/transcriptions":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.transcription","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible transcription (multipart). Bills by reported duration.","x-required-scopes":["inference:call"]}},"/v1/audio/translations":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.translation","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible speech translation to English (multipart). Bills by reported duration.","x-required-scopes":["inference:call"]}},"/v1/audit":{"get":{"description":"**Authorization:** requires `audit:read`.","operationId":"audit.list_mine","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageOfAuditEntryPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["audit:read"]}],"summary":"List your own audit-log entries.","x-required-scopes":["audit:read"]}},"/v1/audit/export":{"get":{"description":"**Authorization:** requires `admin:audit:export`.","operationId":"audit.export_mine","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Streams your own audit log as newline-delimited JSON; each line is an AuditEntry. Not a single JSON document.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["admin:audit:export"]}],"summary":"Export your own audit log as CSV.","x-required-scopes":["admin:audit:export"]}},"/v1/audit/{audit_id}":{"get":{"description":"**Authorization:** requires `audit:read`.","operationId":"audit.entry.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEntryPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["audit:read"]}],"summary":"Get one audit entry by id.","x-required-scopes":["audit:read"]}},"/v1/auth/email/verify":{"post":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"identity.email_verify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailVerificationConfirm"}}},"required":true},"responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Consume an email-verification token and mark the email verified.","x-event-on-success":"user.email_verified","x-required-scopes":[],"x-requires-idempotency-key":true}},"/v1/auth/login":{"post":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"identity.login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSession"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Exchange email + password (+ MFA) for an access + refresh token pair.","x-event-on-failure":"session.open_failed","x-event-on-success":"session.opened","x-required-scopes":[],"x-requires-idempotency-key":true}},"/v1/auth/logout":{"post":{"description":"**Authorization:** requires `identity:write`.","operationId":"identity.logout","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:write"]}],"summary":"Revoke the current session.","x-event-on-success":"session.closed","x-required-scopes":["identity:write"],"x-requires-idempotency-key":true}},"/v1/auth/password/reset-confirm":{"post":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"identity.password_reset_confirm","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirm"}}},"required":true},"responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Consume a reset token and set a new password.","x-event-on-success":"user.password_reset","x-required-scopes":[],"x-requires-idempotency-key":true}},"/v1/auth/password/reset-request":{"post":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"identity.password_reset_request","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Request a password-reset email. Always 204 — never reveals account existence.","x-event-on-success":"user.password_reset_requested","x-required-scopes":[],"x-requires-idempotency-key":true}},"/v1/auth/refresh":{"post":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"identity.refresh","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSession"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Rotate a refresh token, yielding a new access + refresh pair.","x-required-scopes":[],"x-requires-idempotency-key":true}},"/v1/auth/signup":{"post":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"identity.signup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSession"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Create an account with email + password and start a session.","x-event-on-failure":"user.signup_failed","x-event-on-success":"user.signed_up","x-required-scopes":[],"x-requires-idempotency-key":true}},"/v1/billing/balance":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"billing.balance.get_mine","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditBalance"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"Read your own prepaid credit balance.","x-required-scopes":["billing:read"]}},"/v1/billing/costs":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"billing.costs.list_mine","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CostEntryPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"List your own recent cost-ledger entries.","x-required-scopes":["billing:read"]}},"/v1/billing/credits":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"billing.credits.list_mine","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageOfCreditEntryPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"List your own credit ledger entries.","x-required-scopes":["billing:read"]}},"/v1/billing/entitlement":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"billing.entitlement.get_mine","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementView"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"Read your own plan entitlement.","x-required-scopes":["billing:read"]}},"/v1/billing/plans":{"get":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"billing.plans.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Plan"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"List available billing plans.","x-required-scopes":[]}},"/v1/billing/reconcile":{"post":{"description":"**Authorization:** requires `admin:billing:manage`.","operationId":"billing.reconcile","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Operator-triggered Stripe reconciliation. Answers with a `{applied, skipped}` report.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Operator-triggered Stripe reconciliation. Answers with a `{applied, skipped}` report.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["admin:billing:manage"]}],"summary":"Re-apply recent Stripe events to the credit ledger (idempotent).","x-required-scopes":["admin:billing:manage"],"x-requires-idempotency-key":true}},"/v1/blueprints":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"compute_catalog.blueprints.list","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"The deployable Blueprint catalog, relayed from the compute-orchestrator which owns `compute.blueprints`. A Blueprint is `{name, model, model_family, modality, engine, quantization, version, requires: {gpu_class, vram_gb, container_disk_gb, min_cuda_version, capabilities[]}, defaults: {max_model_len, gpu_memory_utilization, port}}`. `name` is the value to send as `blueprint` on POST /v1/instances. Install, launch and readiness scripts are operator-only and are never part of this shape. `defaults.max_model_len` is the engine's TOTAL sequence budget (prompt plus completion), not an input-only ceiling.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"List the deployable Blueprints and the hardware each requires.","x-required-scopes":["catalog:read"]}},"/v1/blueprints/{name}":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"compute_catalog.blueprints.get","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"The deployable Blueprint catalog, relayed from the compute-orchestrator which owns `compute.blueprints`. A Blueprint is `{name, model, model_family, modality, engine, quantization, version, requires: {gpu_class, vram_gb, container_disk_gb, min_cuda_version, capabilities[]}, defaults: {max_model_len, gpu_memory_utilization, port}}`. `name` is the value to send as `blueprint` on POST /v1/instances. Install, launch and readiness scripts are operator-only and are never part of this shape. `defaults.max_model_len` is the engine's TOTAL sequence budget (prompt plus completion), not an input-only ceiling.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"Read one deployable Blueprint by name.","x-required-scopes":["catalog:read"]}},"/v1/byok/credentials":{"get":{"description":"**Authorization:** requires `keys:read`.","operationId":"byok.credentials.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CredentialPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:read"]}],"summary":"List this tenant's provider credentials (last4 only, never key material).","x-required-scopes":["keys:read"]},"post":{"description":"**Authorization:** requires `keys:write`.","operationId":"byok.credentials.create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCredentialRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Upload a provider API key (validated, sealed, one per provider).","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true}},"/v1/byok/credentials/{id}":{"delete":{"description":"**Authorization:** requires `keys:write`.","operationId":"byok.credentials.delete","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Delete a provider credential (hard delete — no ciphertext remains).","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true}},"/v1/byok/credentials/{id}/rotate":{"post":{"description":"**Authorization:** requires `keys:write`.","operationId":"byok.credentials.rotate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateCredentialRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Replace a credential's key (re-validated, re-sealed on the current ring).","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true}},"/v1/catalog":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"catalog.nested","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Nested Model → Variants browse surface. The shape is owned by the model-registry crate (`ModelWithVariants`) and is not described here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"Nested Model → Variants browse surface for the dashboard catalog page.","x-required-scopes":["catalog:read"]}},"/v1/catalog/models":{"get":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"catalog.models.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CatalogModel"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"List the browsable catalog. Each row carries pricing, deployability, and what THIS caller resolves to: `bound`, `provider`, `upstream_model`, `kind` and `wire_capabilities` (the booleans `/v1/models/{id}/capabilities` answers). Optional query filters, all AND-ed: `provider`, `modality`, `q` (substring of id or display name), `min_context`, `max_input_cents_per_mtok`, `bound` (true|false), `deployability` (callable|launchable|blueprint_no_gpu|no_blueprint|all), `limit` (1-500, default 100), `offset`.","x-required-scopes":[]}},"/v1/catalog/models/{id}":{"get":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"catalog.models.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogModel"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Get a single catalog model by id (typed flat shape — legacy).","x-required-scopes":[]}},"/v1/chat/completions":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.chat.completions","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible chat completion. Routes through model_registry.","x-required-scopes":["inference:call"]}},"/v1/classify":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.classify","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"Classify inputs. Bills per classification.","x-required-scopes":["inference:call"]}},"/v1/completions":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.completions","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible legacy text completion. Adapts onto the chat pipeline.","x-required-scopes":["inference:call"]}},"/v1/embeddings":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.embeddings","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible embeddings. Routes through model_registry.","x-required-scopes":["inference:call"]}},"/v1/gpu-offerings":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"compute_catalog.gpu_offerings.list","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Purchasable GPU configurations as last scraped from each provider, relayed from the compute-orchestrator. Each is `{provider, gpu_sku, gpu_class, region, vram_gb, hourly_cents, spot_available, secure_cloud, scraped_at}`. `gpu_sku` is the value to send as `gpu_sku` on POST /v1/instances. `hourly_cents` is NULL when the provider published no price — that is distinct from free, and a large share of upstream SKUs carry no price. `gpu_class` is NULL for hardware nozzle does not model, which means no Blueprint can target it. Optional `provider`, `gpu_class` and `limit` query filters; an unknown `gpu_class` is refused by name with the allowed set in `details`.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"List purchasable GPU configurations with last-scraped hourly pricing.","x-required-scopes":["catalog:read"]}},"/v1/health/liveness":{"get":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"health.liveness","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LivenessResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Cheap probe: returns OK as long as the process is responding.","x-required-scopes":[]}},"/v1/health/readiness":{"get":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"health.readiness","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Returns OK only when every dependency is reachable.","x-required-scopes":[]}},"/v1/images/edits":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.images.edits","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible image edits (multipart: reference images + prompt). gpt-image dialect only; bills from token usage.","x-required-scopes":["inference:call"]}},"/v1/images/generations":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.images","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible image generation. Bills per image at the quality-multiplied baseline, or from token usage on the gpt-image dialect.","x-required-scopes":["inference:call"]}},"/v1/instances":{"get":{"description":"**Authorization:** requires `instances:read`.","operationId":"instances.list","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract. Shapes are defined by that service and are not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["instances:read"]}],"summary":"List the caller's compute Instances.","x-required-scopes":["instances:read"]},"post":{"description":"**Authorization:** requires `instances:write`.","operationId":"instances.create","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract: `{blueprint, provider, gpu_sku, region?, placement?, public_model_name?, replicas?, policy?, tags?, param_overrides?, model_binding_id?}`. `public_model_name` is the name callers send in `model` once ready (default: the Blueprint's model path). `placement` = `{data_center_ids[], country_codes[], gpu_type_ids[], cloud (secure|community), min_download_mbps, min_upload_mbps, min_disk_bandwidth_mbps}`; every field optional, unset fields inherit the platform placement policy. Sending a non-empty `placement` requires the `placement_override` plan feature (or an internal principal) and is refused with 403 `auth.forbidden` otherwise. `tags` is attribution metadata only.","required":true,"x-nozzle-undescribed":true},"responses":{"201":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract: `{blueprint, provider, gpu_sku, region?, placement?, public_model_name?, replicas?, policy?, tags?, param_overrides?, model_binding_id?}`. `public_model_name` is the name callers send in `model` once ready (default: the Blueprint's model path). `placement` = `{data_center_ids[], country_codes[], gpu_type_ids[], cloud (secure|community), min_download_mbps, min_upload_mbps, min_disk_bandwidth_mbps}`; every field optional, unset fields inherit the platform placement policy. Sending a non-empty `placement` requires the `placement_override` plan feature (or an internal principal) and is refused with 403 `auth.forbidden` otherwise. `tags` is attribution metadata only.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["instances:write"]}],"summary":"Enqueue a new compute Instance launch.","x-event-on-failure":"instance.create_failed","x-event-on-success":"instance.create_requested","x-required-scopes":["instances:write"],"x-requires-idempotency-key":true}},"/v1/instances/{id}":{"delete":{"description":"**Authorization:** requires `instances:write`.","operationId":"instances.terminate","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract. Shapes are defined by that service and are not re-declared here.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract. Shapes are defined by that service and are not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["instances:write"]}],"summary":"Hard terminate a compute Instance (no drain).","x-event-on-failure":"instance.terminate_failed","x-event-on-success":"instance.terminate_requested","x-required-scopes":["instances:write"],"x-requires-idempotency-key":true},"get":{"description":"**Authorization:** requires `instances:read`.","operationId":"instances.get","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract. Shapes are defined by that service and are not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["instances:read"]}],"summary":"Read one compute Instance.","x-required-scopes":["instances:read"]}},"/v1/instances/{id}/diagnostics":{"get":{"description":"**Authorization:** requires `instances:read`.","operationId":"instances.diagnostics","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract. Shapes are defined by that service and are not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["instances:read"]}],"summary":"Get typed diagnostic envelope for a compute Instance.","x-required-scopes":["instances:read"]}},"/v1/instances/{id}/logs":{"get":{"description":"**Authorization:** requires `instances:read`.","operationId":"instances.logs","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract. Shapes are defined by that service and are not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["instances:read"]}],"summary":"Get the launch/lifecycle log timeline for a compute Instance.","x-required-scopes":["instances:read"]}},"/v1/instances/{id}/stop":{"post":{"description":"**Authorization:** requires `instances:write`.","operationId":"instances.stop","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract. Shapes are defined by that service and are not re-declared here.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relayed to the compute-orchestrator, which owns the Instance wire contract. Shapes are defined by that service and are not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["instances:write"]}],"summary":"Graceful drain → stop on a running Instance.","x-event-on-failure":"instance.stop_failed","x-event-on-success":"instance.stop_requested","x-required-scopes":["instances:write"],"x-requires-idempotency-key":true}},"/v1/invitations/accept":{"post":{"description":"**Authorization:** requires `identity:write`.","operationId":"tenancy.invitation.accept","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptInvitationRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:write"]}],"summary":"Accept an invitation token and join the target organization.","x-event-on-success":"invitation.accepted","x-required-scopes":["identity:write"],"x-requires-idempotency-key":true}},"/v1/invitations/{invitation_id}":{"delete":{"description":"**Authorization:** requires `tenancy:write`.","operationId":"tenancy.invitation.revoke","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["tenancy:write"]}],"summary":"Revoke a pending invitation.","x-event-on-success":"invitation.revoked","x-required-scopes":["tenancy:write"],"x-requires-idempotency-key":true}},"/v1/keys/{key_id}":{"delete":{"description":"**Authorization:** requires `keys:write`.","operationId":"keys.virtual.revoke","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Revoke a virtual key (immediate, no grace window).","x-event-on-success":"virtual_key.revoked","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true},"get":{"description":"**Authorization:** requires `keys:read`.","operationId":"keys.virtual.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualKeyPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:read"]}],"summary":"Get a virtual key's metadata (no token returned).","x-required-scopes":["keys:read"]},"patch":{"description":"**Authorization:** requires `keys:write`.","operationId":"keys.virtual.update","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVirtualKeyRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualKeyPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Update a virtual key (name, scopes-reduction, rate limit, expiry).","x-event-on-success":"virtual_key.updated","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true}},"/v1/keys/{key_id}/rotate":{"post":{"description":"**Authorization:** requires `keys:write`.","operationId":"keys.virtual.rotate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateKeyRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotatedVirtualKey"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Rotate a virtual key, optionally with a grace window.","x-event-on-success":"virtual_key.rotated","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true}},"/v1/launch-estimate":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"compute_catalog.launch_estimate","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"What one launch would cost and how long it has taken before. Requires `blueprint`, `provider` and `gpu_sku` query parameters; `region` is optional. Answers `{blueprint, provider, gpu_sku, region, compatible, incompatible_reason, hourly_cents, cold_start}`. An unrunnable pairing answers 200 with `compatible: false` and a reason rather than an error, because a rejected option is a valid answer when comparing choices. `cold_start` is `{sample_count, median_secs, fastest_secs, slowest_secs}` computed from this platform's own completed launches, and is absent when none has completed — there is no modelled estimate, only measurements.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"Hourly cost and measured cold-start for a Blueprint on a given GPU.","x-required-scopes":["catalog:read"]}},"/v1/me":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"identity.me.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"Return the authenticated user.","x-required-scopes":["identity:read"]}},"/v1/me/mfa/recovery-codes/generate":{"post":{"description":"**Authorization:** requires `identity:write`.","operationId":"identity.me.mfa.recovery.generate","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoveryCodesResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:write"]}],"summary":"Generate one-time recovery codes for MFA fallback.","x-event-on-success":"user.mfa_recovery_generated","x-required-scopes":["identity:write"],"x-requires-idempotency-key":true}},"/v1/me/mfa/totp/confirm":{"post":{"description":"**Authorization:** requires `identity:write`.","operationId":"identity.me.mfa.totp.confirm","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotpConfirmRequest"}}},"required":true},"responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:write"]}],"summary":"Confirm TOTP enrollment by submitting a current code.","x-event-on-success":"user.mfa_totp_confirmed","x-required-scopes":["identity:write"],"x-requires-idempotency-key":true}},"/v1/me/mfa/totp/enroll":{"post":{"description":"**Authorization:** requires `identity:write`.","operationId":"identity.me.mfa.totp.enroll","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotpEnrollmentResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:write"]}],"summary":"Begin TOTP enrollment; returns the shared secret and provisioning URI.","x-event-on-success":"user.mfa_totp_enrolled","x-required-scopes":["identity:write"],"x-requires-idempotency-key":true}},"/v1/me/organizations":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"tenancy.organization.list_mine","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/MyOrganizationEntry"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"List organizations the authenticated user belongs to.","x-required-scopes":["identity:read"]}},"/v1/me/password":{"post":{"description":"**Authorization:** requires `identity:write`.","operationId":"identity.me.password.change","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:write"]}],"summary":"Change the authenticated user's password.","x-event-on-success":"user.password_changed","x-required-scopes":["identity:write"],"x-requires-idempotency-key":true}},"/v1/me/sessions":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"identity.me.sessions.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SessionPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"List the authenticated user's active sessions.","x-required-scopes":["identity:read"]}},"/v1/me/sessions/revoke-others":{"post":{"description":"**Authorization:** requires `identity:write`.","operationId":"identity.me.sessions.revoke_others","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokedSessions"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:write"]}],"summary":"Revoke every active session except the current one.","x-event-on-success":"user.logged_out_other_devices","x-required-scopes":["identity:write"],"x-requires-idempotency-key":true}},"/v1/models":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"openai_compat.models.list","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAiModelList"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"OpenAI-compatible model list — drop-in for OpenAI SDK clients.","x-required-scopes":["catalog:read"]},"post":{"description":"**Authorization:** requires `catalog:read` and `catalog:write`.","operationId":"catalog.models.register","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterModelRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisteredModel"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read","catalog:write"]}],"summary":"Register a model your project can call, served by a named provider.","x-event-on-success":"model.promoted","x-required-scopes":["catalog:read","catalog:write"],"x-requires-idempotency-key":true}},"/v1/models/{id}":{"delete":{"description":"**Authorization:** requires `catalog:read` and `catalog:write`.","operationId":"catalog.models.deregister","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read","catalog:write"]}],"summary":"Stop serving a model you registered; platform models are unaffected.","x-required-scopes":["catalog:read","catalog:write"],"x-requires-idempotency-key":true},"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"openai_compat.models.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAiModel"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"OpenAI-compatible model retrieve — one callable model by name.","x-required-scopes":["catalog:read"]}},"/v1/models/{id}/capabilities":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"openai_compat.models.capabilities","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Per-wire capability declaration for a model — the same truths the router refuses on. Shape is `{model, provider, wire_family, capabilities: {<axis>: bool}}`; the axis set is owned by the model-registry crate and is not described here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"Per-wire capability declaration for a model — the same truths the router refuses on.","x-required-scopes":["catalog:read"]}},"/v1/models/{id}/health":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"openai_compat.models.health","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelHealth"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"What this model's serving lane did last: healthy, degraded, dead or unknown, with the evidence.","x-required-scopes":["catalog:read"]}},"/v1/moderations":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.moderations","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI-compatible content moderation. Flat per-call rate.","x-required-scopes":["inference:call"]}},"/v1/notifications/subscriptions":{"get":{"description":"**Authorization:** requires `webhooks:read`.","operationId":"notifications.subscriptions.list_mine","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Subscription"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:read"]}],"summary":"List your own notification subscriptions.","x-required-scopes":["webhooks:read"]}},"/v1/openapi.json":{"get":{"description":"**Authorization:** none — this route is callable anonymously.","operationId":"openapi.get","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"This document. An OpenAPI 3.1 object.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"summary":"Get the OpenAPI 3.1 spec describing every Surface::Public route.","x-required-scopes":[]}},"/v1/organizations/{organization_id}":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"tenancy.organization.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"Get an organization by id.","x-required-scopes":["identity:read"]}},"/v1/organizations/{organization_id}/invitations":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"tenancy.invitation.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/InvitationPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"List pending invitations for an organization.","x-required-scopes":["identity:read"]},"post":{"description":"**Authorization:** requires `tenancy:write`.","operationId":"tenancy.invitation.create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvitationRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["tenancy:write"]}],"summary":"Invite an email address to join the organization.","x-event-on-success":"invitation.sent","x-required-scopes":["tenancy:write"],"x-requires-idempotency-key":true}},"/v1/organizations/{organization_id}/members":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"tenancy.members.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/MembershipPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"List members of an organization.","x-required-scopes":["identity:read"]}},"/v1/organizations/{organization_id}/members/{user_id}":{"delete":{"description":"**Authorization:** requires `tenancy:write`.","operationId":"tenancy.members.remove","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["tenancy:write"]}],"summary":"Remove a member from the organization.","x-event-on-success":"member.removed","x-required-scopes":["tenancy:write"],"x-requires-idempotency-key":true},"put":{"description":"**Authorization:** requires `tenancy:write`.","operationId":"tenancy.members.update_role","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMemberRoleRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["tenancy:write"]}],"summary":"Change a member's role in the organization.","x-event-on-success":"member.role_updated","x-required-scopes":["tenancy:write"],"x-requires-idempotency-key":true}},"/v1/organizations/{organization_id}/projects":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"tenancy.project.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ProjectPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"List projects within an organization.","x-required-scopes":["identity:read"]},"post":{"description":"**Authorization:** requires `tenancy:write`.","operationId":"tenancy.project.create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["tenancy:write"]}],"summary":"Create a project within an organization.","x-event-on-success":"project.created","x-required-scopes":["tenancy:write"],"x-requires-idempotency-key":true}},"/v1/organizations/{organization_id}/service-accounts":{"get":{"description":"**Authorization:** requires `keys:read`.","operationId":"keys.service_account.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ServiceAccountPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:read"]}],"summary":"List service accounts in a organization.","x-required-scopes":["keys:read"]},"post":{"description":"**Authorization:** requires `keys:write`.","operationId":"keys.service_account.create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceAccountRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceAccountPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Create a service account (a non-human principal that owns keys).","x-event-on-success":"service_account.created","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true}},"/v1/projects/{project_id}":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"tenancy.project.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"Get a project by id.","x-required-scopes":["identity:read"]}},"/v1/projects/{project_id}/keys":{"get":{"description":"**Authorization:** requires `keys:read`.","operationId":"keys.virtual.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/VirtualKeyPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:read"]}],"summary":"List virtual keys for a project.","x-required-scopes":["keys:read"]},"post":{"description":"**Authorization:** requires `keys:write`.","operationId":"keys.virtual.create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVirtualKeyRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MintedVirtualKey"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Mint a new virtual API key in a project.","x-event-on-success":"virtual_key.created","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true}},"/v1/projects/{project_id}/webhooks":{"get":{"description":"**Authorization:** requires `webhooks:read`.","operationId":"webhooks.subscription.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SubscriptionPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:read"]}],"summary":"List webhook subscriptions in a project.","x-required-scopes":["webhooks:read"]},"post":{"description":"**Authorization:** requires `webhooks:write`.","operationId":"webhooks.subscription.create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:write"]}],"summary":"Create an outbound webhook subscription in a project.","x-required-scopes":["webhooks:write"],"x-requires-idempotency-key":true}},"/v1/providers":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"catalog.providers.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ProviderSummary"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"List providers you can register a model against.","x-required-scopes":["catalog:read"]}},"/v1/quotas":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"quotas.get_mine","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaDigest"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"Read your own quota usage and ceilings.","x-required-scopes":["billing:read"]}},"/v1/registrations":{"get":{"description":"**Authorization:** requires `catalog:read`.","operationId":"catalog.registrations.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/RegisteredModel"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["catalog:read"]}],"summary":"List the models you registered, as opposed to the platform catalog.","x-required-scopes":["catalog:read"]}},"/v1/rerank":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.rerank","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Relays the OpenAI wire format verbatim to the router, which owns the request contract. Send exactly what you would send to `api.openai.com`; the gateway parses only `model` (to resolve the binding) and `stream`. See the OpenAI API reference for the body and response shapes.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"Rerank documents against a query. Bills in search units.","x-required-scopes":["inference:call"]}},"/v1/responses":{"post":{"description":"**Authorization:** requires `inference:call`.","operationId":"openai_compat.responses","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"The OpenAI Responses API, relayed verbatim to the model's upstream. Body and reply are OpenAI's `responses` grammar (input items, `instructions`, function tools, `reasoning`, `previous_response_id`, `max_output_tokens`, `stream`); `model` is any bound chat model whose provider serves `/v1/responses` — OpenAI proper by default, or any provider row with `responses: true`. A model on a provider that does not is refused as `request.unsupported_parameter` on `model`, naming `/v1/chat/completions` as the alternative. `stream: true` returns `text/event-stream` in the Responses event vocabulary (each event named by its `type`, ending at `response.completed`; no `[DONE]` sentinel). Billed from `usage.input_tokens` / `usage.output_tokens` (output includes reasoning) at the model's chat rates; a buffered call carries `x-nozzle-cost-micro-cents`, a streamed one reconciles by `x-request-id` against `GET /v1/billing/costs` with kind `inference.responses`.","required":true,"x-nozzle-undescribed":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"The OpenAI Responses API, relayed verbatim to the model's upstream. Body and reply are OpenAI's `responses` grammar (input items, `instructions`, function tools, `reasoning`, `previous_response_id`, `max_output_tokens`, `stream`); `model` is any bound chat model whose provider serves `/v1/responses` — OpenAI proper by default, or any provider row with `responses: true`. A model on a provider that does not is refused as `request.unsupported_parameter` on `model`, naming `/v1/chat/completions` as the alternative. `stream: true` returns `text/event-stream` in the Responses event vocabulary (each event named by its `type`, ending at `response.completed`; no `[DONE]` sentinel). Billed from `usage.input_tokens` / `usage.output_tokens` (output includes reasoning) at the model's chat rates; a buffered call carries `x-nozzle-cost-micro-cents`, a streamed one reconciles by `x-request-id` against `GET /v1/billing/costs` with kind `inference.responses`.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["inference:call"]}],"summary":"OpenAI Responses API — reasoning items and function tools together, streamed as Responses events, billed like chat.","x-required-scopes":["inference:call"]}},"/v1/service-accounts/{service_account_id}":{"delete":{"description":"**Authorization:** requires `keys:write`.","operationId":"keys.service_account.disable","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:write"]}],"summary":"Disable a service account (keys it owns keep their attribution).","x-event-on-success":"service_account.disabled","x-required-scopes":["keys:write"],"x-requires-idempotency-key":true},"get":{"description":"**Authorization:** requires `keys:read`.","operationId":"keys.service_account.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceAccountPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["keys:read"]}],"summary":"Get a service account.","x-required-scopes":["keys:read"]}},"/v1/tenants":{"post":{"description":"**Authorization:** requires `tenancy:write`.","operationId":"tenancy.tenant.bootstrap","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapTenantRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapTenantResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["tenancy:write"]}],"summary":"Create a tenant with its first organization and project, owned by you.","x-event-on-success":"organization.created","x-required-scopes":["tenancy:write"],"x-requires-idempotency-key":true}},"/v1/tenants/{tenant_id}":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"tenancy.tenant.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"Get a tenant by id.","x-required-scopes":["identity:read"]}},"/v1/tenants/{tenant_id}/analytics/cost":{"get":{"description":"**Authorization:** requires `usage:read`.","operationId":"analytics.cost.daily","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"One row per UTC day, newest first, capped at 400 days: `{day, inference_cents, instance_cents, training_cents, margin_cents}`. Read from the pre-materialized rollup, so the most recent day trails live spend by up to one scheduler tick — use `GET /v1/tenants/{tenant_id}/usage` for up-to-the-second totals. Optional `from` / `to` are inclusive `YYYY-MM-DD` bounds. The shape is owned by analytics-service and is not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["usage:read"]}],"summary":"Daily cost breakdown (inference / instance / training) for a tenant.","x-required-scopes":["usage:read"]}},"/v1/tenants/{tenant_id}/analytics/instances":{"get":{"description":"**Authorization:** requires `usage:read`.","operationId":"analytics.instances.lifetime","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"One row per compute Instance, newest first: `{instance_id, blueprint_name, provider, gpu_sku, started_at, stopped_at, total_seconds, total_cents, total_tokens_in, total_tokens_out}`. `stopped_at` and `total_seconds` are null while an Instance is still running. Optional `limit` (1-1000, default 100). The shape is owned by analytics-service and is not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["usage:read"]}],"summary":"Per-Instance lifetime and spend for a tenant.","x-required-scopes":["usage:read"]}},"/v1/tenants/{tenant_id}/analytics/margin":{"get":{"description":"**Authorization:** requires `usage:read`.","operationId":"analytics.margin.daily","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"`{days: [{day, inference_cents, instance_cents, margin_cents}], total_inference_cents, total_instance_cents, total_margin_cents, markup_note}`. Margin is inference spend minus compute spend; at today's 0% markup that is a cost-versus-cost comparison, not profit, and `markup_note` says so on every response. Negative totals are the honest answer on days a GPU sat idle. The shape is owned by analytics-service and is not re-declared here.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["usage:read"]}],"summary":"Daily inference-versus-compute margin series for a tenant.","x-required-scopes":["usage:read"]}},"/v1/tenants/{tenant_id}/audit":{"get":{"description":"**Authorization:** requires `audit:read`.","operationId":"audit.tenant.list","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageOfAuditEntryPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["audit:read"]}],"summary":"List audit entries for a tenant (cursor-paginated).","x-required-scopes":["audit:read"]}},"/v1/tenants/{tenant_id}/audit/export":{"get":{"description":"**Authorization:** requires `admin:audit:export`.","operationId":"audit.tenant.export","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Streams the tenant's audit log as newline-delimited JSON; each line is an AuditEntry. Not a single JSON document.","x-nozzle-undescribed":true},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["admin:audit:export"]}],"summary":"Stream a tenant's audit log as CSV (capped at 10k rows).","x-required-scopes":["admin:audit:export"]}},"/v1/tenants/{tenant_id}/billing/balance":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"billing.credits.balance","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditBalance"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"Current credit balance for the tenant.","x-required-scopes":["billing:read"]}},"/v1/tenants/{tenant_id}/billing/checkout":{"post":{"description":"**Authorization:** requires `billing:write`.","operationId":"billing.checkout.open","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:write"]}],"summary":"Open a Stripe Checkout session for a plan.","x-required-scopes":["billing:write"],"x-requires-idempotency-key":true}},"/v1/tenants/{tenant_id}/billing/costs":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"billing.costs.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CostEntryPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"Recent cost-ledger entries for the tenant.","x-required-scopes":["billing:read"]}},"/v1/tenants/{tenant_id}/billing/credits":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"billing.credits.list","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageOfCreditEntryPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"Paginated credits ledger for the tenant.","x-required-scopes":["billing:read"]}},"/v1/tenants/{tenant_id}/billing/entitlement":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"billing.entitlement.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementView"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"Get the tenant's active entitlement (plan + overrides).","x-required-scopes":["billing:read"]}},"/v1/tenants/{tenant_id}/billing/entitlement/change-plan":{"post":{"description":"**Authorization:** requires `billing:write`.","operationId":"billing.entitlement.change_plan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePlanRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementView"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:write"]}],"summary":"Switch the tenant to a different plan.","x-required-scopes":["billing:write"],"x-requires-idempotency-key":true}},"/v1/tenants/{tenant_id}/billing/portal":{"post":{"description":"**Authorization:** requires `billing:write`.","operationId":"billing.portal.link","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:write"]}],"summary":"Mint a Stripe Customer Portal session URL.","x-required-scopes":["billing:write"],"x-requires-idempotency-key":true}},"/v1/tenants/{tenant_id}/notifications/subscriptions":{"get":{"description":"**Authorization:** requires `webhooks:read`.","operationId":"notifications.subscriptions.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Subscription"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:read"]}],"summary":"List the tenant's notification subscriptions.","x-required-scopes":["webhooks:read"]},"post":{"description":"**Authorization:** requires `webhooks:write`.","operationId":"notifications.subscriptions.create","responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:write"]}],"summary":"Create a notification subscription (channel + event_type).","x-required-scopes":["webhooks:write"],"x-requires-idempotency-key":true}},"/v1/tenants/{tenant_id}/notifications/subscriptions/{id}":{"delete":{"description":"**Authorization:** requires `webhooks:write`.","operationId":"notifications.subscriptions.delete","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:write"]}],"summary":"Delete a notification subscription.","x-required-scopes":["webhooks:write"],"x-requires-idempotency-key":true}},"/v1/tenants/{tenant_id}/organizations":{"get":{"description":"**Authorization:** requires `identity:read`.","operationId":"tenancy.organization.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/OrganizationPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["identity:read"]}],"summary":"List organizations within a tenant.","x-required-scopes":["identity:read"]},"post":{"description":"**Authorization:** requires `tenancy:write`.","operationId":"tenancy.organization.create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["tenancy:write"]}],"summary":"Create an organization within a tenant.","x-event-on-success":"organization.created","x-required-scopes":["tenancy:write"],"x-requires-idempotency-key":true}},"/v1/tenants/{tenant_id}/quotas":{"get":{"description":"**Authorization:** requires `billing:read`.","operationId":"quotas.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaDigest"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["billing:read"]}],"summary":"Read the tenant's current quota usage and ceilings.","x-required-scopes":["billing:read"]}},"/v1/tenants/{tenant_id}/usage":{"get":{"description":"**Authorization:** requires `usage:read`.","operationId":"tenancy.tenant.usage","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantUsageResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["usage:read"]}],"summary":"Get a tenant's cost rollup over 24h / 7d / 30d / all-time, plus per-kind breakdown.","x-required-scopes":["usage:read"]}},"/v1/usage":{"get":{"description":"**Authorization:** requires `usage:read`.","operationId":"tenancy.usage.get_mine","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantUsageResponse"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["usage:read"]}],"summary":"Read your own usage rollup.","x-required-scopes":["usage:read"]}},"/v1/webhooks/deliveries/{delivery_id}/replay":{"post":{"description":"**Authorization:** requires `webhooks:write`.","operationId":"webhooks.deliveries.replay","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:write"]}],"summary":"Replay a past delivery (creates a fresh delivery).","x-required-scopes":["webhooks:write"],"x-requires-idempotency-key":true}},"/v1/webhooks/event-types":{"get":{"description":"**Authorization:** requires `webhooks:read`.","operationId":"webhooks.event_types.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/EventTypeInfo"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:read"]}],"summary":"List the customer-subscribable webhook event types.","x-required-scopes":["webhooks:read"]}},"/v1/webhooks/{webhook_id}":{"delete":{"description":"**Authorization:** requires `webhooks:write`.","operationId":"webhooks.subscription.delete","responses":{"204":{"description":"Success. No response body."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:write"]}],"summary":"Delete a webhook subscription.","x-required-scopes":["webhooks:write"],"x-requires-idempotency-key":true},"get":{"description":"**Authorization:** requires `webhooks:read`.","operationId":"webhooks.subscription.get","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:read"]}],"summary":"Get a webhook subscription (no signing secret).","x-required-scopes":["webhooks:read"]},"patch":{"description":"**Authorization:** requires `webhooks:write`.","operationId":"webhooks.subscription.update","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSubscriptionRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPublic"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:write"]}],"summary":"Update a webhook subscription (url, events, active).","x-required-scopes":["webhooks:write"],"x-requires-idempotency-key":true}},"/v1/webhooks/{webhook_id}/deliveries":{"get":{"description":"**Authorization:** requires `webhooks:read`.","operationId":"webhooks.deliveries.list","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/DeliveryPublic"},"type":"array"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:read"]}],"summary":"List recent delivery attempts for a subscription.","x-required-scopes":["webhooks:read"]}},"/v1/webhooks/{webhook_id}/rotate-secret":{"post":{"description":"**Authorization:** requires `webhooks:write`.","operationId":"webhooks.subscription.rotate_secret","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotatedSecret"}}},"description":"Success."},"4XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."},"5XX":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Error. See `error.code` for the machine-readable reason."}},"security":[{"VirtualKeyBearer":["webhooks:write"]}],"summary":"Rotate a subscription's signing secret.","x-required-scopes":["webhooks:write"],"x-requires-idempotency-key":true}}},"security":[{"VirtualKeyBearer":[]},{"SessionJwtBearer":[]}],"servers":[{"description":"Production — tenant traffic, TLS","url":"https://api.opennozzle.com"},{"description":"Operator surface only (/internal/v1), HTTP, not for tenant traffic","url":"http://api.49-12-240-8.traefik.me"}]}