From 0856698bbbecedf20d2da7ad0ef932725e873871 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 13 Aug 2026 22:18:50 +0100 Subject: [PATCH] docs: Mintlify documentation site + API reference Adds a deployable Mintlify docs project under docs-site/: - Guides: introduction, quickstart, concepts, authentication, SDKs (Python/TS), production flow, MCP/HITL, ACS Guardian, limits & errors, security. - API Reference auto-generated from the control plane's own OpenAPI schema (95 endpoints), post-processed with the production server URL and a csk_ bearer-auth scheme. - Verified rendering with the Mintlify CLI (mint dev). Host by connecting the repo in the Mintlify dashboard with content directory docs-site/, custom domain docs.identark.io. Co-Authored-By: Claude Opus 4.8 --- docs-site/README.md | 64 + docs-site/api-reference/introduction.mdx | 73 + docs-site/api-reference/openapi.json | 11774 +++++++++++++++++++++ docs-site/authentication.mdx | 78 + docs-site/concepts.mdx | 46 + docs-site/docs.json | 90 + docs-site/favicon.svg | 4 + docs-site/guides/acs.mdx | 60 + docs-site/guides/limits-and-errors.mdx | 50 + docs-site/guides/mcp-hitl.mdx | 62 + docs-site/guides/production.mdx | 89 + docs-site/guides/security.mdx | 44 + docs-site/images/logo-dark.svg | 5 + docs-site/images/logo-light.svg | 5 + docs-site/introduction.mdx | 71 + docs-site/quickstart.mdx | 98 + docs-site/sdks/python.mdx | 104 + docs-site/sdks/typescript.mdx | 73 + 18 files changed, 12790 insertions(+) create mode 100644 docs-site/README.md create mode 100644 docs-site/api-reference/introduction.mdx create mode 100644 docs-site/api-reference/openapi.json create mode 100644 docs-site/authentication.mdx create mode 100644 docs-site/concepts.mdx create mode 100644 docs-site/docs.json create mode 100644 docs-site/favicon.svg create mode 100644 docs-site/guides/acs.mdx create mode 100644 docs-site/guides/limits-and-errors.mdx create mode 100644 docs-site/guides/mcp-hitl.mdx create mode 100644 docs-site/guides/production.mdx create mode 100644 docs-site/guides/security.mdx create mode 100644 docs-site/images/logo-dark.svg create mode 100644 docs-site/images/logo-light.svg create mode 100644 docs-site/introduction.mdx create mode 100644 docs-site/quickstart.mdx create mode 100644 docs-site/sdks/python.mdx create mode 100644 docs-site/sdks/typescript.mdx 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 @@ + + + + IdentArk + 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 @@ + + + + IdentArk + 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. +