diff --git a/docs-site/README.md b/docs-site/README.md
new file mode 100644
index 00000000..3b099cb2
--- /dev/null
+++ b/docs-site/README.md
@@ -0,0 +1,64 @@
+# IdentArk Docs (Mintlify)
+
+Public documentation and API reference for the IdentArk control plane.
+
+## Structure
+
+```
+docs-site/
+├── docs.json # Mintlify config (nav, theme, tabs)
+├── introduction.mdx # Landing
+├── quickstart.mdx
+├── concepts.mdx
+├── authentication.mdx
+├── sdks/{python,typescript}.mdx
+├── guides/ # production, mcp-hitl, acs, limits-and-errors, security
+├── api-reference/
+│ ├── introduction.mdx
+│ └── openapi.json # Generated from the FastAPI app — see below
+└── images/ # logo + favicon
+```
+
+## Develop locally
+
+```bash
+npm i -g mint # Mintlify CLI
+cd docs-site
+mint dev # http://localhost:3000
+```
+
+The **API Reference → Endpoints** group is auto-generated from
+`api-reference/openapi.json`; no per-endpoint MDX to maintain.
+
+## Regenerate the OpenAPI spec
+
+The spec is the FastAPI app's own schema, post-processed to add the production server
+and a bearer-auth scheme. From the repo root:
+
+```bash
+cloud/.venv/bin/python - <<'PY'
+import os, json
+os.environ.setdefault("DATABASE_URL", "postgresql+asyncpg://u:p@localhost/db")
+os.environ.setdefault("REDIS_URL", "redis://localhost:6379/0")
+os.environ.setdefault("SECRET_KEY", "dev-secret")
+os.environ.setdefault("FIREBASE_API_KEY", "x")
+import sys; sys.path.insert(0, "cloud")
+from app.main import app
+spec = app.openapi()
+spec["servers"] = [{"url": "https://api.identark.io", "description": "Production"}]
+spec["components"].setdefault("securitySchemes", {})["bearerAuth"] = {
+ "type": "http", "scheme": "bearer",
+}
+spec["security"] = [{"bearerAuth": []}]
+json.dump(spec, open("docs-site/api-reference/openapi.json", "w"), indent=2)
+print("paths:", len(spec["paths"]))
+PY
+```
+
+> Keep `docs.json`'s navigation in sync only when you add new **guide** pages —
+> endpoint pages come from the spec automatically.
+
+## Deploy
+
+Connect this repo to Mintlify (mintlify.com) and set the docs root to `docs-site/`.
+Pushes to the default branch publish automatically.
diff --git a/docs-site/api-reference/introduction.mdx b/docs-site/api-reference/introduction.mdx
new file mode 100644
index 00000000..f95f847e
--- /dev/null
+++ b/docs-site/api-reference/introduction.mdx
@@ -0,0 +1,73 @@
+---
+title: "API reference"
+description: "Every /v1 endpoint on the IdentArk control plane."
+---
+
+The reference in this section is generated from the control plane's OpenAPI schema —
+each endpoint has a live request builder and real response shapes. This page covers the
+conventions that apply across all of them.
+
+## Base URL
+
+
+```text Production
+https://api.identark.io
+```
+
+```text Local
+http://localhost:8000
+```
+
+
+All application endpoints are versioned under `/v1`. `GET /health` (unversioned) is a
+liveness probe.
+
+## Authentication
+
+Send a scoped `csk_` key as a bearer token on every request:
+
+```http
+Authorization: Bearer csk_…
+```
+
+The required scope is listed on each endpoint. `org:admin` covers all of them. See
+[Authentication & scopes](/authentication) for the full model. A handful of
+endpoints are public: `POST /v1/orgs/signup`, `POST /v1/auth/signup`,
+`POST /v1/auth/login`, `GET /v1/config/public`, and `GET /health`.
+
+## Conventions
+
+
+
+ Request and response bodies are JSON. Send `Content-Type: application/json`.
+
+
+ ISO 8601 strings, UTC (e.g. `2026-08-13T09:00:00Z`).
+
+
+ Opaque strings. Don't parse them; store and echo them back.
+
+
+ JSON with a stable `error_code` and human `message`. See
+ Limits & errors.
+
+
+
+## The endpoints you'll use most
+
+
+
+ Mint a scoped API key.
+
+
+ Store a provider secret, get a `credential_ref`.
+
+
+ Open a bounded, cost-capped session.
+
+
+ Run a governed completion.
+
+
+
+Browse the full surface in the **Endpoints** group in the sidebar.
diff --git a/docs-site/api-reference/openapi.json b/docs-site/api-reference/openapi.json
new file mode 100644
index 00000000..13e07ca2
--- /dev/null
+++ b/docs-site/api-reference/openapi.json
@@ -0,0 +1,11774 @@
+{
+ "openapi": "3.1.0",
+ "info": {
+ "title": "IdentArk Control Plane API",
+ "description": "The IdentArk control plane REST API. Capabilities, not credentials \u2014 authenticate with a `csk_` bearer key whose scopes gate every route.",
+ "version": "0.1.0"
+ },
+ "paths": {
+ "/v1/regions": {
+ "get": {
+ "tags": [
+ "regions"
+ ],
+ "summary": "List Regions",
+ "description": "List all available IdentArk regions.\n\nThis is a public endpoint \u2014 no authentication required.\nResults are cacheable for 1 hour.",
+ "operationId": "list_regions_v1_regions_get",
+ "responses": {
+ "200": {
+ "description": "List of available regions",
+ "headers": {
+ "Cache-Control": {
+ "description": "Caching directive",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RegionsResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/auth/signup": {
+ "post": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Signup",
+ "description": "Register a new user account using Firebase Auth.",
+ "operationId": "signup_v1_auth_signup_post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/app__routers__auth__SignupRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AuthResponse"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ },
+ "security": []
+ }
+ },
+ "/v1/auth/login": {
+ "post": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Login",
+ "description": "Log in using Firebase Auth ID token.",
+ "operationId": "login_v1_auth_login_post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LoginRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AuthResponse"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ },
+ "security": []
+ }
+ },
+ "/v1/auth/logout": {
+ "post": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Logout",
+ "description": "Log out and clear auth cookie.",
+ "operationId": "logout_v1_auth_logout_post",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MessageResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/auth/me": {
+ "get": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Get Me",
+ "description": "Return the currently authenticated user and their organisation.",
+ "operationId": "get_me_v1_auth_me_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/auth/mfa/setup": {
+ "get": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Get Mfa Setup",
+ "description": "Get or generate MFA TOTP secret for the current user.\n\nReturns the TOTP secret and a provisioning URI for QR code generation.\nIf the user does not have an MFA secret, one is auto-generated.",
+ "operationId": "get_mfa_setup_v1_auth_mfa_setup_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MFAResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/auth/mfa/verify": {
+ "post": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Verify Mfa Token",
+ "description": "Verify an MFA TOTP token and enable MFA for the user.",
+ "operationId": "verify_mfa_token_v1_auth_mfa_verify_post",
+ "parameters": [
+ {
+ "name": "token",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Token"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "title": "Response Verify Mfa Token V1 Auth Mfa Verify Post"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/auth/device/code": {
+ "post": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Request Device Code",
+ "description": "Request a device code for CLI authentication.\n\nImplements RFC 8628 Device Authorization Grant.\nReturns device_code (for polling) and user_code (for user to enter).",
+ "operationId": "request_device_code_v1_auth_device_code_post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeviceCodeRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeviceCodeResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/auth/device/token": {
+ "post": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Request Device Token",
+ "description": "Exchange device code for Firebase custom token.\n\nCLI polls this endpoint until user completes authorization.",
+ "operationId": "request_device_token_v1_auth_device_token_post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeviceTokenRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeviceTokenResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/auth/device/authorize": {
+ "post": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Authorize Device",
+ "description": "Authorize a device (called by web UI after user enters user_code)",
+ "operationId": "authorize_device_v1_auth_device_authorize_post",
+ "parameters": [
+ {
+ "name": "user_code",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "User Code"
+ }
+ },
+ {
+ "name": "firebase_uid",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Firebase Uid"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Authorize Device V1 Auth Device Authorize Post"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/auth/device/deny": {
+ "post": {
+ "tags": [
+ "auth"
+ ],
+ "summary": "Deny Device",
+ "description": "Deny a device authorization request.",
+ "operationId": "deny_device_v1_auth_device_deny_post",
+ "parameters": [
+ {
+ "name": "user_code",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "User Code"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Deny Device V1 Auth Device Deny Post"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/config/public": {
+ "get": {
+ "tags": [
+ "config"
+ ],
+ "summary": "Get Public Config",
+ "description": "Return public client configuration.\n\nThis endpoint is unauthenticated and provides the Firebase configuration\nneeded by CLI clients to exchange custom tokens for ID tokens.",
+ "operationId": "get_public_config_v1_config_public_get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PublicConfigResponse"
+ }
+ }
+ }
+ }
+ },
+ "security": []
+ }
+ },
+ "/v1/newsletter": {
+ "post": {
+ "tags": [
+ "newsletter"
+ ],
+ "summary": "Subscribe",
+ "description": "Start a double opt-in subscription.\n\nAlways returns 202 with the same message. Nothing is sent to the address\nbeyond the single confirmation email, and nothing reaches the Resend\naudience until the recipient confirms.",
+ "operationId": "subscribe_v1_newsletter_post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SubscribeRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "202": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SubscribeResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/newsletter/confirm": {
+ "get": {
+ "tags": [
+ "newsletter"
+ ],
+ "summary": "Confirm",
+ "description": "Complete the double opt-in and sync the address into the Resend audience.",
+ "operationId": "confirm_v1_newsletter_confirm_get",
+ "parameters": [
+ {
+ "name": "token",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 128,
+ "title": "Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/newsletter/unsubscribe": {
+ "get": {
+ "tags": [
+ "newsletter"
+ ],
+ "summary": "Unsubscribe",
+ "description": "Withdraw consent.\n\nResend's own footer link is what stops delivery of a broadcast; this exists\nso the withdrawal is also recorded here, where the consent was recorded.",
+ "operationId": "unsubscribe_v1_newsletter_unsubscribe_get",
+ "parameters": [
+ {
+ "name": "token",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 128,
+ "title": "Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/orgs/signup": {
+ "post": {
+ "tags": [
+ "orgs"
+ ],
+ "summary": "Signup",
+ "description": "Create a new organisation and return an API key.\n\nThe API key is shown exactly once. Store it securely.",
+ "operationId": "signup_v1_orgs_signup_post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/app__routers__orgs__SignupRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SignupResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ },
+ "security": []
+ }
+ },
+ "/v1/orgs/set-region": {
+ "post": {
+ "tags": [
+ "orgs"
+ ],
+ "summary": "Set Region",
+ "description": "Set the organisation's region during onboarding.\nOnly allowed if onboarding is not yet completed.",
+ "operationId": "set_region_v1_orgs_set_region_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SetRegionRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Set Region V1 Orgs Set Region Post"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/orgs/regions": {
+ "get": {
+ "tags": [
+ "orgs"
+ ],
+ "summary": "Get Regions",
+ "description": "Get organisation's region configuration.",
+ "operationId": "get_regions_v1_orgs_regions_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/OrgRegionsResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/orgs/info": {
+ "get": {
+ "tags": [
+ "orgs"
+ ],
+ "summary": "Get Org Info",
+ "description": "Get current organisation info.",
+ "operationId": "get_org_info_v1_orgs_info_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/OrgInfoResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/org/export": {
+ "get": {
+ "tags": [
+ "org"
+ ],
+ "summary": "Export Org Data",
+ "description": "Export this organisation's portable data as JSON.\n\nRequires org admin/owner. The export itself is written to the audit log\n(a data export is a security-relevant event).",
+ "operationId": "export_org_data_v1_org_export_get",
+ "parameters": [
+ {
+ "name": "audit_limit",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 10000,
+ "title": "Audit Limit"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Export Org Data V1 Org Export Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/settings": {
+ "get": {
+ "tags": [
+ "settings"
+ ],
+ "summary": "Get Settings",
+ "description": "Return the current organisation's settings.",
+ "operationId": "get_settings_v1_settings_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/OrgSettings"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "settings"
+ ],
+ "summary": "Update Settings",
+ "description": "Update organisation settings.\n\nOnly `name` and `overage_enabled` can be changed here.\nPlan, regions, and subscription status are managed separately.",
+ "operationId": "update_settings_v1_settings_patch",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateSettingsRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/OrgSettings"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/settings/security": {
+ "get": {
+ "tags": [
+ "settings"
+ ],
+ "summary": "Get Security Settings",
+ "operationId": "get_security_settings_v1_settings_security_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SecuritySettingsResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "settings"
+ ],
+ "summary": "Update Security Settings",
+ "description": "Merge security setting keys. Owner/admin only; audit-logged.",
+ "operationId": "update_security_settings_v1_settings_security_patch",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SecuritySettingsUpdate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SecuritySettingsResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/settings/rate-limits": {
+ "get": {
+ "tags": [
+ "settings"
+ ],
+ "summary": "Get Rate Limits",
+ "operationId": "get_rate_limits_v1_settings_rate_limits_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RateLimitsResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "settings"
+ ],
+ "summary": "Update Rate Limits",
+ "description": "Set per-endpoint rate limit overrides. Owner/admin only; audit-logged.",
+ "operationId": "update_rate_limits_v1_settings_rate_limits_put",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RateLimitsUpdate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RateLimitsResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/billing": {
+ "get": {
+ "tags": [
+ "billing"
+ ],
+ "summary": "Get Billing",
+ "description": "Return billing information and plan details for the organisation.",
+ "operationId": "get_billing_v1_billing_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BillingInfo"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/usage": {
+ "get": {
+ "tags": [
+ "billing"
+ ],
+ "summary": "Get Usage",
+ "description": "Return usage statistics for the current billing cycle.",
+ "operationId": "get_usage_v1_usage_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UsageStats"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/billing/checkout": {
+ "post": {
+ "tags": [
+ "billing"
+ ],
+ "summary": "Create Checkout",
+ "description": "Create a Stripe Checkout Session for subscription.\n\nReturns a checkout URL that the client should redirect the user to.\nThe user will complete payment on Stripe's hosted checkout page.",
+ "operationId": "create_checkout_v1_billing_checkout_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CheckoutSessionRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CheckoutSessionResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/billing/portal": {
+ "post": {
+ "tags": [
+ "billing"
+ ],
+ "summary": "Create Portal",
+ "description": "Create a Stripe Customer Portal session.\n\nReturns a portal URL that the client should redirect the user to.\nThe user can manage their subscription, payment methods, and invoices.",
+ "operationId": "create_portal_v1_billing_portal_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PortalSessionRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PortalSessionResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/team/members": {
+ "get": {
+ "tags": [
+ "team"
+ ],
+ "summary": "List Members",
+ "description": "List all members of the current user's organisation.",
+ "operationId": "list_members_v1_team_members_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/TeamListResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "team"
+ ],
+ "summary": "Invite Member Legacy",
+ "description": "Deprecated alias for creating a team invitation.\n\nPrefer ``POST /v1/team/invites``. This endpoint is kept so existing dashboard\nclients continue to work during the cutover.",
+ "operationId": "invite_member_legacy_v1_team_members_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateInviteRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InviteResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/team/members/{user_id}": {
+ "patch": {
+ "tags": [
+ "team"
+ ],
+ "summary": "Update Member",
+ "description": "Change a team member's role.\n\nAccepts the same roles as an invite (``admin``/``member``). Ownership is not\ntransferable here: an owner is the account that provisioned the workspace,\nso neither promoting someone to owner nor demoting the existing one is\nallowed \u2014 that would leave the org with no owner or two.",
+ "operationId": "update_member_v1_team_members__user_id__patch",
+ "parameters": [
+ {
+ "name": "user_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "User Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateMemberRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/TeamMember"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "team"
+ ],
+ "summary": "Remove Member",
+ "description": "Remove a team member from the organisation.\n\nSets `is_active=False` \u2014 a soft delete that preserves audit history.\nOwners cannot remove themselves.",
+ "operationId": "remove_member_v1_team_members__user_id__delete",
+ "parameters": [
+ {
+ "name": "user_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "User Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/team/invites": {
+ "get": {
+ "tags": [
+ "team"
+ ],
+ "summary": "List Invites",
+ "description": "List pending team invitations for the current organisation.",
+ "operationId": "list_invites_v1_team_invites_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InviteListResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "team"
+ ],
+ "summary": "Create Invite",
+ "description": "Create a new team invitation and send the acceptance email.",
+ "operationId": "create_invite_v1_team_invites_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateInviteRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InviteResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/team/invites/{invite_id}/resend": {
+ "post": {
+ "tags": [
+ "team"
+ ],
+ "summary": "Resend Invite",
+ "description": "Re-send an existing pending invitation with a fresh token and expiry.",
+ "operationId": "resend_invite_v1_team_invites__invite_id__resend_post",
+ "parameters": [
+ {
+ "name": "invite_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Invite Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InviteResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/team/invites/{invite_id}": {
+ "delete": {
+ "tags": [
+ "team"
+ ],
+ "summary": "Cancel Invite",
+ "description": "Cancel a pending team invitation.",
+ "operationId": "cancel_invite_v1_team_invites__invite_id__delete",
+ "parameters": [
+ {
+ "name": "invite_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Invite Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/team/invites/validate": {
+ "get": {
+ "tags": [
+ "team"
+ ],
+ "summary": "Validate Invite",
+ "description": "Public endpoint used by the acceptance page.\n\nReturns org name and invited role so the UI can show context before the user\nsigns in. The token itself grants no access.",
+ "operationId": "validate_invite_v1_team_invites_validate_get",
+ "parameters": [
+ {
+ "name": "token",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "minLength": 1,
+ "title": "Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ValidateInviteResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/team/invites/accept": {
+ "post": {
+ "tags": [
+ "team"
+ ],
+ "summary": "Accept Invite",
+ "description": "Accept an invitation.\n\nThe caller must be authenticated with Firebase and the token must match a\npending invitation. The invitee is moved/created in the invited\norganisation with the invited role and scopes.",
+ "operationId": "accept_invite_v1_team_invites_accept_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AcceptInviteRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AcceptInviteResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/roles": {
+ "get": {
+ "tags": [
+ "roles"
+ ],
+ "summary": "List Roles",
+ "description": "List all custom roles for the caller's organisation.",
+ "operationId": "list_roles_v1_roles_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/RoleResponse"
+ },
+ "title": "Response List Roles V1 Roles Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "roles"
+ ],
+ "summary": "Create Role",
+ "description": "Create a custom role. Owner/admin only.",
+ "operationId": "create_role_v1_roles_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RoleCreate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RoleResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/roles/{role_id}": {
+ "patch": {
+ "tags": [
+ "roles"
+ ],
+ "summary": "Update Role",
+ "description": "Update a custom role. Owner/admin only.",
+ "operationId": "update_role_v1_roles__role_id__patch",
+ "parameters": [
+ {
+ "name": "role_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Role Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RoleUpdate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RoleResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "roles"
+ ],
+ "summary": "Delete Role",
+ "description": "Delete a custom role. Owner/admin only.",
+ "operationId": "delete_role_v1_roles__role_id__delete",
+ "parameters": [
+ {
+ "name": "role_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Role Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/notifications": {
+ "get": {
+ "tags": [
+ "notifications"
+ ],
+ "summary": "List Notifications",
+ "operationId": "list_notifications_v1_notifications_get",
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "maximum": 200,
+ "minimum": 1,
+ "default": 50,
+ "title": "Limit"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/NotificationResponse"
+ },
+ "title": "Response List Notifications V1 Notifications Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/notifications/{notification_id}/read": {
+ "post": {
+ "tags": [
+ "notifications"
+ ],
+ "summary": "Mark Read",
+ "operationId": "mark_read_v1_notifications__notification_id__read_post",
+ "parameters": [
+ {
+ "name": "notification_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Notification Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NotificationResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/notifications/{notification_id}/dismiss": {
+ "post": {
+ "tags": [
+ "notifications"
+ ],
+ "summary": "Dismiss",
+ "operationId": "dismiss_v1_notifications__notification_id__dismiss_post",
+ "parameters": [
+ {
+ "name": "notification_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Notification Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/credentials/resolve": {
+ "get": {
+ "tags": [
+ "credentials"
+ ],
+ "summary": "Resolve Credential",
+ "description": "Resolve a vault reference to actual credential value\n\nUsed by CLI to inject credentials into agent processes.\nPath format: {environment}/{credential_name}\n\nExample: /v1/credentials/resolve?path=prod/openai",
+ "operationId": "resolve_credential_v1_credentials_resolve_get",
+ "parameters": [
+ {
+ "name": "path",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "description": "Vault path (e.g., prod/openai)",
+ "title": "Path"
+ },
+ "description": "Vault path (e.g., prod/openai)"
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ResolveCredentialResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/credentials/resolve/batch": {
+ "get": {
+ "tags": [
+ "credentials"
+ ],
+ "summary": "Resolve Credentials Batch",
+ "description": "Resolve multiple credentials at once\n\nUsed by CLI for batch credential injection. Paths that fail to resolve\nmap to an empty string; each failure is logged and audited individually.",
+ "operationId": "resolve_credentials_batch_v1_credentials_resolve_batch_get",
+ "parameters": [
+ {
+ "name": "paths",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "maxItems": 50,
+ "description": "List of vault paths",
+ "title": "Paths"
+ },
+ "description": "List of vault paths"
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "title": "Response Resolve Credentials Batch V1 Credentials Resolve Batch Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/credentials": {
+ "post": {
+ "tags": [
+ "credentials"
+ ],
+ "summary": "Register Credential",
+ "description": "Register an LLM provider credential. The secret is stored in Vault.",
+ "operationId": "register_credential_v1_credentials_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RegisterCredentialRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RegisterCredentialResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "credentials"
+ ],
+ "summary": "List Credentials",
+ "description": "List all active credentials for the organisation.",
+ "operationId": "list_credentials_v1_credentials_get",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CredentialResponse"
+ },
+ "title": "Response List Credentials V1 Credentials Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/credentials/{credential_id}": {
+ "get": {
+ "tags": [
+ "credentials"
+ ],
+ "summary": "Get Credential",
+ "description": "Get a single credential by ID.",
+ "operationId": "get_credential_v1_credentials__credential_id__get",
+ "parameters": [
+ {
+ "name": "credential_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Credential Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CredentialResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "credentials"
+ ],
+ "summary": "Update Credential",
+ "description": "Update the label of a credential.",
+ "operationId": "update_credential_v1_credentials__credential_id__patch",
+ "parameters": [
+ {
+ "name": "credential_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Credential Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateCredentialRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CredentialResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "credentials"
+ ],
+ "summary": "Delete Credential",
+ "description": "Soft-delete a credential. Agents using this credential_ref will fail after deletion.",
+ "operationId": "delete_credential_v1_credentials__credential_id__delete",
+ "parameters": [
+ {
+ "name": "credential_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Credential Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/credentials/{credential_id}/rotate": {
+ "post": {
+ "tags": [
+ "credentials"
+ ],
+ "summary": "Rotate Credential",
+ "description": "Replace the secret stored in Vault for this credential.",
+ "operationId": "rotate_credential_v1_credentials__credential_id__rotate_post",
+ "parameters": [
+ {
+ "name": "credential_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Credential Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RotateCredentialRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CredentialResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/agents": {
+ "post": {
+ "tags": [
+ "agents"
+ ],
+ "summary": "Register Agent",
+ "description": "Register a new AI agent for this organisation.",
+ "operationId": "register_agent_v1_agents_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RegisterAgentRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AgentResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "agents"
+ ],
+ "summary": "List Agents",
+ "description": "List all agents for the organisation.",
+ "operationId": "list_agents_v1_agents_get",
+ "parameters": [
+ {
+ "name": "is_active",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Filter by active status.",
+ "title": "Is Active"
+ },
+ "description": "Filter by active status."
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AgentResponse"
+ },
+ "title": "Response List Agents V1 Agents Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/agents/{agent_id}": {
+ "get": {
+ "tags": [
+ "agents"
+ ],
+ "summary": "Get Agent",
+ "description": "Get a single agent by ID.",
+ "operationId": "get_agent_v1_agents__agent_id__get",
+ "parameters": [
+ {
+ "name": "agent_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Agent Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AgentResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "agents"
+ ],
+ "summary": "Update Agent",
+ "description": "Update an agent's name, description, or default model.",
+ "operationId": "update_agent_v1_agents__agent_id__patch",
+ "parameters": [
+ {
+ "name": "agent_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Agent Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateAgentRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AgentResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "agents"
+ ],
+ "summary": "Delete Agent",
+ "description": "Soft-delete an agent.",
+ "operationId": "delete_agent_v1_agents__agent_id__delete",
+ "parameters": [
+ {
+ "name": "agent_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Agent Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/agents/{agent_id}/sessions": {
+ "get": {
+ "tags": [
+ "agents"
+ ],
+ "summary": "Get Agent Sessions",
+ "description": "Get paginated sessions for a specific agent.",
+ "operationId": "get_agent_sessions_v1_agents__agent_id__sessions_get",
+ "parameters": [
+ {
+ "name": "agent_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Agent Id"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "maximum": 100,
+ "minimum": 1,
+ "default": 20,
+ "title": "Limit"
+ }
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "title": "Offset"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AgentSessionsResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/agbom/agents/{agent_id}": {
+ "get": {
+ "tags": [
+ "agbom"
+ ],
+ "summary": "Agent Agbom",
+ "description": "CycloneDX 1.6 AgBOM for a single agent.",
+ "operationId": "agent_agbom_v1_agbom_agents__agent_id__get",
+ "parameters": [
+ {
+ "name": "agent_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Agent Id"
+ }
+ },
+ {
+ "name": "include_refs",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "description": "Return raw vault references instead of digests. Requires org:admin.",
+ "default": false,
+ "title": "Include Refs"
+ },
+ "description": "Return raw vault references instead of digests. Requires org:admin."
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/agbom/org": {
+ "get": {
+ "tags": [
+ "agbom"
+ ],
+ "summary": "Org Agbom",
+ "description": "CycloneDX 1.6 AgBOM for the whole organisation's agent estate.",
+ "operationId": "org_agbom_v1_agbom_org_get",
+ "parameters": [
+ {
+ "name": "include_refs",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "description": "Return raw vault references instead of digests. Requires org:admin.",
+ "default": false,
+ "title": "Include Refs"
+ },
+ "description": "Return raw vault references instead of digests. Requires org:admin."
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/acs": {
+ "post": {
+ "tags": [
+ "acs"
+ ],
+ "summary": "Acs Dispatch",
+ "description": "Dispatch one ACS JSON-RPC call.",
+ "operationId": "acs_dispatch_v1_acs_post",
+ "parameters": [
+ {
+ "name": "x-acs-extensions",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "X-Acs-Extensions"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/keys/{key_id}/rotate": {
+ "post": {
+ "tags": [
+ "key-rotation"
+ ],
+ "summary": "Rotate Key",
+ "description": "Rotate a specific API key.\n\nCreates a new key and marks the old one as \"rotating\" with a grace period.\nBoth keys work during the grace period. Returns the new key (shown once only).\n\nArgs:\n key_id: API key ID to rotate (UUID)\n request_data: Rotation request with grace period\n request: HTTP request\n db: Database session\n access_token: JWT token from cookie\n\nReturns:\n New API key and rotation event ID\n\nRaises:\n 401: Not authenticated\n 403: Not authorized\n 404: Key not found\n 409: Key already rotating",
+ "operationId": "rotate_key_v1_keys__key_id__rotate_post",
+ "parameters": [
+ {
+ "name": "key_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Key Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RotateKeyRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RotateKeyResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/keys/rotate-all": {
+ "post": {
+ "tags": [
+ "key-rotation"
+ ],
+ "summary": "Rotate All Keys",
+ "description": "Emergency rotation: rotate all active keys for the organization.\n\nUseful when a security incident requires immediate key rotation.\nAll active keys are rotated with the same grace period.\n\nArgs:\n request_data: Rotation request with grace period\n request: HTTP request\n db: Database session\n access_token: JWT token from cookie\n\nReturns:\n Summary of rotated and failed keys\n\nRaises:\n 401: Not authenticated\n 403: Not authorized",
+ "operationId": "rotate_all_keys_v1_keys_rotate_all_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RotateKeyRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RotateAllResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/keys/rotation-status": {
+ "get": {
+ "tags": [
+ "key-rotation"
+ ],
+ "summary": "Get Rotation Status",
+ "description": "Get rotation status for the organization.\n\nShows active, rotating, and deactivated keys, plus pending rotations\nand keys overdue for rotation.\n\nArgs:\n request: HTTP request\n db: Database session\n access_token: JWT token from cookie\n\nReturns:\n Rotation status summary\n\nRaises:\n 401: Not authenticated\n 403: Not authorized",
+ "operationId": "get_rotation_status_v1_keys_rotation_status_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RotationStatusResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/keys/{rotation_event_id}/extend-grace": {
+ "patch": {
+ "tags": [
+ "key-rotation"
+ ],
+ "summary": "Extend Grace Period",
+ "description": "Extend the grace period for an ongoing rotation.\n\nUseful when clients need more time to update their keys.\n\nArgs:\n rotation_event_id: KeyRotationEvent ID\n request_data: Extension request with additional hours\n request: HTTP request\n db: Database session\n access_token: JWT token from cookie\n\nReturns:\n Updated grace period expiration time\n\nRaises:\n 401: Not authenticated\n 403: Not authorized\n 404: Rotation event not found\n 409: Rotation not pending",
+ "operationId": "extend_grace_period_v1_keys__rotation_event_id__extend_grace_patch",
+ "parameters": [
+ {
+ "name": "rotation_event_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Rotation Event Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ExtendGraceRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ExtendGraceResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/keys": {
+ "post": {
+ "tags": [
+ "key-rotation"
+ ],
+ "summary": "Create Api Key",
+ "description": "Create a new scoped API key. The full secret is returned exactly once.",
+ "operationId": "create_api_key_v1_keys_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateKeyRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateKeyResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "key-rotation"
+ ],
+ "summary": "List Api Keys",
+ "description": "List the org's API keys. Secrets are never returned \u2014 only masked prefixes.",
+ "operationId": "list_api_keys_v1_keys_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ApiKeyInfo"
+ },
+ "title": "Response List Api Keys V1 Keys Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/keys/{key_id}": {
+ "delete": {
+ "tags": [
+ "key-rotation"
+ ],
+ "summary": "Revoke Api Key",
+ "description": "Revoke (deactivate) an API key. Scoped to the caller's org.",
+ "operationId": "revoke_api_key_v1_keys__key_id__delete",
+ "parameters": [
+ {
+ "name": "key_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Key Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Revoke Api Key V1 Keys Key Id Delete"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/sessions": {
+ "get": {
+ "tags": [
+ "sessions"
+ ],
+ "summary": "List Sessions",
+ "description": "List paginated sessions for the organization.\n\nQuery parameters:\n- limit: Number of sessions to return (1-100, default 20)\n- offset: Number of sessions to skip (default 0)\n- agent_id: Optional filter by agent_id",
+ "operationId": "list_sessions_v1_sessions_get",
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "maximum": 100,
+ "minimum": 1,
+ "default": 20,
+ "title": "Limit"
+ }
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "title": "Offset"
+ }
+ },
+ {
+ "name": "agent_id",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Agent Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SessionListResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "sessions"
+ ],
+ "summary": "Create Session",
+ "operationId": "create_session_v1_sessions_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateSessionRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateSessionResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/sessions/cost": {
+ "get": {
+ "tags": [
+ "sessions"
+ ],
+ "summary": "Get Session Cost",
+ "operationId": "get_session_cost_v1_sessions_cost_get",
+ "parameters": [
+ {
+ "name": "session_id",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Session Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SessionCostResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/sessions/{session_id}": {
+ "get": {
+ "tags": [
+ "sessions"
+ ],
+ "summary": "Get Session Detail",
+ "description": "Get full session details including message history.",
+ "operationId": "get_session_detail_v1_sessions__session_id__get",
+ "parameters": [
+ {
+ "name": "session_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Session Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SessionDetail"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/llm/invoke": {
+ "post": {
+ "tags": [
+ "llm"
+ ],
+ "summary": "Invoke Llm",
+ "operationId": "invoke_llm_v1_llm_invoke_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Authorization"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InvokeLLMRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InvokeLLMResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/llm/stream": {
+ "post": {
+ "tags": [
+ "llm"
+ ],
+ "summary": "Invoke Llm Stream",
+ "description": "Invoke the LLM with streaming (Server-Sent Events).\n\nReturns an SSE stream where each event is a JSON-encoded StreamChunk.\nThe final chunk includes usage stats and cost.",
+ "operationId": "invoke_llm_stream_v1_llm_stream_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InvokeStreamRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/servers": {
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Create Server",
+ "description": "Register a new MCP server",
+ "operationId": "create_server_v1_mcp_servers_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MCPServerCreate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MCPServerResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "List Servers",
+ "description": "List MCP servers for the organization",
+ "operationId": "list_servers_v1_mcp_servers_get",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MCPServerListResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/servers/{server_id}": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Server",
+ "description": "Get MCP server details",
+ "operationId": "get_server_v1_mcp_servers__server_id__get",
+ "parameters": [
+ {
+ "name": "server_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Server Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MCPServerResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Update Server",
+ "description": "Update MCP server",
+ "operationId": "update_server_v1_mcp_servers__server_id__put",
+ "parameters": [
+ {
+ "name": "server_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Server Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MCPServerCreate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MCPServerResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Delete Server",
+ "description": "Delete (deactivate) an MCP server",
+ "operationId": "delete_server_v1_mcp_servers__server_id__delete",
+ "parameters": [
+ {
+ "name": "server_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Server Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/servers/{server_id}/discover": {
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Discover Server Capabilities",
+ "description": "Discover server capabilities and tools",
+ "operationId": "discover_server_capabilities_v1_mcp_servers__server_id__discover_post",
+ "parameters": [
+ {
+ "name": "server_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Server Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Discover Server Capabilities V1 Mcp Servers Server Id Discover Post"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/rpc": {
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Mcp Rpc",
+ "description": "MCP JSON-RPC endpoint with HITL\n\nMain entry point for MCP protocol requests from agents.",
+ "operationId": "mcp_rpc_v1_mcp_rpc_post",
+ "parameters": [
+ {
+ "name": "x-mcp-server-id",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "X-Mcp-Server-Id"
+ }
+ },
+ {
+ "name": "x-mcp-agent-id",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "X-Mcp-Agent-Id"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/execute": {
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Execute Tool Direct",
+ "description": "Execute an MCP tool directly (dashboard or agent/CLI via csk_ key)",
+ "operationId": "execute_tool_direct_v1_mcp_execute_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ExecuteToolRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Execute Tool Direct V1 Mcp Execute Post"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/approvals/pending": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Pending Approvals",
+ "description": "Get pending approval requests for the organization",
+ "operationId": "get_pending_approvals_v1_mcp_approvals_pending_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "title": "Response Get Pending Approvals V1 Mcp Approvals Pending Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/approvals/{approval_id}": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Approval",
+ "description": "Get approval request details.\n\nReturns 404 both when the approval does not exist and when it belongs\nto another organization (no cross-org existence leakage).",
+ "operationId": "get_approval_v1_mcp_approvals__approval_id__get",
+ "parameters": [
+ {
+ "name": "approval_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Approval Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Get Approval V1 Mcp Approvals Approval Id Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/approvals/{approval_id}/decision": {
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Submit Decision",
+ "description": "Submit an approval decision",
+ "operationId": "submit_decision_v1_mcp_approvals__approval_id__decision_post",
+ "parameters": [
+ {
+ "name": "approval_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Approval Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ApprovalDecisionRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Submit Decision V1 Mcp Approvals Approval Id Decision Post"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/approvals/{approval_id}/cancel": {
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Cancel Approval",
+ "description": "Cancel a pending approval request",
+ "operationId": "cancel_approval_v1_mcp_approvals__approval_id__cancel_post",
+ "parameters": [
+ {
+ "name": "approval_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Approval Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Cancel Approval V1 Mcp Approvals Approval Id Cancel Post"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/policies": {
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Create Policy",
+ "description": "Create a HITL policy",
+ "operationId": "create_policy_v1_mcp_policies_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HITLPolicyCreate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HITLPolicyResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "List Policies",
+ "description": "List HITL policies for the organization",
+ "operationId": "list_policies_v1_mcp_policies_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/HITLPolicyResponse"
+ },
+ "title": "Response List Policies V1 Mcp Policies Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/policies/{policy_id}": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Policy",
+ "description": "Get HITL policy details",
+ "operationId": "get_policy_v1_mcp_policies__policy_id__get",
+ "parameters": [
+ {
+ "name": "policy_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Policy Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HITLPolicyResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Update Policy",
+ "description": "Update a HITL policy",
+ "operationId": "update_policy_v1_mcp_policies__policy_id__put",
+ "parameters": [
+ {
+ "name": "policy_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Policy Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HITLPolicyCreate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HITLPolicyResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Delete Policy",
+ "description": "Delete (deactivate) a HITL policy.\n\nLoads the row before deactivating rather than issuing a blind bulk UPDATE:\nthe audit record needs the prior state, and resolving the 404 before the\nwrite is more honest than inferring it from rowcount afterwards.",
+ "operationId": "delete_policy_v1_mcp_policies__policy_id__delete",
+ "parameters": [
+ {
+ "name": "policy_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Policy Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/requests": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "List Requests",
+ "description": "List MCP request history for the organization",
+ "operationId": "list_requests_v1_mcp_requests_get",
+ "parameters": [
+ {
+ "name": "status",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Status"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 50,
+ "title": "Limit"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "title": "Response List Requests V1 Mcp Requests Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/stats": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Dashboard Stats",
+ "description": "Get MCP dashboard statistics",
+ "operationId": "get_dashboard_stats_v1_mcp_stats_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MCPDashboardStats"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/analytics/risk-calibration": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Risk Calibration",
+ "description": "Risk score calibration: how well do risk scores predict human decisions\nand execution outcomes?\n\nFor each risk bucket (0-19, 20-39, ..., 80-100) over the trailing window:\n- total requests scored in that bucket\n- human approval rate (of decided requests)\n- execution failure rate (of executed requests)\n\nThis is the feedback signal for tuning risk-engine weights: buckets where\nhumans approve nearly everything are over-scored; buckets with high\nexecution failure despite approval are under-scored.",
+ "operationId": "get_risk_calibration_v1_mcp_analytics_risk_calibration_get",
+ "parameters": [
+ {
+ "name": "days",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 30,
+ "title": "Days"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Get Risk Calibration V1 Mcp Analytics Risk Calibration Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/analytics/policy-suggestions": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Policy Suggestions",
+ "description": "Suggest HITL policy rules mined from this org's own approval history.\n\nThis is the first *data-powered* feature \u2014 the moat. Competitors can copy\nthe code; they cannot copy an org's accumulated decision corpus. For each\ntool the org has acted on in the trailing window we look at how humans\nactually decided, and propose rules:\n\n- **auto_approve**: a tool approved >= min_occurrences times, never\n rejected, whose worst-observed risk stayed under low_risk_ceiling.\n Safe to stop bothering a human about.\n- **always_review / block**: a tool rejected the majority of the time \u2014\n a candidate for a hard block or mandatory review.\n\nSuggestions are advisory; nothing is applied automatically.",
+ "operationId": "get_policy_suggestions_v1_mcp_analytics_policy_suggestions_get",
+ "parameters": [
+ {
+ "name": "days",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 30,
+ "title": "Days"
+ }
+ },
+ {
+ "name": "min_occurrences",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 5,
+ "title": "Min Occurrences"
+ }
+ },
+ {
+ "name": "low_risk_ceiling",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 40,
+ "title": "Low Risk Ceiling"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Get Policy Suggestions V1 Mcp Analytics Policy Suggestions Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/kill-switch": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Kill Switch",
+ "description": "Current kill-switch state for the caller's organization.",
+ "operationId": "get_kill_switch_v1_mcp_kill_switch_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/KillSwitchStatusResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Trigger Kill Switch Endpoint",
+ "description": "Halt all agent operations for this organization immediately.",
+ "operationId": "trigger_kill_switch_endpoint_v1_mcp_kill_switch_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/KillSwitchRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/KillSwitchStatusResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/kill-switch/reset": {
+ "post": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Reset Kill Switch Endpoint",
+ "description": "Resume agent operations after the issue is resolved.",
+ "operationId": "reset_kill_switch_endpoint_v1_mcp_kill_switch_reset_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/KillSwitchStatusResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/audit/chain/verify": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Verify Audit Chain",
+ "description": "Re-derive this organisation's approval chain and report its integrity.\n\nReturns the first divergence rather than a bare boolean \u2014 an auditor needs\nto know which record broke and how.",
+ "operationId": "verify_audit_chain_v1_mcp_audit_chain_verify_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Verify Audit Chain V1 Mcp Audit Chain Verify Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/audit/chain/{approval_id}/proof": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Get Audit Chain Proof",
+ "description": "Return the hash, its predecessor, and the exact payload that was hashed.\n\nPublishing the payload is the point: it lets a third party recompute the\ndigest themselves rather than taking the server's word for it.",
+ "operationId": "get_audit_chain_proof_v1_mcp_audit_chain__approval_id__proof_get",
+ "parameters": [
+ {
+ "name": "approval_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "title": "Approval Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": true,
+ "title": "Response Get Audit Chain Proof V1 Mcp Audit Chain Approval Id Proof Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/mcp/health": {
+ "get": {
+ "tags": [
+ "mcp"
+ ],
+ "summary": "Mcp Health",
+ "description": "MCP Gateway health check",
+ "operationId": "mcp_health_v1_mcp_health_get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "additionalProperties": true,
+ "type": "object",
+ "title": "Response Mcp Health V1 Mcp Health Get"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/messages/persist": {
+ "post": {
+ "tags": [
+ "messages"
+ ],
+ "summary": "Persist Messages",
+ "operationId": "persist_messages_v1_messages_persist_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PersistMessagesRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PersistMessagesResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/files/presigned-urls": {
+ "post": {
+ "tags": [
+ "files"
+ ],
+ "summary": "Request Presigned Url",
+ "operationId": "request_presigned_url_v1_files_presigned_urls_post",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PresignedURLRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PresignedURLResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/stats": {
+ "get": {
+ "tags": [
+ "stats"
+ ],
+ "summary": "Get Stats",
+ "description": "Get dashboard summary statistics for the organization.\n\nReturns high-level metrics including credential/agent counts, session counts,\nusage, cost, and plan information.",
+ "operationId": "get_stats_v1_stats_get",
+ "parameters": [
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/StatsResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/stats/analytics": {
+ "get": {
+ "tags": [
+ "stats"
+ ],
+ "summary": "Get Analytics",
+ "description": "Get time-series analytics data for the organization.\n\nQuery parameters:\n- range: Time range for analytics (\"7d\", \"30d\", \"90d\", default \"7d\")\n\nReturns daily aggregates of executions, costs, and success rates for charting.",
+ "operationId": "get_analytics_v1_stats_analytics_get",
+ "parameters": [
+ {
+ "name": "range",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "enum": [
+ "7d",
+ "30d",
+ "90d"
+ ],
+ "type": "string",
+ "default": "7d",
+ "title": "Range"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AnalyticsResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/stats/tokens": {
+ "get": {
+ "tags": [
+ "stats"
+ ],
+ "summary": "Get Token Velocity",
+ "description": "Get token consumption velocity data for the organisation.\n\nReturns aggregated token metrics, per-agent breakdowns, velocity scoring,\nand adoption recommendations \u2014 powering the Token Velocity dashboard widget.",
+ "operationId": "get_token_velocity_v1_stats_tokens_get",
+ "parameters": [
+ {
+ "name": "range",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "enum": [
+ "7d",
+ "30d",
+ "90d"
+ ],
+ "type": "string",
+ "default": "30d",
+ "title": "Range"
+ }
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/TokenVelocityResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/admin/overview": {
+ "get": {
+ "tags": [
+ "admin"
+ ],
+ "summary": "Get Overview",
+ "description": "Platform-wide overview across all orgs and users.",
+ "operationId": "get_overview_v1_admin_overview_get",
+ "parameters": [
+ {
+ "name": "days",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 30,
+ "title": "Days"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/OverviewResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/audit": {
+ "get": {
+ "tags": [
+ "audit"
+ ],
+ "summary": "List Audit Logs",
+ "description": "Return paginated audit log entries for the organisation, newest first.\n\nAudit logs are immutable \u2014 they cannot be modified or deleted via the API.",
+ "operationId": "list_audit_logs_v1_audit_get",
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "maximum": 200,
+ "minimum": 1,
+ "default": 50,
+ "title": "Limit"
+ }
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "title": "Offset"
+ }
+ },
+ {
+ "name": "operation",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Filter by operation name.",
+ "title": "Operation"
+ },
+ "description": "Filter by operation name."
+ },
+ {
+ "name": "success",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Filter by success status.",
+ "title": "Success"
+ },
+ "description": "Filter by success status."
+ },
+ {
+ "name": "session_id",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Filter by session UUID.",
+ "title": "Session Id"
+ },
+ "description": "Filter by session UUID."
+ },
+ {
+ "name": "authorization",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Authorization"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AuditLogResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/webhook-endpoints": {
+ "get": {
+ "tags": [
+ "webhook-endpoints"
+ ],
+ "summary": "List Webhooks",
+ "operationId": "list_webhooks_v1_webhook_endpoints_get",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WebhookResponse"
+ },
+ "title": "Response List Webhooks V1 Webhook Endpoints Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "webhook-endpoints"
+ ],
+ "summary": "Create Webhook",
+ "operationId": "create_webhook_v1_webhook_endpoints_post",
+ "parameters": [
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/WebhookCreate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/WebhookCreatedResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/webhook-endpoints/{endpoint_id}": {
+ "patch": {
+ "tags": [
+ "webhook-endpoints"
+ ],
+ "summary": "Update Webhook",
+ "operationId": "update_webhook_v1_webhook_endpoints__endpoint_id__patch",
+ "parameters": [
+ {
+ "name": "endpoint_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Endpoint Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/WebhookUpdate"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/WebhookResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "webhook-endpoints"
+ ],
+ "summary": "Delete Webhook",
+ "operationId": "delete_webhook_v1_webhook_endpoints__endpoint_id__delete",
+ "parameters": [
+ {
+ "name": "endpoint_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Endpoint Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successful Response"
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/webhook-endpoints/{endpoint_id}/test": {
+ "post": {
+ "tags": [
+ "webhook-endpoints"
+ ],
+ "summary": "Test Webhook",
+ "description": "Send a test.ping event and record the delivery attempt.",
+ "operationId": "test_webhook_v1_webhook_endpoints__endpoint_id__test_post",
+ "parameters": [
+ {
+ "name": "endpoint_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Endpoint Id"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeliveryResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/webhook-endpoints/{endpoint_id}/deliveries": {
+ "get": {
+ "tags": [
+ "webhook-endpoints"
+ ],
+ "summary": "List Deliveries",
+ "operationId": "list_deliveries_v1_webhook_endpoints__endpoint_id__deliveries_get",
+ "parameters": [
+ {
+ "name": "endpoint_id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Endpoint Id"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 50,
+ "title": "Limit"
+ }
+ },
+ {
+ "name": "access_token",
+ "in": "cookie",
+ "required": false,
+ "schema": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Access Token"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DeliveryResponse"
+ },
+ "title": "Response List Deliveries V1 Webhook Endpoints Endpoint Id Deliveries Get"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v1/webhooks/stripe": {
+ "post": {
+ "tags": [
+ "webhooks"
+ ],
+ "summary": "Stripe Webhook",
+ "description": "Receive and process Stripe webhook events.\n\nThis endpoint handles all Stripe webhook events for subscription management:\n- checkout.session.completed \u2014 Activate subscription after checkout\n- customer.subscription.created \u2014 Record new subscription\n- customer.subscription.updated \u2014 Update plan/status changes\n- customer.subscription.deleted \u2014 Handle cancellation\n- invoice.payment_succeeded \u2014 Record successful payments\n- invoice.payment_failed \u2014 Handle failed payments, notify user\n\n## Security\nAll requests are verified using Stripe's signature verification.\nThe STRIPE_WEBHOOK_SECRET environment variable must be set.\n\n## Idempotency\nDuplicate events (based on event ID) are automatically ignored.\n\n## Response Codes\n- 200: Event processed successfully (or duplicate ignored)\n- 400: Invalid signature or malformed request\n- 404: Organisation not found for event\n- 500: Internal processing error",
+ "operationId": "stripe_webhook_v1_webhooks_stripe_post",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "additionalProperties": true,
+ "type": "object",
+ "title": "Response Stripe Webhook V1 Webhooks Stripe Post"
+ }
+ }
+ }
+ }
+ },
+ "security": []
+ }
+ },
+ "/v1/webhooks/health": {
+ "get": {
+ "tags": [
+ "webhooks"
+ ],
+ "summary": "Webhooks Health",
+ "description": "Health check endpoint for webhook monitoring.\n\nReturns configuration status to help diagnose webhook issues.",
+ "operationId": "webhooks_health_v1_webhooks_health_get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "additionalProperties": true,
+ "type": "object",
+ "title": "Response Webhooks Health V1 Webhooks Health Get"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/health": {
+ "get": {
+ "summary": "Health",
+ "operationId": "health_health_get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "additionalProperties": {
+ "type": "string"
+ },
+ "type": "object",
+ "title": "Response Health Health Get"
+ }
+ }
+ }
+ }
+ },
+ "security": []
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "AcceptInviteRequest": {
+ "properties": {
+ "token": {
+ "type": "string",
+ "minLength": 1,
+ "title": "Token"
+ }
+ },
+ "type": "object",
+ "required": [
+ "token"
+ ],
+ "title": "AcceptInviteRequest"
+ },
+ "AcceptInviteResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "email": {
+ "type": "string",
+ "title": "Email"
+ },
+ "org_id": {
+ "type": "string",
+ "title": "Org Id"
+ },
+ "role": {
+ "type": "string",
+ "title": "Role"
+ },
+ "scopes": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Scopes"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "email",
+ "org_id",
+ "role",
+ "scopes"
+ ],
+ "title": "AcceptInviteResponse"
+ },
+ "AgentResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "agent_key": {
+ "type": "string",
+ "title": "Agent Key"
+ },
+ "model": {
+ "type": "string",
+ "title": "Model"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider"
+ },
+ "credential_ref": {
+ "type": "string",
+ "title": "Credential Ref"
+ },
+ "is_active": {
+ "type": "boolean",
+ "title": "Is Active"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "last_active_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Last Active At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "description",
+ "agent_key",
+ "model",
+ "provider",
+ "credential_ref",
+ "is_active",
+ "created_at",
+ "last_active_at"
+ ],
+ "title": "AgentResponse"
+ },
+ "AgentSessionsResponse": {
+ "properties": {
+ "agent_id": {
+ "type": "string",
+ "title": "Agent Id"
+ },
+ "sessions": {
+ "items": {
+ "$ref": "#/components/schemas/app__routers__agents__SessionSummary"
+ },
+ "type": "array",
+ "title": "Sessions"
+ },
+ "total": {
+ "type": "integer",
+ "title": "Total"
+ },
+ "limit": {
+ "type": "integer",
+ "title": "Limit"
+ },
+ "offset": {
+ "type": "integer",
+ "title": "Offset"
+ }
+ },
+ "type": "object",
+ "required": [
+ "agent_id",
+ "sessions",
+ "total",
+ "limit",
+ "offset"
+ ],
+ "title": "AgentSessionsResponse"
+ },
+ "AgentTokenBreakdown": {
+ "properties": {
+ "agent_id": {
+ "type": "string",
+ "title": "Agent Id"
+ },
+ "agent_name": {
+ "type": "string",
+ "title": "Agent Name"
+ },
+ "input_tokens": {
+ "type": "integer",
+ "title": "Input Tokens"
+ },
+ "output_tokens": {
+ "type": "integer",
+ "title": "Output Tokens"
+ },
+ "share_percent": {
+ "type": "number",
+ "title": "Share Percent"
+ }
+ },
+ "type": "object",
+ "required": [
+ "agent_id",
+ "agent_name",
+ "input_tokens",
+ "output_tokens",
+ "share_percent"
+ ],
+ "title": "AgentTokenBreakdown",
+ "description": "Per-agent token consumption for ranking."
+ },
+ "AnalyticsDataPoint": {
+ "properties": {
+ "date": {
+ "type": "string",
+ "title": "Date"
+ },
+ "executions": {
+ "type": "integer",
+ "title": "Executions"
+ },
+ "cost_usd": {
+ "type": "number",
+ "title": "Cost Usd"
+ },
+ "success_rate": {
+ "type": "number",
+ "title": "Success Rate"
+ },
+ "input_tokens": {
+ "type": "integer",
+ "title": "Input Tokens"
+ },
+ "output_tokens": {
+ "type": "integer",
+ "title": "Output Tokens"
+ }
+ },
+ "type": "object",
+ "required": [
+ "date",
+ "executions",
+ "cost_usd",
+ "success_rate",
+ "input_tokens",
+ "output_tokens"
+ ],
+ "title": "AnalyticsDataPoint",
+ "description": "Single data point in time-series analytics."
+ },
+ "AnalyticsResponse": {
+ "properties": {
+ "range": {
+ "type": "string",
+ "title": "Range"
+ },
+ "data_points": {
+ "items": {
+ "$ref": "#/components/schemas/AnalyticsDataPoint"
+ },
+ "type": "array",
+ "title": "Data Points"
+ },
+ "totals": {
+ "$ref": "#/components/schemas/AnalyticsTotals"
+ }
+ },
+ "type": "object",
+ "required": [
+ "range",
+ "data_points",
+ "totals"
+ ],
+ "title": "AnalyticsResponse",
+ "description": "Time-series analytics data for charts."
+ },
+ "AnalyticsTotals": {
+ "properties": {
+ "executions": {
+ "type": "integer",
+ "title": "Executions"
+ },
+ "cost_usd": {
+ "type": "number",
+ "title": "Cost Usd"
+ },
+ "avg_success_rate": {
+ "type": "number",
+ "title": "Avg Success Rate"
+ },
+ "input_tokens": {
+ "type": "integer",
+ "title": "Input Tokens"
+ },
+ "output_tokens": {
+ "type": "integer",
+ "title": "Output Tokens"
+ }
+ },
+ "type": "object",
+ "required": [
+ "executions",
+ "cost_usd",
+ "avg_success_rate",
+ "input_tokens",
+ "output_tokens"
+ ],
+ "title": "AnalyticsTotals",
+ "description": "Aggregated totals for the requested range."
+ },
+ "ApiKeyInfo": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "scopes": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Scopes"
+ },
+ "key_prefix": {
+ "type": "string",
+ "title": "Key Prefix"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "expires_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Expires At"
+ },
+ "is_active": {
+ "type": "boolean",
+ "title": "Is Active"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "scopes",
+ "key_prefix",
+ "created_at",
+ "expires_at",
+ "is_active"
+ ],
+ "title": "ApiKeyInfo"
+ },
+ "ApprovalDecisionRequest": {
+ "properties": {
+ "decision": {
+ "type": "string",
+ "pattern": "^(approved|rejected)$",
+ "title": "Decision"
+ },
+ "comment": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 1000
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Comment"
+ },
+ "mfa_token": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Mfa Token"
+ }
+ },
+ "type": "object",
+ "required": [
+ "decision"
+ ],
+ "title": "ApprovalDecisionRequest",
+ "description": "Submit approval decision"
+ },
+ "AuditEntry": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "operation": {
+ "type": "string",
+ "title": "Operation"
+ },
+ "success": {
+ "type": "boolean",
+ "title": "Success"
+ },
+ "latency_ms": {
+ "type": "integer",
+ "title": "Latency Ms"
+ },
+ "session_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Session Id"
+ },
+ "detail": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Detail"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "operation",
+ "success",
+ "latency_ms",
+ "session_id",
+ "detail",
+ "created_at"
+ ],
+ "title": "AuditEntry"
+ },
+ "AuditLogResponse": {
+ "properties": {
+ "entries": {
+ "items": {
+ "$ref": "#/components/schemas/AuditEntry"
+ },
+ "type": "array",
+ "title": "Entries"
+ },
+ "total": {
+ "type": "integer",
+ "title": "Total"
+ },
+ "limit": {
+ "type": "integer",
+ "title": "Limit"
+ },
+ "offset": {
+ "type": "integer",
+ "title": "Offset"
+ }
+ },
+ "type": "object",
+ "required": [
+ "entries",
+ "total",
+ "limit",
+ "offset"
+ ],
+ "title": "AuditLogResponse"
+ },
+ "AuthResponse": {
+ "properties": {
+ "user": {
+ "$ref": "#/components/schemas/UserResponse"
+ },
+ "tokens": {
+ "$ref": "#/components/schemas/AuthTokens"
+ }
+ },
+ "type": "object",
+ "required": [
+ "user",
+ "tokens"
+ ],
+ "title": "AuthResponse"
+ },
+ "AuthTokens": {
+ "properties": {
+ "access_token": {
+ "type": "string",
+ "title": "Access Token"
+ },
+ "refresh_token": {
+ "type": "string",
+ "title": "Refresh Token"
+ },
+ "token_type": {
+ "type": "string",
+ "title": "Token Type"
+ },
+ "expires_in": {
+ "type": "integer",
+ "title": "Expires In"
+ }
+ },
+ "type": "object",
+ "required": [
+ "access_token",
+ "refresh_token",
+ "token_type",
+ "expires_in"
+ ],
+ "title": "AuthTokens"
+ },
+ "BillingInfo": {
+ "properties": {
+ "plan": {
+ "type": "string",
+ "title": "Plan"
+ },
+ "subscription_status": {
+ "type": "string",
+ "title": "Subscription Status"
+ },
+ "trial_ends_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Trial Ends At"
+ },
+ "monthly_executions": {
+ "type": "integer",
+ "title": "Monthly Executions"
+ },
+ "execution_limit": {
+ "type": "integer",
+ "title": "Execution Limit"
+ },
+ "usage_percent": {
+ "type": "number",
+ "title": "Usage Percent"
+ },
+ "overage_enabled": {
+ "type": "boolean",
+ "title": "Overage Enabled"
+ },
+ "overage_rate": {
+ "type": "number",
+ "title": "Overage Rate"
+ },
+ "stripe_customer_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Stripe Customer Id"
+ }
+ },
+ "type": "object",
+ "required": [
+ "plan",
+ "subscription_status",
+ "trial_ends_at",
+ "monthly_executions",
+ "execution_limit",
+ "usage_percent",
+ "overage_enabled",
+ "overage_rate",
+ "stripe_customer_id"
+ ],
+ "title": "BillingInfo"
+ },
+ "CheckoutSessionRequest": {
+ "properties": {
+ "plan": {
+ "type": "string",
+ "pattern": "^(starter|pro|team)$",
+ "title": "Plan",
+ "description": "Subscription plan to purchase"
+ },
+ "success_url": {
+ "type": "string",
+ "maxLength": 2083,
+ "minLength": 1,
+ "format": "uri",
+ "title": "Success Url",
+ "description": "URL to redirect after successful checkout"
+ },
+ "cancel_url": {
+ "type": "string",
+ "maxLength": 2083,
+ "minLength": 1,
+ "format": "uri",
+ "title": "Cancel Url",
+ "description": "URL to redirect if checkout is cancelled"
+ }
+ },
+ "type": "object",
+ "required": [
+ "plan",
+ "success_url",
+ "cancel_url"
+ ],
+ "title": "CheckoutSessionRequest",
+ "description": "Request to create a Stripe Checkout Session for subscription."
+ },
+ "CheckoutSessionResponse": {
+ "properties": {
+ "checkout_url": {
+ "type": "string",
+ "title": "Checkout Url",
+ "description": "Stripe Checkout Session URL to redirect the user to"
+ },
+ "session_id": {
+ "type": "string",
+ "title": "Session Id",
+ "description": "Stripe Checkout Session ID"
+ }
+ },
+ "type": "object",
+ "required": [
+ "checkout_url",
+ "session_id"
+ ],
+ "title": "CheckoutSessionResponse",
+ "description": "Response containing Stripe Checkout Session URL."
+ },
+ "CreateInviteRequest": {
+ "properties": {
+ "email": {
+ "type": "string",
+ "format": "email",
+ "title": "Email"
+ },
+ "role": {
+ "type": "string",
+ "pattern": "^(admin|member)$",
+ "title": "Role",
+ "default": "member"
+ },
+ "credential_access": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Credential Access"
+ },
+ "message": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 1000
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Message"
+ }
+ },
+ "type": "object",
+ "required": [
+ "email"
+ ],
+ "title": "CreateInviteRequest"
+ },
+ "CreateKeyRequest": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "minLength": 1,
+ "title": "Name",
+ "description": "Human label for the key"
+ },
+ "scopes": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Scopes",
+ "description": "Scopes to grant, or a single preset name (read/invoke/admin)"
+ },
+ "expires_in_days": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "maximum": 365.0,
+ "minimum": 1.0
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Expires In Days",
+ "description": "Days until the key expires. Keys to a secrets vault must expire.",
+ "default": 90
+ }
+ },
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "title": "CreateKeyRequest"
+ },
+ "CreateKeyResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "scopes": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Scopes"
+ },
+ "api_key": {
+ "type": "string",
+ "title": "Api Key",
+ "description": "Full key \u2014 shown only once. Store it securely."
+ },
+ "key_prefix": {
+ "type": "string",
+ "title": "Key Prefix"
+ },
+ "expires_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Expires At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "scopes",
+ "api_key",
+ "key_prefix",
+ "expires_at"
+ ],
+ "title": "CreateKeyResponse"
+ },
+ "CreateSessionRequest": {
+ "properties": {
+ "agent_id": {
+ "type": "string",
+ "title": "Agent Id"
+ },
+ "model": {
+ "type": "string",
+ "title": "Model",
+ "default": "gpt-4o"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider",
+ "default": "openai"
+ },
+ "credential_ref": {
+ "type": "string",
+ "title": "Credential Ref"
+ },
+ "cost_cap_usd": {
+ "type": "number",
+ "title": "Cost Cap Usd",
+ "default": 5.0
+ }
+ },
+ "type": "object",
+ "required": [
+ "agent_id",
+ "credential_ref"
+ ],
+ "title": "CreateSessionRequest"
+ },
+ "CreateSessionResponse": {
+ "properties": {
+ "session_id": {
+ "type": "string",
+ "title": "Session Id"
+ },
+ "agent_id": {
+ "type": "string",
+ "title": "Agent Id"
+ },
+ "model": {
+ "type": "string",
+ "title": "Model"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider"
+ }
+ },
+ "type": "object",
+ "required": [
+ "session_id",
+ "agent_id",
+ "model",
+ "provider"
+ ],
+ "title": "CreateSessionResponse"
+ },
+ "CredentialResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider"
+ },
+ "label": {
+ "type": "string",
+ "title": "Label"
+ },
+ "credential_ref": {
+ "type": "string",
+ "title": "Credential Ref"
+ },
+ "is_active": {
+ "type": "boolean",
+ "title": "Is Active"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "rotated_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Rotated At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "provider",
+ "label",
+ "credential_ref",
+ "is_active",
+ "created_at",
+ "rotated_at"
+ ],
+ "title": "CredentialResponse"
+ },
+ "DeliveryResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "event": {
+ "type": "string",
+ "title": "Event"
+ },
+ "webhook_id": {
+ "type": "string",
+ "title": "Webhook Id"
+ },
+ "webhook_name": {
+ "type": "string",
+ "title": "Webhook Name"
+ },
+ "status": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Status"
+ },
+ "response_ms": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Response Ms"
+ },
+ "success": {
+ "type": "boolean",
+ "title": "Success"
+ },
+ "error": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Error"
+ },
+ "at": {
+ "type": "string",
+ "title": "At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "event",
+ "webhook_id",
+ "webhook_name",
+ "status",
+ "response_ms",
+ "success",
+ "error",
+ "at"
+ ],
+ "title": "DeliveryResponse"
+ },
+ "DeviceCodeRequest": {
+ "properties": {
+ "client_id": {
+ "type": "string",
+ "title": "Client Id"
+ }
+ },
+ "type": "object",
+ "required": [
+ "client_id"
+ ],
+ "title": "DeviceCodeRequest"
+ },
+ "DeviceCodeResponse": {
+ "properties": {
+ "device_code": {
+ "type": "string",
+ "title": "Device Code"
+ },
+ "user_code": {
+ "type": "string",
+ "title": "User Code"
+ },
+ "verification_uri": {
+ "type": "string",
+ "title": "Verification Uri"
+ },
+ "verification_uri_complete": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Verification Uri Complete"
+ },
+ "expires_in": {
+ "type": "integer",
+ "title": "Expires In"
+ },
+ "interval": {
+ "type": "integer",
+ "title": "Interval"
+ }
+ },
+ "type": "object",
+ "required": [
+ "device_code",
+ "user_code",
+ "verification_uri",
+ "expires_in",
+ "interval"
+ ],
+ "title": "DeviceCodeResponse"
+ },
+ "DeviceTokenRequest": {
+ "properties": {
+ "device_code": {
+ "type": "string",
+ "title": "Device Code"
+ },
+ "client_id": {
+ "type": "string",
+ "title": "Client Id"
+ }
+ },
+ "type": "object",
+ "required": [
+ "device_code",
+ "client_id"
+ ],
+ "title": "DeviceTokenRequest"
+ },
+ "DeviceTokenResponse": {
+ "properties": {
+ "custom_token": {
+ "type": "string",
+ "title": "Custom Token"
+ },
+ "token_type": {
+ "type": "string",
+ "title": "Token Type"
+ },
+ "expires_in": {
+ "type": "integer",
+ "title": "Expires In"
+ },
+ "firebase_api_key": {
+ "type": "string",
+ "title": "Firebase Api Key"
+ }
+ },
+ "type": "object",
+ "required": [
+ "custom_token",
+ "token_type",
+ "expires_in",
+ "firebase_api_key"
+ ],
+ "title": "DeviceTokenResponse"
+ },
+ "ErrorResponse": {
+ "properties": {
+ "detail": {
+ "type": "string",
+ "title": "Detail"
+ }
+ },
+ "type": "object",
+ "required": [
+ "detail"
+ ],
+ "title": "ErrorResponse"
+ },
+ "ExecuteToolRequest": {
+ "properties": {
+ "server_id": {
+ "type": "string",
+ "title": "Server Id"
+ },
+ "tool_name": {
+ "type": "string",
+ "title": "Tool Name"
+ },
+ "arguments": {
+ "additionalProperties": true,
+ "type": "object",
+ "title": "Arguments"
+ }
+ },
+ "type": "object",
+ "required": [
+ "server_id",
+ "tool_name"
+ ],
+ "title": "ExecuteToolRequest",
+ "description": "Execute tool request"
+ },
+ "ExtendGraceRequest": {
+ "properties": {
+ "additional_hours": {
+ "type": "integer",
+ "maximum": 720.0,
+ "minimum": 1.0,
+ "title": "Additional Hours",
+ "description": "Additional hours to extend grace period",
+ "default": 24
+ }
+ },
+ "type": "object",
+ "title": "ExtendGraceRequest"
+ },
+ "ExtendGraceResponse": {
+ "properties": {
+ "success": {
+ "type": "boolean",
+ "title": "Success"
+ },
+ "grace_expires_at": {
+ "type": "string",
+ "title": "Grace Expires At"
+ },
+ "message": {
+ "type": "string",
+ "title": "Message"
+ }
+ },
+ "type": "object",
+ "required": [
+ "success",
+ "grace_expires_at",
+ "message"
+ ],
+ "title": "ExtendGraceResponse"
+ },
+ "FunctionOut": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "arguments": {
+ "type": "string",
+ "title": "Arguments"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "arguments"
+ ],
+ "title": "FunctionOut"
+ },
+ "HITLPolicyConditionSchema": {
+ "properties": {
+ "field": {
+ "type": "string",
+ "title": "Field",
+ "description": "Field to check: tool_name, risk_score, agent_id, args."
+ },
+ "operator": {
+ "type": "string",
+ "pattern": "^(eq|ne|gt|gte|lt|lte|contains|regex|in|not_in)$",
+ "title": "Operator"
+ },
+ "value": {
+ "title": "Value"
+ }
+ },
+ "type": "object",
+ "required": [
+ "field",
+ "operator",
+ "value"
+ ],
+ "title": "HITLPolicyConditionSchema",
+ "description": "HITL policy condition"
+ },
+ "HITLPolicyCreate": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "minLength": 1,
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "server_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Server Id"
+ },
+ "risk_threshold": {
+ "type": "integer",
+ "maximum": 100.0,
+ "minimum": 0.0,
+ "title": "Risk Threshold",
+ "default": 50
+ },
+ "conditions": {
+ "items": {
+ "$ref": "#/components/schemas/HITLPolicyConditionSchema"
+ },
+ "type": "array",
+ "title": "Conditions"
+ },
+ "cel_expression": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 2000
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Cel Expression"
+ },
+ "auto_approve": {
+ "type": "boolean",
+ "title": "Auto Approve",
+ "default": false
+ },
+ "auto_approve_after": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "minimum": 0.0
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Auto Approve After"
+ },
+ "schedule_config": {
+ "anyOf": [
+ {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Schedule Config"
+ },
+ "required_approvers": {
+ "type": "integer",
+ "minimum": 1.0,
+ "title": "Required Approvers",
+ "default": 1
+ },
+ "required_roles": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Required Roles"
+ },
+ "notify_channels": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Notify Channels"
+ },
+ "notify_config": {
+ "additionalProperties": true,
+ "type": "object",
+ "title": "Notify Config"
+ },
+ "priority": {
+ "type": "integer",
+ "minimum": 0.0,
+ "title": "Priority",
+ "default": 100
+ }
+ },
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "title": "HITLPolicyCreate",
+ "description": "Create HITL policy request"
+ },
+ "HITLPolicyResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "is_active": {
+ "type": "boolean",
+ "title": "Is Active"
+ },
+ "priority": {
+ "type": "integer",
+ "title": "Priority"
+ },
+ "risk_threshold": {
+ "type": "integer",
+ "title": "Risk Threshold"
+ },
+ "auto_approve": {
+ "type": "boolean",
+ "title": "Auto Approve"
+ },
+ "required_approvers": {
+ "type": "integer",
+ "title": "Required Approvers"
+ },
+ "notify_channels": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Notify Channels"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Created At"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Updated At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "description",
+ "is_active",
+ "priority",
+ "risk_threshold",
+ "auto_approve",
+ "required_approvers",
+ "notify_channels",
+ "created_at",
+ "updated_at"
+ ],
+ "title": "HITLPolicyResponse",
+ "description": "HITL policy response"
+ },
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail"
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError"
+ },
+ "InviteListResponse": {
+ "properties": {
+ "invites": {
+ "items": {
+ "$ref": "#/components/schemas/InviteResponse"
+ },
+ "type": "array",
+ "title": "Invites"
+ },
+ "total": {
+ "type": "integer",
+ "title": "Total"
+ }
+ },
+ "type": "object",
+ "required": [
+ "invites",
+ "total"
+ ],
+ "title": "InviteListResponse"
+ },
+ "InviteResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "email": {
+ "type": "string",
+ "title": "Email"
+ },
+ "role": {
+ "type": "string",
+ "title": "Role"
+ },
+ "status": {
+ "type": "string",
+ "title": "Status"
+ },
+ "scopes": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Scopes"
+ },
+ "invited_by": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Invited By"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "expires_at": {
+ "type": "string",
+ "title": "Expires At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "email",
+ "role",
+ "status",
+ "scopes",
+ "invited_by",
+ "created_at",
+ "expires_at"
+ ],
+ "title": "InviteResponse"
+ },
+ "InvokeLLMRequest": {
+ "properties": {
+ "new_messages": {
+ "items": {
+ "$ref": "#/components/schemas/MessageDict"
+ },
+ "type": "array",
+ "title": "New Messages"
+ },
+ "session_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Session Id"
+ },
+ "tools": {
+ "anyOf": [
+ {
+ "items": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Tools"
+ },
+ "tool_choice": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "additionalProperties": true,
+ "type": "object"
+ }
+ ],
+ "title": "Tool Choice",
+ "default": "auto"
+ }
+ },
+ "type": "object",
+ "required": [
+ "new_messages"
+ ],
+ "title": "InvokeLLMRequest"
+ },
+ "InvokeLLMResponse": {
+ "properties": {
+ "message": {
+ "$ref": "#/components/schemas/MessageOut"
+ },
+ "cost_usd": {
+ "type": "number",
+ "title": "Cost Usd"
+ },
+ "model": {
+ "type": "string",
+ "title": "Model"
+ },
+ "finish_reason": {
+ "type": "string",
+ "title": "Finish Reason"
+ },
+ "tool_calls": {
+ "anyOf": [
+ {
+ "items": {
+ "$ref": "#/components/schemas/ToolCallOut"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Tool Calls"
+ },
+ "usage": {
+ "$ref": "#/components/schemas/TokenUsageOut"
+ },
+ "session_id": {
+ "type": "string",
+ "title": "Session Id"
+ }
+ },
+ "type": "object",
+ "required": [
+ "message",
+ "cost_usd",
+ "model",
+ "finish_reason",
+ "usage",
+ "session_id"
+ ],
+ "title": "InvokeLLMResponse"
+ },
+ "InvokeStreamRequest": {
+ "properties": {
+ "new_messages": {
+ "items": {
+ "$ref": "#/components/schemas/MessageDict"
+ },
+ "type": "array",
+ "title": "New Messages"
+ },
+ "session_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Session Id"
+ },
+ "tools": {
+ "anyOf": [
+ {
+ "items": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Tools"
+ },
+ "tool_choice": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "additionalProperties": true,
+ "type": "object"
+ }
+ ],
+ "title": "Tool Choice",
+ "default": "auto"
+ }
+ },
+ "type": "object",
+ "required": [
+ "new_messages"
+ ],
+ "title": "InvokeStreamRequest"
+ },
+ "KillSwitchRequest": {
+ "properties": {
+ "reason": {
+ "type": "string",
+ "maxLength": 500,
+ "minLength": 1,
+ "title": "Reason"
+ }
+ },
+ "type": "object",
+ "required": [
+ "reason"
+ ],
+ "title": "KillSwitchRequest",
+ "description": "Trigger the org-scoped emergency kill switch."
+ },
+ "KillSwitchStatusResponse": {
+ "properties": {
+ "active": {
+ "type": "boolean",
+ "title": "Active"
+ },
+ "reason": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Reason"
+ },
+ "triggered_at": {
+ "anyOf": [
+ {
+ "type": "string",
+ "format": "date-time"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Triggered At"
+ },
+ "triggered_by": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Triggered By"
+ }
+ },
+ "type": "object",
+ "required": [
+ "active"
+ ],
+ "title": "KillSwitchStatusResponse"
+ },
+ "KpiBlock": {
+ "properties": {
+ "total_users": {
+ "type": "integer",
+ "title": "Total Users"
+ },
+ "new_users_7d": {
+ "type": "integer",
+ "title": "New Users 7D"
+ },
+ "new_users_30d": {
+ "type": "integer",
+ "title": "New Users 30D"
+ },
+ "total_orgs": {
+ "type": "integer",
+ "title": "Total Orgs"
+ },
+ "paying_orgs": {
+ "type": "integer",
+ "title": "Paying Orgs"
+ },
+ "trialing_orgs": {
+ "type": "integer",
+ "title": "Trialing Orgs"
+ },
+ "mrr_gbp": {
+ "type": "number",
+ "title": "Mrr Gbp"
+ },
+ "arr_gbp": {
+ "type": "number",
+ "title": "Arr Gbp"
+ },
+ "total_executions": {
+ "type": "integer",
+ "title": "Total Executions"
+ },
+ "executions_30d": {
+ "type": "integer",
+ "title": "Executions 30D"
+ },
+ "total_cost_usd": {
+ "type": "number",
+ "title": "Total Cost Usd"
+ },
+ "total_sessions": {
+ "type": "integer",
+ "title": "Total Sessions"
+ }
+ },
+ "type": "object",
+ "required": [
+ "total_users",
+ "new_users_7d",
+ "new_users_30d",
+ "total_orgs",
+ "paying_orgs",
+ "trialing_orgs",
+ "mrr_gbp",
+ "arr_gbp",
+ "total_executions",
+ "executions_30d",
+ "total_cost_usd",
+ "total_sessions"
+ ],
+ "title": "KpiBlock"
+ },
+ "LoginRequest": {
+ "properties": {
+ "id_token": {
+ "type": "string",
+ "title": "Id Token"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id_token"
+ ],
+ "title": "LoginRequest",
+ "description": "Firebase ID token from frontend authentication."
+ },
+ "MCPDashboardStats": {
+ "properties": {
+ "total_servers": {
+ "type": "integer",
+ "title": "Total Servers"
+ },
+ "active_servers": {
+ "type": "integer",
+ "title": "Active Servers"
+ },
+ "pending_approvals": {
+ "type": "integer",
+ "title": "Pending Approvals"
+ },
+ "approved_today": {
+ "type": "integer",
+ "title": "Approved Today"
+ },
+ "rejected_today": {
+ "type": "integer",
+ "title": "Rejected Today"
+ },
+ "avg_risk_score": {
+ "type": "number",
+ "title": "Avg Risk Score"
+ }
+ },
+ "type": "object",
+ "required": [
+ "total_servers",
+ "active_servers",
+ "pending_approvals",
+ "approved_today",
+ "rejected_today",
+ "avg_risk_score"
+ ],
+ "title": "MCPDashboardStats",
+ "description": "MCP dashboard statistics"
+ },
+ "MCPServerCreate": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "minLength": 1,
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 1000
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "endpoint_url": {
+ "type": "string",
+ "title": "Endpoint Url"
+ },
+ "transport_type": {
+ "type": "string",
+ "pattern": "^(stdio|http_sse|streamable_http)$",
+ "title": "Transport Type",
+ "default": "stdio"
+ },
+ "auth_config": {
+ "additionalProperties": true,
+ "type": "object",
+ "title": "Auth Config"
+ },
+ "circuit_breaker_enabled": {
+ "type": "boolean",
+ "title": "Circuit Breaker Enabled",
+ "default": true
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "endpoint_url"
+ ],
+ "title": "MCPServerCreate",
+ "description": "Create MCP server request"
+ },
+ "MCPServerListResponse": {
+ "properties": {
+ "servers": {
+ "items": {
+ "$ref": "#/components/schemas/MCPServerResponse"
+ },
+ "type": "array",
+ "title": "Servers"
+ }
+ },
+ "type": "object",
+ "required": [
+ "servers"
+ ],
+ "title": "MCPServerListResponse",
+ "description": "List of MCP servers"
+ },
+ "MCPServerResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "endpoint_url": {
+ "type": "string",
+ "title": "Endpoint Url"
+ },
+ "transport_type": {
+ "type": "string",
+ "title": "Transport Type"
+ },
+ "status": {
+ "type": "string",
+ "title": "Status"
+ },
+ "capabilities": {
+ "additionalProperties": true,
+ "type": "object",
+ "title": "Capabilities"
+ },
+ "tools": {
+ "items": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "type": "array",
+ "title": "Tools"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Created At"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Updated At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "description",
+ "endpoint_url",
+ "transport_type",
+ "status",
+ "capabilities",
+ "tools",
+ "created_at",
+ "updated_at"
+ ],
+ "title": "MCPServerResponse",
+ "description": "MCP server response"
+ },
+ "MFAResponse": {
+ "properties": {
+ "mfa_enabled": {
+ "type": "boolean",
+ "title": "Mfa Enabled"
+ },
+ "mfa_secret": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Mfa Secret"
+ },
+ "provisioning_uri": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Provisioning Uri"
+ },
+ "message": {
+ "type": "string",
+ "title": "Message"
+ }
+ },
+ "type": "object",
+ "required": [
+ "mfa_enabled",
+ "message"
+ ],
+ "title": "MFAResponse",
+ "description": "MFA setup response"
+ },
+ "MessageDict": {
+ "properties": {
+ "role": {
+ "type": "string",
+ "title": "Role"
+ },
+ "content": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "items": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "type": "array"
+ }
+ ],
+ "title": "Content"
+ },
+ "tool_call_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Tool Call Id"
+ },
+ "name": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Name"
+ }
+ },
+ "type": "object",
+ "required": [
+ "role",
+ "content"
+ ],
+ "title": "MessageDict"
+ },
+ "MessageOut": {
+ "properties": {
+ "role": {
+ "type": "string",
+ "title": "Role"
+ },
+ "content": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "items": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "type": "array"
+ }
+ ],
+ "title": "Content"
+ }
+ },
+ "type": "object",
+ "required": [
+ "role",
+ "content"
+ ],
+ "title": "MessageOut"
+ },
+ "MessageResponse": {
+ "properties": {
+ "message": {
+ "type": "string",
+ "title": "Message"
+ }
+ },
+ "type": "object",
+ "required": [
+ "message"
+ ],
+ "title": "MessageResponse"
+ },
+ "NotificationResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "type": {
+ "type": "string",
+ "title": "Type"
+ },
+ "title": {
+ "type": "string",
+ "title": "Title"
+ },
+ "body": {
+ "type": "string",
+ "title": "Body"
+ },
+ "read": {
+ "type": "boolean",
+ "title": "Read"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "type",
+ "title",
+ "body",
+ "read",
+ "created_at"
+ ],
+ "title": "NotificationResponse"
+ },
+ "OrgInfoResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "plan": {
+ "type": "string",
+ "title": "Plan"
+ },
+ "subscription_status": {
+ "type": "string",
+ "title": "Subscription Status"
+ },
+ "primary_region": {
+ "type": "string",
+ "title": "Primary Region"
+ },
+ "enabled_regions": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Enabled Regions"
+ },
+ "onboarding_completed": {
+ "type": "boolean",
+ "title": "Onboarding Completed"
+ },
+ "monthly_executions": {
+ "type": "integer",
+ "title": "Monthly Executions"
+ },
+ "execution_limit": {
+ "type": "integer",
+ "title": "Execution Limit"
+ },
+ "usage_percent": {
+ "type": "number",
+ "title": "Usage Percent"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "plan",
+ "subscription_status",
+ "primary_region",
+ "enabled_regions",
+ "onboarding_completed",
+ "monthly_executions",
+ "execution_limit",
+ "usage_percent"
+ ],
+ "title": "OrgInfoResponse"
+ },
+ "OrgRegionsResponse": {
+ "properties": {
+ "primary_region": {
+ "type": "string",
+ "title": "Primary Region"
+ },
+ "enabled_regions": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Enabled Regions"
+ },
+ "available_regions": {
+ "items": {
+ "$ref": "#/components/schemas/RegionInfo"
+ },
+ "type": "array",
+ "title": "Available Regions"
+ },
+ "max_regions": {
+ "type": "integer",
+ "title": "Max Regions"
+ },
+ "onboarding_completed": {
+ "type": "boolean",
+ "title": "Onboarding Completed"
+ }
+ },
+ "type": "object",
+ "required": [
+ "primary_region",
+ "enabled_regions",
+ "available_regions",
+ "max_regions",
+ "onboarding_completed"
+ ],
+ "title": "OrgRegionsResponse"
+ },
+ "OrgSettings": {
+ "properties": {
+ "org_id": {
+ "type": "string",
+ "title": "Org Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "plan": {
+ "type": "string",
+ "title": "Plan"
+ },
+ "primary_region": {
+ "type": "string",
+ "title": "Primary Region"
+ },
+ "enabled_regions": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Enabled Regions"
+ },
+ "overage_enabled": {
+ "type": "boolean",
+ "title": "Overage Enabled"
+ },
+ "subscription_status": {
+ "type": "string",
+ "title": "Subscription Status"
+ },
+ "trial_ends_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Trial Ends At"
+ },
+ "onboarding_completed": {
+ "type": "boolean",
+ "title": "Onboarding Completed"
+ }
+ },
+ "type": "object",
+ "required": [
+ "org_id",
+ "name",
+ "plan",
+ "primary_region",
+ "enabled_regions",
+ "overage_enabled",
+ "subscription_status",
+ "trial_ends_at",
+ "onboarding_completed"
+ ],
+ "title": "OrgSettings"
+ },
+ "OverviewResponse": {
+ "properties": {
+ "generated_at": {
+ "type": "string",
+ "title": "Generated At"
+ },
+ "kpis": {
+ "$ref": "#/components/schemas/KpiBlock"
+ },
+ "series": {
+ "items": {
+ "$ref": "#/components/schemas/SeriesPoint"
+ },
+ "type": "array",
+ "title": "Series"
+ },
+ "plans": {
+ "items": {
+ "$ref": "#/components/schemas/PlanRow"
+ },
+ "type": "array",
+ "title": "Plans"
+ },
+ "recent_signups": {
+ "items": {
+ "$ref": "#/components/schemas/SignupRow"
+ },
+ "type": "array",
+ "title": "Recent Signups"
+ }
+ },
+ "type": "object",
+ "required": [
+ "generated_at",
+ "kpis",
+ "series",
+ "plans",
+ "recent_signups"
+ ],
+ "title": "OverviewResponse"
+ },
+ "PersistMessagesRequest": {
+ "properties": {
+ "messages": {
+ "items": {
+ "$ref": "#/components/schemas/MessageDict"
+ },
+ "type": "array",
+ "title": "Messages"
+ },
+ "session_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Session Id"
+ }
+ },
+ "type": "object",
+ "required": [
+ "messages"
+ ],
+ "title": "PersistMessagesRequest"
+ },
+ "PersistMessagesResponse": {
+ "properties": {
+ "persisted": {
+ "type": "integer",
+ "title": "Persisted"
+ },
+ "session_id": {
+ "type": "string",
+ "title": "Session Id"
+ }
+ },
+ "type": "object",
+ "required": [
+ "persisted",
+ "session_id"
+ ],
+ "title": "PersistMessagesResponse"
+ },
+ "PlanRow": {
+ "properties": {
+ "plan": {
+ "type": "string",
+ "title": "Plan"
+ },
+ "orgs": {
+ "type": "integer",
+ "title": "Orgs"
+ },
+ "mrr_gbp": {
+ "type": "number",
+ "title": "Mrr Gbp"
+ }
+ },
+ "type": "object",
+ "required": [
+ "plan",
+ "orgs",
+ "mrr_gbp"
+ ],
+ "title": "PlanRow"
+ },
+ "PortalSessionRequest": {
+ "properties": {
+ "return_url": {
+ "type": "string",
+ "maxLength": 2083,
+ "minLength": 1,
+ "format": "uri",
+ "title": "Return Url",
+ "description": "URL to return to after portal session"
+ }
+ },
+ "type": "object",
+ "required": [
+ "return_url"
+ ],
+ "title": "PortalSessionRequest",
+ "description": "Request to create a Stripe Customer Portal session."
+ },
+ "PortalSessionResponse": {
+ "properties": {
+ "portal_url": {
+ "type": "string",
+ "title": "Portal Url",
+ "description": "Stripe Customer Portal URL to redirect the user to"
+ }
+ },
+ "type": "object",
+ "required": [
+ "portal_url"
+ ],
+ "title": "PortalSessionResponse",
+ "description": "Response containing Stripe Customer Portal URL."
+ },
+ "PresignedURLRequest": {
+ "properties": {
+ "file_path": {
+ "type": "string",
+ "title": "File Path"
+ },
+ "method": {
+ "type": "string",
+ "title": "Method",
+ "default": "PUT"
+ },
+ "session_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Session Id"
+ }
+ },
+ "type": "object",
+ "required": [
+ "file_path"
+ ],
+ "title": "PresignedURLRequest"
+ },
+ "PresignedURLResponse": {
+ "properties": {
+ "url": {
+ "type": "string",
+ "title": "Url"
+ },
+ "expires_at": {
+ "type": "string",
+ "title": "Expires At"
+ },
+ "method": {
+ "type": "string",
+ "title": "Method"
+ },
+ "file_path": {
+ "type": "string",
+ "title": "File Path"
+ }
+ },
+ "type": "object",
+ "required": [
+ "url",
+ "expires_at",
+ "method",
+ "file_path"
+ ],
+ "title": "PresignedURLResponse"
+ },
+ "PublicConfigResponse": {
+ "properties": {
+ "firebase_api_key": {
+ "type": "string",
+ "title": "Firebase Api Key"
+ },
+ "firebase_project_id": {
+ "type": "string",
+ "title": "Firebase Project Id"
+ },
+ "firebase_auth_domain": {
+ "type": "string",
+ "title": "Firebase Auth Domain"
+ },
+ "frontend_url": {
+ "type": "string",
+ "title": "Frontend Url"
+ }
+ },
+ "type": "object",
+ "required": [
+ "firebase_api_key",
+ "firebase_project_id",
+ "firebase_auth_domain",
+ "frontend_url"
+ ],
+ "title": "PublicConfigResponse"
+ },
+ "RateLimitEntry": {
+ "properties": {
+ "key": {
+ "type": "string",
+ "title": "Key"
+ },
+ "endpoint": {
+ "type": "string",
+ "title": "Endpoint"
+ },
+ "label": {
+ "type": "string",
+ "title": "Label"
+ },
+ "limit": {
+ "type": "integer",
+ "title": "Limit"
+ },
+ "window": {
+ "type": "string",
+ "title": "Window"
+ },
+ "burst": {
+ "type": "integer",
+ "title": "Burst"
+ },
+ "response": {
+ "type": "string",
+ "title": "Response"
+ }
+ },
+ "type": "object",
+ "required": [
+ "key",
+ "endpoint",
+ "label",
+ "limit",
+ "window",
+ "burst",
+ "response"
+ ],
+ "title": "RateLimitEntry"
+ },
+ "RateLimitOverride": {
+ "properties": {
+ "key": {
+ "type": "string",
+ "title": "Key"
+ },
+ "limit": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "maximum": 1000000.0,
+ "minimum": 1.0
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Limit"
+ },
+ "window": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Window"
+ },
+ "burst": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "maximum": 100000.0,
+ "minimum": 1.0
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Burst"
+ },
+ "response": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Response"
+ }
+ },
+ "type": "object",
+ "required": [
+ "key"
+ ],
+ "title": "RateLimitOverride"
+ },
+ "RateLimitsResponse": {
+ "properties": {
+ "limits": {
+ "items": {
+ "$ref": "#/components/schemas/RateLimitEntry"
+ },
+ "type": "array",
+ "title": "Limits"
+ }
+ },
+ "type": "object",
+ "required": [
+ "limits"
+ ],
+ "title": "RateLimitsResponse"
+ },
+ "RateLimitsUpdate": {
+ "properties": {
+ "overrides": {
+ "items": {
+ "$ref": "#/components/schemas/RateLimitOverride"
+ },
+ "type": "array",
+ "title": "Overrides"
+ }
+ },
+ "type": "object",
+ "required": [
+ "overrides"
+ ],
+ "title": "RateLimitsUpdate"
+ },
+ "RegionInfo": {
+ "properties": {
+ "code": {
+ "type": "string",
+ "title": "Code"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "location": {
+ "type": "string",
+ "title": "Location"
+ },
+ "flag": {
+ "type": "string",
+ "title": "Flag"
+ },
+ "api_url": {
+ "type": "string",
+ "title": "Api Url"
+ },
+ "compliance": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Compliance"
+ }
+ },
+ "type": "object",
+ "required": [
+ "code",
+ "name",
+ "location",
+ "flag",
+ "api_url",
+ "compliance"
+ ],
+ "title": "RegionInfo"
+ },
+ "RegionsResponse": {
+ "properties": {
+ "regions": {
+ "items": {
+ "$ref": "#/components/schemas/RegionInfo"
+ },
+ "type": "array",
+ "title": "Regions"
+ },
+ "default": {
+ "type": "string",
+ "title": "Default"
+ }
+ },
+ "type": "object",
+ "required": [
+ "regions",
+ "default"
+ ],
+ "title": "RegionsResponse"
+ },
+ "RegisterAgentRequest": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "minLength": 1,
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 1000
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "model": {
+ "type": "string",
+ "title": "Model",
+ "description": "Default LLM model for this agent.",
+ "default": "gpt-4o"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider",
+ "description": "Default LLM provider.",
+ "default": "openai"
+ },
+ "credential_ref": {
+ "type": "string",
+ "title": "Credential Ref",
+ "description": "Vault path to the LLM credential."
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "credential_ref"
+ ],
+ "title": "RegisterAgentRequest"
+ },
+ "RegisterCredentialRequest": {
+ "properties": {
+ "provider": {
+ "type": "string",
+ "title": "Provider",
+ "description": "LLM provider: openai, anthropic, mistral, azure_openai, bedrock, kimi"
+ },
+ "credential": {
+ "type": "string",
+ "format": "password",
+ "title": "Credential",
+ "description": "The API key or credential JSON.",
+ "writeOnly": true
+ },
+ "label": {
+ "type": "string",
+ "title": "Label",
+ "description": "Optional label for multiple credentials per provider.",
+ "default": "default"
+ }
+ },
+ "type": "object",
+ "required": [
+ "provider",
+ "credential"
+ ],
+ "title": "RegisterCredentialRequest"
+ },
+ "RegisterCredentialResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "credential_ref": {
+ "type": "string",
+ "title": "Credential Ref"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider"
+ },
+ "label": {
+ "type": "string",
+ "title": "Label"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "credential_ref",
+ "provider",
+ "label"
+ ],
+ "title": "RegisterCredentialResponse"
+ },
+ "ResolveCredentialResponse": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "path": {
+ "type": "string",
+ "title": "Path"
+ },
+ "value": {
+ "type": "string",
+ "title": "Value"
+ },
+ "type": {
+ "type": "string",
+ "title": "Type"
+ },
+ "rotated_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Rotated At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "path",
+ "value",
+ "type"
+ ],
+ "title": "ResolveCredentialResponse",
+ "description": "Response for credential resolution"
+ },
+ "RoleCreate": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "maxLength": 100,
+ "minLength": 1,
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 500
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "permissions": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Permissions"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "title": "RoleCreate"
+ },
+ "RoleResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "permissions": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Permissions"
+ },
+ "member_count": {
+ "type": "integer",
+ "title": "Member Count"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "description",
+ "permissions",
+ "member_count",
+ "created_at"
+ ],
+ "title": "RoleResponse"
+ },
+ "RoleUpdate": {
+ "properties": {
+ "name": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 100,
+ "minLength": 1
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 500
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "permissions": {
+ "anyOf": [
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Permissions"
+ }
+ },
+ "type": "object",
+ "title": "RoleUpdate"
+ },
+ "RotateAllResponse": {
+ "properties": {
+ "success": {
+ "type": "boolean",
+ "title": "Success"
+ },
+ "rotated": {
+ "type": "integer",
+ "title": "Rotated"
+ },
+ "failed": {
+ "type": "integer",
+ "title": "Failed"
+ },
+ "message": {
+ "type": "string",
+ "title": "Message"
+ }
+ },
+ "type": "object",
+ "required": [
+ "success",
+ "rotated",
+ "failed",
+ "message"
+ ],
+ "title": "RotateAllResponse"
+ },
+ "RotateCredentialRequest": {
+ "properties": {
+ "credential": {
+ "type": "string",
+ "format": "password",
+ "title": "Credential",
+ "description": "The new API key or credential JSON.",
+ "writeOnly": true
+ }
+ },
+ "type": "object",
+ "required": [
+ "credential"
+ ],
+ "title": "RotateCredentialRequest"
+ },
+ "RotateKeyRequest": {
+ "properties": {
+ "grace_period_hours": {
+ "type": "integer",
+ "maximum": 720.0,
+ "minimum": 1.0,
+ "title": "Grace Period Hours",
+ "description": "Grace period in hours (1-30 days)",
+ "default": 24
+ }
+ },
+ "type": "object",
+ "title": "RotateKeyRequest"
+ },
+ "RotateKeyResponse": {
+ "properties": {
+ "success": {
+ "type": "boolean",
+ "title": "Success"
+ },
+ "new_key": {
+ "type": "string",
+ "title": "New Key",
+ "description": "New API key. Store securely \u2014 shown only once."
+ },
+ "rotation_event_id": {
+ "type": "string",
+ "title": "Rotation Event Id"
+ },
+ "grace_expires_at": {
+ "type": "string",
+ "title": "Grace Expires At"
+ },
+ "message": {
+ "type": "string",
+ "title": "Message"
+ }
+ },
+ "type": "object",
+ "required": [
+ "success",
+ "new_key",
+ "rotation_event_id",
+ "grace_expires_at",
+ "message"
+ ],
+ "title": "RotateKeyResponse"
+ },
+ "RotationStatusResponse": {
+ "properties": {
+ "org_id": {
+ "type": "string",
+ "title": "Org Id"
+ },
+ "active_keys": {
+ "type": "integer",
+ "title": "Active Keys"
+ },
+ "rotating_keys": {
+ "type": "integer",
+ "title": "Rotating Keys"
+ },
+ "deactivated_keys": {
+ "type": "integer",
+ "title": "Deactivated Keys"
+ },
+ "pending_rotations": {
+ "type": "integer",
+ "title": "Pending Rotations"
+ },
+ "overdue_keys": {
+ "type": "integer",
+ "title": "Overdue Keys"
+ },
+ "pending_rotation_events": {
+ "items": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "type": "array",
+ "title": "Pending Rotation Events"
+ },
+ "overdue_key_ids": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Overdue Key Ids"
+ }
+ },
+ "type": "object",
+ "required": [
+ "org_id",
+ "active_keys",
+ "rotating_keys",
+ "deactivated_keys",
+ "pending_rotations",
+ "overdue_keys",
+ "pending_rotation_events",
+ "overdue_key_ids"
+ ],
+ "title": "RotationStatusResponse"
+ },
+ "SecuritySettingsResponse": {
+ "properties": {
+ "settings": {
+ "additionalProperties": true,
+ "type": "object",
+ "title": "Settings"
+ }
+ },
+ "type": "object",
+ "required": [
+ "settings"
+ ],
+ "title": "SecuritySettingsResponse"
+ },
+ "SecuritySettingsUpdate": {
+ "properties": {
+ "settings": {
+ "additionalProperties": true,
+ "type": "object",
+ "maxProperties": 100,
+ "title": "Settings"
+ }
+ },
+ "type": "object",
+ "required": [
+ "settings"
+ ],
+ "title": "SecuritySettingsUpdate"
+ },
+ "SeriesPoint": {
+ "properties": {
+ "date": {
+ "type": "string",
+ "title": "Date"
+ },
+ "users": {
+ "type": "integer",
+ "title": "Users"
+ },
+ "signups": {
+ "type": "integer",
+ "title": "Signups"
+ },
+ "executions": {
+ "type": "integer",
+ "title": "Executions"
+ }
+ },
+ "type": "object",
+ "required": [
+ "date",
+ "users",
+ "signups",
+ "executions"
+ ],
+ "title": "SeriesPoint"
+ },
+ "SessionCostResponse": {
+ "properties": {
+ "session_id": {
+ "type": "string",
+ "title": "Session Id"
+ },
+ "cost_usd": {
+ "type": "number",
+ "minimum": 0.0,
+ "title": "Cost Usd"
+ }
+ },
+ "type": "object",
+ "required": [
+ "session_id",
+ "cost_usd"
+ ],
+ "title": "SessionCostResponse"
+ },
+ "SessionDetail": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "agent_id": {
+ "type": "string",
+ "title": "Agent Id"
+ },
+ "model": {
+ "type": "string",
+ "title": "Model"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider"
+ },
+ "total_cost_usd": {
+ "type": "number",
+ "title": "Total Cost Usd"
+ },
+ "cost_cap_usd": {
+ "type": "number",
+ "title": "Cost Cap Usd"
+ },
+ "message_count": {
+ "type": "integer",
+ "title": "Message Count"
+ },
+ "messages": {
+ "items": {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ "type": "array",
+ "title": "Messages"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "last_active_at": {
+ "type": "string",
+ "title": "Last Active At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "agent_id",
+ "model",
+ "provider",
+ "total_cost_usd",
+ "cost_cap_usd",
+ "message_count",
+ "messages",
+ "created_at",
+ "last_active_at"
+ ],
+ "title": "SessionDetail"
+ },
+ "SessionListResponse": {
+ "properties": {
+ "sessions": {
+ "items": {
+ "$ref": "#/components/schemas/app__routers__sessions__SessionSummary"
+ },
+ "type": "array",
+ "title": "Sessions"
+ },
+ "total": {
+ "type": "integer",
+ "title": "Total"
+ },
+ "limit": {
+ "type": "integer",
+ "title": "Limit"
+ },
+ "offset": {
+ "type": "integer",
+ "title": "Offset"
+ }
+ },
+ "type": "object",
+ "required": [
+ "sessions",
+ "total",
+ "limit",
+ "offset"
+ ],
+ "title": "SessionListResponse"
+ },
+ "SetRegionRequest": {
+ "properties": {
+ "region": {
+ "type": "string",
+ "title": "Region"
+ },
+ "primary": {
+ "type": "boolean",
+ "title": "Primary",
+ "default": false
+ }
+ },
+ "type": "object",
+ "required": [
+ "region"
+ ],
+ "title": "SetRegionRequest"
+ },
+ "SignupResponse": {
+ "properties": {
+ "org_id": {
+ "type": "string",
+ "title": "Org Id"
+ },
+ "org_name": {
+ "type": "string",
+ "title": "Org Name"
+ },
+ "api_key": {
+ "type": "string",
+ "title": "Api Key",
+ "description": "Your API key. Store it securely \u2014 it will not be shown again."
+ }
+ },
+ "type": "object",
+ "required": [
+ "org_id",
+ "org_name",
+ "api_key"
+ ],
+ "title": "SignupResponse"
+ },
+ "SignupRow": {
+ "properties": {
+ "email": {
+ "type": "string",
+ "title": "Email"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "plan": {
+ "type": "string",
+ "title": "Plan"
+ },
+ "org": {
+ "type": "string",
+ "title": "Org"
+ },
+ "created_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Created At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "email",
+ "name",
+ "plan",
+ "org",
+ "created_at"
+ ],
+ "title": "SignupRow"
+ },
+ "StatsResponse": {
+ "properties": {
+ "credentials_count": {
+ "type": "integer",
+ "title": "Credentials Count"
+ },
+ "agents_count": {
+ "type": "integer",
+ "title": "Agents Count"
+ },
+ "sessions_count": {
+ "type": "integer",
+ "title": "Sessions Count"
+ },
+ "total_executions": {
+ "type": "integer",
+ "title": "Total Executions"
+ },
+ "total_cost_usd": {
+ "type": "number",
+ "title": "Total Cost Usd"
+ },
+ "monthly_executions": {
+ "type": "integer",
+ "title": "Monthly Executions"
+ },
+ "execution_limit": {
+ "type": "integer",
+ "title": "Execution Limit"
+ },
+ "usage_percent": {
+ "type": "number",
+ "title": "Usage Percent"
+ },
+ "plan": {
+ "type": "string",
+ "title": "Plan"
+ },
+ "total_input_tokens": {
+ "type": "integer",
+ "title": "Total Input Tokens"
+ },
+ "total_output_tokens": {
+ "type": "integer",
+ "title": "Total Output Tokens"
+ }
+ },
+ "type": "object",
+ "required": [
+ "credentials_count",
+ "agents_count",
+ "sessions_count",
+ "total_executions",
+ "total_cost_usd",
+ "monthly_executions",
+ "execution_limit",
+ "usage_percent",
+ "plan",
+ "total_input_tokens",
+ "total_output_tokens"
+ ],
+ "title": "StatsResponse",
+ "description": "Dashboard summary statistics response."
+ },
+ "SubscribeRequest": {
+ "properties": {
+ "email": {
+ "type": "string",
+ "format": "email",
+ "title": "Email"
+ }
+ },
+ "type": "object",
+ "required": [
+ "email"
+ ],
+ "title": "SubscribeRequest"
+ },
+ "SubscribeResponse": {
+ "properties": {
+ "message": {
+ "type": "string",
+ "title": "Message"
+ }
+ },
+ "type": "object",
+ "required": [
+ "message"
+ ],
+ "title": "SubscribeResponse"
+ },
+ "TeamListResponse": {
+ "properties": {
+ "members": {
+ "items": {
+ "$ref": "#/components/schemas/TeamMember"
+ },
+ "type": "array",
+ "title": "Members"
+ },
+ "total": {
+ "type": "integer",
+ "title": "Total"
+ }
+ },
+ "type": "object",
+ "required": [
+ "members",
+ "total"
+ ],
+ "title": "TeamListResponse"
+ },
+ "TeamMember": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "email": {
+ "type": "string",
+ "title": "Email"
+ },
+ "first_name": {
+ "type": "string",
+ "title": "First Name"
+ },
+ "last_name": {
+ "type": "string",
+ "title": "Last Name"
+ },
+ "role": {
+ "type": "string",
+ "title": "Role"
+ },
+ "is_active": {
+ "type": "boolean",
+ "title": "Is Active"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "last_login_at": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Last Login At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "email",
+ "first_name",
+ "last_name",
+ "role",
+ "is_active",
+ "created_at",
+ "last_login_at"
+ ],
+ "title": "TeamMember"
+ },
+ "TokenUsageOut": {
+ "properties": {
+ "input_tokens": {
+ "type": "integer",
+ "title": "Input Tokens"
+ },
+ "output_tokens": {
+ "type": "integer",
+ "title": "Output Tokens"
+ },
+ "total_tokens": {
+ "type": "integer",
+ "title": "Total Tokens"
+ },
+ "cached_tokens": {
+ "type": "integer",
+ "title": "Cached Tokens",
+ "default": 0
+ }
+ },
+ "type": "object",
+ "required": [
+ "input_tokens",
+ "output_tokens",
+ "total_tokens"
+ ],
+ "title": "TokenUsageOut"
+ },
+ "TokenVelocityDataPoint": {
+ "properties": {
+ "week": {
+ "type": "string",
+ "title": "Week"
+ },
+ "input_tokens": {
+ "type": "integer",
+ "title": "Input Tokens"
+ },
+ "output_tokens": {
+ "type": "integer",
+ "title": "Output Tokens"
+ },
+ "velocity_score": {
+ "type": "integer",
+ "title": "Velocity Score"
+ }
+ },
+ "type": "object",
+ "required": [
+ "week",
+ "input_tokens",
+ "output_tokens",
+ "velocity_score"
+ ],
+ "title": "TokenVelocityDataPoint",
+ "description": "Weekly token velocity score for trend charting."
+ },
+ "TokenVelocityResponse": {
+ "properties": {
+ "total_input_tokens": {
+ "type": "integer",
+ "title": "Total Input Tokens"
+ },
+ "total_output_tokens": {
+ "type": "integer",
+ "title": "Total Output Tokens"
+ },
+ "budget_total": {
+ "type": "integer",
+ "title": "Budget Total"
+ },
+ "budget_used": {
+ "type": "integer",
+ "title": "Budget Used"
+ },
+ "budget_remaining": {
+ "type": "integer",
+ "title": "Budget Remaining"
+ },
+ "budget_percent": {
+ "type": "number",
+ "title": "Budget Percent"
+ },
+ "velocity_score": {
+ "type": "integer",
+ "title": "Velocity Score"
+ },
+ "velocity_status": {
+ "type": "string",
+ "enum": [
+ "on_track",
+ "caution",
+ "low"
+ ],
+ "title": "Velocity Status"
+ },
+ "top_agent": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/AgentTokenBreakdown"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "time_series": {
+ "items": {
+ "$ref": "#/components/schemas/TokenVelocityDataPoint"
+ },
+ "type": "array",
+ "title": "Time Series"
+ },
+ "agents": {
+ "items": {
+ "$ref": "#/components/schemas/AgentTokenBreakdown"
+ },
+ "type": "array",
+ "title": "Agents"
+ },
+ "recommendations": {
+ "items": {
+ "additionalProperties": {
+ "type": "string"
+ },
+ "type": "object"
+ },
+ "type": "array",
+ "title": "Recommendations"
+ }
+ },
+ "type": "object",
+ "required": [
+ "total_input_tokens",
+ "total_output_tokens",
+ "budget_total",
+ "budget_used",
+ "budget_remaining",
+ "budget_percent",
+ "velocity_score",
+ "velocity_status",
+ "top_agent",
+ "time_series",
+ "agents",
+ "recommendations"
+ ],
+ "title": "TokenVelocityResponse",
+ "description": "Complete token velocity dashboard data."
+ },
+ "ToolCallOut": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "type": {
+ "type": "string",
+ "title": "Type",
+ "default": "function"
+ },
+ "function": {
+ "$ref": "#/components/schemas/FunctionOut"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "function"
+ ],
+ "title": "ToolCallOut"
+ },
+ "UpdateAgentRequest": {
+ "properties": {
+ "name": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 255,
+ "minLength": 1
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Name"
+ },
+ "description": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 1000
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Description"
+ },
+ "model": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Model"
+ },
+ "provider": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Provider"
+ }
+ },
+ "type": "object",
+ "title": "UpdateAgentRequest"
+ },
+ "UpdateCredentialRequest": {
+ "properties": {
+ "label": {
+ "type": "string",
+ "maxLength": 255,
+ "minLength": 1,
+ "title": "Label",
+ "description": "New label for this credential."
+ }
+ },
+ "type": "object",
+ "required": [
+ "label"
+ ],
+ "title": "UpdateCredentialRequest"
+ },
+ "UpdateMemberRequest": {
+ "properties": {
+ "role": {
+ "type": "string",
+ "pattern": "^(admin|member)$",
+ "title": "Role"
+ }
+ },
+ "type": "object",
+ "required": [
+ "role"
+ ],
+ "title": "UpdateMemberRequest"
+ },
+ "UpdateSettingsRequest": {
+ "properties": {
+ "name": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 255,
+ "minLength": 1
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Name"
+ },
+ "overage_enabled": {
+ "anyOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Overage Enabled"
+ }
+ },
+ "type": "object",
+ "title": "UpdateSettingsRequest"
+ },
+ "UsageStats": {
+ "properties": {
+ "period_start": {
+ "type": "string",
+ "title": "Period Start"
+ },
+ "period_end": {
+ "type": "string",
+ "title": "Period End"
+ },
+ "executions_used": {
+ "type": "integer",
+ "title": "Executions Used"
+ },
+ "execution_limit": {
+ "type": "integer",
+ "title": "Execution Limit"
+ },
+ "usage_percent": {
+ "type": "number",
+ "title": "Usage Percent"
+ },
+ "estimated_cost_usd": {
+ "type": "number",
+ "title": "Estimated Cost Usd"
+ },
+ "overage_executions": {
+ "type": "integer",
+ "title": "Overage Executions"
+ },
+ "overage_cost_usd": {
+ "type": "number",
+ "title": "Overage Cost Usd"
+ }
+ },
+ "type": "object",
+ "required": [
+ "period_start",
+ "period_end",
+ "executions_used",
+ "execution_limit",
+ "usage_percent",
+ "estimated_cost_usd",
+ "overage_executions",
+ "overage_cost_usd"
+ ],
+ "title": "UsageStats"
+ },
+ "UserResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid",
+ "title": "Id"
+ },
+ "email": {
+ "type": "string",
+ "title": "Email"
+ },
+ "first_name": {
+ "type": "string",
+ "title": "First Name"
+ },
+ "last_name": {
+ "type": "string",
+ "title": "Last Name"
+ },
+ "org_id": {
+ "anyOf": [
+ {
+ "type": "string",
+ "format": "uuid"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Org Id"
+ },
+ "org_name": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Org Name"
+ },
+ "role": {
+ "type": "string",
+ "title": "Role"
+ },
+ "is_verified": {
+ "type": "boolean",
+ "title": "Is Verified"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Created At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "email",
+ "first_name",
+ "last_name",
+ "org_id",
+ "org_name",
+ "role",
+ "is_verified",
+ "created_at"
+ ],
+ "title": "UserResponse"
+ },
+ "ValidateInviteResponse": {
+ "properties": {
+ "valid": {
+ "type": "boolean",
+ "title": "Valid"
+ },
+ "org_name": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Org Name"
+ },
+ "role": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Role"
+ },
+ "email": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Email"
+ },
+ "message": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Message"
+ }
+ },
+ "type": "object",
+ "required": [
+ "valid"
+ ],
+ "title": "ValidateInviteResponse"
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "integer"
+ }
+ ]
+ },
+ "type": "array",
+ "title": "Location"
+ },
+ "msg": {
+ "type": "string",
+ "title": "Message"
+ },
+ "type": {
+ "type": "string",
+ "title": "Error Type"
+ },
+ "input": {
+ "title": "Input"
+ },
+ "ctx": {
+ "type": "object",
+ "title": "Context"
+ }
+ },
+ "type": "object",
+ "required": [
+ "loc",
+ "msg",
+ "type"
+ ],
+ "title": "ValidationError"
+ },
+ "WebhookCreate": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "maxLength": 200,
+ "minLength": 1,
+ "title": "Name"
+ },
+ "url": {
+ "type": "string",
+ "maxLength": 2000,
+ "minLength": 1,
+ "title": "Url"
+ },
+ "events": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Events"
+ },
+ "secret": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 128
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Secret"
+ },
+ "active": {
+ "type": "boolean",
+ "title": "Active",
+ "default": true
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "url"
+ ],
+ "title": "WebhookCreate"
+ },
+ "WebhookCreatedResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "url": {
+ "type": "string",
+ "title": "Url"
+ },
+ "events": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Events"
+ },
+ "active": {
+ "type": "boolean",
+ "title": "Active"
+ },
+ "secret_hint": {
+ "type": "string",
+ "title": "Secret Hint"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "secret": {
+ "type": "string",
+ "title": "Secret"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "url",
+ "events",
+ "active",
+ "secret_hint",
+ "created_at",
+ "secret"
+ ],
+ "title": "WebhookCreatedResponse",
+ "description": "Creation response \u2014 the only time the full secret is returned."
+ },
+ "WebhookResponse": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "url": {
+ "type": "string",
+ "title": "Url"
+ },
+ "events": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "title": "Events"
+ },
+ "active": {
+ "type": "boolean",
+ "title": "Active"
+ },
+ "secret_hint": {
+ "type": "string",
+ "title": "Secret Hint"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "url",
+ "events",
+ "active",
+ "secret_hint",
+ "created_at"
+ ],
+ "title": "WebhookResponse"
+ },
+ "WebhookUpdate": {
+ "properties": {
+ "name": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 200,
+ "minLength": 1
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Name"
+ },
+ "url": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 2000,
+ "minLength": 1
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Url"
+ },
+ "events": {
+ "anyOf": [
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Events"
+ },
+ "secret": {
+ "anyOf": [
+ {
+ "type": "string",
+ "maxLength": 128
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Secret"
+ },
+ "active": {
+ "anyOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Active"
+ }
+ },
+ "type": "object",
+ "title": "WebhookUpdate"
+ },
+ "app__routers__agents__SessionSummary": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "model": {
+ "type": "string",
+ "title": "Model"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider"
+ },
+ "total_cost_usd": {
+ "type": "number",
+ "title": "Total Cost Usd"
+ },
+ "message_count": {
+ "type": "integer",
+ "title": "Message Count"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "last_active_at": {
+ "type": "string",
+ "title": "Last Active At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "model",
+ "provider",
+ "total_cost_usd",
+ "message_count",
+ "created_at",
+ "last_active_at"
+ ],
+ "title": "SessionSummary"
+ },
+ "app__routers__auth__SignupRequest": {
+ "properties": {
+ "id_token": {
+ "type": "string",
+ "title": "Id Token"
+ },
+ "org_name": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "Org Name"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id_token"
+ ],
+ "title": "SignupRequest",
+ "description": "Firebase ID token + optional org name for new users."
+ },
+ "app__routers__orgs__SignupRequest": {
+ "properties": {
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "minLength": 1,
+ "title": "Name"
+ },
+ "email": {
+ "type": "string",
+ "format": "email",
+ "title": "Email"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "email"
+ ],
+ "title": "SignupRequest"
+ },
+ "app__routers__sessions__SessionSummary": {
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "Id"
+ },
+ "agent_id": {
+ "type": "string",
+ "title": "Agent Id"
+ },
+ "model": {
+ "type": "string",
+ "title": "Model"
+ },
+ "provider": {
+ "type": "string",
+ "title": "Provider"
+ },
+ "total_cost_usd": {
+ "type": "number",
+ "title": "Total Cost Usd"
+ },
+ "cost_cap_usd": {
+ "type": "number",
+ "title": "Cost Cap Usd"
+ },
+ "message_count": {
+ "type": "integer",
+ "title": "Message Count"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
+ "last_active_at": {
+ "type": "string",
+ "title": "Last Active At"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "agent_id",
+ "model",
+ "provider",
+ "total_cost_usd",
+ "cost_cap_usd",
+ "message_count",
+ "created_at",
+ "last_active_at"
+ ],
+ "title": "SessionSummary"
+ }
+ },
+ "securitySchemes": {
+ "bearerAuth": {
+ "type": "http",
+ "scheme": "bearer",
+ "description": "A scoped `csk_` API key. Send as `Authorization: Bearer csk_\u2026`."
+ }
+ }
+ },
+ "servers": [
+ {
+ "url": "https://api.identark.io",
+ "description": "Production"
+ },
+ {
+ "url": "http://localhost:8000",
+ "description": "Local control plane"
+ }
+ ],
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/docs-site/authentication.mdx b/docs-site/authentication.mdx
new file mode 100644
index 00000000..3f6138d0
--- /dev/null
+++ b/docs-site/authentication.mdx
@@ -0,0 +1,78 @@
+---
+title: "Authentication & scopes"
+description: "One header. A capability model underneath it."
+---
+
+Every request authenticates with a bearer key:
+
+```http
+Authorization: Bearer csk_…
+```
+
+Real server keys always start with `csk_`. The dashboard authenticates humans with a
+Firebase session instead — you never need that as an API client.
+
+
+ A key's full secret is returned **exactly once**, at creation. Store it in a secret
+ manager. If it leaks, [rotate it](/api-reference/introduction) — the old key gets a
+ short grace window, then stops working.
+
+
+## Scopes
+
+A scope is a `resource:action` string. A key carries a list; a route declares what it
+requires. `org:admin` is a superscope that implies all others.
+
+| Scope | Grants |
+|---|---|
+| `credentials:read` / `:write` | List credentials / register, rotate, delete them. |
+| `agents:read` / `:write` | Read agent inventory & AGBOM / create & edit agents. |
+| `sessions:read` / `:write` | Read session history & cost / open sessions. |
+| `llm:invoke` | Run LLM calls through the plane. |
+| `acs:evaluate` | Ask the Guardian endpoint for an allow / deny / modify decision. |
+| `audit:read` | Read the immutable action log. |
+| `stats:read` | Read usage analytics. |
+| `policies:read` / `:write` | Read / manage HITL & approval policy. |
+| `org:admin` | Superscope — everything, including key & org management. |
+
+## Presets
+
+Pass a single preset name in `scopes` and it expands at creation time.
+
+
+
+ Every read-only scope. Dashboards, reporting, observers.
+
+
+ `llm:invoke` + `acs:evaluate` + all reads. The agent / CI key.
+
+
+ Full access, including org administration. Keep it out of agents.
+
+
+
+```bash Create a scoped key
+curl -X POST https://api.identark.io/v1/keys \
+ -H "Authorization: Bearer csk_ADMIN" \
+ -d '{"name":"prod-agent","scopes":["invoke"],"expires_in_days":90}'
+```
+
+
+ **Presets expand at mint time.** Granting a new scope to a preset does *not*
+ retro-grant existing keys — rotate a key to pick up new capabilities. Keys to a
+ secrets vault **must** expire (1–365 days).
+
+
+## When a scope is missing
+
+A request with an under-scoped key returns `403` and names exactly what's missing:
+
+```json
+{
+ "error_code": "insufficient_scope",
+ "message": "This API key lacks the required scope: llm:invoke",
+ "required_scope": "llm:invoke"
+}
+```
+
+Mint or rotate a key that includes the named scope, and retry.
diff --git a/docs-site/concepts.mdx b/docs-site/concepts.mdx
new file mode 100644
index 00000000..30c443fb
--- /dev/null
+++ b/docs-site/concepts.mdx
@@ -0,0 +1,46 @@
+---
+title: "Core concepts"
+description: "Six nouns. Learn these and the API reads itself."
+---
+
+| Concept | What it is |
+|---|---|
+| **Organisation** | Your workspace and billing boundary. Every key, credential, agent, and session belongs to exactly one org. Created on signup. |
+| **API key (`csk_`)** | A scoped bearer token for SDK / CLI / agent access. Scopes decide what it can do; it expires. Shown once at creation. |
+| **Credential** | A provider secret (OpenAI, Anthropic, Mistral…) stored in the vault. You get back a `credential_ref` — a pointer, never the secret. |
+| **Agent** | A registered identity for one of your agents. Sessions attach to it; the Agent Bill of Materials (AGBOM) inventories it. |
+| **Session** | A bounded run: an agent + model + `credential_ref` + a `cost_cap_usd`. Holds conversation history and running cost. This is what the zero-secret agent carries. |
+| **Gateway** | The SDK interface your agent codes against. `DirectGateway` for local dev, `ControlPlaneGateway` for production — identical agent code, two-line switch. |
+
+## How they fit together
+
+
+
+ An admin registers a provider secret. The vault returns a `credential_ref` like
+ `secret/orgs/{org}/providers/openai`. The raw secret never comes back out.
+
+
+ A session binds an agent to a model, a `credential_ref`, and a `cost_cap_usd`.
+ It returns a `session_id`.
+
+
+ The agent process gets an `invoke`-scoped `csk_` key and the `session_id` — and
+ nothing else. Every `invoke_llm` call resolves the secret inside the plane,
+ enforces the cost cap, and writes an audit entry.
+
+
+
+## The gateway protocol
+
+Both SDKs implement one interface. Code against it once; swap the implementation to
+change environment.
+
+| Gateway | When to use | Credentials in the agent | History |
+|---|---|---|---|
+| `DirectGateway` | Local development, CI evals | Your provider key | In-memory |
+| `ControlPlaneGateway` | Production on IdentArk | **None** | Control plane DB |
+
+
+ Because the interface is identical, the same agent code you evaluate locally is the
+ code you ship. The only change between environments is which gateway you construct.
+
diff --git a/docs-site/docs.json b/docs-site/docs.json
new file mode 100644
index 00000000..29b2b54f
--- /dev/null
+++ b/docs-site/docs.json
@@ -0,0 +1,90 @@
+{
+ "$schema": "https://mintlify.com/docs.json",
+ "theme": "mint",
+ "name": "IdentArk",
+ "description": "Identity & secrets control plane for autonomous agents — capabilities, not credentials.",
+ "colors": {
+ "primary": "#0b8a7e",
+ "light": "#2bbfad",
+ "dark": "#0b8a7e"
+ },
+ "favicon": "/favicon.svg",
+ "logo": {
+ "light": "/images/logo-light.svg",
+ "dark": "/images/logo-dark.svg"
+ },
+ "navigation": {
+ "tabs": [
+ {
+ "tab": "Documentation",
+ "groups": [
+ {
+ "group": "Get started",
+ "pages": [
+ "introduction",
+ "quickstart",
+ "concepts"
+ ]
+ },
+ {
+ "group": "Build",
+ "pages": [
+ "authentication",
+ "sdks/python",
+ "sdks/typescript",
+ "guides/production"
+ ]
+ },
+ {
+ "group": "Govern",
+ "pages": [
+ "guides/mcp-hitl",
+ "guides/acs",
+ "guides/limits-and-errors"
+ ]
+ },
+ {
+ "group": "Trust",
+ "pages": [
+ "guides/security"
+ ]
+ }
+ ]
+ },
+ {
+ "tab": "API Reference",
+ "groups": [
+ {
+ "group": "Overview",
+ "pages": [
+ "api-reference/introduction"
+ ]
+ },
+ {
+ "group": "Endpoints",
+ "openapi": "api-reference/openapi.json"
+ }
+ ]
+ }
+ ]
+ },
+ "navbar": {
+ "links": [
+ {
+ "label": "SDK on PyPI",
+ "href": "https://pypi.org/project/identark/"
+ }
+ ],
+ "primary": {
+ "type": "button",
+ "label": "Get an API key",
+ "href": "https://app.identark.io"
+ }
+ },
+ "footer": {
+ "socials": {
+ "github": "https://github.com/identark/identark",
+ "website": "https://identark.io"
+ }
+ }
+}
diff --git a/docs-site/favicon.svg b/docs-site/favicon.svg
new file mode 100644
index 00000000..32ffa426
--- /dev/null
+++ b/docs-site/favicon.svg
@@ -0,0 +1,4 @@
+
diff --git a/docs-site/guides/acs.mdx b/docs-site/guides/acs.mdx
new file mode 100644
index 00000000..f2d8794b
--- /dev/null
+++ b/docs-site/guides/acs.mdx
@@ -0,0 +1,60 @@
+---
+title: "ACS Guardian"
+description: "Ask before you act — an in-band allow / deny / modify decision endpoint."
+---
+
+The Guardian endpoint `POST /v1/acs` lets an agent consult IdentArk about a proposed
+action *before* taking it. It takes a JSON-RPC request describing the action plus
+context (agent, user) and returns **allow**, **deny**, or **modify**.
+
+## Scope
+
+Calling the Guardian requires `acs:evaluate`. This scope grants **only** the right to
+be judged — it gives an agent key no read access to org data. It's included in the
+`invoke` preset, so the key your agent already carries can call it.
+
+## Request
+
+`POST /v1/acs` speaks JSON-RPC 2.0. The endpoint always responds `200`; errors travel
+in the JSON-RPC `error` channel rather than the HTTP status.
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "evaluate",
+ "params": {
+ "action": { "tool": "db.query", "args": { "sql": "…" } },
+ "context": {
+ "agent": { "id": "agent_…" },
+ "user": { "id": "user_…" }
+ }
+ }
+}
+```
+
+## Response
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "decision": "allow",
+ "reason": "within policy",
+ "risk_score": 12
+ }
+}
+```
+
+| Decision | Meaning |
+|---|---|
+| `allow` | Proceed as requested. |
+| `deny` | Do not proceed. |
+| `modify` | Proceed only with the adjustments the response describes. |
+
+
+ Use the Guardian for actions your own code takes directly (a DB write, a shell
+ command) — anything outside the LLM and MCP paths that already flow through the
+ plane. It's the same risk engine, exposed as a callable decision.
+
diff --git a/docs-site/guides/limits-and-errors.mdx b/docs-site/guides/limits-and-errors.mdx
new file mode 100644
index 00000000..c9f1d8c1
--- /dev/null
+++ b/docs-site/guides/limits-and-errors.mdx
@@ -0,0 +1,50 @@
+---
+title: "Limits & errors"
+description: "The operating envelope, and how failures are shaped."
+---
+
+## Guardrails
+
+
+
+ `POST /v1/llm/invoke` is capped at **60 calls/min per key** for burst protection.
+ Exceeding it returns `429`.
+
+
+ Every session carries `cost_cap_usd` (default `5.0`). Hitting it returns `402`,
+ before further spend.
+
+
+ Orgs have a monthly execution allowance by plan; over-limit calls are refused at
+ the plane.
+
+
+ Keys expire (1–365 days). Rotate before expiry — the old key gets a grace window.
+
+
+
+## Error shape
+
+Errors return a JSON body with a stable `error_code` and a human `message`. Scope
+errors also name the `required_scope`.
+
+```json
+{
+ "error_code": "insufficient_scope",
+ "message": "This API key lacks the required scope: llm:invoke",
+ "required_scope": "llm:invoke"
+}
+```
+
+| Status | `error_code` | Meaning |
+|---|---|---|
+| `401` | `unauthorized` | Missing or invalid key. |
+| `403` | `insufficient_scope` | Key lacks the named scope. Mint or rotate with it. |
+| `402` | `cost_cap_exceeded` | Session cap reached — includes cap vs. consumed. |
+| `404` | `session_not_found` | Session id unknown or not in your org. |
+| `429` | `rate_limited` | Slow down; retry after the window. |
+
+
+ The `402` body also carries `cap_usd`, `consumed_usd`, and `session_id`, so a client
+ can surface exactly how much of the budget was used.
+
diff --git a/docs-site/guides/mcp-hitl.mdx b/docs-site/guides/mcp-hitl.mdx
new file mode 100644
index 00000000..84e9ea17
--- /dev/null
+++ b/docs-site/guides/mcp-hitl.mdx
@@ -0,0 +1,62 @@
+---
+title: "MCP gateway & human-in-the-loop"
+description: "Put IdentArk in front of any MCP tool server; high-risk calls pause for approval."
+---
+
+Register an MCP tool server once, then route every tool call through
+`POST /v1/mcp/execute`. IdentArk applies policy, pauses high-risk calls for human
+approval (HITL), and writes an audit entry for each decision.
+
+## Risk is computed, not hardcoded
+
+Risk scores are derived from the properties of each call — operation class, data
+sensitivity, scope breadth, environment, and taint — **not** fixed per tool. The same
+tool scores higher when its scope widens: an erase with an unbounded `where` clause
+scores far above a targeted one, which is how an injected instruction gets caught and
+refused.
+
+
+ This is what makes the gateway resistant to prompt injection: widening blast radius
+ raises the score past the approval threshold, regardless of how the request was
+ phrased.
+
+
+## Endpoints
+
+| Method | Path | Scope | Purpose |
+|---|---|---|---|
+| `POST` | `/v1/mcp/servers` | `org:admin` | Register a tool server. |
+| `POST` | `/v1/mcp/servers/{id}/discover` | `org:admin` | Enumerate its tools. |
+| `POST` | `/v1/mcp/execute` | key-scoped | Run a tool call under policy + audit. |
+| `POST` | `/v1/mcp/policies` | `policies:write` | Define HITL / approval thresholds. |
+| `GET` | `/v1/mcp/approvals/pending` | `policies:read` | Approvals awaiting a human. |
+| `POST` | `/v1/mcp/approvals/{id}/decision` | `policies:write` | Approve / deny a paused call. |
+| `POST` | `/v1/mcp/kill-switch` | `org:admin` | Halt all execution instantly. |
+| `GET` | `/v1/mcp/audit/chain/verify` | `audit:read` | Verify audit-chain integrity. |
+
+## The fail-safe is deny
+
+
+ If an approval times out, the default decision is **deny**. High-risk operations
+ never proceed on silence — the system errs toward stopping the agent, not trusting
+ it. There is also an org-wide **kill-switch** (`POST /v1/mcp/kill-switch`) that halts
+ execution immediately.
+
+
+## Approval lifecycle
+
+
+
+ The agent calls `POST /v1/mcp/execute`. Low-risk calls run inline.
+
+
+ A call above the policy threshold is queued and returns an approval id.
+
+
+ A human resolves it via `POST /v1/mcp/approvals/{id}/decision`. No decision before
+ the timeout → **deny**.
+
+
+ The decision and its cryptographic proof are appended to the audit chain.
+
+
diff --git a/docs-site/guides/production.mdx b/docs-site/guides/production.mdx
new file mode 100644
index 00000000..8115209d
--- /dev/null
+++ b/docs-site/guides/production.mdx
@@ -0,0 +1,89 @@
+---
+title: "Going to production"
+description: "Store the secret once. Hand the agent a session. Never hand it the key."
+---
+
+The production pattern has one rule: **the provider key never reaches the agent box.**
+An admin stores it in the vault; the agent runs with only a scoped `csk_` key and a
+session id.
+
+
+
+ Done once, with an admin key, on your control side.
+
+ ```bash
+ curl -X POST https://api.identark.io/v1/credentials \
+ -H "Authorization: Bearer csk_ADMIN" \
+ -d '{"provider":"openai","credential":"sk-…","label":"default"}'
+ # → { "credential_ref": "secret/orgs/{org}/providers/openai", … }
+ ```
+
+ Supported `provider` values include `openai`, `anthropic`, `mistral`, `azure_openai`, `bedrock`, and `kimi`. The raw secret never comes back out — you only ever see the `credential_ref`.
+
+
+
+ ```bash
+ # agent → { "id": "agent_…" }
+ curl -X POST https://api.identark.io/v1/agents \
+ -H "Authorization: Bearer csk_ADMIN" \
+ -d '{"name":"support-bot"}'
+
+ # session binds agent + model + credential_ref + cap
+ curl -X POST https://api.identark.io/v1/sessions \
+ -H "Authorization: Bearer csk_ADMIN" \
+ -d '{"agent_id":"agent_…","model":"gpt-4o","provider":"openai",
+ "credential_ref":"secret/orgs/{org}/providers/openai",
+ "cost_cap_usd":5.0}'
+ # → { "session_id": "sess_…" }
+ ```
+
+
+
+ These are the **only** secrets on the agent box.
+
+ ```bash
+ export IDENTARK_API_KEY=csk_INVOKE
+ export IDENTARK_CONTROL_PLANE_URL=https://api.identark.io
+ export IDENTARK_SESSION_ID=sess_…
+ ```
+
+ ```python
+ from identark import ControlPlaneGateway, Message, Role
+
+ gateway = ControlPlaneGateway() # reads the three vars above
+ resp = await gateway.invoke_llm(
+ new_messages=[Message(role=Role.USER, content="…")]
+ )
+ ```
+
+
+
+## Cost is enforced, not just reported
+
+When a session reaches its `cost_cap_usd`, `POST /v1/llm/invoke` returns `402` with the
+cap and the amount consumed — the agent is stopped **at the plane, before spend**, not
+after a bill.
+
+```json
+{
+ "error_code": "cost_cap_exceeded",
+ "cap_usd": 5.0,
+ "consumed_usd": 5.0021,
+ "session_id": "sess_…",
+ "message": "Session cost cap of $5.0000 reached."
+}
+```
+
+## Read back cost and history
+
+
+
+ `GET /v1/sessions/cost` — authoritative spend.
+
+
+ `GET /v1/sessions/{id}` — full message history.
+
+
+ `GET /v1/stats/analytics` — spend over time.
+
+
diff --git a/docs-site/guides/security.mdx b/docs-site/guides/security.mdx
new file mode 100644
index 00000000..1b593d75
--- /dev/null
+++ b/docs-site/guides/security.mdx
@@ -0,0 +1,44 @@
+---
+title: "Security & a clean exit"
+description: "How secrets are protected — and how to take your data out."
+---
+
+## How secrets are handled
+
+
+
+ Agents receive a `credential_ref`, never the provider key. Credential access is
+ audited; keys are bcrypt-hashed at rest and shown only once.
+
+
+ Credential access, LLM cost, and tool decisions write a tamper-evident chain you
+ can verify via `GET /v1/mcp/audit/chain/verify`.
+
+
+ HITL approval timeouts default to deny; high-risk ops require a human. An org-wide
+ kill-switch halts everything at once.
+
+
+ Export your full org — credential metadata, agents, sessions, audit — via the
+ portable export endpoint. Your data is yours to take.
+
+
+
+## Data residency
+
+Organisations pin a region. Read the options and set yours:
+
+```bash
+curl https://api.identark.io/v1/orgs/regions \
+ -H "Authorization: Bearer csk_ADMIN"
+
+curl -X POST https://api.identark.io/v1/orgs/set-region \
+ -H "Authorization: Bearer csk_ADMIN" \
+ -d '{"region":"eu"}'
+```
+
+## Reporting a vulnerability
+
+Found a security issue? Email **security@identark.io** — please don't file a public
+issue for anything exploitable. The SDK repositories carry a `SECURITY.md` with the
+current disclosure policy.
diff --git a/docs-site/images/logo-dark.svg b/docs-site/images/logo-dark.svg
new file mode 100644
index 00000000..eeea08ff
--- /dev/null
+++ b/docs-site/images/logo-dark.svg
@@ -0,0 +1,5 @@
+
diff --git a/docs-site/images/logo-light.svg b/docs-site/images/logo-light.svg
new file mode 100644
index 00000000..b8e337c5
--- /dev/null
+++ b/docs-site/images/logo-light.svg
@@ -0,0 +1,5 @@
+
diff --git a/docs-site/introduction.mdx b/docs-site/introduction.mdx
new file mode 100644
index 00000000..f58fea6e
--- /dev/null
+++ b/docs-site/introduction.mdx
@@ -0,0 +1,71 @@
+---
+title: "IdentArk"
+description: "The identity & secrets control plane for autonomous agents — capabilities, not credentials."
+---
+
+When an AI agent can call APIs, run code, or touch files, it runs in a process — and
+that process usually holds every dangerous secret in its environment: LLM keys,
+database credentials, cloud tokens. IdentArk removes the secret from the agent
+entirely and puts a governed control plane in front of every privileged action.
+
+
+ **The one idea to keep.** In development, your agent holds a provider key
+ (`DirectGateway`). In production, it holds **nothing** — a session id resolves
+ to the secret *inside* the plane (`ControlPlaneGateway`). The agent logic between
+ them does not change.
+
+
+## What you get
+
+
+
+ The agent process holds a short-lived `csk_` key and a session id — never the
+ provider key. The real secret lives in the vault against the session's
+ `credential_ref`.
+
+
+ Every LLM call, tool call, and credential access flows through the plane. Risk
+ is **computed** from the call; high-risk actions require human approval and
+ fail closed to **deny**.
+
+
+ Credential access, LLM cost, and every tool decision write a tamper-evident
+ audit entry. Verify the chain, and export your whole org, at any time.
+
+
+
+## Start here
+
+
+
+ Zero to a governed LLM call in about ten minutes.
+
+
+ Six nouns. Learn them and the API reads itself.
+
+
+ One bearer header, a capability model underneath.
+
+
+ Every `/v1` endpoint, with live request examples.
+
+
+
+## The two-line switch
+
+Your agent codes against one interface — the **AgentGateway Protocol**. Move from
+laptop to production by swapping the implementation; the agent logic is identical.
+
+
+```python Development
+from identark import DirectGateway, Message, Role
+
+gateway = DirectGateway(llm_client=AsyncOpenAI(), model="gpt-4o")
+```
+
+```python Production
+from identark import ControlPlaneGateway, Message, Role
+
+gateway = ControlPlaneGateway() # zero secrets — reads session from env
+```
+
diff --git a/docs-site/quickstart.mdx b/docs-site/quickstart.mdx
new file mode 100644
index 00000000..490dfd44
--- /dev/null
+++ b/docs-site/quickstart.mdx
@@ -0,0 +1,98 @@
+---
+title: "Quickstart"
+description: "From zero to a governed LLM call."
+---
+
+You'll create an organisation, mint a least-privilege key, install the SDK, and make
+your first cost-accounted LLM call. Total time: about ten minutes.
+
+
+
+ Signup returns an `org:admin` key. Store it in a secret manager — it is shown
+ **only once**.
+
+ ```bash
+ curl -X POST https://api.identark.io/v1/orgs/signup \
+ -H "Content-Type: application/json" \
+ -d '{"name":"acme","email":"you@acme.com"}'
+ # → { "org_id": "…", "org_name": "acme", "api_key": "csk_…" }
+ ```
+
+
+
+ Don't ship the admin key. Create a least-privilege key with the `invoke` preset.
+
+ ```bash
+ curl -X POST https://api.identark.io/v1/keys \
+ -H "Authorization: Bearer csk_ADMIN" \
+ -H "Content-Type: application/json" \
+ -d '{"name":"prod-agent","scopes":["invoke"],"expires_in_days":90}'
+ # → { "api_key": "csk_…", "scopes": [...], "expires_at": "…" } (shown once)
+ ```
+
+ `invoke` expands to `llm:invoke` + `acs:evaluate` + all read scopes — see [Authentication](/authentication).
+
+
+
+ Both SDKs have **zero runtime dependencies**; your provider client is an optional extra.
+
+
+ ```bash Python
+ pip install "identark[openai]"
+ ```
+
+ ```bash TypeScript
+ npm install identark
+ ```
+
+
+
+
+ Local development with `DirectGateway` keeps your provider key out of the agent
+ loop and gives you cost accounting for free.
+
+
+ ```python Python
+ import asyncio
+ from openai import AsyncOpenAI
+ from identark import DirectGateway, Message, Role
+
+ async def main():
+ gateway = DirectGateway(llm_client=AsyncOpenAI(), model="gpt-4o")
+ resp = await gateway.invoke_llm(
+ new_messages=[Message(role=Role.USER, content="Hello, IdentArk!")]
+ )
+ print(resp.message.content)
+ print(f"cost: ${resp.cost_usd:.6f}")
+
+ asyncio.run(main())
+ ```
+
+ ```typescript TypeScript
+ import { DirectGateway } from "identark";
+ import OpenAI from "openai";
+
+ const gateway = new DirectGateway({
+ llmClient: new OpenAI(),
+ model: "gpt-4o",
+ });
+
+ const resp = await gateway.invokeLlm({
+ newMessages: [{ role: "user", content: "Hello, IdentArk!" }],
+ });
+ console.log(resp.message.content, resp.costUsd);
+ ```
+
+
+
+
+## Next
+
+
+
+ Store the secret once, hand the agent a session, never the key.
+
+
+ Orgs, credentials, agents, sessions, gateways.
+
+
diff --git a/docs-site/sdks/python.mdx b/docs-site/sdks/python.mdx
new file mode 100644
index 00000000..788dc4ca
--- /dev/null
+++ b/docs-site/sdks/python.mdx
@@ -0,0 +1,104 @@
+---
+title: "Python SDK"
+description: "The AgentGateway Protocol for Python — zero runtime dependencies."
+---
+
+
+
+ `pip install identark`
+
+
+ Runnable agents in `examples/`.
+
+
+
+## Install
+
+The core package has **no runtime dependencies**. Provider clients are optional extras.
+
+```bash
+pip install "identark[openai]" # or [anthropic], [mistral], [gemini], …
+```
+
+## The AgentGateway Protocol
+
+Any object implementing these methods is a valid gateway. Code your agent against the
+protocol; swap the implementation to change environment.
+
+| Method | Purpose |
+|---|---|
+| `invoke_llm(new_messages, …)` | One governed completion. Returns message, token usage, and `cost_usd`. |
+| `invoke_llm_stream(…)` | Streaming variant; yields `StreamChunk`s. |
+| `persist_messages(messages)` | Append to durable session history (control plane DB in prod). |
+| `request_file_url(…)` | Get a pre-signed URL for file I/O without holding cloud creds. |
+| `get_session_cost()` | Authoritative running spend for the session. |
+
+## DirectGateway — local development
+
+Your provider key stays out of the agent loop, and you get cost accounting for free.
+
+```python
+import asyncio
+from openai import AsyncOpenAI
+from identark import DirectGateway, Message, Role
+
+async def main():
+ gateway = DirectGateway(llm_client=AsyncOpenAI(), model="gpt-4o")
+ resp = await gateway.invoke_llm(
+ new_messages=[Message(role=Role.USER, content="Summarise ticket #42")]
+ )
+ print(resp.message.content)
+ print(f"cost: ${resp.cost_usd:.6f}")
+
+asyncio.run(main())
+```
+
+## ControlPlaneGateway — production
+
+**Zero secrets in the agent.** The gateway auto-detects its configuration from the
+environment.
+
+```python
+from identark import ControlPlaneGateway, Message, Role
+
+gateway = ControlPlaneGateway() # reads env, see below
+
+resp = await gateway.invoke_llm(
+ new_messages=[Message(role=Role.USER, content="Summarise ticket #42")]
+)
+print(resp.message.content, resp.cost_usd)
+```
+
+
+ Your `csk_` key. Inside a sandbox, `IDENTARK_SESSION_TOKEN` is used instead.
+
+
+ Control plane base URL, e.g. `https://api.identark.io`.
+
+
+ Session to run against. Pass explicitly or let the plane resolve it.
+
+
+You can also pass these to the constructor directly:
+
+```python
+gateway = ControlPlaneGateway(
+ api_key="csk_…",
+ url="https://api.identark.io",
+ session_id="sess_…",
+)
+```
+
+## Framework integrations
+
+Drop-in adapters make the gateway the model / execution layer, so governance is
+transparent to your orchestration code.
+
+
+
+
+
+
+
+
+
diff --git a/docs-site/sdks/typescript.mdx b/docs-site/sdks/typescript.mdx
new file mode 100644
index 00000000..1aed4b80
--- /dev/null
+++ b/docs-site/sdks/typescript.mdx
@@ -0,0 +1,73 @@
+---
+title: "TypeScript SDK"
+description: "The AgentGateway Protocol for TypeScript — at parity with Python."
+---
+
+
+
+ `npm install identark`
+
+
+ Runnable examples in `examples/`.
+
+
+
+## Install
+
+```bash
+npm install identark
+```
+
+The SDK ships its own types and has no runtime dependencies; your provider client is a
+peer dependency.
+
+## DirectGateway — local development
+
+```typescript
+import { DirectGateway } from "identark";
+import OpenAI from "openai";
+
+const gateway = new DirectGateway({
+ llmClient: new OpenAI(), // your provider key — not in the agent loop
+ model: "gpt-4o",
+});
+
+const resp = await gateway.invokeLlm({
+ newMessages: [{ role: "user", content: "Hello, IdentArk!" }],
+});
+
+console.log(resp.message.content, resp.costUsd);
+```
+
+## ControlPlaneGateway — production
+
+**Zero secrets in the agent.** Configuration is auto-detected from the environment
+(`IDENTARK_API_KEY`, `IDENTARK_CONTROL_PLANE_URL`, `IDENTARK_SESSION_ID`), or passed in.
+
+```typescript
+import { ControlPlaneGateway } from "identark";
+
+const gateway = new ControlPlaneGateway(); // reads env
+
+const resp = await gateway.invokeLlm({
+ newMessages: [{ role: "user", content: "Summarise ticket #42" }],
+});
+
+console.log(resp.message.content, resp.costUsd);
+```
+
+## Framework integrations
+
+
+
+ Use the gateway as a LangChain chat model.
+
+
+ Governance behind `streamText` / `generateText`.
+
+
+
+
+ The Python and TypeScript SDKs are kept at **parity** — the `AgentGateway` interface
+ is identical. Anything documented for one has an equivalent in the other.
+