{
 "components": {
  "schemas": {
   "A2AIn": {
    "description": "An agent to agent message to send.",
    "properties": {
     "conversation_id": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Conversation the message belongs to (up to 200 characters). A new one is generated when omitted.",
      "title": "Conversation Id"
     },
     "from": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Sender: `agent:<name>` or `run:<id>`. Default: the calling principal (`principal:<id>`).",
      "title": "From"
     },
     "in_reply_to": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the message this one answers.",
      "title": "In Reply To"
     },
     "payload": {
      "description": "Content of the message, any JSON value. Screened for prompt injection before delivery.",
      "title": "Payload"
     },
     "to": {
      "description": "Recipient: `agent:<name>` or `run:<id>` (3 to 300 characters).",
      "maxLength": 300,
      "minLength": 3,
      "title": "To",
      "type": "string"
     },
     "type": {
      "description": "Message type: `request`, `response` or `event`.",
      "enum": [
       "request",
       "response",
       "event"
      ],
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "to",
     "type"
    ],
    "title": "A2AIn",
    "type": "object"
   },
   "AccessIn": {
    "description": "Callers allowed on an MCP server.",
    "properties": {
     "principals": {
      "description": "Users and agents (principal ids, up to 200) allowed to call the server; empty: every member of its project.",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Principals",
      "type": "array"
     }
    },
    "title": "AccessIn",
    "type": "object"
   },
   "Acl": {
    "description": "Access list of a knowledge base. Entries are identities: `*`, `user:<id>`, `agent:<id>`, `service:<id>`, `role:<role>`, `group:<group>` or a bare principal id.",
    "properties": {
     "readers": {
      "description": "Identities allowed to read and query. Default `[\"*\"]` (every principal of the tenant).",
      "items": {
       "type": "string"
      },
      "title": "Readers",
      "type": "array"
     },
     "writers": {
      "description": "Identities allowed to add and delete documents. Empty (default): `tenant_admin`, `developer` and `agent`.",
      "items": {
       "type": "string"
      },
      "title": "Writers",
      "type": "array"
     }
    },
    "title": "Acl",
    "type": "object"
   },
   "AclIn": {
    "description": "New ACL of a knowledge base.",
    "properties": {
     "apply_to_documents": {
      "default": true,
      "description": "When true (default), the documents that inherit the knowledge base ACL get the new readers.",
      "title": "Apply To Documents",
      "type": "boolean"
     },
     "readers": {
      "description": "Identities allowed to read and query. Default `[\"*\"]`.",
      "items": {
       "type": "string"
      },
      "title": "Readers",
      "type": "array"
     },
     "writers": {
      "description": "Identities allowed to write. Empty: `tenant_admin`, `developer` and `agent`.",
      "items": {
       "type": "string"
      },
      "title": "Writers",
      "type": "array"
     }
    },
    "title": "AclIn",
    "type": "object"
   },
   "ActionIn": {
    "description": "Containment action on an incident.",
    "properties": {
     "action": {
      "description": "`suspend_agent`, `resume_agent`, `kill_agent`, `suspend_model`, `disable_model`, `disable_provider`, `rotate_key` or `revoke_key`.",
      "title": "Action",
      "type": "string"
     },
     "reason": {
      "default": "",
      "description": "Why the action is taken, passed to the owning domain and kept in the trail. Default: `incident action <action>`.",
      "title": "Reason",
      "type": "string"
     },
     "target": {
      "additionalProperties": true,
      "description": "Target of the action: `id` or `name` (or `model_id`), plus `scope`, `kind` or `grace_seconds` depending on the action.",
      "title": "Target",
      "type": "object"
     }
    },
    "required": [
     "action",
     "target"
    ],
    "title": "ActionIn",
    "type": "object"
   },
   "AdvanceIn": {
    "description": "Move of a change to its next stage.",
    "properties": {
     "approval_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Approved request for a stage that needs an approval (second call).",
      "title": "Approval Id"
     },
     "evidence": {
      "additionalProperties": true,
      "description": "Results added to the change evidence, by key: `tests`, `staging_smoke`, `production_smoke`, each `{passed, failed, errors}`.",
      "title": "Evidence",
      "type": "object"
     }
    },
    "title": "AdvanceIn",
    "type": "object"
   },
   "AgentMemoryPolicyIn": {
    "description": "Engine choice and memory policy of one agent.",
    "properties": {
     "cognee_instance": {
      "anyOf": [
       {
        "maxLength": 63,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Cognee instance to use (default `cognee`).",
      "title": "Cognee Instance"
     },
     "engine": {
      "default": "builtin",
      "description": "`builtin` (default, Memory Manager store), `mem0` (persistent facts and memories), `cognee` (knowledge and relations) or `hybrid` (memories in Mem0, knowledge in Cognee, merged at recall). Session memory always stays builtin.",
      "enum": [
       "builtin",
       "mem0",
       "cognee",
       "hybrid"
      ],
      "title": "Engine",
      "type": "string"
     },
     "mem0_instance": {
      "anyOf": [
       {
        "maxLength": 63,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Mem0 instance to use (default `mem0`, the platform instance of the Navin Manager), for example a dedicated one.",
      "title": "Mem0 Instance"
     },
     "policy": {
      "$ref": "#/components/schemas/MemoryPolicy",
      "description": "Modes, scopes, memorization limits, retention, sharing and required isolation."
     }
    },
    "title": "AgentMemoryPolicyIn",
    "type": "object"
   },
   "AgentPatch": {
    "description": "Registry fields of an agent to change.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free description of the agent.",
      "title": "Description"
     },
     "labels": {
      "anyOf": [
       {
        "additionalProperties": {
         "type": "string"
        },
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Labels, string keys and string values; replaces the current labels.",
      "title": "Labels"
     },
     "owner": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 3,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owner of the agent (3 to 200 characters).",
      "title": "Owner"
     },
     "risk_level": {
      "anyOf": [
       {
        "enum": [
         "minimal",
         "limited",
         "high"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Risk level: `minimal`, `limited` or `high`.",
      "title": "Risk Level"
     }
    },
    "title": "AgentPatch",
    "type": "object"
   },
   "AlertIn": {
    "description": "One Alertmanager alert.",
    "properties": {
     "annotations": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Annotations of the alert; `summary` and `description` feed the incident.",
      "title": "Annotations",
      "type": "object"
     },
     "endsAt": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "When the alert ended (RFC 3339), for a resolved alert.",
      "title": "Endsat"
     },
     "fingerprint": {
      "description": "Alertmanager fingerprint, 1 to 200 characters, that ties the alert to its incident.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Fingerprint",
      "type": "string"
     },
     "generatorURL": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Link to the expression that produced the alert.",
      "title": "Generatorurl"
     },
     "labels": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Labels of the alert, such as `alertname`, `severity` and optionally `tenant`.",
      "title": "Labels",
      "type": "object"
     },
     "startsAt": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "When the alert started firing (RFC 3339).",
      "title": "Startsat"
     },
     "status": {
      "default": "firing",
      "description": "`firing` (default) or `resolved`.",
      "title": "Status",
      "type": "string"
     }
    },
    "required": [
     "fingerprint"
    ],
    "title": "AlertIn",
    "type": "object"
   },
   "AlertmanagerIn": {
    "description": "Alertmanager webhook payload.",
    "properties": {
     "alerts": {
      "description": "Alerts of the group, at most 500.",
      "items": {
       "$ref": "#/components/schemas/AlertIn"
      },
      "maxItems": 500,
      "title": "Alerts",
      "type": "array"
     },
     "groupKey": {
      "default": "",
      "description": "Key of the alert group in Alertmanager.",
      "title": "Groupkey",
      "type": "string"
     },
     "receiver": {
      "default": "",
      "description": "Name of the Alertmanager receiver.",
      "title": "Receiver",
      "type": "string"
     },
     "status": {
      "default": "firing",
      "description": "Status of the group, `firing` (default) or `resolved`; the status of each alert is the one used.",
      "title": "Status",
      "type": "string"
     },
     "version": {
      "default": "4",
      "description": "Payload version, `4` by default.",
      "title": "Version",
      "type": "string"
     }
    },
    "title": "AlertmanagerIn",
    "type": "object"
   },
   "AllocationPolicyIn": {
    "description": "GPU cost allocation policy.",
    "properties": {
     "currency": {
      "default": "USD",
      "description": "ISO 4217 currency of the prices, default `USD`.",
      "pattern": "^[A-Z]{3}$",
      "title": "Currency",
      "type": "string"
     },
     "deployment_pattern": {
      "default": "*",
      "description": "Glob pattern of the deployment ids the policy applies to, default `*`; the most specific pattern wins.",
      "title": "Deployment Pattern",
      "type": "string"
     },
     "effective_from": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Start of validity, ISO 8601.",
      "title": "Effective From"
     },
     "effective_to": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "End of validity, ISO 8601; null for no end.",
      "title": "Effective To"
     },
     "enabled": {
      "default": true,
      "description": "Whether the policy is used, default true.",
      "title": "Enabled",
      "type": "boolean"
     },
     "energy_kwh_price": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "Price of one kWh of energy, at least 0, default 0.",
      "title": "Energy Kwh Price"
     },
     "gpu_hourly_cost": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "Cost of one GPU hour, at least 0, default 0.",
      "title": "Gpu Hourly Cost"
     },
     "gpu_model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "GPU model the policy applies to; null for any model.",
      "title": "Gpu Model"
     },
     "name": {
      "description": "Name of the policy (at least 1 character).",
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "overhead_pct": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "Overhead added to the total, in percent, at least 0, default 0.",
      "title": "Overhead Pct"
     },
     "pue": {
      "anyOf": [
       {
        "minimum": 1.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "1",
      "description": "Power usage effectiveness of the data center, at least 1, default 1.",
      "title": "Pue"
     },
     "storage_gb": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "Storage of the deployment in GB, at least 0, default 0.",
      "title": "Storage Gb"
     },
     "storage_gb_month_price": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "Price of one GB of storage per month, at least 0, default 0.",
      "title": "Storage Gb Month Price"
     }
    },
    "required": [
     "name"
    ],
    "title": "AllocationPolicyIn",
    "type": "object"
   },
   "ApiKeyIn": {
    "description": "New API key: name, rights, optional project and environment binding, expiry.",
    "properties": {
     "clearance": {
      "default": "internal",
      "description": "Highest data classification the credential may read: `public`, `internal` (default), `confidential`, `restricted` or `secret`.",
      "enum": [
       "public",
       "internal",
       "confidential",
       "restricted",
       "secret"
      ],
      "title": "Clearance",
      "type": "string"
     },
     "environment": {
      "anyOf": [
       {
        "enum": [
         "dev",
         "test",
         "staging",
         "prod"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Environment the key is bound to: `dev`, `test`, `staging` or `prod`. When null, the `X-Environment` header decides.",
      "title": "Environment"
     },
     "expires_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Date and time (ISO 8601) after which the key answers 401 `api_key_expired`. Null with no `expires_in_days`: the key never expires.",
      "title": "Expires At"
     },
     "expires_in_days": {
      "anyOf": [
       {
        "maximum": 3650.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime in days, 1 to 3650. Used only when `expires_at` is not given.",
      "title": "Expires In Days"
     },
     "name": {
      "description": "Display name of the key, 1 to 200 characters, for example the pipeline that uses it.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "project": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Project the key is bound to. When null, the caller picks the project with the `X-Project` header.",
      "title": "Project"
     },
     "roles": {
      "description": "Roles granted to the credential. You can only grant roles you hold yourself, unless you are `tenant_admin`; `platform_admin` can only be granted by a platform administrator.",
      "items": {
       "enum": [
        "platform_admin",
        "tenant_admin",
        "security_officer",
        "finops",
        "developer",
        "auditor",
        "agent",
        "viewer",
        "soc_analyst",
        "ai_governance_officer",
        "data_steward",
        "application_owner",
        "ai_platform_engineer",
        "business_owner",
        "support_engineer"
       ],
       "type": "string"
      },
      "title": "Roles",
      "type": "array"
     },
     "scopes": {
      "description": "Scopes granted to the credential, as glob patterns (`models:invoke`, `admin:*`). Each scope must be held by the caller (403 `forbidden`, reason `scope_not_held`). Empty list by default.",
      "items": {
       "type": "string"
      },
      "title": "Scopes",
      "type": "array"
     }
    },
    "required": [
     "name"
    ],
    "title": "ApiKeyIn",
    "type": "object"
   },
   "AppEventIn": {
    "additionalProperties": false,
    "description": "An application audit event. The actor, the sequence, the hashes and `occurred_at` are always set by the server; any other field is refused, and the action lives in the `app.` namespace, apart from platform events.",
    "properties": {
     "action": {
      "description": "Action name in the `app.` namespace, lowercase, at most 128 characters, for example `app.invoice.approved`.",
      "maxLength": 128,
      "pattern": "^app\\.[a-z0-9]+(?:[._-][a-z0-9]+)*$",
      "title": "Action",
      "type": "string"
     },
     "classification": {
      "anyOf": [
       {
        "enum": [
         "public",
         "internal",
         "confidential",
         "restricted",
         "secret"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Data classification of the event: `public`, `internal`, `confidential`, `restricted` or `secret`.",
      "title": "Classification"
     },
     "details": {
      "additionalProperties": true,
      "description": "Free attributes of the event, at most 16384 bytes once serialized.",
      "title": "Details",
      "type": "object"
     },
     "event_time": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "When the action happened on the client clock (ISO 8601), at most the allowed clock skew ahead of the server. Default: the server time.",
      "title": "Event Time"
     },
     "outcome": {
      "default": "success",
      "description": "`success` (default), `failure` or `error`.",
      "enum": [
       "success",
       "failure",
       "error"
      ],
      "title": "Outcome",
      "type": "string"
     },
     "resource": {
      "$ref": "#/components/schemas/AppResource",
      "description": "Resource the event is about."
     },
     "trace_id": {
      "anyOf": [
       {
        "pattern": "^[a-f0-9]{32}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "W3C trace id, 32 lowercase hexadecimal characters, to correlate the event with a trace.",
      "title": "Trace Id"
     }
    },
    "required": [
     "action",
     "resource"
    ],
    "title": "AppEventIn",
    "type": "object"
   },
   "AppResource": {
    "additionalProperties": false,
    "description": "Resource of an application audit event.",
    "properties": {
     "id": {
      "description": "Resource identifier, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Id",
      "type": "string"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Readable name of the resource, at most 200 characters, optional.",
      "title": "Name"
     },
     "type": {
      "description": "Resource type, lowercase letters, digits and underscores, starting with a letter, at most 64 characters.",
      "pattern": "^[a-z][a-z0-9_]{0,63}$",
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "type",
     "id"
    ],
    "title": "AppResource",
    "type": "object"
   },
   "ApplicationIn": {
    "description": "An application to register.",
    "properties": {
     "agents": {
      "description": "Agents granted to the application (names or patterns).",
      "items": {
       "type": "string"
      },
      "title": "Agents",
      "type": "array"
     },
     "environments": {
      "description": "Environments it may be deployed to (1 to 10). Default `[\"dev\"]`.",
      "items": {
       "type": "string"
      },
      "maxItems": 10,
      "minItems": 1,
      "title": "Environments",
      "type": "array"
     },
     "kind": {
      "description": "`agent_app`, `assistant`, `workflow` or `external_agent`.",
      "enum": [
       "agent_app",
       "assistant",
       "workflow",
       "external_agent"
      ],
      "title": "Kind",
      "type": "string"
     },
     "mcp_servers": {
      "description": "MCP servers its external agents may call (names or patterns).",
      "items": {
       "type": "string"
      },
      "title": "Mcp Servers",
      "type": "array"
     },
     "models": {
      "description": "Models its external agents may use (identifiers or patterns).",
      "items": {
       "type": "string"
      },
      "title": "Models",
      "type": "array"
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits, `.`, `_`, `-`, 1 to 128 characters.",
      "pattern": "^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$",
      "title": "Name",
      "type": "string"
     },
     "origin": {
      "default": "internal",
      "description": "`internal` (default) or `third_party`; forced to `third_party` for an `external_agent`.",
      "enum": [
       "internal",
       "third_party"
      ],
      "title": "Origin",
      "type": "string"
     },
     "owner": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owner of the application. Default: the caller.",
      "title": "Owner"
     },
     "plugins": {
      "description": "Plugins granted to the application (names or patterns).",
      "items": {
       "type": "string"
      },
      "title": "Plugins",
      "type": "array"
     },
     "project": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Project of the application. Default: the `X-Project` header of the request.",
      "title": "Project"
     },
     "risk_level": {
      "default": "medium",
      "description": "`low`, `medium` (default) or `high`.",
      "enum": [
       "low",
       "medium",
       "high"
      ],
      "title": "Risk Level",
      "type": "string"
     },
     "tools": {
      "description": "Tools its external agents may invoke (names or patterns such as `crm.*`).",
      "items": {
       "type": "string"
      },
      "title": "Tools",
      "type": "array"
     }
    },
    "required": [
     "name",
     "kind"
    ],
    "title": "ApplicationIn",
    "type": "object"
   },
   "ApprovalIn": {
    "description": "New approval request.",
    "properties": {
     "action": {
      "description": "Action to approve, 1 to 200 characters, for example `tool.call`, `promotion`, `break_glass` or `mandate`.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Action",
      "type": "string"
     },
     "approver_roles": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Roles allowed to decide. Default: `tenant_admin`, `security_officer`, `developer`, `business_owner`.",
      "title": "Approver Roles"
     },
     "expires_in_seconds": {
      "anyOf": [
       {
        "maximum": 2592000.0,
        "minimum": 60.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime of the request in seconds, 60 to 2592000 (30 days). Default: the platform setting, 86400 (24 hours).",
      "title": "Expires In Seconds"
     },
     "payload": {
      "additionalProperties": true,
      "description": "Details of the action shown to the approvers and checked when the approval is used. `excluded_approvers` lists subjects that may not approve.",
      "title": "Payload",
      "type": "object"
     },
     "quorum": {
      "default": 1,
      "description": "Number of `approve` decisions needed, 1 to 10 (default 1).",
      "maximum": 10.0,
      "minimum": 1.0,
      "title": "Quorum",
      "type": "integer"
     },
     "reason": {
      "default": "",
      "description": "Why the approval is requested, shown to the approvers (empty by default).",
      "title": "Reason",
      "type": "string"
     },
     "resource_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the resource concerned, optional.",
      "title": "Resource Id"
     },
     "resource_type": {
      "description": "Type of the resource concerned, 1 to 100 characters, for example `tool` or `model`.",
      "maxLength": 100,
      "minLength": 1,
      "title": "Resource Type",
      "type": "string"
     },
     "run_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Agent run waiting for the decision, optional. It resumes on approval and fails on refusal, expiry or cancellation.",
      "title": "Run Id"
     }
    },
    "required": [
     "action",
     "resource_type"
    ],
    "title": "ApprovalIn",
    "type": "object"
   },
   "AssessmentIn": {
    "description": "New EU AI Act risk assessment.",
    "properties": {
     "answers": {
      "additionalProperties": true,
      "description": "Questionnaire answers; keys set to true count as use cases for the classification.",
      "title": "Answers",
      "type": "object"
     },
     "evidence": {
      "description": "Evidence attached to the assessment.",
      "items": {
       "$ref": "#/components/schemas/eai__domains__risk__EvidenceIn"
      },
      "title": "Evidence",
      "type": "array"
     },
     "owner": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Subject accountable for the system. Default: the caller.",
      "title": "Owner"
     },
     "status": {
      "default": "submitted",
      "description": "`draft`, `submitted` (default), `approved` or `rejected`.",
      "title": "Status",
      "type": "string"
     },
     "target": {
      "$ref": "#/components/schemas/eai__domains__risk__Target",
      "description": "AI system assessed."
     },
     "use_cases": {
      "description": "Declared use cases, for example `employment`, `credit_scoring`, `interacts_with_humans` or `social_scoring`.",
      "items": {
       "type": "string"
      },
      "title": "Use Cases",
      "type": "array"
     }
    },
    "required": [
     "target"
    ],
    "title": "AssessmentIn",
    "type": "object"
   },
   "AssumeIn": {
    "additionalProperties": false,
    "description": "Request of a signed ExecutionContext acting as a service identity.",
    "properties": {
     "audience": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 10,
        "minItems": 1,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Services allowed to accept the context, 1 to 10 known audiences. Null: the default audience of the Context Authority.",
      "title": "Audience"
     },
     "purpose": {
      "description": "Why the identity is assumed, 3 to 500 characters. Written to the audit trail and the signed context.",
      "maxLength": 500,
      "minLength": 3,
      "title": "Purpose",
      "type": "string"
     },
     "scopes": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 50,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Scopes requested, at most 50. Default: the scopes of the identity. Each must be granted by the identity and held by the caller.",
      "title": "Scopes"
     },
     "ttl_seconds": {
      "default": 900,
      "description": "Lifetime of the context in seconds, 30 to 3600 (default 900).",
      "maximum": 3600.0,
      "minimum": 30.0,
      "title": "Ttl Seconds",
      "type": "integer"
     }
    },
    "required": [
     "purpose"
    ],
    "title": "AssumeIn",
    "type": "object"
   },
   "BreakGlassContextIn": {
    "description": "Options of the execution context of a break glass grant.",
    "properties": {
     "audience": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 10,
        "minItems": 1,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Services allowed to accept the context, 1 to 10 known audiences. Null: the default audience.",
      "title": "Audience"
     },
     "ttl_seconds": {
      "anyOf": [
       {
        "maximum": 86400.0,
        "minimum": 30.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime of the context in seconds, 30 to 86400, never beyond the grant expiry. Null: the default lifetime.",
      "title": "Ttl Seconds"
     }
    },
    "title": "BreakGlassContextIn",
    "type": "object"
   },
   "BreakGlassIn": {
    "description": "Break glass request.",
    "properties": {
     "beneficiary": {
      "anyOf": [
       {
        "maxLength": 300,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Subject who receives the elevation. Default: the caller.",
      "title": "Beneficiary"
     },
     "duration_seconds": {
      "description": "Duration of the elevation once approved, from 60 seconds to the platform maximum (3600 by default).",
      "minimum": 60.0,
      "title": "Duration Seconds",
      "type": "integer"
     },
     "incident_ref": {
      "anyOf": [
       {
        "maxLength": 300,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the incident that justifies the request, optional.",
      "title": "Incident Ref"
     },
     "reason": {
      "description": "Justification, 10 to 4000 characters, shown to the approvers.",
      "maxLength": 4000,
      "minLength": 10,
      "title": "Reason",
      "type": "string"
     },
     "roles": {
      "description": "Tenant roles granted, at most 8, never `platform_admin`. Roles or scopes are required.",
      "items": {
       "type": "string"
      },
      "maxItems": 8,
      "title": "Roles",
      "type": "array"
     },
     "scopes": {
      "description": "Scopes granted, at most 100 patterns.",
      "items": {
       "type": "string"
      },
      "maxItems": 100,
      "title": "Scopes",
      "type": "array"
     }
    },
    "required": [
     "reason",
     "duration_seconds"
    ],
    "title": "BreakGlassIn",
    "type": "object"
   },
   "BundleIn": {
    "description": "Options of an OPA bundle publication.",
    "properties": {
     "data": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Content of the `data.json` file of the bundle, under the `eai` root: `{\"eai\": {...}}`.",
      "title": "Data"
     },
     "revision": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9._-]{1,100}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Revision name, 1 to 100 letters, digits, `.`, `_` or `-`. Default: generated.",
      "title": "Revision"
     }
    },
    "title": "BundleIn",
    "type": "object"
   },
   "BusinessUnitIn": {
    "description": "New business unit.",
    "properties": {
     "description": {
      "default": "",
      "description": "Description, at most 2000 characters (empty by default).",
      "maxLength": 2000,
      "title": "Description",
      "type": "string"
     },
     "metadata": {
      "additionalProperties": true,
      "description": "Free key-value pairs stored with the object. Checked by the database: a refused object answers 422 `invalid_metadata`.",
      "title": "Metadata",
      "type": "object"
     },
     "name": {
      "description": "Display name, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "organization_id": {
      "description": "Organization that holds the unit. Required.",
      "title": "Organization Id",
      "type": "string"
     },
     "parent_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Parent unit in the same organization; null for a top level unit. Cannot be changed later.",
      "title": "Parent Id"
     },
     "slug": {
      "description": "Short identifier, lowercase letters, digits and hyphens, starting with a letter or a digit, at most 63 characters. Unique, it cannot be changed later.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
      "title": "Slug",
      "type": "string"
     }
    },
    "required": [
     "organization_id",
     "slug",
     "name"
    ],
    "title": "BusinessUnitIn",
    "type": "object"
   },
   "BusinessUnitPatch": {
    "description": "Changes to a business unit; omitted fields keep their value.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New description, at most 2000 characters.",
      "title": "Description"
     },
     "expected_version": {
      "anyOf": [
       {
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version the caller last read. A stale version answers 409 `version_conflict` (optimistic concurrency).",
      "title": "Expected Version"
     },
     "metadata": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free key-value pairs stored with the object. Checked by the database: a refused object answers 422 `invalid_metadata`.",
      "title": "Metadata"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New display name, 1 to 200 characters.",
      "title": "Name"
     },
     "status": {
      "anyOf": [
       {
        "enum": [
         "active",
         "archived"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`active` or `archived`.",
      "title": "Status"
     }
    },
    "title": "BusinessUnitPatch",
    "type": "object"
   },
   "ChangeIn": {
    "description": "A change request to open.",
    "properties": {
     "kind": {
      "description": "Kind of object: `prompt`, `skill`, `connector`, `rule`, `model`, `policy`, `tool`, `agent` or `pack`.",
      "enum": [
       "prompt",
       "skill",
       "connector",
       "rule",
       "model",
       "policy",
       "tool",
       "agent",
       "pack"
      ],
      "title": "Kind",
      "type": "string"
     },
     "ref": {
      "description": "Name of the object: lowercase letters, digits, `.`, `_` and `-`, 1 to 128 characters, starting and ending with a letter or digit.",
      "pattern": "^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$",
      "title": "Ref",
      "type": "string"
     },
     "title": {
      "default": "",
      "description": "Title of the change (up to 300 characters).",
      "maxLength": 300,
      "title": "Title",
      "type": "string"
     },
     "version": {
      "description": "Version of the object the change brings (1 to 64 characters).",
      "maxLength": 64,
      "minLength": 1,
      "title": "Version",
      "type": "string"
     }
    },
    "required": [
     "kind",
     "ref",
     "version"
    ],
    "title": "ChangeIn",
    "type": "object"
   },
   "ChannelAuth": {
    "description": "Authentication of the end users of a channel.",
    "properties": {
     "secret_ref": {
      "anyOf": [
       {
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the secret (key, webhook signing secret), `openbao://...` or `env://...`.",
      "title": "Secret Ref"
     },
     "type": {
      "description": "`oidc`, `api_key`, `signed_webhook` or `anonymous`.",
      "enum": [
       "oidc",
       "api_key",
       "signed_webhook",
       "anonymous"
      ],
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "type"
    ],
    "title": "ChannelAuth",
    "type": "object"
   },
   "ChannelInstallIn": {
    "description": "Installation of a channel from a Navin channel adapter.",
    "properties": {
     "agent_ref": {
      "anyOf": [
       {
        "pattern": "^[a-z]+:[A-Za-z0-9._/@:-]+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Agent that answers on the channel, as `<kind>:<name>`, for example `agent:support`.",
      "title": "Agent Ref"
     },
     "auth": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ChannelAuth"
       },
       {
        "type": "null"
       }
      ],
      "description": "End user authentication. Default `api_key`."
     },
     "dlp": {
      "anyOf": [
       {
        "additionalProperties": {
         "enum": [
          "off",
          "detect",
          "mask",
          "block"
         ],
         "type": "string"
        },
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "DLP mode per direction, each `off`, `detect`, `mask` or `block`. Default `{inbound: detect, outbound: mask}`.",
      "title": "Dlp"
     },
     "limits": {
      "anyOf": [
       {
        "additionalProperties": {
         "type": "integer"
        },
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Integer limits. Default `{max_message_bytes: 65536, rate_per_minute: 60}`.",
      "title": "Limits"
     },
     "name": {
      "anyOf": [
       {
        "pattern": "^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Channel name (default `<channel>-<project slug>`); lowercase letters, digits, `.`, `_`, `-`, up to 128 characters.",
      "title": "Name"
     },
     "secret_refs": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Secret fields of the contract as `openbao://` or `env://` references, by field name.",
      "title": "Secret Refs",
      "type": "object"
     },
     "settings": {
      "additionalProperties": true,
      "description": "Non secret fields of the channel contract, each checked against its kind (string up to 2000 characters, int, bool, list, enum).",
      "title": "Settings",
      "type": "object"
     }
    },
    "title": "ChannelInstallIn",
    "type": "object"
   },
   "ChannelPatch": {
    "description": "Fields of a channel to change.",
    "properties": {
     "owner": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 3,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owner of the channel (3 to 200 characters).",
      "title": "Owner"
     },
     "status": {
      "anyOf": [
       {
        "enum": [
         "active",
         "disabled"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`active` or `disabled`.",
      "title": "Status"
     }
    },
    "title": "ChannelPatch",
    "type": "object"
   },
   "CheckIn": {
    "description": "Relation check request.",
    "properties": {
     "contextual_tuples": {
      "description": "Up to 20 tuples `{subject, relation, object}` taken as true for this check only, never stored.",
      "items": {
       "additionalProperties": {
        "type": "string"
       },
       "type": "object"
      },
      "maxItems": 20,
      "title": "Contextual Tuples",
      "type": "array"
     },
     "object": {
      "description": "Object checked, `<type>:<id>`, for example `project:42`.",
      "pattern": "^[a-z_][a-z0-9_]*:[^\\s]+$",
      "title": "Object",
      "type": "string"
     },
     "relation": {
      "description": "Relation name, lowercase letters, digits and underscores, for example `viewer`.",
      "pattern": "^[a-z_][a-z0-9_]*$",
      "title": "Relation",
      "type": "string"
     },
     "subject": {
      "description": "Subject checked, `<type>:<id>`: `user:alice`, `group:fin#member` or `user:*`.",
      "pattern": "^[a-z_][a-z0-9_]*:[^\\s]+$",
      "title": "Subject",
      "type": "string"
     }
    },
    "required": [
     "subject",
     "relation",
     "object"
    ],
    "title": "CheckIn",
    "type": "object"
   },
   "CheckpointIn": {
    "description": "A checkpoint to save on a run.",
    "properties": {
     "label": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Label of the checkpoint (up to 200 characters).",
      "title": "Label"
     },
     "state": {
      "description": "State to save, any JSON value. Default: empty object.",
      "title": "State"
     }
    },
    "title": "CheckpointIn",
    "type": "object"
   },
   "ClassifyIn": {
    "description": "Classification request: a text or a media.",
    "properties": {
     "language": {
      "default": "en",
      "description": "Language of the text for the recognizers, for example `en` (default) or `fr`.",
      "title": "Language",
      "type": "string"
     },
     "media_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of an uploaded media whose stored classification is returned.",
      "title": "Media Id"
     },
     "text": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Text to classify.",
      "title": "Text"
     }
    },
    "title": "ClassifyIn",
    "type": "object"
   },
   "ClientCertificateIn": {
    "additionalProperties": false,
    "description": "Client certificate and private key (PEM) added to the method for mutual TLS. Unknown fields are refused.",
    "properties": {
     "client_cert": {
      "anyOf": [
       {
        "maxLength": 65536,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Client certificate, PEM, 65536 characters at most.",
      "title": "Client Cert"
     },
     "client_key": {
      "anyOf": [
       {
        "maxLength": 65536,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Private key of the client certificate, PEM, 65536 characters at most. Relayed to the Manager, never audited.",
      "title": "Client Key"
     }
    },
    "title": "ClientCertificateIn",
    "type": "object"
   },
   "ClusterIn": {
    "description": "New cluster (environment) of the Manager.",
    "properties": {
     "description": {
      "default": "",
      "description": "Free description, 500 characters at most.",
      "maxLength": 500,
      "title": "Description",
      "type": "string"
     },
     "mode": {
      "default": "production",
      "description": "`production` (default) or `sandbox`.",
      "pattern": "^(production|sandbox)$",
      "title": "Mode",
      "type": "string"
     },
     "name": {
      "description": "Name of the cluster, 1 to 80 characters.",
      "maxLength": 80,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "profile": {
      "anyOf": [
       {
        "pattern": "^(development|standard|banking-secure|air-gapped|hybrid)$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Deployment profile: `development`, `standard`, `banking-secure`, `air-gapped` or `hybrid`; omitted for the Manager default.",
      "title": "Profile"
     }
    },
    "required": [
     "name"
    ],
    "title": "ClusterIn",
    "type": "object"
   },
   "CommitIn": {
    "description": "Measured amount that replaces the reserved one.",
    "properties": {
     "cost": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "Measured cost in the currency of the reservation, at least 0, default 0.",
      "title": "Cost"
     },
     "tokens": {
      "default": 0,
      "description": "Measured tokens, at least 0, default 0.",
      "minimum": 0.0,
      "title": "Tokens",
      "type": "integer"
     }
    },
    "title": "CommitIn",
    "type": "object"
   },
   "ComplianceBrandingIn": {
    "additionalProperties": false,
    "description": "Branding fields to write; an absent field is kept, null brings it back to the default of the runtime.",
    "properties": {
     "agent_name": {
      "anyOf": [
       {
        "maxLength": 80,
        "minLength": 1,
        "pattern": "^[^<>\\x00-\\x1f\\x7f]+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the agent shown to the users, 1 to 80 characters, without `<`, `>` nor control characters.",
      "title": "Agent Name"
     },
     "app_url": {
      "anyOf": [
       {
        "maxLength": 2048,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "URL of the web application of the instance once known, https only, without credentials (up to 2048 characters).",
      "title": "App Url"
     },
     "expected_version": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Branding version the change is based on; another current version answers 409 `compliance_branding_version_conflict`.",
      "title": "Expected Version"
     },
     "navbar_color": {
      "anyOf": [
       {
        "pattern": "^#[0-9A-Fa-f]{6}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Colour of the top bar, `#RRGGBB`; the text on it is black or white with a contrast of 4.5:1 or more.",
      "title": "Navbar Color"
     },
     "sidebar_color": {
      "anyOf": [
       {
        "pattern": "^#[0-9A-Fa-f]{6}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Colour of the sidebar, `#RRGGBB`; the text on it is black or white with a contrast of 4.5:1 or more.",
      "title": "Sidebar Color"
     }
    },
    "title": "ComplianceBrandingIn",
    "type": "object"
   },
   "ComplianceInstanceIn": {
    "description": "A Compliance & Audit Agent instance to create in draft.",
    "properties": {
     "business_unit_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Business unit of the instance (UUID), checked at validation.",
      "title": "Business Unit Id"
     },
     "deployment_model": {
      "description": "`shared` (the existing shared runtime) or `dedicated` (a runtime installed by the Navin Manager).",
      "enum": [
       "shared",
       "dedicated"
      ],
      "title": "Deployment Model",
      "type": "string"
     },
     "description": {
      "default": "",
      "description": "Free description (up to 2000 characters).",
      "maxLength": 2000,
      "title": "Description",
      "type": "string"
     },
     "embedding_model": {
      "description": "Embedding model of the registry (capability `embeddings`), used by the knowledge base of the instance.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Embedding Model",
      "type": "string"
     },
     "generation_model": {
      "description": "Generation model of the registry (capability `chat`) used by the copilot.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Generation Model",
      "type": "string"
     },
     "id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Immutable identifier (UUID) of the instance; generated when absent.",
      "title": "Id"
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 63 characters.",
      "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$",
      "title": "Name",
      "type": "string"
     },
     "organization_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Organization of the instance (UUID), checked at validation.",
      "title": "Organization Id"
     },
     "pack": {
      "anyOf": [
       {
        "enum": [
         "banking",
         "insurance",
         "industry"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Sector pack loaded on top of the generic core: `banking`, `insurance` or `industry`; null for the core alone.",
      "title": "Pack"
     },
     "project": {
      "description": "Project of the instance (identifier or slug); the caller must be a tenant administrator or an owner of it.",
      "maxLength": 100,
      "minLength": 1,
      "title": "Project",
      "type": "string"
     },
     "sector": {
      "default": "generic",
      "description": "Sector of the instance: `generic` (default), `banking`, `insurance` or `industry`.",
      "enum": [
       "generic",
       "banking",
       "insurance",
       "industry"
      ],
      "title": "Sector",
      "type": "string"
     },
     "version": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version to deploy; default: the version the runtime reports in its OpenAPI document at the smoke step.",
      "title": "Version"
     }
    },
    "required": [
     "name",
     "project",
     "deployment_model",
     "generation_model",
     "embedding_model"
    ],
    "title": "ComplianceInstanceIn",
    "type": "object"
   },
   "ComplianceRestoreIn": {
    "description": "A restore request.",
    "properties": {
     "backup_id": {
      "description": "Identifier of the backup to restore.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Backup Id",
      "type": "string"
     }
    },
    "required": [
     "backup_id"
    ],
    "title": "ComplianceRestoreIn",
    "type": "object"
   },
   "ComplianceUpgradeIn": {
    "description": "An upgrade request.",
    "properties": {
     "version": {
      "description": "Version to deploy (letters, digits, `.`, `_`, `+`, `-`, up to 64 characters).",
      "pattern": "^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$",
      "title": "Version",
      "type": "string"
     }
    },
    "required": [
     "version"
    ],
    "title": "ComplianceUpgradeIn",
    "type": "object"
   },
   "ComponentIn": {
    "description": "One component used by a run.",
    "properties": {
     "attributes": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free attributes of the component, such as the provider of a model.",
      "title": "Attributes"
     },
     "digest": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Digest of the component, for example `sha256:<hex>`, at most 200 characters.",
      "title": "Digest"
     },
     "kind": {
      "description": "`model`, `prompt`, `tool`, `skill` or `plugin`.",
      "enum": [
       "model",
       "prompt",
       "tool",
       "skill",
       "plugin"
      ],
      "title": "Kind",
      "type": "string"
     },
     "name": {
      "description": "Name of the component, 1 to 300 characters.",
      "maxLength": 300,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "version": {
      "description": "Version of the component, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Version",
      "type": "string"
     }
    },
    "required": [
     "kind",
     "name",
     "version"
    ],
    "title": "ComponentIn",
    "type": "object"
   },
   "ComponentsIn": {
    "description": "Components reported for a run or one of its steps.",
    "properties": {
     "components": {
      "description": "Components used, 1 to 100.",
      "items": {
       "$ref": "#/components/schemas/ComponentIn"
      },
      "maxItems": 100,
      "minItems": 1,
      "title": "Components",
      "type": "array"
     },
     "step_seq": {
      "anyOf": [
       {
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Sequence number of the step (1 or more); omit it for the run as a whole.",
      "title": "Step Seq"
     }
    },
    "required": [
     "components"
    ],
    "title": "ComponentsIn",
    "type": "object"
   },
   "ConnectAuthIn": {
    "additionalProperties": false,
    "description": "Authentication method among those of the descriptor (`connect.auth`) and its fields. The secret fields are relayed to the Manager, which checks them on the service and seals them; they are never written to the audit. Unknown fields are refused.",
    "properties": {
     "fields": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Fields of the method (for example user and password), up to 16 text values.",
      "maxProperties": 16,
      "title": "Fields",
      "type": "object"
     },
     "method": {
      "anyOf": [
       {
        "pattern": "^[a-z][a-z0-9_]{1,39}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the method: lowercase letter then 1 to 39 lowercase letters, digits or underscores.",
      "title": "Method"
     }
    },
    "title": "ConnectAuthIn",
    "type": "object"
   },
   "ConnectIn": {
    "description": "Configure and Connect: an existing service of the customer (endpoint, authentication method and its fields, TLS with an optional private certificate authority, descriptor fields).",
    "properties": {
     "auth": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ConnectAuthIn"
       },
       {
        "type": "null"
       }
      ],
      "description": "Authentication method and its fields."
     },
     "ca_pem": {
      "anyOf": [
       {
        "maxLength": 65536,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Private certificate authority (PEM) that signs the service certificate, 65536 characters at most.",
      "title": "Ca Pem"
     },
     "config": {
      "additionalProperties": true,
      "description": "Fields of the connect section of the descriptor, up to 100 keys; the audit keeps the keys only.",
      "maxProperties": 100,
      "title": "Config",
      "type": "object"
     },
     "credentials_ref": {
      "anyOf": [
       {
        "maxLength": 512,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of credentials already stored, 512 characters at most; the audit only keeps whether it is set.",
      "title": "Credentials Ref"
     },
     "endpoint": {
      "description": "Address of the existing service, 1 to 2048 characters.",
      "maxLength": 2048,
      "minLength": 1,
      "title": "Endpoint",
      "type": "string"
     },
     "mtls": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ClientCertificateIn"
       },
       {
        "type": "null"
       }
      ],
      "description": "Client certificate for mutual TLS."
     },
     "name": {
      "description": "Catalog name of the service: lowercase letter then up to 62 lowercase letters, digits, dashes or underscores.",
      "pattern": "^[a-z][a-z0-9_-]{0,62}$",
      "title": "Name",
      "type": "string"
     },
     "tls_verify": {
      "default": true,
      "description": "Verify the TLS certificate of the service (default true).",
      "title": "Tls Verify",
      "type": "boolean"
     }
    },
    "required": [
     "name",
     "endpoint"
    ],
    "title": "ConnectIn",
    "type": "object"
   },
   "ConnectionIn": {
    "description": "Connection to save in the Manager: the test fields plus a name and a description.",
    "properties": {
     "description": {
      "default": "",
      "description": "Free description, 1000 characters at most.",
      "maxLength": 1000,
      "title": "Description",
      "type": "string"
     },
     "name": {
      "description": "Name of the connection, 1 to 100 characters.",
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "params": {
      "additionalProperties": true,
      "description": "Connection parameters (host, port, database, issuer...), up to 20 keys; the audit keeps the keys only.",
      "maxProperties": 20,
      "title": "Params",
      "type": "object"
     },
     "secret": {
      "anyOf": [
       {
        "maxLength": 4096,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Password or client secret, 4096 characters at most. Write only: sealed by the Manager, never returned nor audited. An empty value is not sent.",
      "title": "Secret"
     },
     "type": {
      "description": "`postgresql`, `redis` or `oidc`.",
      "pattern": "^(postgresql|redis|oidc)$",
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "type",
     "name"
    ],
    "title": "ConnectionIn",
    "type": "object"
   },
   "ConnectionTestIn": {
    "description": "Dry run of a connection: its type, its parameters and the secret, nothing is stored.",
    "properties": {
     "params": {
      "additionalProperties": true,
      "description": "Connection parameters, up to 20 keys.",
      "maxProperties": 20,
      "title": "Params",
      "type": "object"
     },
     "secret": {
      "anyOf": [
       {
        "maxLength": 4096,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Password or client secret used for the test, 4096 characters at most; never returned nor audited.",
      "title": "Secret"
     },
     "type": {
      "description": "`postgresql`, `redis` or `oidc`.",
      "pattern": "^(postgresql|redis|oidc)$",
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "type"
    ],
    "title": "ConnectionTestIn",
    "type": "object"
   },
   "ConnectorPatch": {
    "description": "Fields of a connector to change.",
    "properties": {
     "owner": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 3,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owner of the connector (3 to 200 characters).",
      "title": "Owner"
     },
     "status": {
      "anyOf": [
       {
        "enum": [
         "active",
         "disabled"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`active` or `disabled` (revokes the leases).",
      "title": "Status"
     }
    },
    "title": "ConnectorPatch",
    "type": "object"
   },
   "ConsentIn": {
    "description": "Consent of one participant of a realtime session.",
    "properties": {
     "method": {
      "default": "api",
      "description": "How the consent was captured: `verbal`, `click`, `written` or `api` (default).",
      "title": "Method",
      "type": "string"
     },
     "participant_identity": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9._:@-]{1,128}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identity of the participant (1 to 128 letters, digits, `.`, `_`, `:`, `@`, `-`). Default: the participant of the session.",
      "title": "Participant Identity"
     },
     "purpose": {
      "description": "Purpose the participant agrees to (1 to 500 characters).",
      "maxLength": 500,
      "minLength": 1,
      "title": "Purpose",
      "type": "string"
     },
     "recording_allowed": {
      "default": false,
      "description": "Whether the audio may be recorded. Default false.",
      "title": "Recording Allowed",
      "type": "boolean"
     },
     "retention_days": {
      "description": "How long transcripts and recordings are kept, in days (1 to 3650).",
      "maximum": 3650.0,
      "minimum": 1.0,
      "title": "Retention Days",
      "type": "integer"
     },
     "transcription_allowed": {
      "default": false,
      "description": "Whether the speech may be transcribed and stored. Default false.",
      "title": "Transcription Allowed",
      "type": "boolean"
     }
    },
    "required": [
     "purpose",
     "retention_days"
    ],
    "title": "ConsentIn",
    "type": "object"
   },
   "ControlIn": {
    "description": "Control adopted by the tenant.",
    "properties": {
     "code": {
      "description": "Code of the control, 1 to 64 characters: a catalogue code such as `EAI-GOV-01`, or a custom one. Unique in the tenant.",
      "maxLength": 64,
      "minLength": 1,
      "title": "Code",
      "type": "string"
     },
     "description": {
      "default": "",
      "description": "How the control is implemented (empty by default).",
      "title": "Description",
      "type": "string"
     },
     "evidence": {
      "description": "Evidence added to the control.",
      "items": {
       "$ref": "#/components/schemas/eai__domains__risk__EvidenceIn"
      },
      "title": "Evidence",
      "type": "array"
     },
     "frameworks": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Requirements covered per framework, keys among `iso_42001`, `nist_ai_rmf`, `gdpr` and `eu_ai_act`, for example `{\"gdpr\": [\"Art. 32\"]}`. Default: the catalogue mapping.",
      "title": "Frameworks"
     },
     "owner": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Subject accountable for the control. Default: the caller.",
      "title": "Owner"
     },
     "status": {
      "default": "planned",
      "description": "`planned` (default), `implemented`, `partially_implemented` or `not_applicable`.",
      "title": "Status",
      "type": "string"
     },
     "title": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Title. Default: the catalogue title; required for a custom code.",
      "title": "Title"
     }
    },
    "required": [
     "code"
    ],
    "title": "ControlIn",
    "type": "object"
   },
   "Dataset": {
    "description": "Dataset of a suite.",
    "properties": {
     "classification": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Data classification of the dataset: `public`, `internal`, `confidential`, `restricted` or `secret`.",
      "title": "Classification"
     },
     "ref": {
      "description": "Reference of the dataset, at least 1 character, for example `golden-faq`.",
      "minLength": 1,
      "title": "Ref",
      "type": "string"
     },
     "version": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version of the dataset, optional.",
      "title": "Version"
     }
    },
    "required": [
     "ref"
    ],
    "title": "Dataset",
    "type": "object"
   },
   "DecisionIn": {
    "description": "Decision of an approver.",
    "properties": {
     "comment": {
      "default": "",
      "description": "Comment kept with the decision (empty by default).",
      "title": "Comment",
      "type": "string"
     },
     "decision": {
      "description": "`approve` or `reject`.",
      "enum": [
       "approve",
       "reject"
      ],
      "title": "Decision",
      "type": "string"
     }
    },
    "required": [
     "decision"
    ],
    "title": "DecisionIn",
    "type": "object"
   },
   "DecisionNoteIn": {
    "description": "Note of a decision.",
    "properties": {
     "reason": {
      "default": "",
      "description": "Reason or note, at most 2000 characters (empty by default). Written to the audit trail.",
      "maxLength": 2000,
      "title": "Reason",
      "type": "string"
     }
    },
    "title": "DecisionNoteIn",
    "type": "object"
   },
   "DelegationIn": {
    "description": "New root delegation.",
    "properties": {
     "audience": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 20,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Services that may accept the delegation, at most 20 patterns. Default `eai-control-plane`.",
      "title": "Audience"
     },
     "data_classification_max": {
      "anyOf": [
       {
        "pattern": "^(public|internal|confidential|restricted|secret)$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Highest data classification the delegate may handle: `public`, `internal`, `confidential`, `restricted` or `secret`. Default: the caller clearance.",
      "title": "Data Classification Max"
     },
     "delegate": {
      "description": "Who receives the rights: `agent:<name>`, `app:<id>`, `service:<name>` or `subagent:<name>`, 3 to 250 characters.",
      "maxLength": 250,
      "minLength": 3,
      "title": "Delegate",
      "type": "string"
     },
     "expires_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Expiry date and time (ISO 8601), instead of `ttl_seconds`.",
      "title": "Expires At"
     },
     "max_depth": {
      "default": 0,
      "description": "How many levels of sub-delegation are allowed below, 0 to 10 (default 0).",
      "maximum": 10.0,
      "minimum": 0.0,
      "title": "Max Depth",
      "type": "integer"
     },
     "purpose": {
      "default": "",
      "description": "Purpose of the delegation, at most 2000 characters, kept in the trail.",
      "maxLength": 2000,
      "title": "Purpose",
      "type": "string"
     },
     "redelegation_allowed": {
      "default": false,
      "description": "When true and `max_depth` is above 0, the delegate may restrict the delegation for others (default false).",
      "title": "Redelegation Allowed",
      "type": "boolean"
     },
     "resources": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 100,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Resources the delegate may act on, at most 100 patterns such as `tool:crm.*`. Default `*`.",
      "title": "Resources"
     },
     "scopes": {
      "description": "Scopes delegated, at most 100. Patterns where `*` matches any sequence (letters, digits and `_ . : / @ * -`, at most 200 characters each); each must be covered by the caller scopes.",
      "items": {
       "type": "string"
      },
      "maxItems": 100,
      "title": "Scopes",
      "type": "array"
     },
     "session_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Session the delegation is bound to, optional.",
      "title": "Session Id"
     },
     "ttl_seconds": {
      "anyOf": [
       {
        "minimum": 60.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime in seconds, at least 60, within the platform maximum. Default: the platform default (8 hours).",
      "title": "Ttl Seconds"
     }
    },
    "required": [
     "delegate"
    ],
    "title": "DelegationIn",
    "type": "object"
   },
   "DeleteObjectIn": {
    "additionalProperties": false,
    "description": "Object to delete from a storage profile. Unknown fields are refused.",
    "properties": {
     "key": {
      "description": "Key of the object relative to the profile key prefix, 1 to 1024 characters, inside a presign prefix; no control character, no leading `/`, no `.` or `..` segment.",
      "maxLength": 1024,
      "minLength": 1,
      "title": "Key",
      "type": "string"
     },
     "version_id": {
      "anyOf": [
       {
        "maxLength": 1024,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version of the object to delete on a versioned bucket, 1 to 1024 characters. Omit it to delete the current version.",
      "title": "Version Id"
     }
    },
    "required": [
     "key"
    ],
    "title": "DeleteObjectIn",
    "type": "object"
   },
   "DeploymentIn": {
    "description": "A deployment request.",
    "properties": {
     "environment": {
      "description": "Target environment, one of the application environments (1 to 50 characters).",
      "maxLength": 50,
      "minLength": 1,
      "title": "Environment",
      "type": "string"
     },
     "reason": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Why the deployment is requested, shown to the approvers (up to 2000 characters).",
      "title": "Reason"
     },
     "version": {
      "description": "Version to deploy (1 to 100 characters).",
      "maxLength": 100,
      "minLength": 1,
      "title": "Version",
      "type": "string"
     }
    },
    "required": [
     "version",
     "environment"
    ],
    "title": "DeploymentIn",
    "type": "object"
   },
   "DetectionIn": {
    "description": "Detection to ingest.",
    "properties": {
     "agent": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Agent concerned, used for correlation.",
      "title": "Agent"
     },
     "confidence": {
      "default": 0.5,
      "description": "Confidence of the detector, 0 to 1 (default 0.5). Automatic containment needs at least 0.9.",
      "title": "Confidence",
      "type": "number"
     },
     "data_classification": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Classification of the data involved: `public` to `secret`.",
      "title": "Data Classification"
     },
     "evidence": {
      "additionalProperties": true,
      "description": "Evidence of the finding, at most 64000 bytes, sealed with the incident.",
      "title": "Evidence",
      "type": "object"
     },
     "fingerprint": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Deduplication key of the finding, at most 200 characters.",
      "title": "Fingerprint"
     },
     "kind": {
      "description": "Detection kind: `prompt_injection`, `data_exfiltration`, `secret_leak`, `runaway_agent`, `cost_loop`, `mcp_compromised`, `unsigned_plugin`, `privilege_escalation`, `rag_poisoning`, `policy_change_unaudited`, `policy_change_unauthorized`, `audit_tampering`, `runtime_threat`, `security_finding`.",
      "title": "Kind",
      "type": "string"
     },
     "occurred_at": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "When it happened (ISO 8601). Default: the reception time.",
      "title": "Occurred At"
     },
     "resource": {
      "additionalProperties": true,
      "description": "Resource concerned, free object such as `{\"type\": \"tool\", \"id\": \"...\"}`.",
      "title": "Resource",
      "type": "object"
     },
     "run_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Agent run concerned.",
      "title": "Run Id"
     },
     "session_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Session concerned.",
      "title": "Session Id"
     },
     "severity": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`sev1` to `sev4`. Default: the base severity of the kind.",
      "title": "Severity"
     },
     "source": {
      "default": "manual",
      "description": "Source: `guard`, `dlp`, `egress`, `quota`, `plugins`, `runtime`, `authz`, `policy`, `audit`, `knowledge`, `mcp`, `falco`, `tetragon`, `opensearch` or `manual` (default).",
      "title": "Source",
      "type": "string"
     },
     "targets": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Targets of the playbook reactions, keyed by `session`, `run`, `agent`, `identity`, `credential`, `workload`, `mcp`, `plugin`, `tool`, `connector`, `knowledge_base`, `model` or `application`.",
      "title": "Targets",
      "type": "object"
     },
     "user": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "User concerned, used for correlation.",
      "title": "User"
     }
    },
    "required": [
     "kind"
    ],
    "title": "DetectionIn",
    "type": "object"
   },
   "DetokenizeIn": {
    "description": "Detokenization request.",
    "properties": {
     "purpose": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Why the values are needed, passed to the policy as `context.purpose` and written to the audit trail.",
      "title": "Purpose"
     },
     "text": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Text whose tokens are found and replaced by their values.",
      "title": "Text"
     },
     "tokens": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tokens to resolve, `tok_<type>_<hex>`.",
      "title": "Tokens"
     }
    },
    "title": "DetokenizeIn",
    "type": "object"
   },
   "DlpIn": {
    "description": "DLP request.",
    "properties": {
     "language": {
      "default": "en",
      "description": "Language of the text for the recognizers, for example `en` (default) or `fr`.",
      "title": "Language",
      "type": "string"
     },
     "mode": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`detect`, `mask`, `tokenize` or `block`. Default: `detect` for inspect, `mask` for redact.",
      "title": "Mode"
     },
     "text": {
      "description": "Text to inspect or redact.",
      "title": "Text",
      "type": "string"
     }
    },
    "required": [
     "text"
    ],
    "title": "DlpIn",
    "type": "object"
   },
   "DocIn": {
    "description": "A document to ingest. Give `content` or `content_base64`.",
    "properties": {
     "chunk_readers": {
      "anyOf": [
       {
        "items": {
         "anyOf": [
          {
           "items": {
            "type": "string"
           },
           "type": "array"
          },
          {
           "type": "null"
          }
         ]
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Readers per chunk from the source permissions, by chunk position; `null` for a chunk keeps the document readers.",
      "title": "Chunk Readers"
     },
     "classification": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`public`, `internal`, `confidential`, `restricted` or `secret`. Default: the classification of the knowledge base; raised when personal data is detected.",
      "title": "Classification"
     },
     "collection": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Collection of the document inside the knowledge base (1 to 200 characters), used by the `collections` query filter. Default none.",
      "title": "Collection"
     },
     "content": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Content as text. Takes precedence over `content_base64`.",
      "title": "Content"
     },
     "content_base64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Content of a binary file (PDF, office document...), base64 encoded.",
      "title": "Content Base64"
     },
     "language": {
      "anyOf": [
       {
        "maxLength": 10,
        "minLength": 2,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Language of the document (ISO 639-1 code such as `fr` or `en`). Default: detected from the text; each chunk also gets its own detected language, which picks its full text configuration (`simple` when unknown).",
      "title": "Language"
     },
     "metadata": {
      "additionalProperties": true,
      "description": "Free key-value pairs stored with the object and returned as they are; the platform never interprets them.",
      "title": "Metadata",
      "type": "object"
     },
     "mime_type": {
      "default": "text/plain",
      "description": "Media type of the content. Default `text/plain`.",
      "title": "Mime Type",
      "type": "string"
     },
     "readers": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Readers of this document. Omitted: the readers of the knowledge base, kept in step with its ACL.",
      "title": "Readers"
     },
     "source_connector": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Connector the document comes from (1 to 200 characters); it must be active, and results from it are dropped once it is not.",
      "title": "Source Connector"
     },
     "title": {
      "default": "",
      "description": "Title of the document, also used as file name for the scan and the extraction. Default empty.",
      "title": "Title",
      "type": "string"
     },
     "uri": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Source URI. A new document with the same URI replaces the previous version.",
      "title": "Uri"
     }
    },
    "title": "DocIn",
    "type": "object"
   },
   "EncryptIn": {
    "description": "Encryption request.",
    "properties": {
     "aad": {
      "default": "",
      "description": "Associated data bound to the ciphertext; the same value is required to decrypt (empty by default).",
      "title": "Aad",
      "type": "string"
     },
     "key": {
      "description": "Key to use, by identifier (UUID) or name.",
      "title": "Key",
      "type": "string"
     },
     "plaintext": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "UTF-8 text to encrypt.",
      "title": "Plaintext"
     },
     "plaintext_base64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Bytes to encrypt, base64 encoded; used instead of `plaintext` when given.",
      "title": "Plaintext Base64"
     }
    },
    "required": [
     "key"
    ],
    "title": "EncryptIn",
    "type": "object"
   },
   "EnrollmentTokenIn": {
    "description": "Options of a new enrollment token.",
    "properties": {
     "expires_in_hours": {
      "default": 24,
      "description": "Lifetime of the token in hours, 1 to 720, default 24.",
      "maximum": 720.0,
      "minimum": 1.0,
      "title": "Expires In Hours",
      "type": "integer"
     },
     "max_uses": {
      "default": 10,
      "description": "Number of machines that may enroll with the token, 1 to 10000, default 10.",
      "maximum": 10000.0,
      "minimum": 1.0,
      "title": "Max Uses",
      "type": "integer"
     }
    },
    "title": "EnrollmentTokenIn",
    "type": "object"
   },
   "EntryIn": {
    "additionalProperties": false,
    "description": "A service of the vault: name, URL, login, password and API key or secret key (the last four optional). Unknown fields are refused.",
    "properties": {
     "api_key": {
      "default": "",
      "description": "API key or secret key, 8192 characters at most. Sealed; returned only by `POST .../reveal`.",
      "maxLength": 8192,
      "title": "Api Key",
      "type": "string"
     },
     "login": {
      "default": "",
      "description": "Login of the account, 320 characters at most.",
      "maxLength": 320,
      "title": "Login",
      "type": "string"
     },
     "name": {
      "description": "Name of the service, 1 to 120 characters, unique in the vault.",
      "maxLength": 120,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "password": {
      "default": "",
      "description": "Password, 4096 characters at most. Sealed; returned only by `POST .../reveal`.",
      "maxLength": 4096,
      "title": "Password",
      "type": "string"
     },
     "url": {
      "default": "",
      "description": "Address of the service, 2048 characters at most.",
      "maxLength": 2048,
      "title": "Url",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "EntryIn",
    "type": "object"
   },
   "EntryPatch": {
    "additionalProperties": false,
    "description": "Fields to change; an omitted field is kept, an empty password or key clears it. Unknown fields are refused.",
    "properties": {
     "api_key": {
      "anyOf": [
       {
        "maxLength": 8192,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New API key or secret key, 8192 characters at most; empty clears it.",
      "title": "Api Key"
     },
     "login": {
      "anyOf": [
       {
        "maxLength": 320,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New login, 320 characters at most.",
      "title": "Login"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 120,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New name, 1 to 120 characters, unique in the vault (case insensitive).",
      "title": "Name"
     },
     "password": {
      "anyOf": [
       {
        "maxLength": 4096,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New password, 4096 characters at most; empty clears it.",
      "title": "Password"
     },
     "url": {
      "anyOf": [
       {
        "maxLength": 2048,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New address, 2048 characters at most.",
      "title": "Url"
     }
    },
    "title": "EntryPatch",
    "type": "object"
   },
   "EnvironmentIn": {
    "description": "New environment of a project.",
    "properties": {
     "name": {
      "description": "`dev`, `test`, `staging` or `prod`.",
      "enum": [
       "dev",
       "test",
       "staging",
       "prod"
      ],
      "title": "Name",
      "type": "string"
     },
     "settings": {
      "additionalProperties": true,
      "description": "Free settings object of the environment (empty by default).",
      "title": "Settings",
      "type": "object"
     }
    },
    "required": [
     "name"
    ],
    "title": "EnvironmentIn",
    "type": "object"
   },
   "EraseIn": {
    "description": "Erasure request for one data subject.",
    "properties": {
     "dry_run": {
      "default": false,
      "description": "When true, counts what would be erased without deleting anything (default false).",
      "title": "Dry Run",
      "type": "boolean"
     },
     "include_documents": {
      "default": false,
      "description": "When true, also deletes the knowledge base documents created by the subject and their vectors (default false).",
      "title": "Include Documents",
      "type": "boolean"
     },
     "reason": {
      "default": "gdpr_art_17",
      "description": "Legal basis of the erasure, written to the audit trail. Default `gdpr_art_17`.",
      "title": "Reason",
      "type": "string"
     },
     "subject_id": {
      "description": "Subject to erase, as known by the platform (user subject), 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Subject Id",
      "type": "string"
     }
    },
    "required": [
     "subject_id"
    ],
    "title": "EraseIn",
    "type": "object"
   },
   "EstimateIn": {
    "description": "Planned call to price.",
    "properties": {
     "at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Date and time the price is taken at, ISO 8601; default now.",
      "title": "At"
     },
     "cache_hit_ratio": {
      "anyOf": [
       {
        "maximum": 1.0,
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Share of the input tokens expected from the cache, 0 to 1, priced as cached input.",
      "title": "Cache Hit Ratio"
     },
     "expected_output_tokens": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Expected output tokens, used when `max_tokens` is not set.",
      "title": "Expected Output Tokens"
     },
     "max_tokens": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum output tokens; when set, it is the output assumed for the worst case.",
      "title": "Max Tokens"
     },
     "model_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model of the call, matched against the model patterns of the price cards.",
      "title": "Model Id"
     },
     "provider": {
      "description": "Provider of the call (required).",
      "title": "Provider",
      "type": "string"
     },
     "reasoning_effort": {
      "anyOf": [
       {
        "enum": [
         "none",
         "minimal",
         "low",
         "medium",
         "high",
         "max"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reasoning effort (`none`, `minimal`, `low`, `medium`, `high`, `max`) giving a default reserve of reasoning tokens.",
      "title": "Reasoning Effort"
     },
     "reasoning_tokens": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Explicit reasoning tokens, at least 0; overrides the reserve of `reasoning_effort`.",
      "title": "Reasoning Tokens"
     },
     "region": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Region of the call; cards of this region win over the `*` ones.",
      "title": "Region"
     },
     "scope": {
      "additionalProperties": true,
      "description": "Scope used to find the matching quotas (`project`, `agent`, `user`, `model`, `provider`, `run`...); `model` and `provider` default to the call values.",
      "title": "Scope",
      "type": "object"
     },
     "units": {
      "additionalProperties": true,
      "description": "Planned units by price key, for example `{\"input_tokens\": 1200}`.",
      "title": "Units",
      "type": "object"
     },
     "usage_type": {
      "default": "llm",
      "description": "Usage type, default `llm`.",
      "title": "Usage Type",
      "type": "string"
     }
    },
    "required": [
     "provider"
    ],
    "title": "EstimateIn",
    "type": "object"
   },
   "EventIn": {
    "description": "An event to publish.",
    "properties": {
     "headers": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Headers of the event, string values. The trace context is added.",
      "title": "Headers",
      "type": "object"
     },
     "payload": {
      "description": "Content of the event, any JSON value. Trigger filters read it.",
      "title": "Payload"
     },
     "subject": {
      "description": "Subject of the event (1 to 255 characters, valid NATS subject without wildcards), for example `orders.created`.",
      "maxLength": 255,
      "minLength": 1,
      "title": "Subject",
      "type": "string"
     }
    },
    "required": [
     "subject"
    ],
    "title": "EventIn",
    "type": "object"
   },
   "ExceptionIn": {
    "description": "Time limited exception to a control or for a target.",
    "properties": {
     "approver": {
      "description": "Subject who approved the exception; it must not be the requester.",
      "minLength": 1,
      "title": "Approver",
      "type": "string"
     },
     "compensating_controls": {
      "default": "",
      "description": "Measures that reduce the risk meanwhile (empty by default).",
      "title": "Compensating Controls",
      "type": "string"
     },
     "control_code": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Code of the control waived, instead of `control_id`.",
      "title": "Control Code"
     },
     "control_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the control waived.",
      "title": "Control Id"
     },
     "expires_at": {
      "description": "End of the exception (ISO 8601), in the future and at most 365 days ahead.",
      "title": "Expires At",
      "type": "string"
     },
     "reason": {
      "description": "Why the control cannot be met, at least 3 characters.",
      "minLength": 3,
      "title": "Reason",
      "type": "string"
     },
     "target_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Target waived (agent, model...), when the exception is not about one control.",
      "title": "Target Ref"
     }
    },
    "required": [
     "reason",
     "approver",
     "expires_at"
    ],
    "title": "ExceptionIn",
    "type": "object"
   },
   "ExerciseIn": {
    "description": "DR exercise request.",
    "properties": {
     "plan_id": {
      "description": "Identifier of the DR plan to exercise, 1 to 100 characters.",
      "maxLength": 100,
      "minLength": 1,
      "title": "Plan Id",
      "type": "string"
     }
    },
    "required": [
     "plan_id"
    ],
    "title": "ExerciseIn",
    "type": "object"
   },
   "ExportIn": {
    "description": "Options of an audit export.",
    "properties": {
     "format": {
      "default": "ndjson",
      "description": "`ndjson` (default, one canonical event per line) or `csv` (one row per event, the canonical event in the last column).",
      "enum": [
       "ndjson",
       "csv"
      ],
      "title": "Format",
      "type": "string"
     },
     "from": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Start of the period (ISO 8601), included. Null: from the first event.",
      "title": "From"
     },
     "retention_days": {
      "default": 365,
      "description": "Days during which the stored files cannot be changed nor deleted, 1 to 3650 (default 365).",
      "maximum": 3650.0,
      "minimum": 1.0,
      "title": "Retention Days",
      "type": "integer"
     },
     "to": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "End of the period (ISO 8601), included. Null: up to the last event.",
      "title": "To"
     }
    },
    "title": "ExportIn",
    "type": "object"
   },
   "ExternalAgentIn": {
    "description": "A third party agent identity to create.",
    "properties": {
     "name": {
      "description": "Name of the identity: lowercase letters, digits, `.`, `_`, `-`; the key is named `app:<application>:<name>`.",
      "pattern": "^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$",
      "title": "Name",
      "type": "string"
     },
     "scopes": {
      "description": "Extra scopes of the key (up to 20), added to `tools:invoke` and `models:invoke`.",
      "items": {
       "type": "string"
      },
      "maxItems": 20,
      "title": "Scopes",
      "type": "array"
     }
    },
    "required": [
     "name"
    ],
    "title": "ExternalAgentIn",
    "type": "object"
   },
   "FxRateIn": {
    "description": "One exchange rate.",
    "properties": {
     "as_of": {
      "description": "Date and time the rate applies from, ISO 8601.",
      "format": "date-time",
      "title": "As Of",
      "type": "string"
     },
     "base": {
      "description": "Base currency, ISO 4217 (three capital letters).",
      "pattern": "^[A-Z]{3}$",
      "title": "Base",
      "type": "string"
     },
     "quote": {
      "description": "Quote currency, ISO 4217 (three capital letters).",
      "pattern": "^[A-Z]{3}$",
      "title": "Quote",
      "type": "string"
     },
     "rate": {
      "anyOf": [
       {
        "exclusiveMinimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "description": "Units of `quote` for one unit of `base`, greater than 0.",
      "title": "Rate"
     },
     "source": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Where the rate comes from; default `manual`.",
      "title": "Source"
     }
    },
    "required": [
     "base",
     "quote",
     "rate",
     "as_of"
    ],
    "title": "FxRateIn",
    "type": "object"
   },
   "FxRatesIn": {
    "description": "Batch of exchange rates.",
    "properties": {
     "rates": {
      "description": "Rates to add or replace, 1 to 1000.",
      "items": {
       "$ref": "#/components/schemas/FxRateIn"
      },
      "maxItems": 1000,
      "minItems": 1,
      "title": "Rates",
      "type": "array"
     }
    },
    "required": [
     "rates"
    ],
    "title": "FxRatesIn",
    "type": "object"
   },
   "GateIn": {
    "description": "Quality gate check request.",
    "properties": {
     "run_missing": {
      "default": false,
      "description": "When true, runs now the suites without any finished run (default false).",
      "title": "Run Missing",
      "type": "boolean"
     },
     "suite_ids": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only these blocking suites. Null: every blocking suite of the target.",
      "title": "Suite Ids"
     },
     "target": {
      "$ref": "#/components/schemas/eai__domains__evaluation__Target",
      "description": "Target whose blocking suites are checked; `version` restricts to the runs of that version."
     }
    },
    "required": [
     "target"
    ],
    "title": "GateIn",
    "type": "object"
   },
   "GpuSampleIn": {
    "description": "One GPU utilization sample.",
    "properties": {
     "deployment_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model deployment running on the GPU during the sample.",
      "title": "Deployment Id"
     },
     "gpu_model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model of the GPU, used to pick the allocation policy.",
      "title": "Gpu Model"
     },
     "gpu_uuid": {
      "description": "UUID of the GPU (required).",
      "minLength": 1,
      "title": "Gpu Uuid",
      "type": "string"
     },
     "interval_seconds": {
      "anyOf": [
       {
        "exclusiveMinimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "description": "Duration the sample covers, in seconds, greater than 0.",
      "title": "Interval Seconds"
     },
     "memory_used_gb": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "GPU memory used in GB, at least 0, default 0.",
      "title": "Memory Used Gb"
     },
     "node": {
      "description": "Node that hosts the GPU (required).",
      "minLength": 1,
      "title": "Node",
      "type": "string"
     },
     "power_w": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "Power draw in watts, at least 0, default 0; used for the energy cost.",
      "title": "Power W"
     },
     "sampled_at": {
      "description": "Time of the sample, ISO 8601.",
      "format": "date-time",
      "title": "Sampled At",
      "type": "string"
     },
     "utilization_pct": {
      "anyOf": [
       {
        "maximum": 100.0,
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "GPU utilization in percent, 0 to 100, default 0.",
      "title": "Utilization Pct"
     }
    },
    "required": [
     "node",
     "gpu_uuid",
     "sampled_at",
     "interval_seconds"
    ],
    "title": "GpuSampleIn",
    "type": "object"
   },
   "GpuSamplesIn": {
    "description": "Batch of GPU samples.",
    "properties": {
     "samples": {
      "description": "Samples to store, 1 to 10000.",
      "items": {
       "$ref": "#/components/schemas/GpuSampleIn"
      },
      "maxItems": 10000,
      "minItems": 1,
      "title": "Samples",
      "type": "array"
     }
    },
    "required": [
     "samples"
    ],
    "title": "GpuSamplesIn",
    "type": "object"
   },
   "GroupMappingIn": {
    "description": "New mapping of a directory group to a project role and an optional quota profile.",
    "properties": {
     "group": {
      "description": "Group name as found in the `groups` or `entra_groups` claim, 1 to 256 characters, matched exactly.",
      "maxLength": 256,
      "minLength": 1,
      "title": "Group",
      "type": "string"
     },
     "project": {
      "anyOf": [
       {
        "maxLength": 63,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Slug of the target project, instead of `project_id` (at most 63 characters).",
      "title": "Project"
     },
     "project_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the target project. Give it or `project`.",
      "title": "Project Id"
     },
     "quota_profile": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the quota profile, instead of `quota_profile_id`.",
      "title": "Quota Profile"
     },
     "quota_profile_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the quota profile given to the members. Optional.",
      "title": "Quota Profile Id"
     },
     "role": {
      "default": "developer",
      "description": "Role given in the project to the members of the group: `tenant_admin`, `security_officer`, `finops`, `developer` (default), `auditor`, `agent` or `viewer`.",
      "enum": [
       "tenant_admin",
       "security_officer",
       "finops",
       "developer",
       "auditor",
       "agent",
       "viewer"
      ],
      "title": "Role",
      "type": "string"
     }
    },
    "required": [
     "group"
    ],
    "title": "GroupMappingIn",
    "type": "object"
   },
   "GroupMappingPatch": {
    "description": "Changes to a group mapping; omitted fields keep their value.",
    "properties": {
     "clear_quota_profile": {
      "default": false,
      "description": "When true, detaches the quota profile from the mapping (default false).",
      "title": "Clear Quota Profile",
      "type": "boolean"
     },
     "group": {
      "anyOf": [
       {
        "maxLength": 256,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New group name, 1 to 256 characters.",
      "title": "Group"
     },
     "project": {
      "anyOf": [
       {
        "maxLength": 63,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New target project, by slug.",
      "title": "Project"
     },
     "project_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New target project, by identifier.",
      "title": "Project Id"
     },
     "quota_profile": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New quota profile, by name.",
      "title": "Quota Profile"
     },
     "quota_profile_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New quota profile, by identifier.",
      "title": "Quota Profile Id"
     },
     "role": {
      "anyOf": [
       {
        "enum": [
         "tenant_admin",
         "security_officer",
         "finops",
         "developer",
         "auditor",
         "agent",
         "viewer"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New role: `tenant_admin`, `security_officer`, `finops`, `developer`, `auditor`, `agent` or `viewer`.",
      "title": "Role"
     }
    },
    "title": "GroupMappingPatch",
    "type": "object"
   },
   "HTTPValidationError": {
    "description": "Body of a 422 answer when the request does not match the declared schema.",
    "properties": {
     "detail": {
      "description": "One entry per invalid field.",
      "items": {
       "$ref": "#/components/schemas/ValidationError"
      },
      "title": "Detail",
      "type": "array"
     }
    },
    "title": "HTTPValidationError",
    "type": "object"
   },
   "HeartbeatIn": {
    "description": "A heartbeat sent by the runtime of a run.",
    "properties": {
     "message": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Status message (up to 2000 characters).",
      "title": "Message"
     },
     "progress": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Progress: a number (for example a fraction from 0 to 1) or an object of the runtime choice.",
      "title": "Progress"
     },
     "step": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Current step, free text (up to 500 characters).",
      "title": "Step"
     },
     "worker": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Worker running the run (up to 200 characters). Default: the calling principal.",
      "title": "Worker"
     }
    },
    "title": "HeartbeatIn",
    "type": "object"
   },
   "HoldIn": {
    "description": "New evidence legal hold.",
    "properties": {
     "case_id": {
      "description": "Case reference, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Case Id",
      "type": "string"
     },
     "reason": {
      "description": "Why the hold is placed, 3 to 1000 characters.",
      "maxLength": 1000,
      "minLength": 3,
      "title": "Reason",
      "type": "string"
     },
     "time_from": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Start of the period of event time covered (ISO 8601). Null: no lower bound.",
      "title": "Time From"
     },
     "time_to": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "End of the period covered (ISO 8601), after `time_from`. Null: no upper bound.",
      "title": "Time To"
     }
    },
    "required": [
     "case_id",
     "reason"
    ],
    "title": "HoldIn",
    "type": "object"
   },
   "ImageEditIn": {
    "description": "An image edition request. Give `media_id` or `content_base64`.",
    "properties": {
     "content_base64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Inline image, base64 encoded (scanned before use).",
      "title": "Content Base64"
     },
     "media_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Stored image media to edit.",
      "title": "Media Id"
     },
     "mime_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Media type of the inline image, for example `image/png`.",
      "title": "Mime Type"
     },
     "model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model to use. Default: the configured adapter.",
      "title": "Model"
     },
     "n": {
      "default": 1,
      "description": "Number of images (1 to 8, default 1).",
      "maximum": 8.0,
      "minimum": 1.0,
      "title": "N",
      "type": "integer"
     },
     "prompt": {
      "description": "What to change (1 to 8000 characters).",
      "maxLength": 8000,
      "minLength": 1,
      "title": "Prompt",
      "type": "string"
     },
     "size": {
      "default": "1024x1024",
      "description": "Size `<width>x<height>` in pixels. Default `1024x1024`.",
      "title": "Size",
      "type": "string"
     }
    },
    "required": [
     "prompt"
    ],
    "title": "ImageEditIn",
    "type": "object"
   },
   "ImageGenIn": {
    "description": "An image generation request.",
    "properties": {
     "model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model to use. Default: the configured adapter.",
      "title": "Model"
     },
     "n": {
      "default": 1,
      "description": "Number of images (1 to 8, default 1).",
      "maximum": 8.0,
      "minimum": 1.0,
      "title": "N",
      "type": "integer"
     },
     "prompt": {
      "description": "Description of the image (1 to 8000 characters), inspected by the DLP.",
      "maxLength": 8000,
      "minLength": 1,
      "title": "Prompt",
      "type": "string"
     },
     "size": {
      "default": "1024x1024",
      "description": "Size `<width>x<height>` in pixels. Default `1024x1024`.",
      "title": "Size",
      "type": "string"
     }
    },
    "required": [
     "prompt"
    ],
    "title": "ImageGenIn",
    "type": "object"
   },
   "ImportIn": {
    "description": "Billing export to import.",
    "properties": {
     "content": {
      "description": "Content of the export as the provider gives it (JSON document or CSV text).",
      "title": "Content"
     },
     "filename": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the imported file, kept for the history.",
      "title": "Filename"
     },
     "mapping": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Column mapping of a `generic_csv` export (which column holds the date, amount, currency, model...).",
      "title": "Mapping"
     },
     "provider": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Provider of the lines when the format does not say it (for example with `generic_csv`).",
      "title": "Provider"
     },
     "source": {
      "description": "Format of the export: `openai`, `anthropic`, `aws_cur`, `azure`, `gcp` or `generic_csv`.",
      "enum": [
       "openai",
       "anthropic",
       "aws_cur",
       "azure",
       "gcp",
       "generic_csv"
      ],
      "title": "Source",
      "type": "string"
     }
    },
    "required": [
     "source",
     "content"
    ],
    "title": "ImportIn",
    "type": "object"
   },
   "IncidentIn": {
    "description": "New incident.",
    "properties": {
     "assignee": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Subject in charge of the incident, optional.",
      "title": "Assignee"
     },
     "category": {
      "default": "other",
      "description": "Free category, for example `data_leak` or `prompt_injection`. Default `other`.",
      "title": "Category",
      "type": "string"
     },
     "description": {
      "default": "",
      "description": "What happened (empty by default).",
      "title": "Description",
      "type": "string"
     },
     "resources": {
      "description": "Resources involved, as objects such as `{\"type\": \"agent\", \"id\": \"...\"}`.",
      "items": {
       "additionalProperties": true,
       "type": "object"
      },
      "title": "Resources",
      "type": "array"
     },
     "severity": {
      "default": "sev3",
      "description": "`sev1` (most severe) to `sev4`; the aliases `critical`, `high`, `medium` and `low` are accepted. Default `sev3`.",
      "title": "Severity",
      "type": "string"
     },
     "title": {
      "description": "Title, 3 to 300 characters.",
      "maxLength": 300,
      "minLength": 3,
      "title": "Title",
      "type": "string"
     }
    },
    "required": [
     "title"
    ],
    "title": "IncidentIn",
    "type": "object"
   },
   "IncidentPatch": {
    "description": "Changes to an incident; omitted fields keep their value.",
    "properties": {
     "assignee": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New subject in charge.",
      "title": "Assignee"
     },
     "note": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Note added to the timeline.",
      "title": "Note"
     },
     "severity": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New severity: `sev1` (most severe) to `sev4`; the aliases `critical`, `high`, `medium` and `low` are accepted.",
      "title": "Severity"
     },
     "status": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New status: `open`, `investigating`, `contained`, `resolved` or `closed`.",
      "title": "Status"
     }
    },
    "title": "IncidentPatch",
    "type": "object"
   },
   "InstallServiceIn": {
    "description": "One service to install from the catalog.",
    "properties": {
     "bindings": {
      "additionalProperties": {
       "additionalProperties": true,
       "type": "object"
      },
      "description": "Bindings of the service to other services or to connections, for example `{kind: connection, ref: <connection id>}`; up to 50.",
      "maxProperties": 50,
      "title": "Bindings",
      "type": "object"
     },
     "config": {
      "additionalProperties": true,
      "description": "Values of the descriptor parameters, up to 500 keys. Never audited (only the keys).",
      "maxProperties": 500,
      "title": "Config",
      "type": "object"
     },
     "method": {
      "anyOf": [
       {
        "pattern": "^[a-z][a-z0-9_-]{0,62}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Install method among those of the descriptor; default the descriptor default method.",
      "title": "Method"
     },
     "mode": {
      "anyOf": [
       {
        "pattern": "^[a-z][a-z0-9_-]{0,62}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Install mode among those of the descriptor; default the descriptor default mode.",
      "title": "Mode"
     },
     "name": {
      "description": "Catalog name of the service: lowercase letter then up to 62 lowercase letters, digits, dashes or underscores.",
      "pattern": "^[a-z][a-z0-9_-]{0,62}$",
      "title": "Name",
      "type": "string"
     },
     "placements": {
      "description": "Hosts of each component: component name to a list of up to 500 host ids; up to 50 components.",
      "maxProperties": 50,
      "patternProperties": {
       "^[a-z][a-z0-9_-]{0,62}$": {
        "items": {
         "maxLength": 64,
         "minLength": 1,
         "type": "string"
        },
        "maxItems": 500,
        "type": "array"
       }
      },
      "title": "Placements",
      "type": "object"
     },
     "version": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version to install, 64 characters at most; default the catalog version.",
      "title": "Version"
     }
    },
    "required": [
     "name"
    ],
    "title": "InstallServiceIn",
    "type": "object"
   },
   "InstanceIn": {
    "description": "An MCP instance to start.",
    "properties": {
     "agents": {
      "description": "Agents (principal ids, up to 20) allowed to call the instance with its owner.",
      "items": {
       "type": "string"
      },
      "maxItems": 20,
      "title": "Agents",
      "type": "array"
     },
     "allowed_tools": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 100,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tools of the instance that may be called (up to 100). Default `[\"*\"]`.",
      "title": "Allowed Tools"
     },
     "credential_ref": {
      "anyOf": [
       {
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Personal secret of the user, `openbao://...` or `env://...` (template with credentials `secret_ref`).",
      "title": "Credential Ref"
     },
     "idle_timeout_seconds": {
      "anyOf": [
       {
        "maximum": 86400.0,
        "minimum": 60.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Idle time before the instance sleeps, in seconds (60 to 86400), never above the project policy. Default: the project policy.",
      "title": "Idle Timeout Seconds"
     },
     "name": {
      "anyOf": [
       {
        "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the instance, unique for the caller in the project (same pattern). Default: the template name.",
      "title": "Name"
     },
     "params": {
      "additionalProperties": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "integer"
        },
        {
         "items": {
          "type": "string"
         },
         "type": "array"
        }
       ]
      },
      "description": "Parameters declared by the template (string, integer or list of strings), checked against it and the project policy.",
      "title": "Params",
      "type": "object"
     },
     "template": {
      "description": "Template of the catalogue: lowercase letters, digits and `-`, 1 to 63 characters.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
      "title": "Template",
      "type": "string"
     }
    },
    "required": [
     "template"
    ],
    "title": "InstanceIn",
    "type": "object"
   },
   "InvokeIn": {
    "description": "A tool call.",
    "properties": {
     "agent_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Agent (UUID or name) making the call; its manifest must grant the tool.",
      "title": "Agent Id"
     },
     "approval_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Approved `tool.invoke` request for these exact arguments (matched by their SHA-256 digest).",
      "title": "Approval Id"
     },
     "arguments": {
      "additionalProperties": true,
      "description": "Arguments, validated against the tool `input_schema`. Sent as JSON body (query string for GET and DELETE endpoints).",
      "title": "Arguments",
      "type": "object"
     },
     "data_classification": {
      "anyOf": [
       {
        "enum": [
         "public",
         "internal",
         "confidential",
         "restricted",
         "secret"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Classification of the data handled: `public`, `internal`, `confidential`, `restricted` or `secret`. Never lower than the tool classification (raised to it).",
      "title": "Data Classification"
     },
     "purpose": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Purpose of the call, given to the policy and to the approvers (up to 500 characters).",
      "title": "Purpose"
     },
     "run_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Run the call belongs to; sent to an HTTP endpoint as `X-EAI-Run-Id` and used for metering.",
      "title": "Run Id"
     }
    },
    "title": "InvokeIn",
    "type": "object"
   },
   "IssueIn": {
    "description": "Request for a signed execution context.",
    "properties": {
     "audience": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 10,
        "minItems": 1,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Services the context is for (1 to 10), among the audiences the platform accepts. Default: the platform audiences.",
      "title": "Audience"
     },
     "delegation_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Delegation the context carries. Ignored when `run_id` is given.",
      "title": "Delegation Id"
     },
     "run_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Agent run the context is for; its delegation and agent are included.",
      "title": "Run Id"
     },
     "ttl_seconds": {
      "anyOf": [
       {
        "maximum": 86400.0,
        "minimum": 30.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime in seconds (30 to 86400 by the schema, and never above the platform maximum, 3600 by default). Default: 900.",
      "title": "Ttl Seconds"
     }
    },
    "title": "IssueIn",
    "type": "object"
   },
   "JobCompleteIn": {
    "description": "Result of a queued job, reported by a worker.",
    "properties": {
     "error": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Error message of a failed job.",
      "title": "Error"
     },
     "output": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Output of the operation (transcript, image references...).",
      "title": "Output"
     },
     "status": {
      "description": "`running`, `succeeded`, `failed` or `cancelled`.",
      "title": "Status",
      "type": "string"
     },
     "units": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Measured usage units, for example `{\"audio_seconds\": 12.5}`.",
      "title": "Units"
     }
    },
    "required": [
     "status"
    ],
    "title": "JobCompleteIn",
    "type": "object"
   },
   "KbIn": {
    "description": "A knowledge base to create.",
    "properties": {
     "acl": {
      "$ref": "#/components/schemas/Acl",
      "description": "Readers and writers. Default: every principal reads, default roles write."
     },
     "chunk_overlap": {
      "default": 40,
      "description": "Overlap between two chunks, in words (0 or more, lower than `chunk_size`, default 40).",
      "minimum": 0.0,
      "title": "Chunk Overlap",
      "type": "integer"
     },
     "chunk_size": {
      "default": 200,
      "description": "Size of a chunk, in words (20 to 4000, default 200).",
      "maximum": 4000.0,
      "minimum": 20.0,
      "title": "Chunk Size",
      "type": "integer"
     },
     "chunking": {
      "default": "words",
      "description": "`words` (default: word chunks of `chunk_size` with `chunk_overlap`, each located in the text with its page, section and element type, a chunk boundary inside a table marked `table_split`) or `structure` (chunks follow titles, paragraphs, lists, tables and code; a table stays whole up to 3 chunk sizes, a longer one is split between rows with its header row repeated).",
      "enum": [
       "words",
       "structure"
      ],
      "title": "Chunking",
      "type": "string"
     },
     "classification": {
      "default": "internal",
      "description": "Default classification of the documents: `public`, `internal` (default), `confidential`, `restricted` or `secret`.",
      "title": "Classification",
      "type": "string"
     },
     "description": {
      "default": "",
      "description": "Free description. Default empty.",
      "title": "Description",
      "type": "string"
     },
     "dimensions": {
      "anyOf": [
       {
        "maximum": 16384.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Vector size, one of the sizes the model declares (1 to 16384; default: its native size).",
      "title": "Dimensions"
     },
     "embedding_model": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Registry model with the embeddings capability (default: the platform RAG embedding model).",
      "title": "Embedding Model"
     },
     "name": {
      "description": "Name, unique in the tenant (1 to 120 characters).",
      "maxLength": 120,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "retrieval": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/RetrievalIn"
       },
       {
        "type": "null"
       }
      ],
      "description": "Retrieval strategy of the knowledge base (see RetrievalIn). Default: every field at its default."
     }
    },
    "required": [
     "name"
    ],
    "title": "KbIn",
    "type": "object"
   },
   "KeyPatch": {
    "additionalProperties": false,
    "description": "Changes of a project key; every field is optional. Unknown fields are refused.",
    "properties": {
     "budget_period": {
      "anyOf": [
       {
        "enum": [
         "daily",
         "weekly",
         "monthly",
         "total"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Period after which the key spend resets: `daily`, `weekly`, `monthly` or `total` (never resets).",
      "title": "Budget Period"
     },
     "max_budget": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum spend of the key per budget period, decimal, at least 0 and never above the project budget.",
      "title": "Max Budget"
     },
     "max_parallel_requests": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Requests the key may run at the same time, at least 0, never above the project limit.",
      "title": "Max Parallel Requests"
     },
     "models": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 200,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model ids the key may call, up to 200; each must be allowed by the project when the project restricts its models.",
      "title": "Models"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 128,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Display name of the key, 128 characters at most.",
      "title": "Name"
     },
     "rpm_limit": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Requests per minute allowed to the key, at least 0, never above the project limit.",
      "title": "Rpm Limit"
     },
     "tpm_limit": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tokens per minute allowed to the key, at least 0, never above the project limit.",
      "title": "Tpm Limit"
     }
    },
    "title": "KeyPatch",
    "type": "object"
   },
   "LeaseIn": {
    "description": "A credential lease request.",
    "properties": {
     "connector": {
      "description": "Name of the connector.",
      "title": "Connector",
      "type": "string"
     },
     "on_behalf_of": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "User whose own right is enforced when the target only accepts a technical credential (1 to 200 characters).",
      "title": "On Behalf Of"
     },
     "run_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Run the lease is issued for, recorded with it.",
      "title": "Run Id"
     },
     "scopes": {
      "description": "Scopes of the lease, among those the connector declares. Empty (default): all of them.",
      "items": {
       "type": "string"
      },
      "title": "Scopes",
      "type": "array"
     },
     "ttl_seconds": {
      "anyOf": [
       {
        "maximum": 3600.0,
        "minimum": 30.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime of the lease in seconds (30 to 3600, default 600).",
      "title": "Ttl Seconds"
     }
    },
    "required": [
     "connector"
    ],
    "title": "LeaseIn",
    "type": "object"
   },
   "LegalHoldIn": {
    "description": "New legal hold, or change of an existing one.",
    "properties": {
     "active": {
      "default": true,
      "description": "true (default) to hold, false to release the hold given by `hold_id`.",
      "title": "Active",
      "type": "boolean"
     },
     "hold_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of an existing hold to activate or release. Omit it to create a hold.",
      "title": "Hold Id"
     },
     "reason": {
      "default": "",
      "description": "Why the hold is placed, for example a case number. Required for a new hold.",
      "title": "Reason",
      "type": "string"
     },
     "resource_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the held resource.",
      "title": "Resource Id"
     },
     "resource_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Type of the held resource, for example `memory`, `media`, `sessions` or `documents`. Goes with `resource_id`.",
      "title": "Resource Type"
     },
     "subject_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Subject whose resources are all held.",
      "title": "Subject Id"
     }
    },
    "title": "LegalHoldIn",
    "type": "object"
   },
   "LoginIn": {
    "additionalProperties": false,
    "description": "Credentials of a local account.",
    "properties": {
     "password": {
      "description": "Password, 1 to 256 characters. Write only: never returned nor logged.",
      "maxLength": 256,
      "minLength": 1,
      "title": "Password",
      "type": "string"
     },
     "username": {
      "description": "Login of the account, 1 to 128 characters, compared without case.",
      "maxLength": 128,
      "minLength": 1,
      "title": "Username",
      "type": "string"
     }
    },
    "required": [
     "username",
     "password"
    ],
    "title": "LoginIn",
    "type": "object"
   },
   "MandateIn": {
    "description": "New mandate of an agent.",
    "properties": {
     "agent": {
      "description": "Name of the agent, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Agent",
      "type": "string"
     },
     "audience": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 20,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Audiences, at most 20 patterns. Default `eai-control-plane`.",
      "title": "Audience"
     },
     "data_classification_max": {
      "anyOf": [
       {
        "pattern": "^(public|internal|confidential|restricted|secret)$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Classification ceiling: `public`, `internal`, `confidential`, `restricted` or `secret`. Default: the clearance of the service identity.",
      "title": "Data Classification Max"
     },
     "max_depth": {
      "default": 0,
      "description": "Sub-delegation depth allowed, 0 to 10 (default 0).",
      "maximum": 10.0,
      "minimum": 0.0,
      "title": "Max Depth",
      "type": "integer"
     },
     "purpose": {
      "description": "Purpose of the mandate, 3 to 2000 characters, shown to the approvers.",
      "maxLength": 2000,
      "minLength": 3,
      "title": "Purpose",
      "type": "string"
     },
     "resources": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 100,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Resource restrictions, at most 100 patterns. Default `*`.",
      "title": "Resources"
     },
     "schedule_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Single schedule of the agent covered by the mandate; null for every schedule of the agent.",
      "title": "Schedule Id"
     },
     "scopes": {
      "description": "Scopes of the mandate, at most 100, covered by those of the service identity.",
      "items": {
       "type": "string"
      },
      "maxItems": 100,
      "title": "Scopes",
      "type": "array"
     },
     "service_identity_id": {
      "description": "Service identity the runs act as; it must be active.",
      "title": "Service Identity Id",
      "type": "string"
     },
     "ttl_days": {
      "default": 30,
      "description": "Lifetime in days, 1 to the platform maximum (365 by default); default 30.",
      "maximum": 3650.0,
      "minimum": 1.0,
      "title": "Ttl Days",
      "type": "integer"
     }
    },
    "required": [
     "agent",
     "service_identity_id",
     "purpose"
    ],
    "title": "MandateIn",
    "type": "object"
   },
   "McpAuth": {
    "description": "How the gateway authenticates to the upstream MCP server.",
    "properties": {
     "connector": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Connector whose credentials are used, for `connector`.",
      "title": "Connector"
     },
     "credential_ref": {
      "anyOf": [
       {
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Secret reference, `openbao://...` or `env://...`; required for `bearer`, `api_key` and `query_param`. Resolved at call time, never returned.",
      "title": "Credential Ref"
     },
     "header": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Header carrying the key for `api_key`. Default `X-API-Key`.",
      "title": "Header"
     },
     "param": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9_.-]{1,64}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Query parameter carrying the secret for `query_param` (1 to 64 letters, digits, `_`, `.`, `-`).",
      "title": "Param"
     },
     "type": {
      "default": "none",
      "description": "`none` (default), `bearer` (Authorization header), `api_key` (custom header), `query_param` (secret in a query parameter) or `connector` (credentials of a connector).",
      "enum": [
       "none",
       "bearer",
       "api_key",
       "query_param",
       "connector"
      ],
      "title": "Type",
      "type": "string"
     }
    },
    "title": "McpAuth",
    "type": "object"
   },
   "McpInstallIn": {
    "description": "Installation of an MCP server from a Navin preset.",
    "properties": {
     "allowed_tools": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tools of the server that may be called. Omitted: every tool.",
      "title": "Allowed Tools"
     },
     "credential_refs": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Secret preset fields as `openbao://` or `env://` references, by field name.",
      "title": "Credential Refs",
      "type": "object"
     },
     "name": {
      "anyOf": [
       {
        "pattern": "^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Server name (default `<preset>-<project slug>`); lowercase letters, digits, `.`, `_`, `-`.",
      "title": "Name"
     },
     "transport": {
      "anyOf": [
       {
        "enum": [
         "streamable_http",
         "sse"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`streamable_http` or `sse`. Default: the transport of the preset.",
      "title": "Transport"
     },
     "url": {
      "anyOf": [
       {
        "maxLength": 2000,
        "minLength": 8,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "HTTP endpoint (8 to 2000 characters); required for a stdio preset run by the Navin Manager. Default: the preset URL for an HTTP preset.",
      "title": "Url"
     },
     "values": {
      "additionalProperties": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "integer"
        },
        {
         "type": "boolean"
        }
       ]
      },
      "description": "Non secret preset fields (string, integer or boolean), by field name.",
      "title": "Values",
      "type": "object"
     }
    },
    "title": "McpInstallIn",
    "type": "object"
   },
   "MemberIn": {
    "description": "New membership of a user in the tenant or in one project.",
    "properties": {
     "clearance": {
      "default": "internal",
      "description": "Highest data classification the member may read: `public`, `internal` (default), `confidential`, `restricted` or `secret`.",
      "enum": [
       "public",
       "internal",
       "confidential",
       "restricted",
       "secret"
      ],
      "title": "Clearance",
      "type": "string"
     },
     "display_name": {
      "default": "",
      "description": "Name shown in the portal (empty by default).",
      "title": "Display Name",
      "type": "string"
     },
     "email": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Email address of the user, optional.",
      "title": "Email"
     },
     "project_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Project the membership is limited to; null for the whole tenant.",
      "title": "Project Id"
     },
     "role": {
      "description": "Role given: `platform_admin`, `tenant_admin`, `security_officer`, `finops`, `developer`, `auditor`, `agent`, `viewer`, `soc_analyst`, `ai_governance_officer`, `data_steward`, `application_owner`, `ai_platform_engineer`, `business_owner` or `support_engineer`.",
      "enum": [
       "platform_admin",
       "tenant_admin",
       "security_officer",
       "finops",
       "developer",
       "auditor",
       "agent",
       "viewer",
       "soc_analyst",
       "ai_governance_officer",
       "data_steward",
       "application_owner",
       "ai_platform_engineer",
       "business_owner",
       "support_engineer"
      ],
      "title": "Role",
      "type": "string"
     },
     "user": {
      "description": "Subject of the user: the OIDC `sub` claim, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "User",
      "type": "string"
     }
    },
    "required": [
     "user",
     "role"
    ],
    "title": "MemberIn",
    "type": "object"
   },
   "MemberPatch": {
    "description": "Changes to a membership.",
    "properties": {
     "clearance": {
      "anyOf": [
       {
        "enum": [
         "public",
         "internal",
         "confidential",
         "restricted",
         "secret"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New clearance: `public`, `internal`, `confidential`, `restricted` or `secret`.",
      "title": "Clearance"
     },
     "role": {
      "anyOf": [
       {
        "enum": [
         "platform_admin",
         "tenant_admin",
         "security_officer",
         "finops",
         "developer",
         "auditor",
         "agent",
         "viewer",
         "soc_analyst",
         "ai_governance_officer",
         "data_steward",
         "application_owner",
         "ai_platform_engineer",
         "business_owner",
         "support_engineer"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New role, same values as at creation.",
      "title": "Role"
     }
    },
    "title": "MemberPatch",
    "type": "object"
   },
   "MemoryAcl": {
    "description": "Access list of a memory item. Entries are identities: `user:<id>`, `agent:<id>`, `service:<id>`, `role:<role>`, `group:<group>`, `*` or a bare principal id.",
    "properties": {
     "owners": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owners, also allowed to update and delete. Default for a new item: the caller; not changed by an update.",
      "title": "Owners"
     },
     "readers": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identities allowed to read. Default for a new item: the caller.",
      "title": "Readers"
     },
     "writers": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identities allowed to update and delete. Default for a new item: the caller.",
      "title": "Writers"
     }
    },
    "title": "MemoryAcl",
    "type": "object"
   },
   "MemoryEngineCredentialIn": {
    "description": "Credential of the tenant on a shared engine instance.",
    "properties": {
     "credential_ref": {
      "description": "Reference `openbao://<path>` to a secret of the tenant.",
      "maxLength": 210,
      "pattern": "^openbao://.+$",
      "title": "Credential Ref",
      "type": "string"
     }
    },
    "required": [
     "credential_ref"
    ],
    "title": "MemoryEngineCredentialIn",
    "type": "object"
   },
   "MemoryEngineIn": {
    "description": "An engine instance installed and operated by the Navin Manager.",
    "properties": {
     "access_control": {
      "default": false,
      "description": "Cognee only: the instance runs with backend access control (one user per tenant gives a `backend` separation).",
      "title": "Access Control",
      "type": "boolean"
     },
     "base_url": {
      "description": "Address of the API rendered by the Navin Manager (https in staging and prod).",
      "maxLength": 500,
      "pattern": "^https?://[^/@\\s]+(/[^\\s]*)?$",
      "title": "Base Url",
      "type": "string"
     },
     "credential_ref": {
      "anyOf": [
       {
        "maxLength": 210,
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference to the API key: `openbao://<path>` or `env://EAI_CRED_<NAME>`.",
      "title": "Credential Ref"
     },
     "id": {
      "description": "Identifier (lowercase letters, digits and dashes, 2 to 63 characters).",
      "pattern": "^[a-z0-9][a-z0-9-]{1,62}$",
      "title": "Id",
      "type": "string"
     },
     "manager_cluster": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Cluster of the Navin Manager that operates the instance (information).",
      "title": "Manager Cluster"
     },
     "manager_service": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Service of the Navin Manager catalog (information).",
      "title": "Manager Service"
     },
     "provider": {
      "description": "`mem0` or `cognee`.",
      "enum": [
       "mem0",
       "cognee"
      ],
      "title": "Provider",
      "type": "string"
     },
     "tenant_id": {
      "anyOf": [
       {
        "maxLength": 36,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tenant the instance is dedicated to; empty: shared instance.",
      "title": "Tenant Id"
     },
     "timeout_seconds": {
      "default": 10.0,
      "description": "Timeout of one call in seconds (default 10, at most 300).",
      "exclusiveMinimum": 0.0,
      "maximum": 300.0,
      "title": "Timeout Seconds",
      "type": "number"
     },
     "tls_verify": {
      "default": true,
      "description": "Verify the certificate of the engine (default true; the Manager CA of EAI_MEMORY_ENGINES_CA_FILE is trusted).",
      "title": "Tls Verify",
      "type": "boolean"
     }
    },
    "required": [
     "id",
     "provider",
     "base_url"
    ],
    "title": "MemoryEngineIn",
    "type": "object"
   },
   "MemoryExportIn": {
    "description": "Export of the memories of an agent.",
    "properties": {
     "scopes": {
      "anyOf": [
       {
        "items": {
         "enum": [
          "session",
          "user",
          "agent",
          "shared_agents",
          "project",
          "team",
          "organization",
          "global"
         ],
         "type": "string"
        },
        "maxItems": 8,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Isolation levels to export (default: every readable scope).",
      "title": "Scopes"
     }
    },
    "title": "MemoryExportIn",
    "type": "object"
   },
   "MemoryGraphBuildIn": {
    "description": "Datasets whose graph is built.",
    "properties": {
     "dataset_ids": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 50,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Navin index ids of the datasets (default: every readable dataset).",
      "title": "Dataset Ids"
     }
    },
    "title": "MemoryGraphBuildIn",
    "type": "object"
   },
   "MemoryGraphSearchIn": {
    "description": "A search in the knowledge graph.",
    "properties": {
     "dataset_ids": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 50,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Navin index ids of the datasets (default: every readable dataset).",
      "title": "Dataset Ids"
     },
     "query": {
      "description": "Text of the query (1 to 4000 characters).",
      "maxLength": 4000,
      "minLength": 1,
      "title": "Query",
      "type": "string"
     },
     "search_type": {
      "default": "CHUNKS",
      "description": "Cognee search type: `CHUNKS` (default), `CHUNKS_LEXICAL`, `SUMMARIES`, `RAG_COMPLETION` or `GRAPH_COMPLETION`.",
      "enum": [
       "CHUNKS",
       "CHUNKS_LEXICAL",
       "SUMMARIES",
       "RAG_COMPLETION",
       "GRAPH_COMPLETION"
      ],
      "title": "Search Type",
      "type": "string"
     },
     "top_k": {
      "default": 10,
      "description": "Number of results (1 to 50, default 10).",
      "maximum": 50.0,
      "minimum": 1.0,
      "title": "Top K",
      "type": "integer"
     }
    },
    "required": [
     "query"
    ],
    "title": "MemoryGraphSearchIn",
    "type": "object"
   },
   "MemoryIn": {
    "description": "A memory item to create or update. Give `content` or `content_ref`.",
    "properties": {
     "acl": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/MemoryAcl"
       },
       {
        "type": "null"
       }
      ],
      "description": "Readers, writers and owners. On an update, omitted lists are kept."
     },
     "classification": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`public`, `internal` (default), `confidential`, `restricted` or `secret`; raised when personal data is detected, and never above the caller clearance.",
      "title": "Classification"
     },
     "content": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Text to remember; embedded for vector search.",
      "title": "Content"
     },
     "content_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference to content stored elsewhere (not searchable).",
      "title": "Content Ref"
     },
     "deletable": {
      "default": true,
      "description": "When false, only `tenant_admin` can delete the item. Default true.",
      "title": "Deletable",
      "type": "boolean"
     },
     "kind": {
      "default": "fact",
      "description": "`episodic`, `semantic`, `procedural`, `preference` or `fact` (default).",
      "title": "Kind",
      "type": "string"
     },
     "legal_hold": {
      "default": false,
      "description": "When true, the item cannot be deleted. Once set, an update cannot clear it. Default false.",
      "title": "Legal Hold",
      "type": "boolean"
     },
     "memory_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Existing item to update (new version). Omit it to create an item.",
      "title": "Memory Id"
     },
     "scope": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Scope"
       },
       {
        "type": "null"
       }
      ],
      "description": "Scope of a new item. Default: `{type: user, id: <caller>}`."
     },
     "source": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Provenance"
       },
       {
        "type": "null"
       }
      ],
      "description": "Provenance of the content."
     },
     "subject_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Data subject the item is about (used by privacy requests). Default: the scope id for a `user` scope, else the caller.",
      "title": "Subject Id"
     },
     "ttl_seconds": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime in seconds (0 or more); after it the item is no longer returned. Omitted: no expiry.",
      "title": "Ttl Seconds"
     }
    },
    "title": "MemoryIn",
    "type": "object"
   },
   "MemoryKnowledgeIn": {
    "description": "Texts to ingest into the knowledge graph (Cognee).",
    "properties": {
     "build_graph": {
      "default": false,
      "description": "Build the graph right after the ingestion (Cognee cognify). Default false.",
      "title": "Build Graph",
      "type": "boolean"
     },
     "classification": {
      "anyOf": [
       {
        "enum": [
         "public",
         "internal",
         "confidential",
         "restricted"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Declared classification of the texts.",
      "title": "Classification"
     },
     "dataset_id": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Existing dataset of the same scope (Navin index id); default: the dataset of the scope, created when missing.",
      "title": "Dataset Id"
     },
     "legal_hold": {
      "default": false,
      "description": "Put the dataset under legal hold. Default false.",
      "title": "Legal Hold",
      "type": "boolean"
     },
     "retention_days": {
      "anyOf": [
       {
        "maximum": 3650.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Retention in days, within the limit of the policy.",
      "title": "Retention Days"
     },
     "scope": {
      "default": "agent",
      "description": "Isolation level of the dataset: `agent` (default), `shared_agents`, `project`, `team`, `organization` or `global`.",
      "enum": [
       "agent",
       "shared_agents",
       "project",
       "team",
       "organization",
       "global"
      ],
      "title": "Scope",
      "type": "string"
     },
     "source": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/MemoryKnowledgeSource"
       },
       {
        "type": "null"
       }
      ],
      "description": "Source of the texts, for example one document of a knowledge base: it selects, or creates, the one dataset of that source in the scope (ignored when `dataset_id` is given)."
     },
     "team": {
      "anyOf": [
       {
        "maxLength": 63,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Team of the `team` scope.",
      "title": "Team"
     },
     "texts": {
      "description": "One to 50 texts (each up to 100000 characters); secrets are refused.",
      "items": {
       "type": "string"
      },
      "maxItems": 50,
      "minItems": 1,
      "title": "Texts",
      "type": "array"
     }
    },
    "required": [
     "texts"
    ],
    "title": "MemoryKnowledgeIn",
    "type": "object"
   },
   "MemoryKnowledgeSource": {
    "description": "Source of a knowledge dataset; `source_type` and `source_id` are required when a source is given.",
    "properties": {
     "source_id": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the source in its system, the key of its dataset in the scope.",
      "title": "Source Id"
     },
     "source_type": {
      "anyOf": [
       {
        "maxLength": 64,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Kind of source, for example `rag.document`.",
      "title": "Source Type"
     },
     "uri": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Address of the source.",
      "title": "Uri"
     },
     "version": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version of the source, kept with the dataset.",
      "title": "Version"
     }
    },
    "title": "MemoryKnowledgeSource",
    "type": "object"
   },
   "MemoryModes": {
    "description": "Memory modes enabled for the agent.",
    "properties": {
     "agent": {
      "default": true,
      "description": "Memory private to the agent (scope `agent`). Default true.",
      "title": "Agent",
      "type": "boolean"
     },
     "knowledge_graph": {
      "default": false,
      "description": "Knowledge graph through Cognee (ingestion, graph, relations). Default false.",
      "title": "Knowledge Graph",
      "type": "boolean"
     },
     "long_term": {
      "default": true,
      "description": "Long term memory of one user with this agent (scope `user`). Default true.",
      "title": "Long Term",
      "type": "boolean"
     },
     "session": {
      "default": true,
      "description": "Session memory (scope `session`, builtin store only). Default true.",
      "title": "Session",
      "type": "boolean"
     },
     "shared": {
      "default": false,
      "description": "Shared memories (scopes `shared_agents`, `project`, `team`, `organization`, `global`). Default false.",
      "title": "Shared",
      "type": "boolean"
     }
    },
    "title": "MemoryModes",
    "type": "object"
   },
   "MemoryPolicy": {
    "description": "Memorization and access policy of an agent. Memorization is driven by this policy: nothing is written into an engine without an explicit call allowed by it.",
    "properties": {
     "allow_personal_data": {
      "default": true,
      "description": "When false, a content with personal data is refused. Default true (the classification is raised).",
      "title": "Allow Personal Data",
      "type": "boolean"
     },
     "allowed_kinds": {
      "description": "Kinds that may be remembered (default all five).",
      "items": {
       "enum": [
        "episodic",
        "semantic",
        "procedural",
        "preference",
        "fact"
       ],
       "type": "string"
      },
      "title": "Allowed Kinds",
      "type": "array"
     },
     "default_scope": {
      "default": "user",
      "description": "Scope of a memory written without `scope` (default `user`); must be a write scope.",
      "enum": [
       "session",
       "user",
       "agent",
       "shared_agents",
       "project",
       "team",
       "organization",
       "global"
      ],
      "title": "Default Scope",
      "type": "string"
     },
     "global_access": {
      "default": false,
      "description": "Allows the `global` scope (whole tenant); set by `tenant_admin` only. Default false.",
      "title": "Global Access",
      "type": "boolean"
     },
     "infer": {
      "default": false,
      "description": "Let Mem0 extract facts with its LLM (`infer=true`); default false: the text is stored as given.",
      "title": "Infer",
      "type": "boolean"
     },
     "legal_hold": {
      "default": false,
      "description": "Every new memory of the agent is under legal hold. Default false.",
      "title": "Legal Hold",
      "type": "boolean"
     },
     "max_classification": {
      "default": "confidential",
      "description": "Highest classification the agent may remember and read: `public`, `internal`, `confidential` (default) or `restricted`; never above the caller clearance.",
      "enum": [
       "public",
       "internal",
       "confidential",
       "restricted"
      ],
      "title": "Max Classification",
      "type": "string"
     },
     "modes": {
      "$ref": "#/components/schemas/MemoryModes",
      "description": "Enabled memory modes."
     },
     "read_scopes": {
      "description": "Isolation levels the agent may read (default `session`, `user`, `agent`).",
      "items": {
       "enum": [
        "session",
        "user",
        "agent",
        "shared_agents",
        "project",
        "team",
        "organization",
        "global"
       ],
       "type": "string"
      },
      "title": "Read Scopes",
      "type": "array"
     },
     "recall_top_k": {
      "default": 8,
      "description": "Default number of recalled memories (1 to 50, default 8).",
      "maximum": 50.0,
      "minimum": 1.0,
      "title": "Recall Top K",
      "type": "integer"
     },
     "required_isolation": {
      "default": "logical",
      "description": "Separation the engine must guarantee: `logical` (default, Navin identifiers and namespace), `backend` (access control of the engine) or `dedicated_instance` (an instance installed for this tenant by the Navin Manager).",
      "enum": [
       "logical",
       "backend",
       "dedicated_instance"
      ],
      "title": "Required Isolation",
      "type": "string"
     },
     "retention_days": {
      "anyOf": [
       {
        "maximum": 3650.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Retention limit in days (1 to 3650); applied by default and sent to Mem0 as `expiration_date`. Empty: no limit.",
      "title": "Retention Days"
     },
     "shared_with": {
      "description": "Agents allowed to read the `shared_agents` memories of this agent (OpenFGA relation `memory_reader`).",
      "items": {
       "type": "string"
      },
      "maxItems": 50,
      "title": "Shared With",
      "type": "array"
     },
     "teams": {
      "description": "Teams (OpenFGA groups) of the `team` scope; a reader must be a member.",
      "items": {
       "type": "string"
      },
      "maxItems": 20,
      "title": "Teams",
      "type": "array"
     },
     "write_scopes": {
      "description": "Isolation levels the agent may write (default `session`, `user`, `agent`).",
      "items": {
       "enum": [
        "session",
        "user",
        "agent",
        "shared_agents",
        "project",
        "team",
        "organization",
        "global"
       ],
       "type": "string"
      },
      "title": "Write Scopes",
      "type": "array"
     }
    },
    "title": "MemoryPolicy",
    "type": "object"
   },
   "MemoryPolicyRestoreIn": {
    "description": "A version of the memory policy to restore.",
    "properties": {
     "version": {
      "description": "Version number (1 or more).",
      "minimum": 1.0,
      "title": "Version",
      "type": "integer"
     }
    },
    "required": [
     "version"
    ],
    "title": "MemoryPolicyRestoreIn",
    "type": "object"
   },
   "MemoryPurgeIn": {
    "description": "Purge of one scope.",
    "properties": {
     "confirm": {
      "default": false,
      "description": "Must be true.",
      "title": "Confirm",
      "type": "boolean"
     },
     "scope": {
      "description": "Isolation level to purge.",
      "enum": [
       "session",
       "user",
       "agent",
       "shared_agents",
       "project",
       "team",
       "organization",
       "global"
      ],
      "title": "Scope",
      "type": "string"
     },
     "session_id": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Session of the `session` scope.",
      "title": "Session Id"
     },
     "team": {
      "anyOf": [
       {
        "maxLength": 63,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Team of the `team` scope.",
      "title": "Team"
     }
    },
    "required": [
     "scope"
    ],
    "title": "MemoryPurgeIn",
    "type": "object"
   },
   "MemoryRecallIn": {
    "description": "A recall or a search in the memories of an agent.",
    "properties": {
     "query": {
      "description": "Text of the query (1 to 4000 characters).",
      "maxLength": 4000,
      "minLength": 1,
      "title": "Query",
      "type": "string"
     },
     "scopes": {
      "anyOf": [
       {
        "items": {
         "enum": [
          "session",
          "user",
          "agent",
          "shared_agents",
          "project",
          "team",
          "organization",
          "global"
         ],
         "type": "string"
        },
        "maxItems": 8,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Isolation levels to search (default: the readable scopes of the policy).",
      "title": "Scopes"
     },
     "session_id": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Session of the caller, to include its session memory.",
      "title": "Session Id"
     },
     "top_k": {
      "anyOf": [
       {
        "maximum": 50.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Number of results (1 to 50, default `recall_top_k` of the policy).",
      "title": "Top K"
     }
    },
    "required": [
     "query"
    ],
    "title": "MemoryRecallIn",
    "type": "object"
   },
   "MemoryRememberIn": {
    "description": "A memory to remember through the engine of the agent.",
    "properties": {
     "classification": {
      "anyOf": [
       {
        "enum": [
         "public",
         "internal",
         "confidential",
         "restricted"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Declared classification; raised by the detection, refused above the policy or the clearance.",
      "title": "Classification"
     },
     "content": {
      "description": "Text to remember (1 to 20000 characters); secrets are refused.",
      "maxLength": 20000,
      "minLength": 1,
      "title": "Content",
      "type": "string"
     },
     "kind": {
      "default": "fact",
      "description": "`episodic`, `semantic`, `procedural`, `preference` or `fact` (default).",
      "enum": [
       "episodic",
       "semantic",
       "procedural",
       "preference",
       "fact"
      ],
      "title": "Kind",
      "type": "string"
     },
     "legal_hold": {
      "default": false,
      "description": "Put the memory under legal hold. Default false.",
      "title": "Legal Hold",
      "type": "boolean"
     },
     "retention_days": {
      "anyOf": [
       {
        "maximum": 3650.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Retention in days, within the limit of the policy.",
      "title": "Retention Days"
     },
     "scope": {
      "anyOf": [
       {
        "enum": [
         "session",
         "user",
         "agent",
         "shared_agents",
         "project",
         "team",
         "organization",
         "global"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Isolation level: `session`, `user`, `agent`, `shared_agents`, `project`, `team`, `organization` or `global`. Default: `default_scope` of the policy.",
      "title": "Scope"
     },
     "session_id": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Session of the caller (required for the `session` scope; verified server side).",
      "title": "Session Id"
     },
     "source": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/MemorySource"
       },
       {
        "type": "null"
       }
      ],
      "description": "Provenance of the content."
     },
     "team": {
      "anyOf": [
       {
        "maxLength": 63,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Team of the policy for the `team` scope (default: its first team).",
      "title": "Team"
     }
    },
    "required": [
     "content"
    ],
    "title": "MemoryRememberIn",
    "type": "object"
   },
   "MemorySource": {
    "description": "Provenance of a remembered content.",
    "properties": {
     "source_id": {
      "description": "Identifier of the source object.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Source Id",
      "type": "string"
     },
     "source_type": {
      "description": "Kind of source, for example `conversation`, `rag` or `tool`.",
      "maxLength": 64,
      "minLength": 1,
      "title": "Source Type",
      "type": "string"
     },
     "uri": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "URI of the source.",
      "title": "Uri"
     },
     "version": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version of the source.",
      "title": "Version"
     }
    },
    "required": [
     "source_type",
     "source_id"
    ],
    "title": "MemorySource",
    "type": "object"
   },
   "MemoryUpdateIn": {
    "description": "New content of a memory.",
    "properties": {
     "content": {
      "description": "Text (1 to 20000 characters); secrets are refused.",
      "maxLength": 20000,
      "minLength": 1,
      "title": "Content",
      "type": "string"
     }
    },
    "required": [
     "content"
    ],
    "title": "MemoryUpdateIn",
    "type": "object"
   },
   "MessageIn": {
    "description": "A message to add to a session.",
    "properties": {
     "content": {
      "description": "Text of the message (1 to 200000 characters).",
      "maxLength": 200000,
      "minLength": 1,
      "title": "Content",
      "type": "string"
     },
     "metadata": {
      "additionalProperties": true,
      "description": "Free key-value pairs stored with the object and returned as they are; the platform never interprets them.",
      "title": "Metadata",
      "type": "object"
     },
     "role": {
      "default": "user",
      "description": "Author role: `user` (default), `assistant`, `system` or `tool`.",
      "enum": [
       "user",
       "assistant",
       "system",
       "tool"
      ],
      "title": "Role",
      "type": "string"
     }
    },
    "required": [
     "content"
    ],
    "title": "MessageIn",
    "type": "object"
   },
   "Metric": {
    "description": "Metric of a suite and its threshold.",
    "properties": {
     "comparator": {
      "default": "gte",
      "description": "`gte` (default): the score must be at least the threshold; `lte`: at most.",
      "title": "Comparator",
      "type": "string"
     },
     "name": {
      "description": "Metric name. For the `custom` engine: `exact_match`, `contains`, `not_contains`, `json_valid`, `faithfulness`, `latency` or `refusal`; other engines use their own names.",
      "title": "Name",
      "type": "string"
     },
     "threshold": {
      "description": "Value the score is compared with.",
      "title": "Threshold",
      "type": "number"
     },
     "weight": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "description": "Relative weight of the metric, optional.",
      "title": "Weight"
     }
    },
    "required": [
     "name",
     "threshold"
    ],
    "title": "Metric",
    "type": "object"
   },
   "ModeIn": {
    "description": "Operating mode to apply to a service.",
    "properties": {
     "approval_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the Manager approval that authorizes the mode when the Manager requires one.",
      "title": "Approval Id"
     },
     "drain_timeout_s": {
      "anyOf": [
       {
        "maximum": 3600.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Seconds the drain waits for running work, 0 to 3600.",
      "title": "Drain Timeout S"
     },
     "mode": {
      "description": "`drain`, `scale_to_zero`, `security_suspend`, `emergency_stop`, `disable`, `quarantine`, `maintenance` or `enable`.",
      "pattern": "^(drain|scale_to_zero|security_suspend|emergency_stop|disable|quarantine|maintenance|enable)$",
      "title": "Mode",
      "type": "string"
     },
     "reason": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Why the mode is applied, 500 characters at most; recorded by the Manager and in the audit.",
      "title": "Reason"
     }
    },
    "required": [
     "mode"
    ],
    "title": "ModeIn",
    "type": "object"
   },
   "MultimodalDlpIn": {
    "description": "A DLP check. Give `text`, `media_id` or `content_base64`.",
    "properties": {
     "content_base64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Inline file, base64 encoded; scanned, then its text is extracted.",
      "title": "Content Base64"
     },
     "media_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Stored media whose extracted text is inspected.",
      "title": "Media Id"
     },
     "mime_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Media type of the inline file.",
      "title": "Mime Type"
     },
     "mode": {
      "default": "detect",
      "description": "`detect` (default), `mask`, `tokenize` or `block`.",
      "title": "Mode",
      "type": "string"
     },
     "text": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Text to inspect; takes precedence over the media.",
      "title": "Text"
     }
    },
    "title": "MultimodalDlpIn",
    "type": "object"
   },
   "Obligation": {
    "description": "Obligation attached to an allow decision.",
    "properties": {
     "params": {
      "additionalProperties": true,
      "description": "Parameters of the obligation, for example `{\"mode\": \"mask\"}` for `dlp`.",
      "title": "Params",
      "type": "object"
     },
     "type": {
      "description": "Kind of obligation: `dlp` (masking of the data) and `approval` (four eyes approval first) are enforced by the platform; other kinds are returned to the caller.",
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "type"
    ],
    "title": "Obligation",
    "type": "object"
   },
   "OciIn": {
    "description": "OCI artifact of the pack.",
    "properties": {
     "digest": {
      "description": "Digest of the artifact, `sha256:` followed by 64 lowercase hexadecimal characters.",
      "pattern": "^sha256:[a-f0-9]{64}$",
      "title": "Digest",
      "type": "string"
     },
     "ref": {
      "description": "OCI reference of the artifact (3 to 500 characters).",
      "maxLength": 500,
      "minLength": 3,
      "title": "Ref",
      "type": "string"
     }
    },
    "required": [
     "ref",
     "digest"
    ],
    "title": "OciIn",
    "type": "object"
   },
   "OperationIn": {
    "description": "Operation to run on a service.",
    "properties": {
     "action": {
      "description": "`start`, `stop`, `restart`, `rolling_restart` or `reinstall`.",
      "pattern": "^(start|stop|restart|rolling_restart|reinstall)$",
      "title": "Action",
      "type": "string"
     },
     "approval_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the Manager approval that authorizes the operation when the Manager requires one.",
      "title": "Approval Id"
     },
     "batch_size": {
      "default": 1,
      "description": "Hosts handled at the same time, 1 to 100, default 1.",
      "maximum": 100.0,
      "minimum": 1.0,
      "title": "Batch Size",
      "type": "integer"
     },
     "components": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only these components of the service; default all.",
      "title": "Components"
     },
     "hosts": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only these hosts; default all hosts of the service.",
      "title": "Hosts"
     },
     "tolerate_failures": {
      "default": 0,
      "description": "Host failures tolerated before the operation stops, 0 to 100, default 0.",
      "maximum": 100.0,
      "minimum": 0.0,
      "title": "Tolerate Failures",
      "type": "integer"
     }
    },
    "required": [
     "action"
    ],
    "title": "OperationIn",
    "type": "object"
   },
   "OrderIn": {
    "description": "Manual containment order.",
    "properties": {
     "confidence": {
      "default": 1.0,
      "description": "Confidence of the decision, 0 to 1 (default 1).",
      "maximum": 1.0,
      "minimum": 0.0,
      "title": "Confidence",
      "type": "number"
     },
     "incident_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Incident the order belongs to, optional (404 when unknown).",
      "title": "Incident Id"
     },
     "max_blast_radius": {
      "anyOf": [
       {
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Largest number of objects the order may affect (1 or more); above it the order is refused.",
      "title": "Max Blast Radius"
     },
     "params": {
      "additionalProperties": true,
      "description": "Parameters of the reaction, for example a rate for `RATE_LIMIT`.",
      "title": "Params",
      "type": "object"
     },
     "reaction": {
      "description": "Typed reaction: `BLOCK_REQUEST`, `RATE_LIMIT`, `REQUIRE_APPROVAL`, `CANCEL_RUN`, `CANCEL_SUBAGENTS`, `SUSPEND_AGENT`, `SUSPEND_APPLICATION`, `DISABLE_TOOL`, `QUARANTINE_CONNECTOR`, `REVOKE_CREDENTIAL`, `DISABLE_MODEL_ROUTE`, `ISOLATE_NETWORK`, `TERMINATE_WORKLOAD`, `SUSPEND_IDENTITY`, `SUSPEND_TENANT`, `EMERGENCY_LOCKDOWN`.",
      "title": "Reaction",
      "type": "string"
     },
     "reason": {
      "description": "Why the containment is ordered, 3 to 2000 characters.",
      "maxLength": 2000,
      "minLength": 3,
      "title": "Reason",
      "type": "string"
     },
     "target": {
      "$ref": "#/components/schemas/eai__domains__soc__TargetIn",
      "description": "Typed target of the reaction."
     }
    },
    "required": [
     "reaction",
     "target",
     "reason"
    ],
    "title": "OrderIn",
    "type": "object"
   },
   "OrganizationIn": {
    "description": "New organization of the tenant.",
    "properties": {
     "description": {
      "default": "",
      "description": "Description, at most 2000 characters (empty by default).",
      "maxLength": 2000,
      "title": "Description",
      "type": "string"
     },
     "metadata": {
      "additionalProperties": true,
      "description": "Free key-value pairs stored with the object. Checked by the database: a refused object answers 422 `invalid_metadata`.",
      "title": "Metadata",
      "type": "object"
     },
     "name": {
      "description": "Display name, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "slug": {
      "description": "Short identifier, lowercase letters, digits and hyphens, starting with a letter or a digit, at most 63 characters. Unique, it cannot be changed later.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
      "title": "Slug",
      "type": "string"
     }
    },
    "required": [
     "slug",
     "name"
    ],
    "title": "OrganizationIn",
    "type": "object"
   },
   "OrganizationPatch": {
    "description": "Changes to an organization; omitted fields keep their value.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New description, at most 2000 characters.",
      "title": "Description"
     },
     "expected_version": {
      "anyOf": [
       {
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version the caller last read. A stale version answers 409 `version_conflict` (optimistic concurrency).",
      "title": "Expected Version"
     },
     "metadata": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free key-value pairs stored with the object. Checked by the database: a refused object answers 422 `invalid_metadata`.",
      "title": "Metadata"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New display name, 1 to 200 characters.",
      "title": "Name"
     },
     "status": {
      "anyOf": [
       {
        "enum": [
         "active",
         "archived"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`active` or `archived`.",
      "title": "Status"
     }
    },
    "title": "OrganizationPatch",
    "type": "object"
   },
   "PackageStatusIn": {
    "description": "Kill switch of a package.",
    "properties": {
     "approval_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Approved `marketplace.package.resume` request, to lift the kill switch.",
      "title": "Approval Id"
     },
     "reason": {
      "default": "",
      "description": "Why the status changes (up to 1000 characters).",
      "maxLength": 1000,
      "title": "Reason",
      "type": "string"
     },
     "status": {
      "description": "`suspended` (immediate) or `active` (lifting, with approval).",
      "enum": [
       "suspended",
       "active"
      ],
      "title": "Status",
      "type": "string"
     }
    },
    "required": [
     "status"
    ],
    "title": "PackageStatusIn",
    "type": "object"
   },
   "PasswordIn": {
    "additionalProperties": false,
    "description": "Password change of the signed in local account.",
    "properties": {
     "current_password": {
      "description": "Current password, 1 to 256 characters.",
      "maxLength": 256,
      "minLength": 1,
      "title": "Current Password",
      "type": "string"
     },
     "new_password": {
      "description": "New password: at least the configured minimum length (12 by default), at most 256 characters, with letters and non letters.",
      "maxLength": 256,
      "minLength": 1,
      "title": "New Password",
      "type": "string"
     }
    },
    "required": [
     "current_password",
     "new_password"
    ],
    "title": "PasswordIn",
    "type": "object"
   },
   "PresignIn": {
    "description": "Request of a presigned URL for one object.",
    "properties": {
     "content_type": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Content type passed to the backend when the URL is signed (the type the upload is expected to send); 200 characters at most.",
      "title": "Content Type"
     },
     "expires_seconds": {
      "default": 900,
      "description": "Lifetime of the URL in seconds, default 900, at most `EAI_STORAGE_PRESIGN_MAX_SECONDS` (3600 by default) and never more than 604800.",
      "maximum": 604800.0,
      "minimum": 1.0,
      "title": "Expires Seconds",
      "type": "integer"
     },
     "key": {
      "description": "Key of the object relative to the profile key prefix, 1 to 1024 characters, inside a presign prefix of the profile.",
      "maxLength": 1024,
      "minLength": 1,
      "title": "Key",
      "type": "string"
     },
     "purpose": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free label of why the URL is issued, stored with the grant; 200 characters at most.",
      "title": "Purpose"
     },
     "scope": {
      "description": "Direction of the URL: `read` gives a `GET` URL, `write` a `PUT` URL.",
      "enum": [
       "read",
       "write"
      ],
      "title": "Scope",
      "type": "string"
     }
    },
    "required": [
     "scope",
     "key"
    ],
    "title": "PresignIn",
    "type": "object"
   },
   "PriceCardIn": {
    "description": "New price card. Prices are decimals; token, character and similar keys are priced per one million units.",
    "properties": {
     "currency": {
      "description": "ISO 4217 currency of the prices (required).",
      "pattern": "^[A-Z]{3}$",
      "title": "Currency",
      "type": "string"
     },
     "effective_from": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Start of validity, ISO 8601; default now. The card in force at that date is closed.",
      "title": "Effective From"
     },
     "effective_to": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "End of validity, ISO 8601; null for no end.",
      "title": "Effective To"
     },
     "image_prices": {
      "additionalProperties": {
       "anyOf": [
        {
         "type": "number"
        },
        {
         "type": "string"
        }
       ]
      },
      "description": "Image prices by dimension key (size, quality), at least 0.",
      "title": "Image Prices",
      "type": "object"
     },
     "model_pattern": {
      "description": "Model id or case insensitive glob pattern (for example `gpt-4o*`), 1 to 200 characters; an exact id wins over a pattern.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Model Pattern",
      "type": "string"
     },
     "notes": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free notes.",
      "title": "Notes"
     },
     "prices": {
      "additionalProperties": {
       "anyOf": [
        {
         "type": "number"
        },
        {
         "type": "string"
        }
       ]
      },
      "description": "Flat prices by key, for example `input_tokens`, `output_tokens`, `cached_input_tokens`, `reasoning_tokens`, `characters` (per million), `images`, `audio_seconds`, `video_seconds`, `requests`, `gpu_seconds`. At least one of `prices`, `image_prices`, `video_prices` is required.",
      "title": "Prices",
      "type": "object"
     },
     "provider": {
      "description": "Provider of the card, 1 to 100 characters.",
      "maxLength": 100,
      "minLength": 1,
      "title": "Provider",
      "type": "string"
     },
     "reasoning_billing": {
      "default": "included_in_output",
      "description": "How reasoning tokens are billed: `included_in_output` (default), `separate`, `not_billed` or `not_exposed`.",
      "enum": [
       "included_in_output",
       "separate",
       "not_billed",
       "not_exposed"
      ],
      "title": "Reasoning Billing",
      "type": "string"
     },
     "reference": {
      "default": false,
      "description": "Marks the card as a reference price card; the flag is copied into the pricing record of every usage event costed with it. Default false.",
      "title": "Reference",
      "type": "boolean"
     },
     "region": {
      "default": "*",
      "description": "Region of the card, default `*` (every region).",
      "title": "Region",
      "type": "string"
     },
     "source": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Where the prices come from (contract, public page...).",
      "title": "Source"
     },
     "tiers": {
      "description": "Price tiers that apply from a number of input tokens (long context pricing).",
      "items": {
       "$ref": "#/components/schemas/TierIn"
      },
      "title": "Tiers",
      "type": "array"
     },
     "usage_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Usage type the card prices; null for any.",
      "title": "Usage Type"
     },
     "version": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version label; default `v<n>` from the number of cards of the same key.",
      "title": "Version"
     },
     "video_prices": {
      "additionalProperties": {
       "anyOf": [
        {
         "type": "number"
        },
        {
         "type": "string"
        }
       ]
      },
      "description": "Video prices by dimension key (resolution, frame rate, mode), at least 0.",
      "title": "Video Prices",
      "type": "object"
     }
    },
    "required": [
     "provider",
     "model_pattern",
     "currency"
    ],
    "title": "PriceCardIn",
    "type": "object"
   },
   "ProductionIn": {
    "description": "Promotion of a version to production.",
    "properties": {
     "approval_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Approved `marketplace.promote` request. Omit it on the first call.",
      "title": "Approval Id"
     }
    },
    "title": "ProductionIn",
    "type": "object"
   },
   "ProfileIn": {
    "additionalProperties": false,
    "description": "New storage profile. Unknown fields are refused; secret values are refused in every field.",
    "properties": {
     "auth": {
      "additionalProperties": true,
      "description": "Non secret authentication settings: `method` (`sigv4` for S3 family providers, also `ibm_iam` for IBM COS; `shared_key`, `sas`, `entra_client_secret` or `workload_identity` for Azure; `service_account` for GCS) and, as needed, `account`, `tenant_id`, `client_id`, `service_instance_id`, `token_url`, `scope`. `account` is required for Azure; `workload_identity` is for platform profiles only.",
      "title": "Auth",
      "type": "object"
     },
     "bucket": {
      "description": "Bucket or container name: 3 to 222 characters, lowercase letters, digits, dots, dashes and underscores, starting and ending with a letter or digit, no `..`.",
      "maxLength": 222,
      "minLength": 3,
      "title": "Bucket",
      "type": "string"
     },
     "credential_ref": {
      "anyOf": [
       {
        "maxLength": 210,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the secret, 210 characters at most: `openbao://<path>` for a tenant profile, `env://EAI_CRED_<NAME>` for a platform profile. Not used with `workload_identity`. The secret value is never sent.",
      "title": "Credential Ref"
     },
     "description": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free description, 500 characters at most.",
      "title": "Description"
     },
     "encryption": {
      "additionalProperties": true,
      "description": "Server side encryption, default `{mode: provider_default}`. Modes: `provider_default`, `sse-s3`, `sse-kms` for the S3 family; `provider_default`, `encryption-scope` (with `encryption_scope`) for Azure; `provider_default`, `cmek` (with `kms_key_id`) for GCS.",
      "title": "Encryption",
      "type": "object"
     },
     "endpoint": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "HTTPS address of the storage service, 500 characters at most. Required for `ibm_cos`, `seaweedfs` and `s3_compatible`; optional otherwise.",
      "title": "Endpoint"
     },
     "key_prefix": {
      "default": "",
      "description": "Prefix added to every object key written through this profile, 512 characters at most; empty by default.",
      "maxLength": 512,
      "title": "Key Prefix",
      "type": "string"
     },
     "name": {
      "description": "Unique name of the profile in its scope: 2 to 63 characters, lowercase letters, digits and dashes, starting with a letter or a digit.",
      "pattern": "^[a-z0-9][a-z0-9-]{1,62}$",
      "title": "Name",
      "type": "string"
     },
     "options": {
      "additionalProperties": true,
      "description": "Provider options: `path_style` (path style addressing for S3) and `storage_class`. Any other key is refused.",
      "title": "Options",
      "type": "object"
     },
     "presign_prefixes": {
      "description": "Key prefixes reachable through the API (presigned URLs, listing, deletion), up to 20. Empty by default: no key is reachable.",
      "items": {
       "type": "string"
      },
      "maxItems": 20,
      "title": "Presign Prefixes",
      "type": "array"
     },
     "provider": {
      "description": "Storage provider: `aws_s3`, `ibm_cos`, `seaweedfs`, `s3_compatible`, `azure_blob` or `gcs`.",
      "enum": [
       "aws_s3",
       "ibm_cos",
       "seaweedfs",
       "s3_compatible",
       "azure_blob",
       "gcs"
      ],
      "title": "Provider",
      "type": "string"
     },
     "purposes": {
      "description": "What the profile is used for, up to 10 among `audit_worm`, `evidence`, `documents`, `media`, `exports`, `backups`, `general`. `audit_worm` needs object lock, retention and integrity; `evidence` needs object lock and integrity.",
      "items": {
       "type": "string"
      },
      "maxItems": 10,
      "title": "Purposes",
      "type": "array"
     },
     "region": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Region of the bucket, 64 characters at most.",
      "title": "Region"
     },
     "required_capabilities": {
      "description": "Capabilities the profile must have beyond those of its purposes, up to 20 among `versioning`, `object_lock`, `legal_hold`, `retention`, `multipart`, `presign`, `sse`, `kms`, `storage_classes`, `lifecycle`, `replication`, `integrity`.",
      "items": {
       "type": "string"
      },
      "maxItems": 20,
      "title": "Required Capabilities",
      "type": "array"
     },
     "scope": {
      "default": "tenant",
      "description": "`tenant` (default) for a profile of the caller's tenant, `platform` for a profile shared by the platform (platform administrator only).",
      "enum": [
       "tenant",
       "platform"
      ],
      "title": "Scope",
      "type": "string"
     }
    },
    "required": [
     "name",
     "provider",
     "bucket"
    ],
    "title": "ProfileIn",
    "type": "object"
   },
   "ProfilePatch": {
    "additionalProperties": false,
    "description": "Changes of a storage profile; every field is optional and an omitted field keeps its value. The name, scope and provider cannot be changed here. Unknown fields are refused.",
    "properties": {
     "auth": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "New non secret authentication settings (same fields as on creation). Changing them clears the capabilities.",
      "title": "Auth"
     },
     "bucket": {
      "anyOf": [
       {
        "maxLength": 222,
        "minLength": 3,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Bucket or container name, 3 to 222 characters. Changing it clears the capabilities.",
      "title": "Bucket"
     },
     "credential_ref": {
      "anyOf": [
       {
        "maxLength": 210,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New reference of the secret, 210 characters at most (`openbao://` for a tenant profile, `env://EAI_CRED_` for a platform profile). Changing it clears the capabilities.",
      "title": "Credential Ref"
     },
     "description": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free description, 500 characters at most.",
      "title": "Description"
     },
     "encryption": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "New server side encryption settings. Changing them clears the capabilities.",
      "title": "Encryption"
     },
     "endpoint": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "HTTPS address of the storage service, 500 characters at most. Changing it clears the capabilities.",
      "title": "Endpoint"
     },
     "key_prefix": {
      "anyOf": [
       {
        "maxLength": 512,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Prefix added to every object key, 512 characters at most.",
      "title": "Key Prefix"
     },
     "options": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "New provider options (`path_style`, `storage_class`). Changing them clears the capabilities.",
      "title": "Options"
     },
     "presign_prefixes": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 20,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "New list of presign prefixes, up to 20.",
      "title": "Presign Prefixes"
     },
     "purposes": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 10,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "New list of purposes, up to 10.",
      "title": "Purposes"
     },
     "region": {
      "anyOf": [
       {
        "maxLength": 64,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Region of the bucket, 64 characters at most. Changing it clears the capabilities.",
      "title": "Region"
     },
     "required_capabilities": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 20,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "New list of required capabilities, up to 20.",
      "title": "Required Capabilities"
     },
     "status": {
      "anyOf": [
       {
        "enum": [
         "active",
         "disabled"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`disabled` stops every use of the profile; `active` on a disabled profile makes it `unverified` again (verify it before use).",
      "title": "Status"
     }
    },
    "title": "ProfilePatch",
    "type": "object"
   },
   "PromptIn": {
    "description": "A prompt version to publish.",
    "properties": {
     "description": {
      "default": "",
      "description": "Description of the prompt; an empty value keeps the current one. Default empty.",
      "title": "Description",
      "type": "string"
     },
     "model_hint": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model the template is written for, informative only.",
      "title": "Model Hint"
     },
     "name": {
      "description": "Name of the prompt: lowercase letters, digits, `.`, `_`, `-`, 1 to 128 characters, starting and ending with a letter or digit.",
      "title": "Name",
      "type": "string"
     },
     "template": {
      "description": "Template text with `{{ variable }}` placeholders (at least 1 character).",
      "minLength": 1,
      "title": "Template",
      "type": "string"
     },
     "variables": {
      "anyOf": [
       {
        "items": {
         "$ref": "#/components/schemas/Variable"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Declared variables. Omitted: every placeholder becomes a required string variable.",
      "title": "Variables"
     }
    },
    "required": [
     "name",
     "template"
    ],
    "title": "PromptIn",
    "type": "object"
   },
   "Provenance": {
    "description": "Where the content of a memory item comes from.",
    "properties": {
     "classification": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Classification of the source.",
      "title": "Classification"
     },
     "hash": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Digest of the source content, for example `sha256:...`.",
      "title": "Hash"
     },
     "source_id": {
      "description": "Identifier of the source object.",
      "title": "Source Id",
      "type": "string"
     },
     "source_type": {
      "description": "Kind of source, for example `rag`, `conversation` or `tool`.",
      "title": "Source Type",
      "type": "string"
     },
     "uri": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "URI of the source.",
      "title": "Uri"
     },
     "version": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version of the source.",
      "title": "Version"
     }
    },
    "required": [
     "source_type",
     "source_id"
    ],
    "title": "Provenance",
    "type": "object"
   },
   "PublishIn": {
    "description": "A pack version to publish with its supply chain evidence.",
    "properties": {
     "archive": {
      "description": "The `.tar.gz` pack, base64 encoded (up to 12 MiB of text).",
      "maxLength": 12582912,
      "minLength": 4,
      "title": "Archive",
      "type": "string"
     },
     "evaluation_report": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Evaluation report bound to the archive digest.",
      "title": "Evaluation Report"
     },
     "oci": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/OciIn"
       },
       {
        "type": "null"
       }
      ],
      "description": "OCI artifact of the pack; its digest is required later by the production gate."
     },
     "provenance": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Signed in-toto Statement v1 with a SLSA v1 predicate: `{statement, signature: {value, signer}}`.",
      "title": "Provenance"
     },
     "sbom": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Software bill of materials of the pack.",
      "title": "Sbom"
     },
     "signature": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/SignatureIn"
       },
       {
        "type": "null"
       }
      ],
      "description": "Signature of the archive digest by a trusted publisher."
     },
     "skill_signatures": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Signatures of the skills of the pack, by skill name.",
      "title": "Skill Signatures",
      "type": "object"
     },
     "test_report": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Test report bound to the archive digest.",
      "title": "Test Report"
     },
     "vulnerability_scan": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Vulnerability scan report bound to the archive digest.",
      "title": "Vulnerability Scan"
     }
    },
    "required": [
     "archive"
    ],
    "title": "PublishIn",
    "type": "object"
   },
   "PublisherIn": {
    "description": "A trusted publisher key.",
    "properties": {
     "name": {
      "description": "Publisher name, same pattern as a package name.",
      "pattern": "^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$",
      "title": "Name",
      "type": "string"
     },
     "public_key": {
      "description": "Public key, PEM or text form (40 to 4000 characters).",
      "maxLength": 4000,
      "minLength": 40,
      "title": "Public Key",
      "type": "string"
     }
    },
    "required": [
     "name",
     "public_key"
    ],
    "title": "PublisherIn",
    "type": "object"
   },
   "PurgeIn": {
    "description": "Audit payload purge request.",
    "properties": {
     "cutoff": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "For `retention`: payloads of events older than this date are purged (ISO 8601). Default: now minus the payload retention period.",
      "title": "Cutoff"
     },
     "dry_run": {
      "default": false,
      "description": "When true, reports what would be purged without deleting anything (default false).",
      "title": "Dry Run",
      "type": "boolean"
     },
     "event_ids": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 1000,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "For `erasure`: events whose payloads are erased, at most 1000. Required for an erasure.",
      "title": "Event Ids"
     },
     "kind": {
      "default": "retention",
      "description": "`retention` (default, by age) or `erasure` (listed events).",
      "enum": [
       "retention",
       "erasure"
      ],
      "title": "Kind",
      "type": "string"
     }
    },
    "title": "PurgeIn",
    "type": "object"
   },
   "QueryFilters": {
    "description": "Filters of a query, applied inside the store together with the ACL and the clearance.",
    "properties": {
     "collections": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 50,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only the documents of these collections (`collection` given at ingestion), up to 50.",
      "title": "Collections"
     },
     "document_ids": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 1000,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only these documents (UUIDs, up to 1000); an id that is not a readable active document matches nothing.",
      "title": "Document Ids"
     },
     "element_types": {
      "anyOf": [
       {
        "items": {
         "enum": [
          "title",
          "paragraph",
          "table",
          "list",
          "caption",
          "code",
          "formula",
          "footnote",
          "figure",
          "other"
         ],
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only the chunks of these element types: `title`, `paragraph`, `table`, `list`, `caption`, `code`, `formula`, `footnote`, `figure`, `other`.",
      "title": "Element Types"
     },
     "languages": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 20,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only the chunks in these languages (ISO 639-1 codes such as `fr`, `en`), up to 20.",
      "title": "Languages"
     },
     "metadata": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only the documents whose metadata contain this JSON object (containment).",
      "title": "Metadata"
     }
    },
    "title": "QueryFilters",
    "type": "object"
   },
   "QueryIn": {
    "description": "A retrieval query.",
    "properties": {
     "candidates": {
      "anyOf": [
       {
        "maximum": 20.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Candidates fetched per requested result in each list (1 to 20, default 4).",
      "title": "Candidates"
     },
     "conflicts": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "When true (default), compute the possible conflict signal between passages.",
      "title": "Conflicts"
     },
     "context_window": {
      "anyOf": [
       {
        "maximum": 5.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Neighbour chunks added on each side of a passage (0 to 5, default 0: none).",
      "title": "Context Window"
     },
     "dedupe": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "When true (default), drop passages that are near duplicates of a better ranked one.",
      "title": "Dedupe"
     },
     "dedupe_threshold": {
      "anyOf": [
       {
        "maximum": 1.0,
        "minimum": 0.5,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "description": "Word 3-shingle Jaccard overlap from which two passages are near duplicates (0.5 to 1, default 0.9).",
      "title": "Dedupe Threshold"
     },
     "diagnostics": {
      "default": false,
      "description": "When true, the answer adds `diagnostics` (stages with timing, candidate counts, strategy, filters); the retrieval cache is not read. Default false; the diagnostics are recorded in any case.",
      "title": "Diagnostics",
      "type": "boolean"
     },
     "filters": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/QueryFilters"
       },
       {
        "type": "null"
       }
      ],
      "description": "Filters by collection, document, metadata, element type and language (see QueryFilters)."
     },
     "fusion": {
      "anyOf": [
       {
        "enum": [
         "rrf",
         "weighted"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Hybrid fusion: `rrf` (reciprocal rank fusion, default) or `weighted` (0.5 similarity + 0.5 keyword overlap of the dense candidates).",
      "title": "Fusion"
     },
     "min_score": {
      "default": 0.0,
      "description": "Minimum vector similarity score of a result. Default 0.",
      "title": "Min Score",
      "type": "number"
     },
     "mode": {
      "anyOf": [
       {
        "enum": [
         "vector",
         "dense",
         "lexical",
         "hybrid"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`vector` or `dense` (cosine similarity), `lexical` (PostgreSQL full text) or `hybrid` (fusion of both). Default: the mode of the knowledge base strategy, else `vector`.",
      "title": "Mode"
     },
     "query": {
      "description": "Text of the query (at least 1 character).",
      "minLength": 1,
      "title": "Query",
      "type": "string"
     },
     "rerank": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "When true, order the results with a rerank model. Default: the strategy of the knowledge base, else false.",
      "title": "Rerank"
     },
     "rerank_candidates": {
      "anyOf": [
       {
        "maximum": 200.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Passages sent to the reranker (1 to 200, at least `top_k`; default `top_k`).",
      "title": "Rerank Candidates"
     },
     "rerank_model": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Registry model with the rerank capability (default: the platform rerank model). Without one, `warnings` reports `reranker_not_configured`.",
      "title": "Rerank Model"
     },
     "rrf_k": {
      "anyOf": [
       {
        "maximum": 1000.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Constant `k` of the reciprocal rank fusion (1 to 1000, default 60).",
      "title": "Rrf K"
     },
     "token_budget": {
      "anyOf": [
       {
        "maximum": 32000.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Token budget of the passages and their neighbours; neighbours are added nearest first while it allows (0 to 32000, default 2000).",
      "title": "Token Budget"
     },
     "top_k": {
      "default": 5,
      "description": "Number of results (1 to 100, default 5).",
      "maximum": 100.0,
      "minimum": 1.0,
      "title": "Top K",
      "type": "integer"
     }
    },
    "required": [
     "query"
    ],
    "title": "QueryIn",
    "type": "object"
   },
   "QuotaProfileIn": {
    "description": "New quota profile.",
    "properties": {
     "currency": {
      "anyOf": [
       {
        "pattern": "^[A-Z]{3}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "ISO 4217 code of `limit_cost`, three capital letters such as `EUR`. Null: the tenant currency.",
      "title": "Currency"
     },
     "enforcement": {
      "default": "hard",
      "description": "`hard` (default) refuses the call once the limit is reached; `soft` only reports the overrun.",
      "enum": [
       "hard",
       "soft"
      ],
      "title": "Enforcement",
      "type": "string"
     },
     "limit_cost": {
      "anyOf": [
       {
        "maximum": 1000000000000000.0,
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Spending limit of the period, in `currency`, between 0 and 10^15. At least one of `limit_cost` and `limit_tokens` is required.",
      "title": "Limit Cost"
     },
     "limit_tokens": {
      "anyOf": [
       {
        "maximum": 4.611686018427388e+18,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Token limit of the period (input and output tokens), between 0 and 2^62.",
      "title": "Limit Tokens"
     },
     "name": {
      "description": "Unique name of the profile in the tenant, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "period": {
      "default": "month",
      "description": "Window of the quota: `request`, `run`, `hour`, `day` or `month` (default `month`).",
      "enum": [
       "request",
       "run",
       "hour",
       "day",
       "month"
      ],
      "title": "Period",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "QuotaProfileIn",
    "type": "object"
   },
   "QuotaProfilePatch": {
    "description": "Changes to a quota profile; omitted fields keep their value.",
    "properties": {
     "enforcement": {
      "anyOf": [
       {
        "enum": [
         "hard",
         "soft"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New enforcement: `hard` or `soft`.",
      "title": "Enforcement"
     },
     "limit_cost": {
      "anyOf": [
       {
        "maximum": 1000000000000000.0,
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New spending limit, between 0 and 10^15.",
      "title": "Limit Cost"
     },
     "limit_tokens": {
      "anyOf": [
       {
        "maximum": 4.611686018427388e+18,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "New token limit, between 0 and 2^62.",
      "title": "Limit Tokens"
     },
     "period": {
      "anyOf": [
       {
        "enum": [
         "request",
         "run",
         "hour",
         "day",
         "month"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New window: `request`, `run`, `hour`, `day` or `month`.",
      "title": "Period"
     }
    },
    "title": "QuotaProfilePatch",
    "type": "object"
   },
   "RagAgentBrandingIn": {
    "additionalProperties": false,
    "description": "Branding fields to write; an absent field is kept, null brings it back to the default of the runtime.",
    "properties": {
     "agent_name": {
      "anyOf": [
       {
        "maxLength": 80,
        "minLength": 1,
        "pattern": "^[^<>\\x00-\\x1f\\x7f]+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the agent shown to the users, 1 to 80 characters, without `<`, `>` nor control characters.",
      "title": "Agent Name"
     },
     "app_url": {
      "anyOf": [
       {
        "maxLength": 2048,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "URL of the web application of the instance once known, https only, without credentials (up to 2048 characters).",
      "title": "App Url"
     },
     "expected_version": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Branding version the change is based on; another current version answers 409 `rag_agent_branding_version_conflict`.",
      "title": "Expected Version"
     },
     "navbar_color": {
      "anyOf": [
       {
        "pattern": "^#[0-9A-Fa-f]{6}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Colour of the top bar, `#RRGGBB`; the text on it is black or white with a contrast of 4.5:1 or more.",
      "title": "Navbar Color"
     },
     "sidebar_color": {
      "anyOf": [
       {
        "pattern": "^#[0-9A-Fa-f]{6}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Colour of the sidebar, `#RRGGBB`; the text on it is black or white with a contrast of 4.5:1 or more.",
      "title": "Sidebar Color"
     }
    },
    "title": "RagAgentBrandingIn",
    "type": "object"
   },
   "RagAgentInstanceIn": {
    "description": "A RAG Agent instance to create in draft.",
    "properties": {
     "business_unit_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Business unit of the instance (UUID), checked at validation.",
      "title": "Business Unit Id"
     },
     "deployment_model": {
      "description": "`shared` (the existing shared runtime) or `dedicated` (a runtime installed by the Navin Manager).",
      "enum": [
       "shared",
       "dedicated"
      ],
      "title": "Deployment Model",
      "type": "string"
     },
     "description": {
      "default": "",
      "description": "Free description (up to 2000 characters).",
      "maxLength": 2000,
      "title": "Description",
      "type": "string"
     },
     "embedding_model": {
      "description": "Embedding model of the registry (capability `embeddings`), used by the knowledge base of the instance.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Embedding Model",
      "type": "string"
     },
     "generation_model": {
      "description": "Generation model of the registry (capability `chat`).",
      "maxLength": 200,
      "minLength": 1,
      "title": "Generation Model",
      "type": "string"
     },
     "id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Immutable identifier (UUID) of the instance; generated when absent.",
      "title": "Id"
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 63 characters.",
      "pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$",
      "title": "Name",
      "type": "string"
     },
     "organization_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Organization of the instance (UUID), checked at validation.",
      "title": "Organization Id"
     },
     "project": {
      "description": "Project of the instance (identifier or slug); the caller must be a tenant administrator or an owner of it.",
      "maxLength": 100,
      "minLength": 1,
      "title": "Project",
      "type": "string"
     },
     "version": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version to deploy; default: the version the runtime reports at the smoke step.",
      "title": "Version"
     }
    },
    "required": [
     "name",
     "project",
     "deployment_model",
     "generation_model",
     "embedding_model"
    ],
    "title": "RagAgentInstanceIn",
    "type": "object"
   },
   "RagAgentRestoreIn": {
    "description": "A restore request.",
    "properties": {
     "backup_id": {
      "description": "Identifier of the backup to restore.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Backup Id",
      "type": "string"
     }
    },
    "required": [
     "backup_id"
    ],
    "title": "RagAgentRestoreIn",
    "type": "object"
   },
   "RagAgentUpgradeIn": {
    "description": "An upgrade request.",
    "properties": {
     "version": {
      "description": "Version to deploy (letters, digits, `.`, `_`, `+`, `-`, up to 64 characters).",
      "pattern": "^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$",
      "title": "Version",
      "type": "string"
     }
    },
    "required": [
     "version"
    ],
    "title": "RagAgentUpgradeIn",
    "type": "object"
   },
   "ReconRunIn": {
    "description": "Period of a reconciliation run.",
    "properties": {
     "from": {
      "anyOf": [
       {
        "format": "date",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "First day (ISO 8601 date); default the first day of the month of `to`.",
      "title": "From"
     },
     "to": {
      "anyOf": [
       {
        "format": "date",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Last day (ISO 8601 date); default today. Must not be before `from` (422).",
      "title": "To"
     }
    },
    "title": "ReconRunIn",
    "type": "object"
   },
   "ReconcileIn": {
    "description": "Reconciliation of a side effecting transaction.",
    "properties": {
     "note": {
      "default": "",
      "description": "Note of the reconciliation, at most 2000 characters.",
      "maxLength": 2000,
      "title": "Note",
      "type": "string"
     },
     "outcome": {
      "description": "`committed` (it happened at the provider) or `not_executed`.",
      "title": "Outcome",
      "type": "string"
     },
     "provider_reference": {
      "anyOf": [
       {
        "maxLength": 300,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the operation at the provider, at most 300 characters.",
      "title": "Provider Reference"
     }
    },
    "required": [
     "outcome"
    ],
    "title": "ReconcileIn",
    "type": "object"
   },
   "RecoveryIn": {
    "description": "Recovery request.",
    "properties": {
     "kill_switch_id": {
      "description": "Kill switch to lift.",
      "title": "Kill Switch Id",
      "type": "string"
     },
     "reason": {
      "description": "Why the containment can end, 3 to 2000 characters.",
      "maxLength": 2000,
      "minLength": 3,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "kill_switch_id",
     "reason"
    ],
    "title": "RecoveryIn",
    "type": "object"
   },
   "RedTeamIn": {
    "description": "Red team run request.",
    "properties": {
     "engine": {
      "default": "builtin",
      "description": "`builtin` (default) or `garak`.",
      "title": "Engine",
      "type": "string"
     },
     "max_attack_success_rate": {
      "default": 0.0,
      "description": "Highest share of successful attacks accepted, 0 to 1 (default 0: any successful attack fails the run).",
      "maximum": 1.0,
      "minimum": 0.0,
      "title": "Max Attack Success Rate",
      "type": "number"
     },
     "probes": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Probes to send. Default: every builtin probe, or `promptinject` and `dan` for garak.",
      "title": "Probes"
     },
     "target": {
      "$ref": "#/components/schemas/eai__domains__evaluation__Target",
      "description": "Target attacked: `model`, `agent`, `prompt`, `rag_pipeline`, `skill` or `tool`."
     }
    },
    "required": [
     "target"
    ],
    "title": "RedTeamIn",
    "type": "object"
   },
   "ReindexIn": {
    "description": "Target of a reindex.",
    "properties": {
     "dimensions": {
      "anyOf": [
       {
        "maximum": 16384.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Vector size, one of the sizes the model declares (1 to 16384; default: native).",
      "title": "Dimensions"
     },
     "embedding_model": {
      "description": "Registry model with the embeddings capability (1 to 200 characters).",
      "maxLength": 200,
      "minLength": 1,
      "title": "Embedding Model",
      "type": "string"
     }
    },
    "required": [
     "embedding_model"
    ],
    "title": "ReindexIn",
    "type": "object"
   },
   "RejectIn": {
    "description": "Rejection of a change.",
    "properties": {
     "reason": {
      "description": "Why the change is rejected (3 to 1000 characters).",
      "maxLength": 1000,
      "minLength": 3,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "reason"
    ],
    "title": "RejectIn",
    "type": "object"
   },
   "ReleaseIn": {
    "description": "Release approval of a legal hold.",
    "properties": {
     "reason": {
      "description": "Why the hold can be released, 3 to 1000 characters.",
      "maxLength": 1000,
      "minLength": 3,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "reason"
    ],
    "title": "ReleaseIn",
    "type": "object"
   },
   "RenderIn": {
    "description": "Values to render a prompt.",
    "properties": {
     "strict": {
      "default": true,
      "description": "When true (default), values for undeclared variables are an error.",
      "title": "Strict",
      "type": "boolean"
     },
     "variables": {
      "additionalProperties": true,
      "description": "Value of each variable, by name.",
      "title": "Variables",
      "type": "object"
     },
     "version": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version number to render. Default: the latest.",
      "title": "Version"
     }
    },
    "title": "RenderIn",
    "type": "object"
   },
   "ReserveIn": {
    "description": "Amount to reserve on the matching quotas.",
    "properties": {
     "cost": {
      "anyOf": [
       {
        "maximum": 1000000000000000.0,
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       }
      ],
      "default": "0",
      "description": "Cost to reserve in the tenant currency, 0 to 10^15, default 0; converted to the currency of each quota.",
      "title": "Cost"
     },
     "scope": {
      "additionalProperties": true,
      "description": "Who the call is for: keys `project`, `agent`, `user`, `model`, `provider`, `run` (or the same with `_id`), matched against the quota scopes.",
      "title": "Scope",
      "type": "object"
     },
     "tokens": {
      "default": 0,
      "description": "Tokens to reserve, 0 to 2^62, default 0.",
      "maximum": 4.611686018427388e+18,
      "minimum": 0.0,
      "title": "Tokens",
      "type": "integer"
     },
     "ttl_seconds": {
      "anyOf": [
       {
        "exclusiveMinimum": 0.0,
        "maximum": 86400.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime of the reservation in seconds, 1 to 86400; default the tenant `reservation_ttl_seconds` (900). An expired reservation is released.",
      "title": "Ttl Seconds"
     }
    },
    "title": "ReserveIn",
    "type": "object"
   },
   "RestorePlanIn": {
    "description": "Restore plan request.",
    "properties": {
     "artifact_id": {
      "description": "Identifier of the backup artefact to restore, 1 to 100 characters.",
      "maxLength": 100,
      "minLength": 1,
      "title": "Artifact Id",
      "type": "string"
     },
     "environment": {
      "description": "Target environment: `isolated`, `staging` or `production`.",
      "pattern": "^(isolated|staging|production)$",
      "title": "Environment",
      "type": "string"
     },
     "target_versions": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Versions of the target environment by component, compared by the Manager with the artefact (same major version, or incompatible).",
      "title": "Target Versions",
      "type": "object"
     }
    },
    "required": [
     "artifact_id",
     "environment"
    ],
    "title": "RestorePlanIn",
    "type": "object"
   },
   "RestrictIn": {
    "description": "Child delegation; omitted fields inherit the parent values.",
    "properties": {
     "audience": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 20,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Narrower audiences, at most 20.",
      "title": "Audience"
     },
     "data_classification_max": {
      "anyOf": [
       {
        "pattern": "^(public|internal|confidential|restricted|secret)$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lower or equal classification ceiling: `public`, `internal`, `confidential`, `restricted` or `secret`.",
      "title": "Data Classification Max"
     },
     "delegate": {
      "description": "Sub-delegate: `agent:<name>`, `app:<id>`, `service:<name>` or `subagent:<name>`.",
      "maxLength": 250,
      "minLength": 3,
      "title": "Delegate",
      "type": "string"
     },
     "expires_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Expiry date and time (ISO 8601), never beyond the parent expiry.",
      "title": "Expires At"
     },
     "max_depth": {
      "anyOf": [
       {
        "maximum": 10.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum depth of the chain under this branch, 0 to 10: at least the depth of the child, at most the parent `max_depth` (default: the parent value).",
      "title": "Max Depth"
     },
     "purpose": {
      "default": "",
      "description": "Purpose of the child delegation, at most 2000 characters.",
      "maxLength": 2000,
      "title": "Purpose",
      "type": "string"
     },
     "redelegation_allowed": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the sub-delegate may restrict again.",
      "title": "Redelegation Allowed"
     },
     "resources": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 100,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Narrower resource restrictions, at most 100.",
      "title": "Resources"
     },
     "scopes": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 100,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Narrower scopes, at most 100, covered by the parent ones.",
      "title": "Scopes"
     },
     "ttl_seconds": {
      "anyOf": [
       {
        "minimum": 60.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime in seconds, at least 60, never beyond the parent expiry.",
      "title": "Ttl Seconds"
     }
    },
    "required": [
     "delegate"
    ],
    "title": "RestrictIn",
    "type": "object"
   },
   "ResumeIn": {
    "description": "How to resume a run.",
    "properties": {
     "checkpoint_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Checkpoint of this run to resume from. Default: the last one with `from_last_checkpoint`.",
      "title": "Checkpoint Id"
     },
     "strategy": {
      "anyOf": [
       {
        "enum": [
         "from_last_checkpoint",
         "restart_step",
         "restart_run"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`from_last_checkpoint`, `restart_step` or `restart_run`. Default: `restart_step` for a run waiting for input, else `from_last_checkpoint`.",
      "title": "Strategy"
     }
    },
    "title": "ResumeIn",
    "type": "object"
   },
   "RetrievalIn": {
    "description": "Retrieval strategy of a knowledge base; a field left out takes its default and the options of a query override it.",
    "properties": {
     "candidates": {
      "anyOf": [
       {
        "maximum": 20.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Candidates per requested result in each list (1 to 20, default 4).",
      "title": "Candidates"
     },
     "conflicts": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Compute the possible conflict signal. Default true.",
      "title": "Conflicts"
     },
     "context_window": {
      "anyOf": [
       {
        "maximum": 5.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Neighbour chunks on each side of a passage (0 to 5, default 0).",
      "title": "Context Window"
     },
     "dedupe": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Drop near duplicate passages. Default true.",
      "title": "Dedupe"
     },
     "dedupe_threshold": {
      "anyOf": [
       {
        "maximum": 1.0,
        "minimum": 0.5,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "description": "Near duplicate threshold, word 3-shingle Jaccard (0.5 to 1, default 0.9).",
      "title": "Dedupe Threshold"
     },
     "fusion": {
      "anyOf": [
       {
        "enum": [
         "rrf",
         "weighted"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Hybrid fusion: `rrf` (default) or `weighted`.",
      "title": "Fusion"
     },
     "mode": {
      "anyOf": [
       {
        "enum": [
         "vector",
         "dense",
         "lexical",
         "hybrid"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Default mode: `vector` (default), `dense`, `lexical` or `hybrid`.",
      "title": "Mode"
     },
     "rerank": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Rerank every query by default. Default false.",
      "title": "Rerank"
     },
     "rerank_candidates": {
      "anyOf": [
       {
        "maximum": 200.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Passages sent to the reranker (1 to 200; default `top_k`).",
      "title": "Rerank Candidates"
     },
     "rerank_model": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Registry model with the rerank capability (1 to 200 characters; default: the platform rerank model).",
      "title": "Rerank Model"
     },
     "rrf_k": {
      "anyOf": [
       {
        "maximum": 1000.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Constant `k` of the reciprocal rank fusion (1 to 1000, default 60).",
      "title": "Rrf K"
     },
     "token_budget": {
      "anyOf": [
       {
        "maximum": 32000.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Token budget of the passages and their neighbours (0 to 32000, default 2000).",
      "title": "Token Budget"
     }
    },
    "title": "RetrievalIn",
    "type": "object"
   },
   "RetryIn": {
    "description": "Retry of a failed ingestion job.",
    "properties": {
     "reason": {
      "default": "",
      "description": "Why the job is retried (up to 2000 characters), kept in the history. Default empty.",
      "maxLength": 2000,
      "title": "Reason",
      "type": "string"
     }
    },
    "title": "RetryIn",
    "type": "object"
   },
   "ReviewIn": {
    "description": "Decision on a quarantined document.",
    "properties": {
     "decision": {
      "description": "`release` (searchable again) or `reject`.",
      "enum": [
       "release",
       "reject"
      ],
      "title": "Decision",
      "type": "string"
     },
     "reason": {
      "default": "",
      "description": "Why (up to 2000 characters). Default empty.",
      "maxLength": 2000,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "decision"
    ],
    "title": "ReviewIn",
    "type": "object"
   },
   "RevokeIn": {
    "description": "Revocation reason.",
    "properties": {
     "reason": {
      "default": "",
      "description": "Why it is revoked, at most 2000 characters (empty by default). Written to the audit trail.",
      "maxLength": 2000,
      "title": "Reason",
      "type": "string"
     }
    },
    "title": "RevokeIn",
    "type": "object"
   },
   "RevokeKeyIn": {
    "description": "Revocation of a signing key.",
    "properties": {
     "reason": {
      "description": "Why the key is revoked (3 to 2000 characters).",
      "maxLength": 2000,
      "minLength": 3,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "reason"
    ],
    "title": "RevokeKeyIn",
    "type": "object"
   },
   "RevokePrincipalIn": {
    "description": "Revocation of every delegation of a principal.",
    "properties": {
     "principal_id": {
      "description": "Principal whose delegations are revoked, for example a user subject, 1 to 300 characters.",
      "maxLength": 300,
      "minLength": 1,
      "title": "Principal Id",
      "type": "string"
     },
     "reason": {
      "default": "",
      "description": "Why, at most 2000 characters (empty by default). Written to the audit trail.",
      "maxLength": 2000,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "principal_id"
    ],
    "title": "RevokePrincipalIn",
    "type": "object"
   },
   "RotateIn": {
    "description": "Options of an API key rotation.",
    "properties": {
     "grace_seconds": {
      "default": 0,
      "description": "Seconds during which the old key stays valid, 0 to 604800 (7 days). 0 (default) revokes it at once.",
      "maximum": 604800.0,
      "minimum": 0.0,
      "title": "Grace Seconds",
      "type": "integer"
     }
    },
    "title": "RotateIn",
    "type": "object"
   },
   "Rule": {
    "description": "Rule of a builtin policy.",
    "properties": {
     "actions": {
      "description": "Actions targeted, glob patterns such as `model.*`. Default `[\"*\"]`.",
      "items": {
       "type": "string"
      },
      "title": "Actions",
      "type": "array"
     },
     "conditions": {
      "additionalProperties": true,
      "description": "Conditions that must all hold for the rule to apply: `classification_max`, `classification_min` (on `context.data_classification`), `clearance_required`, `regions`, `roles`, `environments`, `cost_max`, `cost_min` (on `context.cost_estimate`), `resource_attributes`, `subject_kinds`, `purposes`. An unknown condition never holds.",
      "title": "Conditions",
      "type": "object"
     },
     "effect": {
      "default": "allow",
      "description": "`allow` (default) or `deny`. A matching deny always wins.",
      "enum": [
       "allow",
       "deny"
      ],
      "title": "Effect",
      "type": "string"
     },
     "id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the rule inside the policy, shown in the reasons.",
      "title": "Id"
     },
     "obligations": {
      "description": "Obligations added to the decision when this allow rule applies.",
      "items": {
       "$ref": "#/components/schemas/Obligation"
      },
      "title": "Obligations",
      "type": "array"
     },
     "reason": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reason shown in the decision. Default: `allowed by <policy>/<rule>` or `denied by <policy>/<rule>`.",
      "title": "Reason"
     },
     "resource_types": {
      "description": "Resource types targeted, glob patterns. Empty (default): every type.",
      "items": {
       "type": "string"
      },
      "title": "Resource Types",
      "type": "array"
     }
    },
    "title": "Rule",
    "type": "object"
   },
   "RuleFile": {
    "description": "One file of a repository to import as a rule.",
    "properties": {
     "content": {
      "description": "Content of the file (up to 65536 characters).",
      "maxLength": 65536,
      "title": "Content",
      "type": "string"
     },
     "path": {
      "description": "Path of the file in the repository, for example `.cursor/rules/style.mdc` (1 to 500 characters).",
      "maxLength": 500,
      "minLength": 1,
      "title": "Path",
      "type": "string"
     }
    },
    "required": [
     "path",
     "content"
    ],
    "title": "RuleFile",
    "type": "object"
   },
   "RulesImportIn": {
    "description": "Rule files to import.",
    "properties": {
     "files": {
      "description": "Files to import (1 to 200).",
      "items": {
       "$ref": "#/components/schemas/RuleFile"
      },
      "maxItems": 200,
      "minItems": 1,
      "title": "Files",
      "type": "array"
     }
    },
    "required": [
     "files"
    ],
    "title": "RulesImportIn",
    "type": "object"
   },
   "SandboxIn": {
    "description": "A command to execute in an isolated sandbox.",
    "properties": {
     "command": {
      "description": "Command and arguments, one item per argument.",
      "items": {
       "type": "string"
      },
      "title": "Command",
      "type": "array"
     },
     "env": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Environment variables, string values.",
      "title": "Env",
      "type": "object"
     },
     "image": {
      "description": "Container image reference (1 to 500 characters, lowercase registry path, tag or digest allowed).",
      "maxLength": 500,
      "minLength": 1,
      "title": "Image",
      "type": "string"
     },
     "limits": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Resource limits: `cpu` (default `500m`, at most 4 cores), `memory` (default `512Mi`, at most `8Gi`), `timeout_seconds` (1 to 3600, default 300), `gpu` (at most 1), `max_steps`.",
      "title": "Limits"
     },
     "profile": {
      "default": "gvisor",
      "description": "Isolation profile: `gvisor` (default), `kata`, `wasm` or `none` (no isolation, `tenant_admin` only).",
      "enum": [
       "gvisor",
       "kata",
       "wasm",
       "none"
      ],
      "title": "Profile",
      "type": "string"
     },
     "run_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Run the execution belongs to (must exist); used for metering.",
      "title": "Run Id"
     }
    },
    "required": [
     "image"
    ],
    "title": "SandboxIn",
    "type": "object"
   },
   "ScheduleIn": {
    "description": "A cron schedule of an agent.",
    "properties": {
     "agent_id": {
      "description": "Agent to run (UUID or name).",
      "title": "Agent Id",
      "type": "string"
     },
     "cron": {
      "description": "Cron expression (1 to 200 characters), evaluated in `timezone`.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Cron",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "description": "When false, the schedule is kept but starts no run. Default true.",
      "title": "Enabled",
      "type": "boolean"
     },
     "input": {
      "additionalProperties": true,
      "description": "Input given to every run started by the schedule.",
      "title": "Input",
      "type": "object"
     },
     "timezone": {
      "default": "UTC",
      "description": "IANA time zone, for example `Europe/Paris`. Default `UTC`.",
      "title": "Timezone",
      "type": "string"
     }
    },
    "required": [
     "agent_id",
     "cron"
    ],
    "title": "ScheduleIn",
    "type": "object"
   },
   "SchedulePatch": {
    "description": "Fields of a schedule to change.",
    "properties": {
     "cron": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New cron expression.",
      "title": "Cron"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Enable or pause the schedule.",
      "title": "Enabled"
     },
     "input": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "New run input.",
      "title": "Input"
     },
     "timezone": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New IANA time zone.",
      "title": "Timezone"
     }
    },
    "title": "SchedulePatch",
    "type": "object"
   },
   "Scope": {
    "description": "Scope of a memory item.",
    "properties": {
     "id": {
      "description": "Identifier of the session, agent, user, project or tenant (1 to 200 characters).",
      "maxLength": 200,
      "minLength": 1,
      "title": "Id",
      "type": "string"
     },
     "type": {
      "description": "`session`, `agent`, `user`, `project` or `tenant`.",
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "type",
     "id"
    ],
    "title": "Scope",
    "type": "object"
   },
   "SearchIn": {
    "description": "A memory search.",
    "properties": {
     "kind": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only the items of this kind.",
      "title": "Kind"
     },
     "mode": {
      "default": "hybrid",
      "description": "`hybrid` (default), `keyword` (no embedding call) or `vector`.",
      "title": "Mode",
      "type": "string"
     },
     "query": {
      "description": "Text of the query (at least 1 character).",
      "minLength": 1,
      "title": "Query",
      "type": "string"
     },
     "scope": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Scope"
       },
       {
        "type": "null"
       }
      ],
      "description": "Only the items of this scope."
     },
     "top_k": {
      "default": 10,
      "description": "Number of results (1 to 100, default 10).",
      "maximum": 100.0,
      "minimum": 1.0,
      "title": "Top K",
      "type": "integer"
     }
    },
    "required": [
     "query"
    ],
    "title": "SearchIn",
    "type": "object"
   },
   "SecretIn": {
    "description": "Secret to write.",
    "properties": {
     "path": {
      "description": "Path of the secret, 1 to 255 characters among letters, digits, `_`, `.`, `/` and `-`, not starting with `.`, `/` or `-`.",
      "pattern": "^[A-Za-z0-9_][A-Za-z0-9_./-]{0,254}$",
      "title": "Path",
      "type": "string"
     },
     "value": {
      "description": "Secret value, 1 to 65536 characters. Write only: encrypted at rest, never returned nor logged.",
      "maxLength": 65536,
      "minLength": 1,
      "title": "Value",
      "type": "string"
     }
    },
    "required": [
     "path",
     "value"
    ],
    "title": "SecretIn",
    "type": "object"
   },
   "ServerIn": {
    "description": "An MCP server to register.",
    "properties": {
     "allowed_resources": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Resource URIs that may be listed and read (patterns). Default `[\"*\"]`.",
      "title": "Allowed Resources"
     },
     "allowed_tools": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tools that may be listed and called (patterns). Default `[\"*\"]`.",
      "title": "Allowed Tools"
     },
     "auth": {
      "$ref": "#/components/schemas/McpAuth",
      "description": "Upstream authentication. Default `none`."
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits, `.`, `_`, `-`, 1 to 128 characters.",
      "pattern": "^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$",
      "title": "Name",
      "type": "string"
     },
     "owner": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owner of the server. Default: the caller.",
      "title": "Owner"
     },
     "project": {
      "anyOf": [
       {
        "maxLength": 64,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Project id or slug the server belongs to (default: the `X-Project` header; none: shared by the tenant).",
      "title": "Project"
     },
     "transport": {
      "default": "streamable_http",
      "description": "`streamable_http` (default) or `sse`.",
      "enum": [
       "streamable_http",
       "sse"
      ],
      "title": "Transport",
      "type": "string"
     },
     "url": {
      "description": "HTTP(S) endpoint of the server on an internal host (8 to 2000 characters).",
      "maxLength": 2000,
      "minLength": 8,
      "title": "Url",
      "type": "string"
     }
    },
    "required": [
     "name",
     "url"
    ],
    "title": "ServerIn",
    "type": "object"
   },
   "ServerStatusIn": {
    "description": "Status change of an MCP server.",
    "properties": {
     "reason": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Why the status changes (up to 2000 characters).",
      "title": "Reason"
     },
     "status": {
      "description": "`active` (through a promotion) or `disabled` (immediate).",
      "enum": [
       "active",
       "disabled"
      ],
      "title": "Status",
      "type": "string"
     }
    },
    "required": [
     "status"
    ],
    "title": "ServerStatusIn",
    "type": "object"
   },
   "ServiceIdentityIn": {
    "description": "New service identity (workload) of the tenant.",
    "properties": {
     "clearance": {
      "default": "internal",
      "description": "Highest data classification the credential may read: `public`, `internal` (default), `confidential`, `restricted` or `secret`.",
      "enum": [
       "public",
       "internal",
       "confidential",
       "restricted",
       "secret"
      ],
      "title": "Clearance",
      "type": "string"
     },
     "name": {
      "description": "Name of the identity, 1 to 200 characters; the subject becomes `service:<name>`.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "roles": {
      "description": "Roles of the identity. Only roles the caller holds, unless the caller is `tenant_admin`.",
      "items": {
       "enum": [
        "platform_admin",
        "tenant_admin",
        "security_officer",
        "finops",
        "developer",
        "auditor",
        "agent",
        "viewer",
        "soc_analyst",
        "ai_governance_officer",
        "data_steward",
        "application_owner",
        "ai_platform_engineer",
        "business_owner",
        "support_engineer"
       ],
       "type": "string"
      },
      "title": "Roles",
      "type": "array"
     },
     "scopes": {
      "description": "Scopes of the identity, glob patterns held by the caller. Empty by default.",
      "items": {
       "type": "string"
      },
      "title": "Scopes",
      "type": "array"
     },
     "spiffe_id": {
      "description": "SPIFFE ID of the workload, `spiffe://<trust domain>/<path>`, unique on the platform.",
      "pattern": "^spiffe://[A-Za-z0-9._-]+/.+$",
      "title": "Spiffe Id",
      "type": "string"
     }
    },
    "required": [
     "name",
     "spiffe_id"
    ],
    "title": "ServiceIdentityIn",
    "type": "object"
   },
   "SettingsIn": {
    "description": "FinOps settings of the tenant; every field is optional.",
    "properties": {
     "currency": {
      "anyOf": [
       {
        "pattern": "^[A-Z]{3}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "ISO 4217 currency in which the tenant costs are kept.",
      "title": "Currency"
     },
     "monthly_budget": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Monthly budget of the tenant, at least 0: the measured spend of the month is compared to it and budget alerts fire at the thresholds (50, 80 and 100 percent by default). It does not refuse calls by itself; use hard quotas for that.",
      "title": "Monthly Budget"
     },
     "reservation_ttl_seconds": {
      "anyOf": [
       {
        "exclusiveMinimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Default lifetime of a quota reservation in seconds, greater than 0 (default 900).",
      "title": "Reservation Ttl Seconds"
     },
     "variance_threshold_pct": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Variance between measured and billed cost, in percent, above which a variance alert is raised (default 10).",
      "title": "Variance Threshold Pct"
     }
    },
    "title": "SettingsIn",
    "type": "object"
   },
   "SignatureIn": {
    "description": "Signature of a pack archive.",
    "properties": {
     "signer": {
      "description": "Name of the publisher key that signed (1 to 200 characters).",
      "maxLength": 200,
      "minLength": 1,
      "title": "Signer",
      "type": "string"
     },
     "value": {
      "description": "Signature value or cosign bundle (1 to 4096 characters).",
      "maxLength": 4096,
      "minLength": 1,
      "title": "Value",
      "type": "string"
     }
    },
    "required": [
     "value",
     "signer"
    ],
    "title": "SignatureIn",
    "type": "object"
   },
   "SimulateIn": {
    "description": "Simulation of a candidate policy.",
    "properties": {
     "candidate": {
      "$ref": "#/components/schemas/eai__domains__policies__PolicyIn",
      "description": "Candidate policy, engine `builtin`."
     },
     "inputs": {
      "description": "Policy Contract requests `{subject, action, resource, context}` to decide, at most 200. Without `subject`, the caller is used.",
      "items": {
       "additionalProperties": true,
       "type": "object"
      },
      "maxItems": 200,
      "title": "Inputs",
      "type": "array"
     },
     "policy_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Policy the candidate replaces; null to add it to the active set.",
      "title": "Policy Id"
     },
     "recorded": {
      "default": 0,
      "description": "Also replay the last N recorded decisions, 0 to 500 (default 0).",
      "maximum": 500.0,
      "minimum": 0.0,
      "title": "Recorded",
      "type": "integer"
     }
    },
    "required": [
     "candidate"
    ],
    "title": "SimulateIn",
    "type": "object"
   },
   "SkillStatusIn": {
    "description": "Status change of a skill.",
    "properties": {
     "reason": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Why the status changes (up to 2000 characters).",
      "title": "Reason"
     },
     "status": {
      "description": "`draft`, `approved` (through an approval), `restricted`, `deprecated` or `blocked`.",
      "enum": [
       "draft",
       "approved",
       "restricted",
       "deprecated",
       "blocked"
      ],
      "title": "Status",
      "type": "string"
     }
    },
    "required": [
     "status"
    ],
    "title": "SkillStatusIn",
    "type": "object"
   },
   "SshBootstrapIn": {
    "description": "Machines to enroll over SSH.",
    "properties": {
     "host_key_fingerprints": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Expected SSH host key fingerprint (`SHA256:...`) of each host, host to fingerprint, up to 200. Every host needs one (the Manager answers 422 otherwise); the bootstrap task of the host is pinned to it.",
      "maxProperties": 200,
      "title": "Host Key Fingerprints",
      "type": "object"
     },
     "hosts": {
      "description": "Host names or addresses, 1 to 200, each 1 to 253 characters (letters, digits, dots, dashes).",
      "items": {
       "maxLength": 253,
       "minLength": 1,
       "pattern": "^[A-Za-z0-9]([A-Za-z0-9.-]{0,252})$",
       "type": "string"
      },
      "maxItems": 200,
      "minItems": 1,
      "title": "Hosts",
      "type": "array"
     },
     "private_key": {
      "description": "SSH private key, 20 to 20000 characters. Relayed to the Manager, kept in memory for the bootstrap only; never stored nor audited by the Control Plane.",
      "maxLength": 20000,
      "minLength": 20,
      "title": "Private Key",
      "type": "string"
     },
     "ssh_port": {
      "default": 22,
      "description": "SSH port, 1 to 65535, default 22.",
      "maximum": 65535.0,
      "minimum": 1.0,
      "title": "Ssh Port",
      "type": "integer"
     },
     "ssh_user": {
      "description": "SSH account, 1 to 64 characters, lowercase letter or underscore first.",
      "maxLength": 64,
      "minLength": 1,
      "pattern": "^[a-z_][a-z0-9_.-]*$",
      "title": "Ssh User",
      "type": "string"
     },
     "use_sudo": {
      "default": true,
      "description": "Run the installation with sudo (default true).",
      "title": "Use Sudo",
      "type": "boolean"
     }
    },
    "required": [
     "hosts",
     "ssh_user",
     "private_key",
     "host_key_fingerprints"
    ],
    "title": "SshBootstrapIn",
    "type": "object"
   },
   "StepIn": {
    "description": "A step reported by the runtime of a run.",
    "properties": {
     "approval_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Approved request that authorizes a step needing human approval; it must be approved for this run.",
      "title": "Approval Id"
     },
     "attempt": {
      "default": 1,
      "description": "Attempt number, from 1 (default 1). Compared with `retry_policy.max_attempts`.",
      "minimum": 1.0,
      "title": "Attempt",
      "type": "integer"
     },
     "cost": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Cost of the step: an amount, or `{amount, currency}` in the currency of the run budget.",
      "title": "Cost"
     },
     "error": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Error of a failed step (`code`, `message`, `retryable`); the code decides whether a retry is allowed.",
      "title": "Error"
     },
     "final": {
      "default": false,
      "description": "True when this is the last step of the run. Default false.",
      "title": "Final",
      "type": "boolean"
     },
     "input_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the step input (stored elsewhere, not the content).",
      "title": "Input Ref"
     },
     "kind": {
      "description": "Kind of step: `plan`, `act`, `verify`, `recover`, `model_call`, `tool_call`, `subagent`, `approval` or `checkpoint`.",
      "enum": [
       "plan",
       "act",
       "verify",
       "recover",
       "model_call",
       "tool_call",
       "subagent",
       "approval",
       "checkpoint"
      ],
      "title": "Kind",
      "type": "string"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the target (tool, model, agent), matched against `autonomy.human_approval_for` (up to 500 characters).",
      "title": "Name"
     },
     "output_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the step output.",
      "title": "Output Ref"
     },
     "quorum": {
      "anyOf": [
       {
        "maximum": 10.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Number of approvers needed by a step of kind `approval` (1 to 10, default 1).",
      "title": "Quorum"
     },
     "run_state": {
      "anyOf": [
       {
        "enum": [
         "running",
         "waiting_input",
         "succeeded",
         "failed"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "State the runtime asks for when the controller keeps the run running: `running`, `waiting_input`, `succeeded` or `failed`.",
      "title": "Run State"
     },
     "state": {
      "default": "succeeded",
      "description": "State of the step: `pending`, `running`, `succeeded` (default), `failed`, `skipped` or `cancelled`.",
      "enum": [
       "pending",
       "running",
       "succeeded",
       "failed",
       "skipped",
       "cancelled"
      ],
      "title": "State",
      "type": "string"
     },
     "tokens": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tokens used (0 or more). Default: the sum of the input, output and reasoning tokens of `usage`.",
      "title": "Tokens"
     },
     "usage": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Usage counters added to the budget consumption, for example `input_tokens`, `output_tokens`.",
      "title": "Usage"
     }
    },
    "required": [
     "kind"
    ],
    "title": "StepIn",
    "type": "object"
   },
   "SttIn": {
    "description": "A speech to text or diarization request. Give `media_id` or `content_base64`.",
    "properties": {
     "content_base64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Inline audio, base64 encoded (scanned before use).",
      "title": "Content Base64"
     },
     "dlp_mode": {
      "default": "detect",
      "description": "DLP applied to the transcript: `detect` (default), `mask`, `tokenize` or `block`.",
      "title": "Dlp Mode",
      "type": "string"
     },
     "duration_seconds": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "description": "Duration of the audio in seconds, used for metering. Default: read from a WAV header, else 0.",
      "title": "Duration Seconds"
     },
     "language": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Spoken language, for example `fr`. Default: detected by the adapter.",
      "title": "Language"
     },
     "max_speakers": {
      "anyOf": [
       {
        "maximum": 32.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum number of speakers (1 to 32, diarization only).",
      "title": "Max Speakers"
     },
     "media_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Stored audio media.",
      "title": "Media Id"
     },
     "mime_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Media type of the inline audio, for example `audio/wav`.",
      "title": "Mime Type"
     },
     "min_speakers": {
      "anyOf": [
       {
        "maximum": 32.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Minimum number of speakers (1 to 32, diarization only).",
      "title": "Min Speakers"
     },
     "model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model to use. Default: the configured adapter.",
      "title": "Model"
     },
     "word_timestamps": {
      "default": false,
      "description": "Return a timestamp per word (`stt` only). Default false.",
      "title": "Word Timestamps",
      "type": "boolean"
     }
    },
    "title": "SttIn",
    "type": "object"
   },
   "SubagentIn": {
    "description": "A sub-agent run to start.",
    "properties": {
     "agent": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Child agent, name or `agent:<name>`. Default: the agent of the parent run.",
      "title": "Agent"
     },
     "budgets": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Budget limits of the child, capped by what the parent has left.",
      "title": "Budgets"
     },
     "start": {
      "default": false,
      "description": "When true, the child run starts in `running`. Default false (`pending`).",
      "title": "Start",
      "type": "boolean"
     },
     "task": {
      "additionalProperties": true,
      "description": "Task of the child run (`task_id`, `objective`, `input`).",
      "title": "Task",
      "type": "object"
     }
    },
    "title": "SubagentIn",
    "type": "object"
   },
   "SuiteIn": {
    "description": "New evaluation suite.",
    "properties": {
     "blocking": {
      "default": true,
      "description": "When true (default), the suite takes part in the quality gate of its target.",
      "title": "Blocking",
      "type": "boolean"
     },
     "cases": {
      "description": "Cases of the suite: objects with `input`, optional `system`, expected values for the metrics and optionally a ready `output`.",
      "items": {
       "additionalProperties": true,
       "type": "object"
      },
      "title": "Cases",
      "type": "array"
     },
     "dataset": {
      "$ref": "#/components/schemas/Dataset",
      "description": "Dataset reference of the cases."
     },
     "engine": {
      "default": "custom",
      "description": "`ragas`, `promptfoo`, `garak` or `custom` (default).",
      "title": "Engine",
      "type": "string"
     },
     "kind": {
      "default": "quality",
      "description": "`quality` (default), `regression`, `red_team`, `safety`, `cost` or `latency`.",
      "title": "Kind",
      "type": "string"
     },
     "metrics": {
      "description": "Metrics and thresholds, at least one.",
      "items": {
       "$ref": "#/components/schemas/Metric"
      },
      "minItems": 1,
      "title": "Metrics",
      "type": "array"
     },
     "name": {
      "description": "Unique name of the suite in the tenant, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "run_on_promotion": {
      "default": true,
      "description": "When true (default), the suite runs when its target is promoted.",
      "title": "Run On Promotion",
      "type": "boolean"
     },
     "target": {
      "$ref": "#/components/schemas/eai__domains__evaluation__Target",
      "description": "Target evaluated: `model`, `agent`, `prompt`, `rag_pipeline`, `skill` or `tool`."
     }
    },
    "required": [
     "name",
     "target",
     "dataset",
     "metrics"
    ],
    "title": "SuiteIn",
    "type": "object"
   },
   "SyncIn": {
    "description": "Options of a synchronisation run.",
    "properties": {
     "full": {
      "default": false,
      "description": "When true, ignore the cursor of the last run and synchronise everything. Default false.",
      "title": "Full",
      "type": "boolean"
     },
     "resources": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Resources to synchronise, among the readable ones. Default: every readable resource.",
      "title": "Resources"
     }
    },
    "title": "SyncIn",
    "type": "object"
   },
   "TelephonyAgentIn": {
    "description": "A human agent of the tenant.",
    "properties": {
     "display_name": {
      "description": "Name of the agent.",
      "maxLength": 80,
      "minLength": 1,
      "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
      "title": "Display Name",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "extension_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Extension of the tenant the agent answers on.",
      "title": "Extension Id"
     },
     "skills": {
      "description": "Skills of the agent (up to 50).",
      "items": {
       "type": "string"
      },
      "maxItems": 50,
      "title": "Skills",
      "type": "array"
     },
     "user_id": {
      "description": "Identifier of the user in the platform, unique in the tenant.",
      "maxLength": 200,
      "minLength": 1,
      "title": "User Id",
      "type": "string"
     }
    },
    "required": [
     "user_id",
     "display_name"
    ],
    "title": "TelephonyAgentIn",
    "type": "object"
   },
   "TelephonyAgentPatch": {
    "description": "Fields to change: a human agent of the tenant. Omitted fields keep their value.",
    "properties": {
     "display_name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the agent.",
      "title": "Display Name"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled"
     },
     "extension_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Extension of the tenant the agent answers on.",
      "title": "Extension Id"
     },
     "skills": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Skills of the agent (up to 50).",
      "title": "Skills"
     },
     "user_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the user in the platform, unique in the tenant.",
      "title": "User Id"
     }
    },
    "title": "TelephonyAgentPatch",
    "type": "object"
   },
   "TelephonyBlockIn": {
    "description": "A manual block of the tenant or of one extension.",
    "properties": {
     "extension": {
      "anyOf": [
       {
        "pattern": "^[0-9]{2,8}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Extension number, required for the scope `extension` only.",
      "title": "Extension"
     },
     "reason": {
      "description": "Reason kept with the block and in the audit trail.",
      "maxLength": 300,
      "minLength": 1,
      "title": "Reason",
      "type": "string"
     },
     "scope": {
      "description": "`tenant` (every call of the tenant) or `extension`.",
      "enum": [
       "tenant",
       "extension"
      ],
      "title": "Scope",
      "type": "string"
     }
    },
    "required": [
     "scope",
     "reason"
    ],
    "title": "TelephonyBlockIn",
    "type": "object"
   },
   "TelephonyConferenceIn": {
    "description": "A conference room of the tenant.",
    "properties": {
     "max_members": {
      "default": 10,
      "description": "Maximum participants, 2 to 500 (default 10).",
      "maximum": 500.0,
      "minimum": 2.0,
      "title": "Max Members",
      "type": "integer"
     },
     "name": {
      "description": "Name of the room.",
      "maxLength": 80,
      "minLength": 1,
      "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
      "title": "Name",
      "type": "string"
     },
     "number": {
      "description": "Number of the room, 2 to 8 digits, unique in the tenant.",
      "pattern": "^[0-9]{2,8}$",
      "title": "Number",
      "type": "string"
     },
     "pin": {
      "anyOf": [
       {
        "pattern": "^[0-9]{4,8}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "PIN, 4 to 8 digits. Write only (`has_pin`).",
      "title": "Pin"
     },
     "recording": {
      "default": false,
      "description": "Whether the conference is recorded.",
      "title": "Recording",
      "type": "boolean"
     }
    },
    "required": [
     "number",
     "name"
    ],
    "title": "TelephonyConferenceIn",
    "type": "object"
   },
   "TelephonyConferencePatch": {
    "description": "Fields to change: a conference room of the tenant. Omitted fields keep their value.",
    "properties": {
     "max_members": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum participants, 2 to 500 (default 10).",
      "title": "Max Members"
     },
     "name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the room.",
      "title": "Name"
     },
     "number": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Number of the room, 2 to 8 digits, unique in the tenant.",
      "title": "Number"
     },
     "pin": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "PIN, 4 to 8 digits. Write only (`has_pin`).",
      "title": "Pin"
     },
     "recording": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the conference is recorded.",
      "title": "Recording"
     }
    },
    "title": "TelephonyConferencePatch",
    "type": "object"
   },
   "TelephonyDeleteIn": {
    "description": "Reason of a deletion, kept in the audit trail.",
    "properties": {
     "reason": {
      "default": "user request",
      "description": "Reason (default `user request`).",
      "maxLength": 300,
      "minLength": 1,
      "title": "Reason",
      "type": "string"
     }
    },
    "title": "TelephonyDeleteIn",
    "type": "object"
   },
   "TelephonyDrainIn": {
    "description": "A dispatcher destination and its state.",
    "properties": {
     "address": {
      "description": "SIP URI of the destination, for example `sip:10.0.0.20:5070`.",
      "pattern": "^sip:[A-Za-z0-9.:;=-]{1,200}$",
      "title": "Address",
      "type": "string"
     },
     "group": {
      "anyOf": [
       {
        "maximum": 65535.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Dispatcher set (default: the set of the pool).",
      "title": "Group"
     },
     "state": {
      "description": "`drain` (no new call) or `active`.",
      "enum": [
       "drain",
       "active"
      ],
      "title": "State",
      "type": "string"
     }
    },
    "required": [
     "address",
     "state"
    ],
    "title": "TelephonyDrainIn",
    "type": "object"
   },
   "TelephonyExtensionIn": {
    "description": "An extension of the tenant.",
    "properties": {
     "display_name": {
      "description": "Name shown as caller id.",
      "maxLength": 80,
      "minLength": 1,
      "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
      "title": "Display Name",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "forwarding": {
      "$ref": "#/components/schemas/TelephonyForwarding",
      "description": "Call forwarding rules."
     },
     "kind": {
      "default": "sip",
      "description": "`sip` (phone with a password) or `webrtc` (softphone of the portal, ephemeral credentials).",
      "enum": [
       "sip",
       "webrtc"
      ],
      "title": "Kind",
      "type": "string"
     },
     "max_concurrent_calls": {
      "default": 2,
      "description": "Simultaneous calls of the extension, 1 to 100 (default 2), enforced by the dialplan.",
      "maximum": 100.0,
      "minimum": 1.0,
      "title": "Max Concurrent Calls",
      "type": "integer"
     },
     "number": {
      "description": "Extension number, 2 to 8 digits, unique in the tenant.",
      "pattern": "^[0-9]{2,8}$",
      "title": "Number",
      "type": "string"
     },
     "password": {
      "anyOf": [
       {
        "maxLength": 128,
        "minLength": 12,
        "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "SIP password, 12 to 128 characters, required for `sip`. Write only: kept in the vault, never returned (`has_password`).",
      "title": "Password"
     },
     "permissions": {
      "$ref": "#/components/schemas/TelephonyPermissions",
      "description": "Destinations the extension may call."
     },
     "recording_policy": {
      "default": "off",
      "description": "Recording: `off` (default), `always`, `inbound` or `outbound` (MixMonitor into the folder of the tenant).",
      "enum": [
       "off",
       "always",
       "inbound",
       "outbound"
      ],
      "title": "Recording Policy",
      "type": "string"
     },
     "voicemail_email": {
      "anyOf": [
       {
        "maxLength": 200,
        "pattern": "^[^@\\s,;]+@[^@\\s,;]+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Address told of new messages.",
      "title": "Voicemail Email"
     },
     "voicemail_enabled": {
      "default": false,
      "description": "Whether the extension has a voicemail box (needs a PIN).",
      "title": "Voicemail Enabled",
      "type": "boolean"
     },
     "voicemail_pin": {
      "anyOf": [
       {
        "pattern": "^[0-9]{4,8}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Voicemail PIN, 4 to 8 digits. Write only (`has_voicemail_pin`).",
      "title": "Voicemail Pin"
     }
    },
    "required": [
     "number",
     "display_name"
    ],
    "title": "TelephonyExtensionIn",
    "type": "object"
   },
   "TelephonyExtensionPatch": {
    "description": "Fields to change: an extension of the tenant. Omitted fields keep their value.",
    "properties": {
     "display_name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name shown as caller id.",
      "title": "Display Name"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled"
     },
     "forwarding": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/TelephonyForwarding"
       },
       {
        "type": "null"
       }
      ],
      "description": "Call forwarding rules."
     },
     "kind": {
      "anyOf": [
       {
        "enum": [
         "sip",
         "webrtc"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`sip` (phone with a password) or `webrtc` (softphone of the portal, ephemeral credentials).",
      "title": "Kind"
     },
     "max_concurrent_calls": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Simultaneous calls of the extension, 1 to 100 (default 2), enforced by the dialplan.",
      "title": "Max Concurrent Calls"
     },
     "number": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Extension number, 2 to 8 digits, unique in the tenant.",
      "title": "Number"
     },
     "password": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "SIP password, 12 to 128 characters, required for `sip`. Write only: kept in the vault, never returned (`has_password`).",
      "title": "Password"
     },
     "permissions": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/TelephonyPermissions"
       },
       {
        "type": "null"
       }
      ],
      "description": "Destinations the extension may call."
     },
     "recording_policy": {
      "anyOf": [
       {
        "enum": [
         "off",
         "always",
         "inbound",
         "outbound"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Recording: `off` (default), `always`, `inbound` or `outbound` (MixMonitor into the folder of the tenant).",
      "title": "Recording Policy"
     },
     "voicemail_email": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Address told of new messages.",
      "title": "Voicemail Email"
     },
     "voicemail_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the extension has a voicemail box (needs a PIN).",
      "title": "Voicemail Enabled"
     },
     "voicemail_pin": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Voicemail PIN, 4 to 8 digits. Write only (`has_voicemail_pin`).",
      "title": "Voicemail Pin"
     }
    },
    "title": "TelephonyExtensionPatch",
    "type": "object"
   },
   "TelephonyForwarding": {
    "description": "Call forwarding of an extension.",
    "properties": {
     "always": {
      "anyOf": [
       {
        "pattern": "^([0-9]{2,8}|\\+[1-9][0-9]{6,14})$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Unconditional forwarding target: an extension number or an E.164 number.",
      "title": "Always"
     },
     "busy": {
      "anyOf": [
       {
        "pattern": "^([0-9]{2,8}|\\+[1-9][0-9]{6,14})$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Target when the extension is busy.",
      "title": "Busy"
     },
     "no_answer": {
      "anyOf": [
       {
        "pattern": "^([0-9]{2,8}|\\+[1-9][0-9]{6,14})$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Target when the extension does not answer.",
      "title": "No Answer"
     },
     "no_answer_seconds": {
      "default": 25,
      "description": "Ring time before the no answer case, 5 to 120 seconds (default 25).",
      "maximum": 120.0,
      "minimum": 5.0,
      "title": "No Answer Seconds",
      "type": "integer"
     }
    },
    "title": "TelephonyForwarding",
    "type": "object"
   },
   "TelephonyInventorySyncIn": {
    "description": "The Asterisk instance of the Navin Manager whose PBX pool is created or refreshed.",
    "properties": {
     "cluster_id": {
      "description": "Identifier of the Manager cluster.",
      "maxLength": 64,
      "minLength": 1,
      "pattern": "^[A-Za-z0-9_-]{1,64}$",
      "title": "Cluster Id",
      "type": "string"
     },
     "kamailio_service": {
      "anyOf": [
       {
        "pattern": "^[a-z][a-z0-9_-]{0,62}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Kamailio instance to use (default: those bound to this Asterisk).",
      "title": "Kamailio Service"
     },
     "livekit_service": {
      "anyOf": [
       {
        "pattern": "^[a-z][a-z0-9_-]{0,62}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "LiveKit instance to use (default: the one LiveKit SIP is bound to, else the only one).",
      "title": "Livekit Service"
     },
     "livekit_sip_service": {
      "anyOf": [
       {
        "pattern": "^[a-z][a-z0-9_-]{0,62}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "LiveKit SIP instance to use (default: the one Kamailio is bound to, else the only one).",
      "title": "Livekit Sip Service"
     },
     "mode": {
      "default": "shared",
      "description": "`shared` (default) or `dedicated` for a new pool.",
      "enum": [
       "shared",
       "dedicated"
      ],
      "title": "Mode",
      "type": "string"
     },
     "name": {
      "anyOf": [
       {
        "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of a new pool (default: the name of the instance); ignored on a refresh.",
      "title": "Name"
     },
     "service": {
      "description": "Name of the Asterisk instance in the Manager (for example `asterisk`).",
      "pattern": "^[a-z][a-z0-9_-]{0,62}$",
      "title": "Service",
      "type": "string"
     },
     "tenant_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tenant of a new dedicated pool.",
      "title": "Tenant Id"
     }
    },
    "required": [
     "cluster_id",
     "service"
    ],
    "title": "TelephonyInventorySyncIn",
    "type": "object"
   },
   "TelephonyIvrFlowIn": {
    "description": "An IVR flow of the tenant.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Description of the flow.",
      "title": "Description"
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
      "title": "Name",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "TelephonyIvrFlowIn",
    "type": "object"
   },
   "TelephonyIvrFlowPatch": {
    "description": "Fields to change: an IVR flow of the tenant. Omitted fields keep their value.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Description of the flow.",
      "title": "Description"
     },
     "name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "title": "Name"
     }
    },
    "title": "TelephonyIvrFlowPatch",
    "type": "object"
   },
   "TelephonyIvrVersionIn": {
    "description": "A draft version of an IVR flow.",
    "properties": {
     "graph": {
      "additionalProperties": true,
      "description": "Graph of the flow: `start` and `nodes`; menu nodes carry `prompt`, `options` (`digit`, `next`), `timeout`, `invalid`, `timeout_seconds` and `max_retries`.",
      "title": "Graph",
      "type": "object"
     }
    },
    "required": [
     "graph"
    ],
    "title": "TelephonyIvrVersionIn",
    "type": "object"
   },
   "TelephonyKamailioEndpoint": {
    "description": "A Kamailio JSONRPC endpoint.",
    "properties": {
     "name": {
      "description": "Name of the Kamailio instance.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
      "title": "Name",
      "type": "string"
     },
     "url": {
      "description": "JSONRPC address, for example `http://10.0.0.10:5071/jsonrpc`.",
      "pattern": "^https?://[^\\s]+$",
      "title": "Url",
      "type": "string"
     }
    },
    "required": [
     "name",
     "url"
    ],
    "title": "TelephonyKamailioEndpoint",
    "type": "object"
   },
   "TelephonyLegalHoldIn": {
    "description": "Legal hold of a recording.",
    "properties": {
     "legal_hold": {
      "description": "true: hold the recording; false: release it.",
      "title": "Legal Hold",
      "type": "boolean"
     },
     "reason": {
      "description": "Reason kept in the audit trail (300 characters at most).",
      "maxLength": 300,
      "minLength": 1,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "legal_hold",
     "reason"
    ],
    "title": "TelephonyLegalHoldIn",
    "type": "object"
   },
   "TelephonyLiftIn": {
    "description": "Why a block is lifted.",
    "properties": {
     "reason": {
      "description": "Reason kept with the block and in the audit trail.",
      "maxLength": 300,
      "minLength": 1,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "reason"
    ],
    "title": "TelephonyLiftIn",
    "type": "object"
   },
   "TelephonyLiveKitBinding": {
    "description": "LiveKit binding of a pool.",
    "properties": {
     "sip_host": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9.:-]{1,253}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "SIP address of LiveKit SIP that Asterisk dials, for example `10.0.0.30:5090`.",
      "title": "Sip Host"
     },
     "url": {
      "anyOf": [
       {
        "pattern": "^https?://[^\\s]+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "HTTP address of LiveKit for the Twirp SIP API (none: the LiveKit objects are not reconciled).",
      "title": "Url"
     }
    },
    "title": "TelephonyLiveKitBinding",
    "type": "object"
   },
   "TelephonyMemberIn": {
    "description": "A member of a queue.",
    "properties": {
     "agent_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Human agent of the tenant, reached on its extension.",
      "title": "Agent Id"
     },
     "extension_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Extension of the tenant (or `agent_id`, not both).",
      "title": "Extension Id"
     },
     "penalty": {
      "default": 0,
      "description": "Penalty 0 to 100, lower rings first.",
      "maximum": 100.0,
      "minimum": 0.0,
      "title": "Penalty",
      "type": "integer"
     }
    },
    "title": "TelephonyMemberIn",
    "type": "object"
   },
   "TelephonyMemberPatch": {
    "description": "New penalty of a queue member.",
    "properties": {
     "penalty": {
      "description": "New penalty, 0 to 100.",
      "maximum": 100.0,
      "minimum": 0.0,
      "title": "Penalty",
      "type": "integer"
     }
    },
    "required": [
     "penalty"
    ],
    "title": "TelephonyMemberPatch",
    "type": "object"
   },
   "TelephonyNumberIn": {
    "description": "A public number of the tenant and its destination.",
    "properties": {
     "branch": {
      "default": "pbx",
      "description": "`pbx` (Kamailio to Asterisk, default) or `ai` (Kamailio to LiveKit SIP directly, voice agent only).",
      "enum": [
       "pbx",
       "ai"
      ],
      "title": "Branch",
      "type": "string"
     },
     "destination_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier (UUID) of the destination object in the tenant (every kind except `external`).",
      "title": "Destination Id"
     },
     "destination_kind": {
      "description": "Kind of destination: `extension`, `ivr`, `queue`, `voice_agent`, `conference` or `external`.",
      "enum": [
       "extension",
       "ivr",
       "queue",
       "voice_agent",
       "external",
       "conference"
      ],
      "title": "Destination Kind",
      "type": "string"
     },
     "destination_value": {
      "anyOf": [
       {
        "pattern": "^\\+[1-9][0-9]{6,14}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "E.164 number of an `external` destination.",
      "title": "Destination Value"
     },
     "e164": {
      "description": "Public number in E.164 format, unique on the platform.",
      "pattern": "^\\+[1-9][0-9]{6,14}$",
      "title": "E164",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "label": {
      "anyOf": [
       {
        "maxLength": 80,
        "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Label for display.",
      "title": "Label"
     },
     "trunk_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Trunk of the tenant the number comes from.",
      "title": "Trunk Id"
     }
    },
    "required": [
     "e164",
     "destination_kind"
    ],
    "title": "TelephonyNumberIn",
    "type": "object"
   },
   "TelephonyNumberPatch": {
    "description": "Fields to change: a public number of the tenant and its destination. Omitted fields keep their value.",
    "properties": {
     "branch": {
      "anyOf": [
       {
        "enum": [
         "pbx",
         "ai"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`pbx` (Kamailio to Asterisk, default) or `ai` (Kamailio to LiveKit SIP directly, voice agent only).",
      "title": "Branch"
     },
     "destination_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier (UUID) of the destination object in the tenant (every kind except `external`).",
      "title": "Destination Id"
     },
     "destination_kind": {
      "anyOf": [
       {
        "enum": [
         "extension",
         "ivr",
         "queue",
         "voice_agent",
         "external",
         "conference"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Kind of destination: `extension`, `ivr`, `queue`, `voice_agent`, `conference` or `external`.",
      "title": "Destination Kind"
     },
     "destination_value": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "E.164 number of an `external` destination.",
      "title": "Destination Value"
     },
     "e164": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Public number in E.164 format, unique on the platform.",
      "title": "E164"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled"
     },
     "label": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Label for display.",
      "title": "Label"
     },
     "trunk_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Trunk of the tenant the number comes from.",
      "title": "Trunk Id"
     }
    },
    "title": "TelephonyNumberPatch",
    "type": "object"
   },
   "TelephonyNumberingSettings": {
    "description": "Numbering plan and options of the tenant.",
    "properties": {
     "country_code": {
      "default": "33",
      "description": "Country code of the tenant, for example `33` (default).",
      "pattern": "^[1-9][0-9]{0,3}$",
      "title": "Country Code",
      "type": "string"
     },
     "emergency_numbers": {
      "description": "Emergency numbers, always allowed, routed on every trunk (default `112`).",
      "items": {
       "type": "string"
      },
      "maxItems": 10,
      "title": "Emergency Numbers",
      "type": "array"
     },
     "international_prefix": {
      "default": "00",
      "description": "International prefix (default `00`).",
      "pattern": "^[0-9]{1,4}$",
      "title": "International Prefix",
      "type": "string"
     },
     "national_prefix": {
      "default": "0",
      "description": "National prefix dialled before national numbers (default `0`).",
      "pattern": "^[0-9]{0,2}$",
      "title": "National Prefix",
      "type": "string"
     },
     "timezone": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z_]+(/[A-Za-z_+-]+){0,2}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Time zone of the time conditions, for example `Europe/Paris`.",
      "title": "Timezone"
     },
     "wss_url": {
      "anyOf": [
       {
        "pattern": "^wss://[^\\s]+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "WSS address of Kamailio for the softphone (default `wss://<sip domain>:7443`).",
      "title": "Wss Url"
     }
    },
    "title": "TelephonyNumberingSettings",
    "type": "object"
   },
   "TelephonyPermissions": {
    "description": "Destinations an extension may call.",
    "properties": {
     "internal": {
      "default": true,
      "description": "Calls to the other extensions of the tenant (default true).",
      "title": "Internal",
      "type": "boolean"
     },
     "international": {
      "default": false,
      "description": "Calls to other countries, limited to the allowed country prefixes of the quotas (default false).",
      "title": "International",
      "type": "boolean"
     },
     "national": {
      "default": true,
      "description": "Calls to national numbers (default true).",
      "title": "National",
      "type": "boolean"
     },
     "premium": {
      "default": false,
      "description": "Calls to the premium prefixes of the quotas (default false).",
      "title": "Premium",
      "type": "boolean"
     }
    },
    "title": "TelephonyPermissions",
    "type": "object"
   },
   "TelephonyPoolIn": {
    "description": "A PBX pool installed by the Navin Manager.",
    "properties": {
     "ami_events_secret_ref": {
      "anyOf": [
       {
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the secret of the read only AMI events user: `openbao://<path>` or `env://EAI_CRED_<NAME>`.",
      "title": "Ami Events Secret Ref"
     },
     "ami_events_username": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9_.-]{1,64}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Read only AMI user of the event connection (classes call, cdr, cel, agent, reporting, user); none: the configuration user.",
      "title": "Ami Events Username"
     },
     "ami_secret_ref": {
      "anyOf": [
       {
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the AMI secret: `openbao://<path>` or `env://EAI_CRED_<NAME>`.",
      "title": "Ami Secret Ref"
     },
     "ami_tls": {
      "default": false,
      "description": "Whether AMI is reached over TLS.",
      "title": "Ami Tls",
      "type": "boolean"
     },
     "ami_username": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9_.-]{1,64}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "AMI user of the pool.",
      "title": "Ami Username"
     },
     "ari_secret_ref": {
      "anyOf": [
       {
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the ARI secret.",
      "title": "Ari Secret Ref"
     },
     "ari_username": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9_.-]{1,64}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "ARI user of the pool.",
      "title": "Ari Username"
     },
     "dispatcher_set": {
      "default": 1,
      "description": "Dispatcher set of the pool (1 for the shared pool, 100 and up for dedicated pools).",
      "maximum": 65535.0,
      "minimum": 1.0,
      "title": "Dispatcher Set",
      "type": "integer"
     },
     "enabled": {
      "default": true,
      "description": "Whether the pool is reconciled (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "ephemeral_secret_ref": {
      "anyOf": [
       {
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the secret shared with Kamailio `auth_ephemeral`.",
      "title": "Ephemeral Secret Ref"
     },
     "kamailio_addresses": {
      "description": "Addresses of the Kamailio instances: the only sources the extensions accept.",
      "items": {
       "type": "string"
      },
      "maxItems": 16,
      "title": "Kamailio Addresses",
      "type": "array"
     },
     "kamailio_endpoints": {
      "description": "Kamailio JSONRPC endpoints of the pool (up to 8).",
      "items": {
       "$ref": "#/components/schemas/TelephonyKamailioEndpoint"
      },
      "maxItems": 8,
      "title": "Kamailio Endpoints",
      "type": "array"
     },
     "kamailio_secret_ref": {
      "anyOf": [
       {
        "pattern": "^(openbao|env)://.+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the JSONRPC credential `user:password` (none: no authentication).",
      "title": "Kamailio Secret Ref"
     },
     "livekit_binding": {
      "$ref": "#/components/schemas/TelephonyLiveKitBinding",
      "description": "LiveKit binding of the pool."
     },
     "livekit_sip_set": {
      "default": 2,
      "description": "Dispatcher set of LiveKit SIP (default 2).",
      "maximum": 65535.0,
      "minimum": 1.0,
      "title": "Livekit Sip Set",
      "type": "integer"
     },
     "manager_cluster": {
      "anyOf": [
       {
        "maxLength": 120,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Cluster of the pool in the Navin Manager.",
      "title": "Manager Cluster"
     },
     "manager_service": {
      "default": "asterisk",
      "description": "Service of the Navin Manager catalogue (default `asterisk`).",
      "maxLength": 120,
      "title": "Manager Service",
      "type": "string"
     },
     "mode": {
      "description": "`shared` (several tenants) or `dedicated` (one tenant).",
      "enum": [
       "shared",
       "dedicated"
      ],
      "title": "Mode",
      "type": "string"
     },
     "name": {
      "description": "Name of the pool, unique on the platform.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
      "title": "Name",
      "type": "string"
     },
     "nodes": {
      "description": "Asterisk nodes of the pool (up to 32): each one gets every publication.",
      "items": {
       "$ref": "#/components/schemas/TelephonyPoolNode"
      },
      "maxItems": 32,
      "title": "Nodes",
      "type": "array"
     },
     "tenant_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tenant of a dedicated pool (none for a shared pool).",
      "title": "Tenant Id"
     },
     "tls_verify": {
      "default": true,
      "description": "Whether the TLS certificates of the engines are checked (default true).",
      "title": "Tls Verify",
      "type": "boolean"
     }
    },
    "required": [
     "name",
     "mode"
    ],
    "title": "TelephonyPoolIn",
    "type": "object"
   },
   "TelephonyPoolNode": {
    "description": "An Asterisk node of a pool.",
    "properties": {
     "ami_port": {
      "default": 5038,
      "description": "AMI port (default 5038, 5039 with TLS).",
      "maximum": 65535.0,
      "minimum": 1.0,
      "title": "Ami Port",
      "type": "integer"
     },
     "ari_url": {
      "anyOf": [
       {
        "pattern": "^https?://[^\\s]+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Base URL of ARI on the node, for example `https://10.0.0.20:8089` (default `http://<host>:8088`); the path `/ari` is added.",
      "title": "Ari Url"
     },
     "host": {
      "description": "Administration address of the node (AMI).",
      "pattern": "^[A-Za-z0-9.:-]{1,253}$",
      "title": "Host",
      "type": "string"
     },
     "manager_instance": {
      "anyOf": [
       {
        "maxLength": 120,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the service instance in the Navin Manager.",
      "title": "Manager Instance"
     },
     "name": {
      "description": "Name of the node.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
      "title": "Name",
      "type": "string"
     },
     "sip_address": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9.:-]{1,253}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "SIP address of the node, allowed by the LiveKit SIP trunks.",
      "title": "Sip Address"
     }
    },
    "required": [
     "name",
     "host"
    ],
    "title": "TelephonyPoolNode",
    "type": "object"
   },
   "TelephonyPoolPatch": {
    "description": "Fields to change: a PBX pool installed by the Navin Manager. Omitted fields keep their value.",
    "properties": {
     "ami_events_secret_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the secret of the read only AMI events user: `openbao://<path>` or `env://EAI_CRED_<NAME>`.",
      "title": "Ami Events Secret Ref"
     },
     "ami_events_username": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Read only AMI user of the event connection (classes call, cdr, cel, agent, reporting, user); none: the configuration user.",
      "title": "Ami Events Username"
     },
     "ami_secret_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the AMI secret: `openbao://<path>` or `env://EAI_CRED_<NAME>`.",
      "title": "Ami Secret Ref"
     },
     "ami_tls": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether AMI is reached over TLS.",
      "title": "Ami Tls"
     },
     "ami_username": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "AMI user of the pool.",
      "title": "Ami Username"
     },
     "ari_secret_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the ARI secret.",
      "title": "Ari Secret Ref"
     },
     "ari_username": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "ARI user of the pool.",
      "title": "Ari Username"
     },
     "dispatcher_set": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Dispatcher set of the pool (1 for the shared pool, 100 and up for dedicated pools).",
      "title": "Dispatcher Set"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the pool is reconciled (default true).",
      "title": "Enabled"
     },
     "ephemeral_secret_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the secret shared with Kamailio `auth_ephemeral`.",
      "title": "Ephemeral Secret Ref"
     },
     "kamailio_addresses": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Addresses of the Kamailio instances: the only sources the extensions accept.",
      "title": "Kamailio Addresses"
     },
     "kamailio_endpoints": {
      "anyOf": [
       {
        "items": {
         "$ref": "#/components/schemas/TelephonyKamailioEndpoint"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Kamailio JSONRPC endpoints of the pool (up to 8).",
      "title": "Kamailio Endpoints"
     },
     "kamailio_secret_ref": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reference of the JSONRPC credential `user:password` (none: no authentication).",
      "title": "Kamailio Secret Ref"
     },
     "livekit_binding": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/TelephonyLiveKitBinding"
       },
       {
        "type": "null"
       }
      ],
      "description": "LiveKit binding of the pool."
     },
     "livekit_sip_set": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Dispatcher set of LiveKit SIP (default 2).",
      "title": "Livekit Sip Set"
     },
     "manager_cluster": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Cluster of the pool in the Navin Manager.",
      "title": "Manager Cluster"
     },
     "manager_service": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Service of the Navin Manager catalogue (default `asterisk`).",
      "title": "Manager Service"
     },
     "mode": {
      "anyOf": [
       {
        "enum": [
         "shared",
         "dedicated"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`shared` (several tenants) or `dedicated` (one tenant).",
      "title": "Mode"
     },
     "name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the pool, unique on the platform.",
      "title": "Name"
     },
     "nodes": {
      "anyOf": [
       {
        "items": {
         "$ref": "#/components/schemas/TelephonyPoolNode"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Asterisk nodes of the pool (up to 32): each one gets every publication.",
      "title": "Nodes"
     },
     "tenant_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tenant of a dedicated pool (none for a shared pool).",
      "title": "Tenant Id"
     },
     "tls_verify": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the TLS certificates of the engines are checked (default true).",
      "title": "Tls Verify"
     }
    },
    "title": "TelephonyPoolPatch",
    "type": "object"
   },
   "TelephonyPublishIn": {
    "description": "A publication request.",
    "properties": {
     "reason": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reason, kept with the version and in the audit.",
      "title": "Reason"
     }
    },
    "title": "TelephonyPublishIn",
    "type": "object"
   },
   "TelephonyQueueIn": {
    "description": "A call queue of the tenant.",
    "properties": {
     "display_name": {
      "anyOf": [
       {
        "maxLength": 80,
        "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name for display.",
      "title": "Display Name"
     },
     "max_wait_seconds": {
      "default": 300,
      "description": "Maximum wait of a caller, 0 to 86400 seconds (default 300).",
      "maximum": 86400.0,
      "minimum": 0.0,
      "title": "Max Wait Seconds",
      "type": "integer"
     },
     "music_on_hold": {
      "default": "default",
      "description": "Music on hold class (default `default`).",
      "pattern": "^[a-z0-9][a-z0-9_-]{0,40}$",
      "title": "Music On Hold",
      "type": "string"
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
      "title": "Name",
      "type": "string"
     },
     "number": {
      "anyOf": [
       {
        "pattern": "^[0-9]{2,8}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Internal number that reaches the queue (optional).",
      "title": "Number"
     },
     "recording": {
      "default": false,
      "description": "Whether the calls of the queue are recorded.",
      "title": "Recording",
      "type": "boolean"
     },
     "sla_seconds": {
      "default": 20,
      "description": "Service level threshold, 1 to 3600 seconds (default 20).",
      "maximum": 3600.0,
      "minimum": 1.0,
      "title": "Sla Seconds",
      "type": "integer"
     },
     "strategy": {
      "default": "ringall",
      "description": "Ring strategy: ringall, leastrecent, fewestcalls, random, rrmemory, linear or wrandom.",
      "enum": [
       "ringall",
       "leastrecent",
       "fewestcalls",
       "random",
       "rrmemory",
       "linear",
       "wrandom"
      ],
      "title": "Strategy",
      "type": "string"
     },
     "timeout_seconds": {
      "default": 15,
      "description": "Ring time per member, 1 to 600 seconds (default 15).",
      "maximum": 600.0,
      "minimum": 1.0,
      "title": "Timeout Seconds",
      "type": "integer"
     },
     "wrapup_seconds": {
      "default": 0,
      "description": "Pause of a member after a call, 0 to 3600 seconds.",
      "maximum": 3600.0,
      "minimum": 0.0,
      "title": "Wrapup Seconds",
      "type": "integer"
     }
    },
    "required": [
     "name"
    ],
    "title": "TelephonyQueueIn",
    "type": "object"
   },
   "TelephonyQueuePatch": {
    "description": "Fields to change: a call queue of the tenant. Omitted fields keep their value.",
    "properties": {
     "display_name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name for display.",
      "title": "Display Name"
     },
     "max_wait_seconds": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum wait of a caller, 0 to 86400 seconds (default 300).",
      "title": "Max Wait Seconds"
     },
     "music_on_hold": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Music on hold class (default `default`).",
      "title": "Music On Hold"
     },
     "name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "title": "Name"
     },
     "number": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Internal number that reaches the queue (optional).",
      "title": "Number"
     },
     "recording": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the calls of the queue are recorded.",
      "title": "Recording"
     },
     "sla_seconds": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Service level threshold, 1 to 3600 seconds (default 20).",
      "title": "Sla Seconds"
     },
     "strategy": {
      "anyOf": [
       {
        "enum": [
         "ringall",
         "leastrecent",
         "fewestcalls",
         "random",
         "rrmemory",
         "linear",
         "wrandom"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Ring strategy: ringall, leastrecent, fewestcalls, random, rrmemory, linear or wrandom.",
      "title": "Strategy"
     },
     "timeout_seconds": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Ring time per member, 1 to 600 seconds (default 15).",
      "title": "Timeout Seconds"
     },
     "wrapup_seconds": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Pause of a member after a call, 0 to 3600 seconds.",
      "title": "Wrapup Seconds"
     }
    },
    "title": "TelephonyQueuePatch",
    "type": "object"
   },
   "TelephonyQuotasIn": {
    "description": "Quotas and fraud limits of the tenant.",
    "properties": {
     "allowed_country_prefixes": {
      "description": "International prefixes allowed, for example `+32` (none: every country for the extensions with the international permission).",
      "items": {
       "type": "string"
      },
      "maxItems": 300,
      "title": "Allowed Country Prefixes",
      "type": "array"
     },
     "blocked_premium_prefixes": {
      "description": "Premium prefixes, for example `+3389`: only the extensions with the premium permission reach them.",
      "items": {
       "type": "string"
      },
      "maxItems": 300,
      "title": "Blocked Premium Prefixes",
      "type": "array"
     },
     "cps": {
      "default": 2,
      "description": "New calls per second, enforced by Kamailio.",
      "maximum": 10000.0,
      "minimum": 0.0,
      "title": "Cps",
      "type": "integer"
     },
     "max_call_duration_seconds": {
      "default": 7200,
      "description": "Maximum duration of a call, 60 to 86400 seconds (default 7200).",
      "maximum": 86400.0,
      "minimum": 60.0,
      "title": "Max Call Duration Seconds",
      "type": "integer"
     },
     "max_concurrent_calls": {
      "default": 10,
      "description": "Simultaneous calls of the tenant (Kamailio `tenant_limits` and dialplan).",
      "maximum": 100000.0,
      "minimum": 0.0,
      "title": "Max Concurrent Calls",
      "type": "integer"
     },
     "monthly_minutes": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Minutes per month (none: unlimited).",
      "title": "Monthly Minutes"
     },
     "recording_retention_days": {
      "default": 90,
      "description": "Retention of the recordings, 1 to 3650 days (default 90).",
      "maximum": 3650.0,
      "minimum": 1.0,
      "title": "Recording Retention Days",
      "type": "integer"
     }
    },
    "title": "TelephonyQuotasIn",
    "type": "object"
   },
   "TelephonyRollbackIn": {
    "description": "A rollback request.",
    "properties": {
     "reason": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Reason, kept with the version and in the audit.",
      "title": "Reason"
     },
     "version": {
      "description": "Number of the version to publish again.",
      "minimum": 1.0,
      "title": "Version",
      "type": "integer"
     }
    },
    "required": [
     "version"
    ],
    "title": "TelephonyRollbackIn",
    "type": "object"
   },
   "TelephonyRuleIn": {
    "description": "A routing rule of the tenant.",
    "properties": {
     "destination_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier (UUID) of the destination object in the tenant (every kind except `external`).",
      "title": "Destination Id"
     },
     "destination_kind": {
      "anyOf": [
       {
        "enum": [
         "extension",
         "ivr",
         "queue",
         "voice_agent",
         "external",
         "conference"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Kind of destination: `extension`, `ivr`, `queue`, `voice_agent`, `conference` or `external`.",
      "title": "Destination Kind"
     },
     "destination_value": {
      "anyOf": [
       {
        "pattern": "^\\+[1-9][0-9]{6,14}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "E.164 number of an `external` destination.",
      "title": "Destination Value"
     },
     "direction": {
      "description": "`inbound` (called DID) or `outbound` (dialled E.164 number).",
      "enum": [
       "inbound",
       "outbound"
      ],
      "title": "Direction",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
      "title": "Name",
      "type": "string"
     },
     "pattern": {
      "description": "Asterisk pattern on the E.164 number, for example `_+33X.`.",
      "pattern": "^_?[0-9XZN.+\\[\\]-]{1,40}$",
      "title": "Pattern",
      "type": "string"
     },
     "prepend": {
      "default": "",
      "description": "Digits added before the number when dialling.",
      "pattern": "^\\+?[0-9]{0,10}$",
      "title": "Prepend",
      "type": "string"
     },
     "priority": {
      "default": 100,
      "description": "Order of the rules, lower first (default 100).",
      "maximum": 10000.0,
      "minimum": 0.0,
      "title": "Priority",
      "type": "integer"
     },
     "strip_digits": {
      "default": 0,
      "description": "Digits removed from the start of the number before dialling (0 to 10).",
      "maximum": 10.0,
      "minimum": 0.0,
      "title": "Strip Digits",
      "type": "integer"
     },
     "time_conditions": {
      "description": "Time ranges when the rule applies (none: always).",
      "items": {
       "$ref": "#/components/schemas/TelephonyTimeWindow"
      },
      "maxItems": 20,
      "title": "Time Conditions",
      "type": "array"
     },
     "trunk_ids": {
      "description": "Outbound: trunks of the tenant tried in this order on failure (none: every trunk by `failover_order`).",
      "items": {
       "format": "uuid",
       "type": "string"
      },
      "maxItems": 10,
      "title": "Trunk Ids",
      "type": "array"
     }
    },
    "required": [
     "name",
     "direction",
     "pattern"
    ],
    "title": "TelephonyRuleIn",
    "type": "object"
   },
   "TelephonyRulePatch": {
    "description": "Fields to change: a routing rule of the tenant. Omitted fields keep their value.",
    "properties": {
     "destination_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier (UUID) of the destination object in the tenant (every kind except `external`).",
      "title": "Destination Id"
     },
     "destination_kind": {
      "anyOf": [
       {
        "enum": [
         "extension",
         "ivr",
         "queue",
         "voice_agent",
         "external",
         "conference"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Kind of destination: `extension`, `ivr`, `queue`, `voice_agent`, `conference` or `external`.",
      "title": "Destination Kind"
     },
     "destination_value": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "E.164 number of an `external` destination.",
      "title": "Destination Value"
     },
     "direction": {
      "anyOf": [
       {
        "enum": [
         "inbound",
         "outbound"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`inbound` (called DID) or `outbound` (dialled E.164 number).",
      "title": "Direction"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled"
     },
     "name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "title": "Name"
     },
     "pattern": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Asterisk pattern on the E.164 number, for example `_+33X.`.",
      "title": "Pattern"
     },
     "prepend": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Digits added before the number when dialling.",
      "title": "Prepend"
     },
     "priority": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Order of the rules, lower first (default 100).",
      "title": "Priority"
     },
     "strip_digits": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Digits removed from the start of the number before dialling (0 to 10).",
      "title": "Strip Digits"
     },
     "time_conditions": {
      "anyOf": [
       {
        "items": {
         "$ref": "#/components/schemas/TelephonyTimeWindow"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Time ranges when the rule applies (none: always).",
      "title": "Time Conditions"
     },
     "trunk_ids": {
      "anyOf": [
       {
        "items": {
         "format": "uuid",
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Outbound: trunks of the tenant tried in this order on failure (none: every trunk by `failover_order`).",
      "title": "Trunk Ids"
     }
    },
    "title": "TelephonyRulePatch",
    "type": "object"
   },
   "TelephonyRuntimeSettingsIn": {
    "description": "Runtime settings of the telephony of the tenant.",
    "properties": {
     "fraud_auto_block": {
      "default": true,
      "description": "Whether the fraud signals block automatically (default true).",
      "title": "Fraud Auto Block",
      "type": "boolean"
     },
     "fraud_extension_hourly_calls": {
      "default": 60,
      "description": "Outbound calls of one extension in one hour above which it is flagged and blocked (default 60).",
      "maximum": 100000.0,
      "minimum": 1.0,
      "title": "Fraud Extension Hourly Calls",
      "type": "integer"
     },
     "fraud_refused_attempts": {
      "default": 5,
      "description": "Refused destinations of one extension that block it, 1 to 1000 (default 5).",
      "maximum": 1000.0,
      "minimum": 1.0,
      "title": "Fraud Refused Attempts",
      "type": "integer"
     },
     "fraud_tenant_block_factor": {
      "default": 2,
      "description": "The tenant is blocked when its active calls reach this multiple of its quota; 0 disables (default 2).",
      "maximum": 100.0,
      "minimum": 0.0,
      "title": "Fraud Tenant Block Factor",
      "type": "integer"
     },
     "fraud_window_minutes": {
      "default": 10,
      "description": "Window of the refused destinations, 1 to 1440 minutes (default 10).",
      "maximum": 1440.0,
      "minimum": 1.0,
      "title": "Fraud Window Minutes",
      "type": "integer"
     },
     "voicemail_max_seconds": {
      "default": 180,
      "description": "Longest platform voicemail message, 10 to 600 seconds (default 180).",
      "maximum": 600.0,
      "minimum": 10.0,
      "title": "Voicemail Max Seconds",
      "type": "integer"
     },
     "voicemail_storage": {
      "default": "asterisk",
      "description": "`asterisk` (app_voicemail keeps the messages on the PBX) or `platform` (recorded and filed in SeaweedFS, listed by the API).",
      "enum": [
       "asterisk",
       "platform"
      ],
      "title": "Voicemail Storage",
      "type": "string"
     }
    },
    "title": "TelephonyRuntimeSettingsIn",
    "type": "object"
   },
   "TelephonySettingsIn": {
    "description": "Telephony settings of the tenant.",
    "properties": {
     "cdr_retention_days": {
      "default": 365,
      "description": "Retention of the call records, 1 to 3650 days (default 365).",
      "maximum": 3650.0,
      "minimum": 1.0,
      "title": "Cdr Retention Days",
      "type": "integer"
     },
     "enabled": {
      "default": true,
      "description": "Whether the tenant is compiled into its pool (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "model": {
      "default": "shared",
      "description": "`shared` (pool shared by several tenants, default) or `dedicated`. Changed by `platform_admin`.",
      "enum": [
       "shared",
       "dedicated"
      ],
      "title": "Model",
      "type": "string"
     },
     "pbx_instance_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "PBX pool serving the tenant. Changed by `platform_admin`.",
      "title": "Pbx Instance Id"
     },
     "settings": {
      "$ref": "#/components/schemas/TelephonyNumberingSettings",
      "description": "Numbering plan and options."
     },
     "sip_domain": {
      "description": "SIP domain of the tenant, unique on the platform; Kamailio maps it to the tenant.",
      "pattern": "^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?)+$",
      "title": "Sip Domain",
      "type": "string"
     }
    },
    "required": [
     "sip_domain"
    ],
    "title": "TelephonySettingsIn",
    "type": "object"
   },
   "TelephonyTimeWindow": {
    "description": "A time range in Asterisk syntax.",
    "properties": {
     "days": {
      "default": "*",
      "description": "Days: `*` or `mon` to `sun`, or a range such as `mon-fri` (default `*`).",
      "pattern": "^(\\*|[a-z]{3}(-[a-z]{3})?)$",
      "title": "Days",
      "type": "string"
     },
     "end": {
      "description": "End time, HH:MM, after the start.",
      "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
      "title": "End",
      "type": "string"
     },
     "mdays": {
      "default": "*",
      "description": "Days of the month: `*` or a range such as `1-15` (default `*`).",
      "pattern": "^(\\*|[0-9]{1,2}(-[0-9]{1,2})?)$",
      "title": "Mdays",
      "type": "string"
     },
     "months": {
      "default": "*",
      "description": "Months: `*` or `jan` to `dec`, or a range (default `*`).",
      "pattern": "^(\\*|[a-z]{3}(-[a-z]{3})?)$",
      "title": "Months",
      "type": "string"
     },
     "start": {
      "description": "Start time, HH:MM.",
      "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
      "title": "Start",
      "type": "string"
     }
    },
    "required": [
     "start",
     "end"
    ],
    "title": "TelephonyTimeWindow",
    "type": "object"
   },
   "TelephonyTransferIn": {
    "description": "Transfer of an active call.",
    "properties": {
     "target": {
      "description": "Extension number of the tenant (2 to 8 digits) or E.164 number.",
      "pattern": "^([0-9]{2,8}|\\+[1-9][0-9]{6,14})$",
      "title": "Target",
      "type": "string"
     },
     "uniqueid": {
      "anyOf": [
       {
        "maxLength": 64,
        "pattern": "^[A-Za-z0-9._-]{1,64}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Channel to move (default: the first channel of the call).",
      "title": "Uniqueid"
     }
    },
    "required": [
     "target"
    ],
    "title": "TelephonyTransferIn",
    "type": "object"
   },
   "TelephonyTrunkIn": {
    "description": "A SIP trunk of the tenant toward an operator.",
    "properties": {
     "allowed_numbers": {
      "description": "E.164 numbers the trunk may present (up to 200).",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Allowed Numbers",
      "type": "array"
     },
     "auth_username": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9_.+-]{1,64}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "User name of the digest authentication toward the operator.",
      "title": "Auth Username"
     },
     "codecs": {
      "description": "Codecs in preference order among ulaw, alaw, g722, g729, opus and gsm (default ulaw, alaw).",
      "items": {
       "type": "string"
      },
      "maxItems": 6,
      "title": "Codecs",
      "type": "array"
     },
     "enabled": {
      "default": true,
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "failover_order": {
      "default": 100,
      "description": "Order of the trunk when a rule names no trunk (lower first, default 100).",
      "maximum": 10000.0,
      "minimum": 0.0,
      "title": "Failover Order",
      "type": "integer"
     },
     "host": {
      "description": "Host name or address of the operator SIP server.",
      "pattern": "^[A-Za-z0-9.:-]{1,253}$",
      "title": "Host",
      "type": "string"
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
      "title": "Name",
      "type": "string"
     },
     "outbound_caller_id": {
      "anyOf": [
       {
        "pattern": "^\\+[1-9][0-9]{6,14}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "E.164 number presented on the calls through this trunk.",
      "title": "Outbound Caller Id"
     },
     "password": {
      "anyOf": [
       {
        "maxLength": 128,
        "minLength": 8,
        "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Password of the trunk, 8 to 128 characters. Write only: kept in the vault, never returned (`has_password`).",
      "title": "Password"
     },
     "port": {
      "default": 5060,
      "description": "SIP port of the operator (default 5060).",
      "maximum": 65535.0,
      "minimum": 1.0,
      "title": "Port",
      "type": "integer"
     },
     "provider": {
      "anyOf": [
       {
        "maxLength": 80,
        "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the operator, for display.",
      "title": "Provider"
     },
     "registration": {
      "default": false,
      "description": "Whether Asterisk registers to the operator (needs `auth_username`).",
      "title": "Registration",
      "type": "boolean"
     },
     "transport": {
      "default": "udp",
      "description": "SIP transport: `udp` (default), `tcp` or `tls`.",
      "enum": [
       "udp",
       "tcp",
       "tls"
      ],
      "title": "Transport",
      "type": "string"
     }
    },
    "required": [
     "name",
     "host"
    ],
    "title": "TelephonyTrunkIn",
    "type": "object"
   },
   "TelephonyTrunkPatch": {
    "description": "Fields to change: a SIP trunk of the tenant toward an operator. Omitted fields keep their value.",
    "properties": {
     "allowed_numbers": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "E.164 numbers the trunk may present (up to 200).",
      "title": "Allowed Numbers"
     },
     "auth_username": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "User name of the digest authentication toward the operator.",
      "title": "Auth Username"
     },
     "codecs": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Codecs in preference order among ulaw, alaw, g722, g729, opus and gsm (default ulaw, alaw).",
      "title": "Codecs"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled"
     },
     "failover_order": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Order of the trunk when a rule names no trunk (lower first, default 100).",
      "title": "Failover Order"
     },
     "host": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Host name or address of the operator SIP server.",
      "title": "Host"
     },
     "name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "title": "Name"
     },
     "outbound_caller_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "E.164 number presented on the calls through this trunk.",
      "title": "Outbound Caller Id"
     },
     "password": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Password of the trunk, 8 to 128 characters. Write only: kept in the vault, never returned (`has_password`).",
      "title": "Password"
     },
     "port": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "SIP port of the operator (default 5060).",
      "title": "Port"
     },
     "provider": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name of the operator, for display.",
      "title": "Provider"
     },
     "registration": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether Asterisk registers to the operator (needs `auth_username`).",
      "title": "Registration"
     },
     "transport": {
      "anyOf": [
       {
        "enum": [
         "udp",
         "tcp",
         "tls"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "SIP transport: `udp` (default), `tcp` or `tls`.",
      "title": "Transport"
     }
    },
    "title": "TelephonyTrunkPatch",
    "type": "object"
   },
   "TelephonyVoiceAgentIn": {
    "description": "An AI voice agent of the tenant, run by the LiveKit Agents workers `navin-voice`.",
    "properties": {
     "allowed_tools": {
      "description": "Tools the agent may call (up to 100).",
      "items": {
       "type": "string"
      },
      "maxItems": 100,
      "title": "Allowed Tools",
      "type": "array"
     },
     "display_name": {
      "anyOf": [
       {
        "maxLength": 80,
        "pattern": "^[^\\x00-\\x1f\\[\\];]*$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name for display.",
      "title": "Display Name"
     },
     "enabled": {
      "default": true,
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "fallback_queue_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Queue of the tenant that takes the call when the agent fails.",
      "title": "Fallback Queue Id"
     },
     "greeting": {
      "anyOf": [
       {
        "maxLength": 1000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "First sentence said to the caller.",
      "title": "Greeting"
     },
     "instructions": {
      "default": "",
      "description": "Instructions of the agent (system prompt), 20000 characters at most.",
      "maxLength": 20000,
      "title": "Instructions",
      "type": "string"
     },
     "language": {
      "default": "fr-FR",
      "description": "Language, for example `fr-FR` (default).",
      "pattern": "^[a-z]{2}(-[A-Z]{2})?$",
      "title": "Language",
      "type": "string"
     },
     "llm_model_alias": {
      "description": "Alias of the language model in the LLM gateway.",
      "maxLength": 120,
      "minLength": 1,
      "title": "Llm Model Alias",
      "type": "string"
     },
     "max_duration_seconds": {
      "default": 900,
      "description": "Maximum duration of a call, 30 to 14400 seconds (default 900).",
      "maximum": 14400.0,
      "minimum": 30.0,
      "title": "Max Duration Seconds",
      "type": "integer"
     },
     "name": {
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
      "title": "Name",
      "type": "string"
     },
     "stt_model": {
      "anyOf": [
       {
        "maxLength": 120,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Speech to text model.",
      "title": "Stt Model"
     },
     "transfer_target": {
      "anyOf": [
       {
        "maxLength": 60,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Transfer to a human: `extension:<number>`, `queue:<name>` or `number:<E.164>`.",
      "title": "Transfer Target"
     },
     "tts_model": {
      "anyOf": [
       {
        "maxLength": 120,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Text to speech model.",
      "title": "Tts Model"
     },
     "tts_voice": {
      "anyOf": [
       {
        "maxLength": 120,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Voice of the text to speech model.",
      "title": "Tts Voice"
     }
    },
    "required": [
     "name",
     "llm_model_alias"
    ],
    "title": "TelephonyVoiceAgentIn",
    "type": "object"
   },
   "TelephonyVoiceAgentPatch": {
    "description": "Fields to change: an AI voice agent of the tenant, run by the LiveKit Agents workers `navin-voice`. Omitted fields keep their value.",
    "properties": {
     "allowed_tools": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tools the agent may call (up to 100).",
      "title": "Allowed Tools"
     },
     "display_name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name for display.",
      "title": "Display Name"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether the object is compiled and published (default true).",
      "title": "Enabled"
     },
     "fallback_queue_id": {
      "anyOf": [
       {
        "format": "uuid",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Queue of the tenant that takes the call when the agent fails.",
      "title": "Fallback Queue Id"
     },
     "greeting": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "First sentence said to the caller.",
      "title": "Greeting"
     },
     "instructions": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Instructions of the agent (system prompt), 20000 characters at most.",
      "title": "Instructions"
     },
     "language": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Language, for example `fr-FR` (default).",
      "title": "Language"
     },
     "llm_model_alias": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Alias of the language model in the LLM gateway.",
      "title": "Llm Model Alias"
     },
     "max_duration_seconds": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum duration of a call, 30 to 14400 seconds (default 900).",
      "title": "Max Duration Seconds"
     },
     "name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Name, unique in the tenant: lowercase letters, digits and `-`, 1 to 41 characters; it is part of the names on the engines.",
      "title": "Name"
     },
     "stt_model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Speech to text model.",
      "title": "Stt Model"
     },
     "transfer_target": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Transfer to a human: `extension:<number>`, `queue:<name>` or `number:<E.164>`.",
      "title": "Transfer Target"
     },
     "tts_model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Text to speech model.",
      "title": "Tts Model"
     },
     "tts_voice": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Voice of the text to speech model.",
      "title": "Tts Voice"
     }
    },
    "title": "TelephonyVoiceAgentPatch",
    "type": "object"
   },
   "TelephonyWebrtcIn": {
    "description": "A request of WebRTC credentials.",
    "properties": {
     "extension_id": {
      "description": "WebRTC extension of the tenant.",
      "format": "uuid",
      "title": "Extension Id",
      "type": "string"
     },
     "ttl_seconds": {
      "default": 3600,
      "description": "Lifetime of the credentials, 60 to 3600 seconds (default 3600).",
      "maximum": 3600.0,
      "minimum": 60.0,
      "title": "Ttl Seconds",
      "type": "integer"
     }
    },
    "required": [
     "extension_id"
    ],
    "title": "TelephonyWebrtcIn",
    "type": "object"
   },
   "TelephonyWorkerEventIn": {
    "description": "An event of a call reported by a voice worker.",
    "properties": {
     "data": {
      "additionalProperties": true,
      "description": "Free details of the event (no audio, no transcript).",
      "title": "Data",
      "type": "object"
     },
     "occurred_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Time of the event (ISO 8601, default now).",
      "title": "Occurred At"
     },
     "type": {
      "description": "`started`, `answered`, `transfer_requested`, `ended` or `error`.",
      "enum": [
       "started",
       "answered",
       "transfer_requested",
       "ended",
       "error"
      ],
      "title": "Type",
      "type": "string"
     },
     "voice_agent_id": {
      "description": "Voice agent of the call.",
      "format": "uuid",
      "title": "Voice Agent Id",
      "type": "string"
     }
    },
    "required": [
     "type",
     "voice_agent_id"
    ],
    "title": "TelephonyWorkerEventIn",
    "type": "object"
   },
   "TelephonyWorkerToolIn": {
    "description": "Arguments of a lookup tool called by a voice agent.",
    "properties": {
     "arguments": {
      "additionalProperties": true,
      "description": "Arguments of the tool, checked against its input schema.",
      "title": "Arguments",
      "type": "object"
     },
     "voice_agent_id": {
      "description": "Voice agent of the call.",
      "format": "uuid",
      "title": "Voice Agent Id",
      "type": "string"
     }
    },
    "required": [
     "voice_agent_id"
    ],
    "title": "TelephonyWorkerToolIn",
    "type": "object"
   },
   "TelephonyWorkerTransferIn": {
    "description": "Transfer of the SIP participant of a call asked by its voice agent.",
    "properties": {
     "reason": {
      "default": "",
      "description": "Why the agent transfers (500 characters at most).",
      "maxLength": 500,
      "title": "Reason",
      "type": "string"
     },
     "target_uri": {
      "description": "Target URI (sip:, sips: or tel:), the transfer target of the runtime.",
      "pattern": "^(sip|sips|tel):[^\\s]{1,256}$",
      "title": "Target Uri",
      "type": "string"
     },
     "voice_agent_id": {
      "description": "Voice agent of the call.",
      "format": "uuid",
      "title": "Voice Agent Id",
      "type": "string"
     }
    },
    "required": [
     "voice_agent_id",
     "target_uri"
    ],
    "title": "TelephonyWorkerTransferIn",
    "type": "object"
   },
   "TenantIn": {
    "description": "New tenant.",
    "properties": {
     "admins": {
      "description": "OIDC subjects made `tenant_admin` of the new tenant.",
      "items": {
       "type": "string"
      },
      "title": "Admins",
      "type": "array"
     },
     "data_residency": {
      "default": "eu",
      "description": "Region where the data of the tenant must stay, for example `eu` (default).",
      "title": "Data Residency",
      "type": "string"
     },
     "name": {
      "description": "Display name, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "settings": {
      "additionalProperties": true,
      "description": "Free settings object of the tenant (empty by default).",
      "title": "Settings",
      "type": "object"
     },
     "slug": {
      "description": "Short identifier of the tenant, lowercase letters, digits and hyphens, 2 to 63 characters. Also used in the `tenant` claim and in directory group names.",
      "pattern": "^[a-z0-9][a-z0-9-]{1,62}$",
      "title": "Slug",
      "type": "string"
     }
    },
    "required": [
     "slug",
     "name"
    ],
    "title": "TenantIn",
    "type": "object"
   },
   "TenantPatch": {
    "description": "Changes to a tenant; omitted fields keep their value.",
    "properties": {
     "data_residency": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New data residency region.",
      "title": "Data Residency"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New display name, 1 to 200 characters.",
      "title": "Name"
     },
     "settings": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "New settings object, replaces the current one.",
      "title": "Settings"
     },
     "status": {
      "anyOf": [
       {
        "enum": [
         "active",
         "suspended"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`active` or `suspended`. Platform administrators only.",
      "title": "Status"
     }
    },
    "title": "TenantPatch",
    "type": "object"
   },
   "TierIn": {
    "description": "Price tier applying from a number of input tokens.",
    "properties": {
     "min_input_tokens": {
      "description": "Input tokens from which the tier applies, at least 0.",
      "minimum": 0.0,
      "title": "Min Input Tokens",
      "type": "integer"
     },
     "prices": {
      "additionalProperties": {
       "anyOf": [
        {
         "type": "number"
        },
        {
         "type": "string"
        }
       ]
      },
      "description": "Prices of the tier by price key (same keys as `prices`).",
      "title": "Prices",
      "type": "object"
     }
    },
    "required": [
     "min_input_tokens",
     "prices"
    ],
    "title": "TierIn",
    "type": "object"
   },
   "TokenValue": {
    "description": "One value to tokenize.",
    "properties": {
     "type": {
      "description": "Entity type, for example `email`, `iban` or `person`; it appears in the token.",
      "title": "Type",
      "type": "string"
     },
     "value": {
      "description": "Value to tokenize. Stored encrypted, never logged.",
      "title": "Value",
      "type": "string"
     }
    },
    "required": [
     "type",
     "value"
    ],
    "title": "TokenValue",
    "type": "object"
   },
   "TokenizeIn": {
    "description": "Tokenization request.",
    "properties": {
     "text": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Text whose detected entities are replaced by tokens.",
      "title": "Text"
     },
     "values": {
      "anyOf": [
       {
        "items": {
         "$ref": "#/components/schemas/TokenValue"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Values to tokenize, each with its type.",
      "title": "Values"
     }
    },
    "title": "TokenizeIn",
    "type": "object"
   },
   "ToolPatch": {
    "description": "Fields of a tool to change.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free description of the tool.",
      "title": "Description"
     },
     "owner": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 3,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owner of the tool (3 to 200 characters).",
      "title": "Owner"
     },
     "status": {
      "anyOf": [
       {
        "enum": [
         "draft",
         "approved",
         "restricted",
         "deprecated",
         "blocked"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`draft`, `approved` (through a promotion), `restricted`, `deprecated` or `blocked`.",
      "title": "Status"
     }
    },
    "title": "ToolPatch",
    "type": "object"
   },
   "TriggerIn": {
    "description": "An event trigger of an agent.",
    "properties": {
     "agent_id": {
      "description": "Agent to run (UUID or name).",
      "title": "Agent Id",
      "type": "string"
     },
     "filter": {
      "anyOf": [
       {
        "maxLength": 1000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Payload filter (up to 1000 characters): `path=value` or `path!=value` clauses joined by `&&`, the path dotted into the payload, for example `order.status=paid && region!=us`.",
      "title": "Filter"
     },
     "subject": {
      "description": "NATS subject to match (1 to 255 characters, wildcards `*` and `>` allowed).",
      "maxLength": 255,
      "minLength": 1,
      "title": "Subject",
      "type": "string"
     }
    },
    "required": [
     "agent_id",
     "subject"
    ],
    "title": "TriggerIn",
    "type": "object"
   },
   "TtsIn": {
    "description": "A text to speech request.",
    "properties": {
     "dlp_mode": {
      "default": "block",
      "description": "DLP applied to the text: `block` (default), `mask`, `tokenize` or `detect`.",
      "title": "Dlp Mode",
      "type": "string"
     },
     "model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model to use. Default: the configured adapter.",
      "title": "Model"
     },
     "text": {
      "description": "Text to speak (1 to 20000 characters).",
      "maxLength": 20000,
      "minLength": 1,
      "title": "Text",
      "type": "string"
     },
     "voice": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Voice name of the adapter. Default: the adapter default voice.",
      "title": "Voice"
     }
    },
    "required": [
     "text"
    ],
    "title": "TtsIn",
    "type": "object"
   },
   "UpgradeIn": {
    "description": "An upgrade request.",
    "properties": {
     "approved_permissions": {
      "description": "Permission scopes granted to the new version, among the ones it requests (up to 200).",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Approved Permissions",
      "type": "array"
     },
     "config": {
      "additionalProperties": true,
      "description": "Configuration of the pack, validated against its `configSchema`. Empty: the current one.",
      "title": "Config",
      "type": "object"
     },
     "secret_refs": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Secret reference per connector name, `openbao://...` or `env://...`. Empty: the current ones.",
      "title": "Secret Refs",
      "type": "object"
     },
     "version": {
      "description": "Target version, higher than the installed one (5 to 64 characters).",
      "maxLength": 64,
      "minLength": 5,
      "title": "Version",
      "type": "string"
     }
    },
    "required": [
     "version"
    ],
    "title": "UpgradeIn",
    "type": "object"
   },
   "UploadIn": {
    "description": "A file to ingest asynchronously, base64 encoded like the synchronous route.",
    "properties": {
     "classification": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`public`, `internal`, `confidential`, `restricted` or `secret`. Default: the classification of the knowledge base.",
      "title": "Classification"
     },
     "collection": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Collection of the document inside the knowledge base (1 to 200 characters). Default none.",
      "title": "Collection"
     },
     "content_base64": {
      "description": "Bytes of the file, base64 encoded.",
      "minLength": 1,
      "title": "Content Base64",
      "type": "string"
     },
     "filename": {
      "default": "",
      "description": "Original file name (up to 500 characters); its extension must match the declared format. Default: the title.",
      "maxLength": 500,
      "title": "Filename",
      "type": "string"
     },
     "language": {
      "anyOf": [
       {
        "maxLength": 10,
        "minLength": 2,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Language of the document (ISO 639-1 code). Default: detected from the extracted text.",
      "title": "Language"
     },
     "metadata": {
      "additionalProperties": true,
      "description": "Free metadata kept with the document.",
      "title": "Metadata",
      "type": "object"
     },
     "mime_type": {
      "description": "Declared media type, checked against the real signature of the bytes.",
      "maxLength": 255,
      "minLength": 1,
      "title": "Mime Type",
      "type": "string"
     },
     "readers": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Readers of this document. Omitted: the readers of the knowledge base.",
      "title": "Readers"
     },
     "title": {
      "default": "",
      "description": "Title of the document (up to 500 characters). Default empty.",
      "maxLength": 500,
      "title": "Title",
      "type": "string"
     },
     "uri": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Source URI. A document with the URI of an existing one becomes its next version.",
      "title": "Uri"
     }
    },
    "required": [
     "content_base64",
     "mime_type"
    ],
    "title": "UploadIn",
    "type": "object"
   },
   "ValidationError": {
    "description": "One invalid field of a request.",
    "properties": {
     "ctx": {
      "description": "Context of the error, for example the bound that was crossed.",
      "title": "Context",
      "type": "object"
     },
     "input": {
      "description": "Value received for the field.",
      "title": "Input"
     },
     "loc": {
      "description": "Location of the field: `body`, `query`, `path` or `header`, then the field path.",
      "items": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "integer"
        }
       ]
      },
      "title": "Location",
      "type": "array"
     },
     "msg": {
      "description": "Human readable message.",
      "title": "Message",
      "type": "string"
     },
     "type": {
      "description": "Error type, for example `missing` or `string_too_long`.",
      "title": "Error Type",
      "type": "string"
     }
    },
    "required": [
     "loc",
     "msg",
     "type"
    ],
    "title": "ValidationError",
    "type": "object"
   },
   "Variable": {
    "description": "A typed variable of a prompt template.",
    "properties": {
     "default": {
      "description": "Value used when none is given.",
      "title": "Default"
     },
     "description": {
      "default": "",
      "description": "What the variable is for. Default empty.",
      "title": "Description",
      "type": "string"
     },
     "enum": {
      "anyOf": [
       {
        "items": {},
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Allowed values.",
      "title": "Enum"
     },
     "max_length": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum length of a string value, in characters.",
      "title": "Max Length"
     },
     "name": {
      "description": "Name used in the placeholder: a letter or `_`, then letters, digits or `_`.",
      "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
      "title": "Name",
      "type": "string"
     },
     "required": {
      "default": true,
      "description": "When true (default), rendering without a value and without default fails.",
      "title": "Required",
      "type": "boolean"
     },
     "type": {
      "default": "string",
      "description": "`string` (default), `integer`, `number`, `boolean`, `array` or `object`.",
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "Variable",
    "type": "object"
   },
   "VideoGenIn": {
    "description": "A video generation request.",
    "properties": {
     "model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model to use. Default: the configured adapter.",
      "title": "Model"
     },
     "prompt": {
      "description": "Description of the video (1 to 8000 characters).",
      "maxLength": 8000,
      "minLength": 1,
      "title": "Prompt",
      "type": "string"
     },
     "seconds": {
      "default": 5,
      "description": "Duration in seconds (more than 0, at most 120, default 5).",
      "exclusiveMinimum": 0.0,
      "maximum": 120.0,
      "title": "Seconds",
      "type": "number"
     },
     "size": {
      "default": "1280x720",
      "description": "Size `<width>x<height>` in pixels. Default `1280x720`.",
      "title": "Size",
      "type": "string"
     }
    },
    "required": [
     "prompt"
    ],
    "title": "VideoGenIn",
    "type": "object"
   },
   "VideoProcessIn": {
    "description": "A video processing request. Give `media_id` or `content_base64`.",
    "properties": {
     "content_base64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Inline video, base64 encoded (scanned before use).",
      "title": "Content Base64"
     },
     "fps": {
      "default": 1,
      "description": "Frames extracted per second (more than 0, at most 60, default 1).",
      "exclusiveMinimum": 0.0,
      "maximum": 60.0,
      "title": "Fps",
      "type": "number"
     },
     "media_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Stored video media.",
      "title": "Media Id"
     },
     "mime_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Media type of the inline video, for example `video/mp4`.",
      "title": "Mime Type"
     },
     "operations": {
      "description": "What to extract: `frames`, `audio` or both. Default `[\"frames\", \"audio\"]`.",
      "items": {
       "type": "string"
      },
      "title": "Operations",
      "type": "array"
     },
     "sample_rate": {
      "default": 16000,
      "description": "Sample rate of the extracted audio, in Hz. Default 16000.",
      "title": "Sample Rate",
      "type": "integer"
     }
    },
    "title": "VideoProcessIn",
    "type": "object"
   },
   "VisionIn": {
    "description": "A vision understanding request. Give `media_id` or `content_base64`.",
    "properties": {
     "content_base64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Inline image, base64 encoded (scanned before use).",
      "title": "Content Base64"
     },
     "detail": {
      "anyOf": [
       {
        "enum": [
         "auto",
         "low",
         "high"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Image detail level: `auto`, `low` or `high`, when the provider supports it.",
      "title": "Detail"
     },
     "dlp_mode": {
      "default": "detect",
      "description": "DLP applied to the answer: `detect` (default), `mask`, `tokenize` or `block`.",
      "title": "Dlp Mode",
      "type": "string"
     },
     "media_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Stored image media.",
      "title": "Media Id"
     },
     "mime_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Media type of the inline image, for example `image/jpeg`.",
      "title": "Mime Type"
     },
     "model": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model to use. Default: the configured adapter.",
      "title": "Model"
     },
     "prompt": {
      "default": "Describe this image.",
      "description": "Question about the image. Default `Describe this image.`",
      "title": "Prompt",
      "type": "string"
     }
    },
    "title": "VisionIn",
    "type": "object"
   },
   "eai__domains__agents__routes__CancelIn": {
    "description": "Cancellation of a run.",
    "properties": {
     "reason": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Why the run is cancelled; kept in the run errors and the audit trail.",
      "title": "Reason"
     }
    },
    "title": "CancelIn",
    "type": "object"
   },
   "eai__domains__agents__routes__RunIn": {
    "description": "A run to create.",
    "properties": {
     "budgets": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Budget limits (for example max tokens, `max_cost` with amount and currency). They can only tighten the agent manifest budget; the currency must match.",
      "title": "Budgets"
     },
     "delegation_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Delegation granted to this agent. Default: the implicit delegation from the caller.",
      "title": "Delegation Id"
     },
     "retry_policy": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Retry policy: `max_attempts` (1 or more, default 3) and `backoff_seconds` (0 or more, default 2).",
      "title": "Retry Policy"
     },
     "session_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Session (UUID) the run belongs to.",
      "title": "Session Id"
     },
     "start": {
      "default": false,
      "description": "When true, the run starts in `running`. Default false (`pending` until the first step).",
      "title": "Start",
      "type": "boolean"
     },
     "task": {
      "additionalProperties": true,
      "description": "Task of the run: `task_id`, `objective`, `input` are kept; `data_classification` is used by the policy check.",
      "title": "Task",
      "type": "object"
     }
    },
    "title": "RunIn",
    "type": "object"
   },
   "eai__domains__agents__routes__SessionIn": {
    "description": "A session to open.",
    "properties": {
     "agent_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Agent of the conversation (UUID or name).",
      "title": "Agent Id"
     },
     "channel": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Channel the conversation comes from.",
      "title": "Channel"
     },
     "metadata": {
      "additionalProperties": true,
      "description": "Free key-value pairs stored with the object and returned as they are; the platform never interprets them.",
      "title": "Metadata",
      "type": "object"
     },
     "title": {
      "default": "",
      "description": "Title of the session. Default empty.",
      "title": "Title",
      "type": "string"
     },
     "ttl_minutes": {
      "anyOf": [
       {
        "maximum": 525600.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime in minutes (1 to 525600, one year). After it, no message can be added. Default: no expiry.",
      "title": "Ttl Minutes"
     },
     "user_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owner of the session. Default: the caller; another user needs `tenant_admin` or `agent`.",
      "title": "User Id"
     }
    },
    "title": "SessionIn",
    "type": "object"
   },
   "eai__domains__agents__routes__StatusIn": {
    "description": "Reason of an agent status change.",
    "properties": {
     "reason": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Why the status changes (up to 2000 characters).",
      "title": "Reason"
     }
    },
    "title": "StatusIn",
    "type": "object"
   },
   "eai__domains__applications__routes__StatusIn": {
    "description": "Status change of an application.",
    "properties": {
     "reason": {
      "description": "Why (1 to 2000 characters); kept on a suspended application.",
      "maxLength": 2000,
      "minLength": 1,
      "title": "Reason",
      "type": "string"
     },
     "status": {
      "description": "`suspended` or `retired`.",
      "enum": [
       "suspended",
       "retired"
      ],
      "title": "Status",
      "type": "string"
     }
    },
    "required": [
     "status",
     "reason"
    ],
    "title": "StatusIn",
    "type": "object"
   },
   "eai__domains__approvals__routes__CancelIn": {
    "additionalProperties": false,
    "description": "Cancellation of a pending approval request.",
    "properties": {
     "reason": {
      "description": "Why the request is withdrawn, 3 to 2000 characters. Written to the audit trail.",
      "maxLength": 2000,
      "minLength": 3,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "reason"
    ],
    "title": "CancelIn",
    "type": "object"
   },
   "eai__domains__context__routes__VerifyIn": {
    "description": "A token to verify.",
    "properties": {
     "audience": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Audience the verifier expects (up to 200 characters). Default: the first platform audience.",
      "title": "Audience"
     },
     "token": {
      "description": "The JWS compact token (10 to 65536 characters).",
      "maxLength": 65536,
      "minLength": 10,
      "title": "Token",
      "type": "string"
     }
    },
    "required": [
     "token"
    ],
    "title": "VerifyIn",
    "type": "object"
   },
   "eai__domains__delegation__routes__AuthorizeIn": {
    "description": "Authorization request of an action under a delegation.",
    "properties": {
     "action": {
      "description": "Action, dotted lowercase name such as `tool.call` or `model.invoke`, 3 to 200 characters.",
      "maxLength": 200,
      "minLength": 3,
      "pattern": "^[a-z_]+(\\.[a-z_]+)+$",
      "title": "Action",
      "type": "string"
     },
     "audience": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Service that will receive the call, at most 200 characters.",
      "title": "Audience"
     },
     "data_classification": {
      "anyOf": [
       {
        "pattern": "^(public|internal|confidential|restricted|secret)$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Classification of the data handled: `public`, `internal`, `confidential`, `restricted` or `secret`.",
      "title": "Data Classification"
     },
     "delegation_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Delegation to check. Give it or `run_id`.",
      "title": "Delegation Id"
     },
     "relation": {
      "anyOf": [
       {
        "pattern": "^[a-z_][a-z0-9_]*$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "ReBAC relation checked on the resource, for example `viewer`.",
      "title": "Relation"
     },
     "resource": {
      "anyOf": [
       {
        "maxLength": 300,
        "pattern": "^[a-z_]+:[^\\s]+$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Resource acted on, `<type>:<id>` such as `tool:crm.search`, at most 300 characters.",
      "title": "Resource"
     },
     "run_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Run whose delegation is checked, instead of `delegation_id`.",
      "title": "Run Id"
     },
     "scope": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Scope the action needs, at most 200 characters.",
      "title": "Scope"
     }
    },
    "required": [
     "action"
    ],
    "title": "AuthorizeIn",
    "type": "object"
   },
   "eai__domains__evaluation__RunIn": {
    "description": "Evaluation run request.",
    "properties": {
     "outputs": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Precomputed outputs, one per case in order; the target is not called for those cases.",
      "title": "Outputs"
     },
     "suite_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Suite to run. Required unless `trigger` is `promotion`.",
      "title": "Suite Id"
     },
     "target": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/eai__domains__evaluation__Target"
       },
       {
        "type": "null"
       }
      ],
      "description": "Target to evaluate instead of the suite target, for example another version. Required for `trigger: promotion` without suite."
     },
     "trigger": {
      "default": "manual",
      "description": "Why the run starts: `manual` (default), `promotion`, `gate`, `comparison` or a free label such as `ci`.",
      "title": "Trigger",
      "type": "string"
     }
    },
    "title": "RunIn",
    "type": "object"
   },
   "eai__domains__evaluation__Target": {
    "description": "Target of an evaluation.",
    "properties": {
     "ref": {
      "description": "Reference of the target, for example a model id or an agent name, at least 1 character.",
      "minLength": 1,
      "title": "Ref",
      "type": "string"
     },
     "type": {
      "description": "Type of the target: `model`, `agent`, `prompt`, `rag_pipeline`, `skill` or `tool`.",
      "title": "Type",
      "type": "string"
     },
     "version": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version of the target, optional.",
      "title": "Version"
     }
    },
    "required": [
     "type",
     "ref"
    ],
    "title": "Target",
    "type": "object"
   },
   "eai__domains__evidence__routes__DecryptIn": {
    "description": "Decryption request of an audit payload.",
    "properties": {
     "reason": {
      "description": "Why the payload is read, 5 to 500 characters. Written to the access log.",
      "maxLength": 500,
      "minLength": 5,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "reason"
    ],
    "title": "DecryptIn",
    "type": "object"
   },
   "eai__domains__file_security__PolicyIn": {
    "additionalProperties": true,
    "description": "Editable fields of the tenant policy, all optional; a locked or unknown field is refused (422).",
    "properties": {
     "allow_archives": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether archives (zip, gzip, tar, 7z, rar) are accepted; default true.",
      "title": "Allow Archives"
     },
     "allowed_types": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Detected file types accepted, among the known types (`text`, `html`, `pdf`, `ooxml`, `ole`, `odf`, `zip`, `gzip`, `tar`, `7z`, `rar`, `png`, `jpeg`, `gif`, `webp`, `tiff`, `wav`, `mp3`, `ogg`, `flac`, `mp4`, `webm`, `avi`, `executable`, `binary`). Default: every known type except `executable`.",
      "title": "Allowed Types"
     },
     "block_office_macros": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether Office documents with macros are blocked; default true. When false, the macro is only reported in the reasons.",
      "title": "Block Office Macros"
     },
     "block_type_mismatch": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether a file whose detected type contradicts its declared media type is blocked; default true.",
      "title": "Block Type Mismatch"
     },
     "max_file_bytes": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Largest file accepted, in bytes: 1024 to the platform ceiling `EAI_FILE_SCAN_MAX_BYTES` (the default). A larger file is blocked as a policy violation without reaching the engines.",
      "title": "Max File Bytes"
     },
     "max_signature_age_hours": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum age of the ClamAV signatures in hours, 1 to 720, default 48. Older or undated signatures are stale.",
      "title": "Max Signature Age Hours"
     },
     "quarantine_retention_days": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Days a sample is kept before the retention job deletes it, 1 to 365, default 30.",
      "title": "Quarantine Retention Days"
     },
     "retain_samples": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "description": "Whether an encrypted sample of each blocked file is kept for a later rescan; default true.",
      "title": "Retain Samples"
     },
     "stale_signatures": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "What stale ClamAV signatures do to a scan: `warn` (default) only adds a reason, `block` blocks the file with verdict `scan_error`.",
      "title": "Stale Signatures"
     }
    },
    "title": "PolicyIn",
    "type": "object"
   },
   "eai__domains__finops__QuotaIn": {
    "description": "Quota of the tenant: a cost and/or token limit over a period, for one scope.",
    "properties": {
     "currency": {
      "anyOf": [
       {
        "pattern": "^[A-Z]{3}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "ISO 4217 currency of `limit_cost`; default the tenant currency.",
      "title": "Currency"
     },
     "enabled": {
      "default": true,
      "description": "Whether the quota is applied, default true.",
      "title": "Enabled",
      "type": "boolean"
     },
     "enforcement": {
      "default": "hard",
      "description": "`hard` (default): a reservation that would exceed the limit is refused with 429; `soft`: it is accepted and reported.",
      "enum": [
       "hard",
       "soft"
      ],
      "title": "Enforcement",
      "type": "string"
     },
     "limit_cost": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Cost limit per window, at least 0, in `currency`.",
      "title": "Limit Cost"
     },
     "limit_tokens": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Token limit per window, at least 0.",
      "title": "Limit Tokens"
     },
     "name": {
      "description": "Name of the quota, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "period": {
      "default": "month",
      "description": "Window of the limit: `request` (each call), `run`, `hour`, `day` or `month` (default), in UTC.",
      "enum": [
       "request",
       "run",
       "hour",
       "day",
       "month"
      ],
      "title": "Period",
      "type": "string"
     },
     "scope_type": {
      "default": "tenant",
      "description": "What the quota limits: `tenant` (default), `project`, `agent`, `user`, `model` or `provider`.",
      "enum": [
       "tenant",
       "project",
       "agent",
       "user",
       "model",
       "provider"
      ],
      "title": "Scope Type",
      "type": "string"
     },
     "scope_value": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Identifier of the project, agent, user, model or provider; required unless `scope_type` is `tenant`, where it must be null.",
      "title": "Scope Value"
     }
    },
    "required": [
     "name"
    ],
    "title": "QuotaIn",
    "type": "object"
   },
   "eai__domains__licensing__routes__ActivationIn": {
    "description": "Licence activation request.",
    "properties": {
     "token": {
      "description": "Signed licence: JWS compact serialization (three base64url segments separated by dots), algorithm EdDSA, 20 to 16384 characters.",
      "maxLength": 16384,
      "minLength": 20,
      "title": "Token",
      "type": "string"
     }
    },
    "required": [
     "token"
    ],
    "title": "ActivationIn",
    "type": "object"
   },
   "eai__domains__llm_management__KeyIn": {
    "additionalProperties": false,
    "description": "New project key. An absent limit inherits the project (LiteLLM team) limit. Unknown fields are refused.",
    "properties": {
     "budget_period": {
      "anyOf": [
       {
        "enum": [
         "daily",
         "weekly",
         "monthly",
         "total"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Period after which the key spend resets: `daily`, `weekly`, `monthly` or `total`. Default: the budget period of the project.",
      "title": "Budget Period"
     },
     "duration_days": {
      "anyOf": [
       {
        "maximum": 3650.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Lifetime of the key in days, 1 to 3650; the key expires afterwards. Omit it for a key without expiry.",
      "title": "Duration Days"
     },
     "key_alias": {
      "anyOf": [
       {
        "maxLength": 120,
        "minLength": 1,
        "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Unique alias of the key in LiteLLM, 1 to 120 characters, letters, digits, dots, dashes and underscores, starting with a letter or digit. Generated from the tenant and project names when omitted.",
      "title": "Key Alias"
     },
     "max_budget": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum spend of the key per budget period, decimal, at least 0 and never above the project budget. LiteLLM also gets a soft budget at the alert threshold of the project.",
      "title": "Max Budget"
     },
     "max_parallel_requests": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Requests the key may run at the same time, at least 0, never above the project limit.",
      "title": "Max Parallel Requests"
     },
     "models": {
      "description": "Model ids the key may call, up to 200, each allowed by the project. Empty: every model of the project.",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Models",
      "type": "array"
     },
     "name": {
      "default": "",
      "description": "Display name of the key, 128 characters at most; empty by default.",
      "maxLength": 128,
      "title": "Name",
      "type": "string"
     },
     "rpm_limit": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Requests per minute allowed to the key, at least 0, never above the project limit.",
      "title": "Rpm Limit"
     },
     "tpm_limit": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tokens per minute allowed to the key, at least 0, never above the project limit.",
      "title": "Tpm Limit"
     }
    },
    "title": "KeyIn",
    "type": "object"
   },
   "eai__domains__llm_management__ProjectIn": {
    "additionalProperties": false,
    "description": "New LLM project. Unknown fields are refused.",
    "properties": {
     "allowed_categories": {
      "description": "Model categories the project may use, up to 200: every registry model whose category, categories or capabilities match is allowed.",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Allowed Categories",
      "type": "array"
     },
     "allowed_models": {
      "description": "Model ids the project may use, up to 200 of at most 200 characters each. With `allowed_categories` empty too, every model is allowed.",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Allowed Models",
      "type": "array"
     },
     "description": {
      "default": "",
      "description": "Free description, 2000 characters at most.",
      "maxLength": 2000,
      "title": "Description",
      "type": "string"
     },
     "name": {
      "description": "Unique name of the project in the tenant, 1 to 128 characters: letters, digits, spaces, dots, dashes and underscores, starting with a letter or digit.",
      "maxLength": 128,
      "minLength": 1,
      "pattern": "^[A-Za-z0-9][A-Za-z0-9 ._-]{0,127}$",
      "title": "Name",
      "type": "string"
     },
     "owner": {
      "default": "",
      "description": "Owner of the project, 200 characters at most. Default: the caller.",
      "maxLength": 200,
      "title": "Owner",
      "type": "string"
     },
     "project_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tenant project (identifier or slug) the LLM project is linked to; its FinOps quotas apply to that project. Omit it for an LLM project limited by LiteLLM only.",
      "title": "Project Id"
     },
     "quota": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/eai__domains__llm_management__QuotaIn"
       },
       {
        "type": "null"
       }
      ],
      "description": "Initial quota of the project; the defaults of the quota apply when omitted."
     },
     "status": {
      "default": "active",
      "description": "`active` (default), `suspended` or `archived`. Only an active project gets new keys and FinOps quotas.",
      "enum": [
       "active",
       "suspended",
       "archived"
      ],
      "title": "Status",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "ProjectIn",
    "type": "object"
   },
   "eai__domains__llm_management__ProjectPatch": {
    "additionalProperties": false,
    "description": "Changes of an LLM project; every field is optional. Unknown fields are refused.",
    "properties": {
     "allowed_categories": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 200,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "New list of allowed model categories, up to 200.",
      "title": "Allowed Categories"
     },
     "allowed_models": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "maxItems": 200,
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "New list of allowed model ids, up to 200.",
      "title": "Allowed Models"
     },
     "description": {
      "anyOf": [
       {
        "maxLength": 2000,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free description, 2000 characters at most.",
      "title": "Description"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 128,
        "minLength": 1,
        "pattern": "^[A-Za-z0-9][A-Za-z0-9 ._-]{0,127}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New unique name in the tenant, 1 to 128 characters (same rule as on creation).",
      "title": "Name"
     },
     "owner": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Owner of the project, 200 characters at most.",
      "title": "Owner"
     },
     "project_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tenant project (identifier or slug) to link; null removes the link and its FinOps quotas.",
      "title": "Project Id"
     },
     "status": {
      "anyOf": [
       {
        "enum": [
         "active",
         "suspended",
         "archived"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "`active`, `suspended` or `archived`. A project that is not active loses its FinOps quotas and cannot get new keys.",
      "title": "Status"
     }
    },
    "title": "ProjectPatch",
    "type": "object"
   },
   "eai__domains__llm_management__QuotaIn": {
    "additionalProperties": false,
    "description": "Quota of an LLM project. Every limit is optional (null: no limit). Unknown fields are refused.",
    "properties": {
     "alert_threshold_pct": {
      "default": 80,
      "description": "Alert threshold as a share of the budget, in percent (1 to 100, default 80): sent in the LiteLLM team metadata and used as the soft budget of each new key (this share of its `max_budget`).",
      "maximum": 100.0,
      "minimum": 1.0,
      "title": "Alert Threshold Pct",
      "type": "integer"
     },
     "budget_amount": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "number"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Budget per `budget_period`, decimal, at least 0, in `budget_currency`.",
      "title": "Budget Amount"
     },
     "budget_currency": {
      "default": "USD",
      "description": "ISO 4217 currency of the budget, three capital letters, default `USD`.",
      "pattern": "^[A-Z]{3}$",
      "title": "Budget Currency",
      "type": "string"
     },
     "budget_period": {
      "default": "monthly",
      "description": "Period of the budget: `daily`, `weekly`, `monthly` (default) or `total`. Only `daily` and `monthly` also become FinOps quotas.",
      "enum": [
       "daily",
       "weekly",
       "monthly",
       "total"
      ],
      "title": "Budget Period",
      "type": "string"
     },
     "hard_stop": {
      "default": true,
      "description": "When true (default), calls are refused once the budget is spent (LiteLLM maximum budget, hard FinOps quotas). When false, the budget only alerts.",
      "title": "Hard Stop",
      "type": "boolean"
     },
     "max_parallel_requests": {
      "anyOf": [
       {
        "maximum": 100000.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Requests the project may run at the same time, 0 to 100000.",
      "title": "Max Parallel Requests"
     },
     "rpm_limit": {
      "anyOf": [
       {
        "maximum": 10000000.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Requests per minute of the whole project, 0 to 10000000.",
      "title": "Rpm Limit"
     },
     "token_limit": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Maximum tokens per `token_period`, at least 0. Enforced by the Control Plane gateway through a FinOps quota when the project is linked and the period is `daily` or `monthly`.",
      "title": "Token Limit"
     },
     "token_period": {
      "default": "monthly",
      "description": "Period of the token limit: `daily`, `weekly`, `monthly` (default) or `total`.",
      "enum": [
       "daily",
       "weekly",
       "monthly",
       "total"
      ],
      "title": "Token Period",
      "type": "string"
     },
     "tpm_limit": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Tokens per minute of the whole project, at least 0.",
      "title": "Tpm Limit"
     }
    },
    "title": "QuotaIn",
    "type": "object"
   },
   "eai__domains__marketplace__routes__AuthorizeIn": {
    "description": "A runtime permission check.",
    "properties": {
     "permission": {
      "description": "Permission scope, for example `crm.contacts:read` (2 to 128 characters, lowercase).",
      "pattern": "^[a-z][a-z0-9_.:*-]{1,127}$",
      "title": "Permission",
      "type": "string"
     }
    },
    "required": [
     "permission"
    ],
    "title": "AuthorizeIn",
    "type": "object"
   },
   "eai__domains__marketplace__routes__InstallIn": {
    "description": "An installation request (also the preflight body).",
    "properties": {
     "approved_permissions": {
      "description": "Permission scopes granted to the pack, among the ones it requests (up to 200). Wildcards and administration scopes are refused.",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Approved Permissions",
      "type": "array"
     },
     "config": {
      "additionalProperties": true,
      "description": "Configuration of the pack, validated against its `configSchema`; `model_id` must name an approved model.",
      "title": "Config",
      "type": "object"
     },
     "environment": {
      "description": "Target environment: `dev`, `test`, `staging` or `prod`.",
      "enum": [
       "dev",
       "test",
       "staging",
       "prod"
      ],
      "title": "Environment",
      "type": "string"
     },
     "package": {
      "description": "Name of the package.",
      "pattern": "^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$",
      "title": "Package",
      "type": "string"
     },
     "secret_refs": {
      "additionalProperties": {
       "type": "string"
      },
      "description": "Secret reference per connector name, `openbao://...` or `env://...`; required for a connector with authentication.",
      "title": "Secret Refs",
      "type": "object"
     },
     "version": {
      "description": "Version to install (5 to 64 characters).",
      "maxLength": 64,
      "minLength": 5,
      "title": "Version",
      "type": "string"
     }
    },
    "required": [
     "package",
     "version",
     "environment"
    ],
    "title": "InstallIn",
    "type": "object"
   },
   "eai__domains__marketplace__routes__StatusIn": {
    "description": "Suspension or resumption of an installation.",
    "properties": {
     "approval_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Approved `marketplace.resume` request, to resume.",
      "title": "Approval Id"
     },
     "permissions": {
      "description": "Suspend only these granted capabilities (up to 200; empty: the whole installation).",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Permissions",
      "type": "array"
     },
     "reason": {
      "default": "",
      "description": "Why the status changes (up to 1000 characters).",
      "maxLength": 1000,
      "title": "Reason",
      "type": "string"
     },
     "status": {
      "description": "`suspended` (immediate) or `installed` (resumption, with approval).",
      "enum": [
       "suspended",
       "installed"
      ],
      "title": "Status",
      "type": "string"
     }
    },
    "required": [
     "status"
    ],
    "title": "StatusIn",
    "type": "object"
   },
   "eai__domains__mcp_runtime__routes__PolicyIn": {
    "description": "Policy of the MCP Runtime of a project.",
    "properties": {
     "allowed_database_roles": {
      "description": "Database roles a template may use (up to 100). Empty (default): none.",
      "items": {
       "type": "string"
      },
      "maxItems": 100,
      "title": "Allowed Database Roles",
      "type": "array"
     },
     "allowed_hosts": {
      "description": "Hosts the instances may reach, exact names or `*.domain` patterns (up to 200). Empty (default): no host, so a template that needs a host cannot start.",
      "items": {
       "type": "string"
      },
      "maxItems": 200,
      "title": "Allowed Hosts",
      "type": "array"
     },
     "allowed_templates": {
      "description": "Templates users may start (up to 100). Empty (default): every template of the catalogue.",
      "items": {
       "type": "string"
      },
      "maxItems": 100,
      "title": "Allowed Templates",
      "type": "array"
     },
     "idle_timeout_seconds": {
      "default": 900,
      "description": "Maximum idle time before an instance sleeps, in seconds (60 to 86400, default 900).",
      "maximum": 86400.0,
      "minimum": 60.0,
      "title": "Idle Timeout Seconds",
      "type": "integer"
     },
     "max_instances_per_project": {
      "default": 20,
      "description": "Running instances per project (1 to 200, default 20).",
      "maximum": 200.0,
      "minimum": 1.0,
      "title": "Max Instances Per Project",
      "type": "integer"
     },
     "max_instances_per_user": {
      "default": 3,
      "description": "Running instances per user (1 to 20, default 3); sleeping and failed ones are not counted.",
      "maximum": 20.0,
      "minimum": 1.0,
      "title": "Max Instances Per User",
      "type": "integer"
     },
     "max_lifetime_seconds": {
      "default": 28800,
      "description": "Maximum lifetime of a running generation, in seconds (300 to 86400, default 28800).",
      "maximum": 86400.0,
      "minimum": 300.0,
      "title": "Max Lifetime Seconds",
      "type": "integer"
     }
    },
    "title": "PolicyIn",
    "type": "object"
   },
   "eai__domains__navin_library__routes__ActivationIn": {
    "description": "A library item to activate for a project.",
    "properties": {
     "kind": {
      "description": "`skill`, `plugin`, `command` or `agent`.",
      "enum": [
       "skill",
       "plugin",
       "command",
       "agent"
      ],
      "title": "Kind",
      "type": "string"
     },
     "name": {
      "description": "Name of the item in the library (1 to 128 characters).",
      "maxLength": 128,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     }
    },
    "required": [
     "kind",
     "name"
    ],
    "title": "ActivationIn",
    "type": "object"
   },
   "eai__domains__navin_library__routes__RuleIn": {
    "description": "A project rule.",
    "properties": {
     "content": {
      "description": "Markdown content of the rule (1 to 65536 characters, at most 64 KiB).",
      "maxLength": 65536,
      "minLength": 1,
      "title": "Content",
      "type": "string"
     },
     "description": {
      "default": "",
      "description": "When the rule applies (up to 2000 characters).",
      "maxLength": 2000,
      "title": "Description",
      "type": "string"
     },
     "globs": {
      "description": "File patterns the rule applies to, for example `src/**/*.ts` (up to 50).",
      "items": {
       "type": "string"
      },
      "maxItems": 50,
      "title": "Globs",
      "type": "array"
     },
     "mode": {
      "default": "always",
      "description": "`always` (default, inlined in the prompt of every run) or `conditional` (listed, read when its scope matches).",
      "enum": [
       "always",
       "conditional"
      ],
      "title": "Mode",
      "type": "string"
     },
     "source": {
      "default": "navin",
      "description": "Origin of the rule: `navin` (default), `cursor`, `cursor_legacy`, `cline`, `windsurf` or `copilot`.",
      "enum": [
       "navin",
       "cursor",
       "cursor_legacy",
       "cline",
       "windsurf",
       "copilot"
      ],
      "title": "Source",
      "type": "string"
     }
    },
    "required": [
     "content"
    ],
    "title": "RuleIn",
    "type": "object"
   },
   "eai__domains__observability__slo__TargetIn": {
    "additionalProperties": false,
    "description": "Objectives of one service, with the same bounds as the `EAI_SLO_*` settings. Unknown fields are refused (422).",
    "properties": {
     "availability": {
      "description": "Availability target: share of requests that must not fail with a 5xx, from 0.5 included to 1 excluded (for example 0.999).",
      "exclusiveMaximum": 1.0,
      "minimum": 0.5,
      "title": "Availability",
      "type": "number"
     },
     "latency_objective": {
      "description": "Share of requests that must be faster than `latency_seconds`, from 0.5 included to 1 excluded.",
      "exclusiveMaximum": 1.0,
      "minimum": 0.5,
      "title": "Latency Objective",
      "type": "number"
     },
     "latency_seconds": {
      "description": "Latency target in seconds: a request slower than this counts against the latency objective. Greater than 0, at most 300.",
      "exclusiveMinimum": 0.0,
      "maximum": 300.0,
      "title": "Latency Seconds",
      "type": "number"
     },
     "reason": {
      "default": "",
      "description": "Why the objectives change, 500 characters at most, empty by default. Written to the audit trail.",
      "maxLength": 500,
      "title": "Reason",
      "type": "string"
     }
    },
    "required": [
     "availability",
     "latency_seconds",
     "latency_objective"
    ],
    "title": "TargetIn",
    "type": "object"
   },
   "eai__domains__platform_manager__InstallIn": {
    "description": "Install request of catalog services.",
    "properties": {
     "service_check": {
      "default": true,
      "description": "Run the service checks after the install (default true).",
      "title": "Service Check",
      "type": "boolean"
     },
     "services": {
      "description": "Services to install, 1 to 20.",
      "items": {
       "$ref": "#/components/schemas/InstallServiceIn"
      },
      "maxItems": 20,
      "minItems": 1,
      "title": "Services",
      "type": "array"
     },
     "start": {
      "default": true,
      "description": "Start the services once installed (default true).",
      "title": "Start",
      "type": "boolean"
     }
    },
    "required": [
     "services"
    ],
    "title": "InstallIn",
    "type": "object"
   },
   "eai__domains__policies__PolicyIn": {
    "description": "Content of a policy.",
    "properties": {
     "description": {
      "default": "",
      "description": "Description of the policy (empty by default).",
      "title": "Description",
      "type": "string"
     },
     "engine": {
      "default": "builtin",
      "description": "`builtin` (default, `rules`) or `opa` (`rego`).",
      "enum": [
       "builtin",
       "opa"
      ],
      "title": "Engine",
      "type": "string"
     },
     "name": {
      "description": "Unique name in the tenant: lowercase letters, digits, `_`, `.` and `-`, starting with a letter or a digit, at most 100 characters.",
      "pattern": "^[a-z0-9][a-z0-9_.-]{0,99}$",
      "title": "Name",
      "type": "string"
     },
     "priority": {
      "default": 100,
      "description": "Evaluation order, lower first (default 100); equal priorities are sorted by name.",
      "title": "Priority",
      "type": "integer"
     },
     "rego": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Rego module of an `opa` policy. Required for that engine.",
      "title": "Rego"
     },
     "rules": {
      "description": "Rules of a `builtin` policy.",
      "items": {
       "$ref": "#/components/schemas/Rule"
      },
      "title": "Rules",
      "type": "array"
     },
     "status": {
      "default": "active",
      "description": "`active` (default, evaluated), `draft` (not evaluated; for OPA, shipped as a library) or `disabled`.",
      "enum": [
       "draft",
       "active",
       "disabled"
      ],
      "title": "Status",
      "type": "string"
     },
     "version": {
      "default": "1.0.0",
      "description": "Version label of the policy, recorded in each decision. Default `1.0.0`.",
      "title": "Version",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "PolicyIn",
    "type": "object"
   },
   "eai__domains__privacy__DecryptIn": {
    "description": "Decryption request.",
    "properties": {
     "aad": {
      "default": "",
      "description": "Associated data given at encryption (empty by default).",
      "title": "Aad",
      "type": "string"
     },
     "as_base64": {
      "default": false,
      "description": "When true, returns the data as `plaintext_base64` (default false).",
      "title": "As Base64",
      "type": "boolean"
     },
     "ciphertext": {
      "description": "Ciphertext returned by encrypt, `eaienc1:<key id>:<version>:...`.",
      "title": "Ciphertext",
      "type": "string"
     }
    },
    "required": [
     "ciphertext"
    ],
    "title": "DecryptIn",
    "type": "object"
   },
   "eai__domains__privacy__KeyIn": {
    "description": "New encryption key.",
    "properties": {
     "name": {
      "description": "Unique name: lowercase letters, digits, `.`, `_` or `-`, starting with a letter or a digit, at most 63 characters.",
      "title": "Name",
      "type": "string"
     },
     "purpose": {
      "default": "data",
      "description": "Free label of the use of the key, `data` by default.",
      "title": "Purpose",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "KeyIn",
    "type": "object"
   },
   "eai__domains__privacy__RuleIn": {
    "description": "DLP rule of the tenant.",
    "properties": {
     "action": {
      "default": "mask",
      "description": "Action on a finding: `allow`, `detect`, `mask` (default), `tokenize` or `block`; it overrides the mode of the request.",
      "title": "Action",
      "type": "string"
     },
     "classification": {
      "default": "confidential",
      "description": "Classification of the data found: `public`, `internal`, `confidential` (default), `restricted` or `secret`.",
      "title": "Classification",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "description": "When false, the rule is ignored (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "entity_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Builtin entity type the rule applies to, for example `credit_card`. Give it or `pattern`.",
      "title": "Entity Type"
     },
     "min_score": {
      "default": 0,
      "description": "Minimum confidence score of a finding, 0 by default.",
      "title": "Min Score",
      "type": "number"
     },
     "name": {
      "description": "Unique name of the rule, 1 to 120 characters.",
      "maxLength": 120,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "pattern": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Regular expression of a custom entity, at most 500 characters.",
      "title": "Pattern"
     }
    },
    "required": [
     "name"
    ],
    "title": "RuleIn",
    "type": "object"
   },
   "eai__domains__realtime__SessionIn": {
    "description": "A realtime session to open.",
    "properties": {
     "agent_id": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9._:@-]{1,128}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Agent of the session when a user opens it (1 to 128 characters). Ignored for an agent caller, which is the agent itself.",
      "title": "Agent Id"
     },
     "config": {
      "additionalProperties": true,
      "description": "Session configuration: `dlp_mode` (`mask` default, `tokenize` or `block`), `vad` (`enabled` boolean, `threshold` in (0, 1]), `record` and pipeline options.",
      "title": "Config",
      "type": "object"
     },
     "on_behalf_of": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9._:@-]{1,128}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "User the agent acts for (agent caller). For a user caller, only its own id is accepted.",
      "title": "On Behalf Of"
     },
     "pipeline": {
      "default": "echo",
      "description": "`echo` (default) or `stt`.",
      "title": "Pipeline",
      "type": "string"
     },
     "room": {
      "anyOf": [
       {
        "pattern": "^[A-Za-z0-9._-]{1,128}$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "LiveKit room name (1 to 128 letters, digits, `.`, `_`, `-`). Default: derived from the tenant and the session.",
      "title": "Room"
     },
     "ttl_seconds": {
      "default": 3600,
      "description": "Lifetime of the LiveKit token, in seconds (60 to 86400, default 3600).",
      "maximum": 86400.0,
      "minimum": 60.0,
      "title": "Ttl Seconds",
      "type": "integer"
     }
    },
    "title": "SessionIn",
    "type": "object"
   },
   "eai__domains__retention__PolicyIn": {
    "description": "Retention policy of one resource type.",
    "properties": {
     "action": {
      "default": "erase",
      "description": "`erase` (default) deletes; `archive` keeps an encrypted copy before deletion (memory items).",
      "title": "Action",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "description": "When false, runs ignore the policy (default true).",
      "title": "Enabled",
      "type": "boolean"
     },
     "resource_type": {
      "description": "Resource type: `memory`, `sessions`, `media`, `usage_raw`, `telemetry`, `documents` or `realtime`.",
      "title": "Resource Type",
      "type": "string"
     },
     "ttl_days": {
      "description": "Lifetime in days, 0 to 36500. Items older than that are purged by the next run.",
      "maximum": 36500.0,
      "minimum": 0.0,
      "title": "Ttl Days",
      "type": "integer"
     }
    },
    "required": [
     "resource_type",
     "ttl_days"
    ],
    "title": "PolicyIn",
    "type": "object"
   },
   "eai__domains__retention__RunIn": {
    "description": "Options of a retention run.",
    "properties": {
     "dry_run": {
      "default": false,
      "description": "When true, reports what would be purged without deleting anything (default false).",
      "title": "Dry Run",
      "type": "boolean"
     },
     "resource_types": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "description": "Resource types to process, among `memory`, `sessions`, `media`, `usage_raw`, `telemetry`, `documents` or `realtime`. Null: all of them.",
      "title": "Resource Types"
     }
    },
    "title": "RunIn",
    "type": "object"
   },
   "eai__domains__risk__EvidenceIn": {
    "description": "Evidence attached to a control or an assessment.",
    "properties": {
     "digest": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Digest of the evidence content, for example `sha256:<hex>`, to prove it did not change.",
      "title": "Digest"
     },
     "kind": {
      "default": "document",
      "description": "Kind of evidence, for example `document`, `report` or `screenshot`. Default `document`.",
      "title": "Kind",
      "type": "string"
     },
     "title": {
      "description": "Title of the evidence, at least 1 character.",
      "minLength": 1,
      "title": "Title",
      "type": "string"
     },
     "uri": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Where the evidence is stored, optional.",
      "title": "Uri"
     }
    },
    "required": [
     "title"
    ],
    "title": "EvidenceIn",
    "type": "object"
   },
   "eai__domains__risk__Target": {
    "description": "AI system an assessment is about.",
    "properties": {
     "ref": {
      "description": "Reference of the target: name or identifier, at least 1 character.",
      "minLength": 1,
      "title": "Ref",
      "type": "string"
     },
     "type": {
      "description": "Type of the target, for example `agent`, `model` or `application`. An `agent` target updates the registry.",
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "type",
     "ref"
    ],
    "title": "Target",
    "type": "object"
   },
   "eai__domains__soc__EvidenceIn": {
    "description": "Evidence to seal on an incident.",
    "properties": {
     "content": {
      "additionalProperties": true,
      "description": "Content of the record, a JSON object; only its hash enters the chain next to it.",
      "title": "Content",
      "type": "object"
     },
     "kind": {
      "default": "note",
      "description": "Kind of record, 1 to 64 characters, `note` by default.",
      "maxLength": 64,
      "minLength": 1,
      "title": "Kind",
      "type": "string"
     }
    },
    "required": [
     "content"
    ],
    "title": "EvidenceIn",
    "type": "object"
   },
   "eai__domains__soc__TargetIn": {
    "description": "Typed target of a containment order.",
    "properties": {
     "ref": {
      "description": "Reference of the target (identifier or name), 1 to 300 characters.",
      "maxLength": 300,
      "minLength": 1,
      "title": "Ref",
      "type": "string"
     },
     "type": {
      "description": "Target type accepted by the reaction: `request`, `session`, `run`, `agent`, `subagent`, `application`, `tool`, `plugin`, `mcp`, `connector`, `knowledge_base`, `model`, `credential`, `identity`, `tenant`, `workload` or `service`.",
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "type",
     "ref"
    ],
    "title": "TargetIn",
    "type": "object"
   },
   "eai__domains__storage__routes__VerifyIn": {
    "description": "Options of a capability verification.",
    "properties": {
     "probe_write": {
      "default": true,
      "description": "When true (default), a probe object is written with the configured encryption, storage class and legal hold, read back and removed, to verify storage classes and integrity. It is skipped when the bucket has a default retention. When false, those two capabilities stay unverified.",
      "title": "Probe Write",
      "type": "boolean"
     }
    },
    "title": "VerifyIn",
    "type": "object"
   },
   "eai__domains__tenancy__ProjectIn": {
    "description": "New project.",
    "properties": {
     "business_unit_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Business unit the project is attached to, optional; it must belong to the organization.",
      "title": "Business Unit Id"
     },
     "description": {
      "default": "",
      "description": "Description of the project (empty by default).",
      "title": "Description",
      "type": "string"
     },
     "environments": {
      "description": "Environments created with the project, among `dev`, `test`, `staging` and `prod`; duplicates are ignored.",
      "items": {
       "enum": [
        "dev",
        "test",
        "staging",
        "prod"
       ],
       "type": "string"
      },
      "title": "Environments",
      "type": "array"
     },
     "metadata": {
      "additionalProperties": true,
      "description": "Free key-value pairs stored with the object. Checked by the database: a refused object answers 422 `invalid_metadata`.",
      "title": "Metadata",
      "type": "object"
     },
     "name": {
      "description": "Display name, 1 to 200 characters.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "organization_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Organization the project is attached to, optional.",
      "title": "Organization Id"
     },
     "settings": {
      "additionalProperties": true,
      "description": "Free settings object of the project (empty by default).",
      "title": "Settings",
      "type": "object"
     },
     "slug": {
      "description": "Short identifier of the project, lowercase letters, digits and hyphens, at most 63 characters, unique in the tenant. Used in the `X-Project` header.",
      "pattern": "^[a-z0-9][a-z0-9-]{0,62}$",
      "title": "Slug",
      "type": "string"
     }
    },
    "required": [
     "slug",
     "name"
    ],
    "title": "ProjectIn",
    "type": "object"
   },
   "eai__domains__tenancy__ProjectPatch": {
    "description": "Changes to a project; omitted fields keep their value.",
    "properties": {
     "business_unit_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New business unit; null detaches the project from its unit.",
      "title": "Business Unit Id"
     },
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New description.",
      "title": "Description"
     },
     "expected_version": {
      "anyOf": [
       {
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "description": "Version the caller last read. A stale version answers 409 `version_conflict` (optimistic concurrency).",
      "title": "Expected Version"
     },
     "metadata": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Free key-value pairs stored with the object. Checked by the database: a refused object answers 422 `invalid_metadata`.",
      "title": "Metadata"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New display name, 1 to 200 characters.",
      "title": "Name"
     },
     "organization_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "New organization; null detaches the project.",
      "title": "Organization Id"
     },
     "settings": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "New settings object, replaces the current one.",
      "title": "Settings"
     }
    },
    "title": "ProjectPatch",
    "type": "object"
   }
  }
 },
 "info": {
  "description": "The Control Plane API is the single entry point of the Enterprise AI Platform. Every portal screen, SDK (Python, TypeScript, Go, Java), CLI command and Navin Manager action goes through it. It manages tenants and projects, identities and access, agents and their runs, models and the LLM gateway, knowledge bases, tools and MCP servers, governance (policies, approvals, risk, privacy, retention, evidence), security operations and costs.\n\n## Overview\n\nThe API is a JSON over HTTPS REST API. Resources are grouped by tag in the menu on the left; the groups follow the order in which a new reader usually meets them: identity and access, tenancy, agents and AI, knowledge and data, tools and integrations, governance and compliance, security, FinOps and platform operations.\n\nCommon rules:\n\n- requests and responses use `application/json` encoded in UTF-8, except the upload routes (`multipart/form-data`) and the streaming routes (Server-Sent Events, WebSocket);\n- dates and times are ISO 8601 strings in UTC, for example `2026-03-14T09:30:00Z`;\n- identifiers are opaque strings (most of them UUIDs); never build them yourself;\n- unknown fields in a request body are refused with `422 validation_error` on the routes whose model forbids extra fields;\n- the language of error messages follows the `Accept-Language` header (`en` or `fr`, default `en`).\n\n## Base URL, versioning and compatibility\n\nEvery route lives under the `/v1` prefix of the address your administrator published, for example `https://api.example.internal/v1`. When the documentation is enabled, the same server serves this reference at `/redoc`, the interactive console at `/docs` and the machine contract at `/openapi.json`.\n\nThe published contract is `docs/api/openapi-v1.json`. It carries `info.x-contract-version` (currently `1.0`). Inside a major version the contract only grows: new routes, new optional fields, new response fields and new enumeration values may appear at any time, so clients must ignore fields they do not know. The following changes are breaking and are refused by the contract check unless the major number of the contract version is raised:\n\n1. removing a route (method and path);\n2. removing a field from a 2xx JSON response;\n3. adding a required request field (body or query parameter);\n4. removing a value from a request enumeration.\n\n## Authentication\n\nEvery `/v1` route needs a credential, except the few public ones (sign in, health). The tenant of the call always comes from the credential, never from the request body. The API accepts, in this order:\n\n| Credential | Header | Typical caller |\n|---|---|---|\n| OIDC access token (JWT) issued by Keycloak | `Authorization: Bearer <token>` | users of the portal, SDKs and CLI after a sign in |\n| Portal session `eais_<prefix>_<secret>` opened by `POST /v1/auth/login` | `Authorization: Bearer eais_...` | local accounts (installer administrator) |\n| API key `eai_<prefix>_<secret>` | `X-API-Key: eai_...` or `Authorization: Bearer eai_...` | scripts, CI pipelines, back end services |\n| SPIFFE workload identity | `X-SPIFFE-ID` (set by the mesh sidecar only) | workloads of the platform, when SPIFFE is enabled |\n\nAn OIDC token must be signed with an allowed algorithm by a key of the configured JWKS, and carry `exp`, `iat`, `iss`, `sub` (and `aud` when an audience is configured). Roles are read from the Keycloak realm roles, the client roles of the audience and a plain `roles` claim; directory groups (`groups`, `entra_groups`) may grant `platform_admin` or `tenant_admin` and apply the group mappings of the tenant. The tenant comes from the `tenant_id` or `tenant` claim.\n\nTo get a token with the client credentials grant of Keycloak, then call the API:\n\n```bash\ncurl -s -X POST \"https://sso.example.internal/realms/<realm>/protocol/openid-connect/token\" \\\n  -d grant_type=client_credentials -d client_id=<client_id> -d client_secret=<client_secret>\n\ncurl -s \"https://api.example.internal/v1/identity/whoami\" \\\n  -H \"Authorization: Bearer <token>\"\n```\n\n`GET /v1/identity/whoami` returns the identity the platform resolved: subject, tenant, roles, scopes, clearance and authentication method. API keys are created with `POST /v1/api-keys`; the full key is shown once and only its hash is stored.\n\nAuthentication errors answer `401` (`unauthenticated`, `invalid_token`, `invalid_api_key`, `api_key_revoked`, `api_key_expired`, `invalid_session`, `session_expired`) with a `WWW-Authenticate: Bearer` header when no credential was sent. A suspended tenant answers `403 tenant_suspended`. A suspended identity or credential (kill switch of the SOC) is refused on every request.\n\n## Tenancy and projects\n\nThe platform is multi-tenant: every object belongs to exactly one tenant and a credential only ever sees its own tenant. Inside a tenant, organizations and business units form the hierarchy, and projects are the workspaces that own agents, knowledge bases, quotas and secrets. Each project has environments (`dev`, `test`, `staging`, `prod`).\n\n- Send `X-Project: <project>` to work inside a project when the credential is not already bound to one (an API key may be bound to a project and an environment).\n- Send `X-Environment: dev|test|staging|prod` to select the environment; any other value is refused with `400 invalid_request`.\n- Routes that need a tenant answer `403 tenant_required` to a platform credential that has none.\n\n## Roles and scopes\n\nAccess is checked in three layers:\n\n1. **Roles** (RBAC) held in the tenant: `platform_admin`, `tenant_admin`, `security_officer`, `finops`, `developer`, `auditor`, `agent`, `viewer`, `soc_analyst`, `ai_governance_officer`, `data_steward`, `application_owner`, `ai_platform_engineer`, `business_owner`, `support_engineer`. `platform_admin` passes every role check. A missing role answers `403 forbidden` with `details.required_roles`.\n2. **Scopes** carried by the credential, matched as globs (`*`, `admin:*`, `models:invoke`). User tokens without a `scope` claim, or with `openid`, get `*`. A missing scope answers `403 insufficient_scope` with `details.required_scope`.\n3. **Relations** (ReBAC, OpenFGA) on a resource, inherited from tenant to project to resource, for example `can_assume` on a service identity. A missing relation answers `403 relation_required`, and the refusal is audited.\n\nPolicies (OPA) and approvals may then add obligations or ask for a four-eyes approval before a sensitive action.\n\n## Errors\n\nEvery error, whatever the route, uses the same envelope. `code` is stable and never changes: test it, not the message. `message` is in the language negotiated from `Accept-Language`; `message_i18n` gives both languages; `details` gives machine readable context; `request_id` is the identifier to give to support.\n\n```json\n{\n  \"error\": {\n    \"code\": \"forbidden\",\n    \"message\": \"You do not have the required role for this operation.\",\n    \"message_i18n\": {\"en\": \"You do not have the required role for this operation.\", \"fr\": \"Vous n'avez pas le rôle requis pour cette opération.\"},\n    \"details\": {\"required_roles\": [\"tenant_admin\"]},\n    \"request_id\": \"req_3f9a1c2b7d4e5f60\"\n  }\n}\n```\n\nCommon codes:\n\n| HTTP | Code | Meaning |\n|---|---|---|\n| 400 | `invalid_request`, `invalid_cursor`, `json_too_deep` | malformed request, bad cursor, JSON nested too deep |\n| 401 | `unauthenticated`, `invalid_token`, `invalid_api_key` | no valid credential |\n| 403 | `forbidden`, `insufficient_scope`, `relation_required`, `tenant_required` | authenticated but not allowed |\n| 404 | `not_found` | unknown resource, or a resource of another tenant |\n| 409 | `conflict`, `idempotency_conflict`, `operation_in_progress` | duplicate, version or state conflict |\n| 413 | `payload_too_large` | body over the size limit |\n| 414 | `query_too_long` | query string over 8192 characters |\n| 422 | `validation_error` | body or parameters do not match the schema; `details.errors` lists `loc`, `msg` and `type` |\n| 429 | `rate_limited` | rate limit reached; wait `Retry-After` seconds |\n| 431 | `headers_too_large` | too many headers, or headers too large |\n| 500 | `internal_error` | unexpected error; only the request id is returned |\n| 502 | `authz_backend_error` | the authorization backend could not answer (fail closed) |\n| 503 | `service_unavailable` | a dependency is down |\n\nDatabase constraint violations become `409 conflict` and invalid values `400 invalid_request`, never with SQL text.\n\n## Pagination\n\nList routes use keyset pagination. Pass `limit` (default 50, maximum 500; a higher value is lowered to 500, a value below 1 is refused with `400`) and read the page envelope:\n\n```json\n{\"items\": [ ... ], \"next_cursor\": \"eyJpZCI6IjQyIn0\"}\n```\n\nTo read the next page, send the same query with `cursor=<next_cursor>`. `next_cursor` is `null` on the last page. The cursor is opaque: do not decode or build it; a damaged cursor answers `400 invalid_cursor`. Some routes document their own lower maximum.\n\n## Idempotency and long operations\n\nLong creations (agent runs, evaluation and red team runs, marketplace installations and upgrades, knowledge base reindexing, connector synchronization, video generation) return an `Operation-Id` header and an `Operation-Location` header (`/v1/operations/{operation_id}`). Follow the operation with `GET /v1/operations/{operation_id}`: it returns the accepted answer, the tracked resource and its live state, read with your own credentials.\n\nSend an `Idempotency-Key` header (1 to 200 characters) to make a retry safe:\n\n1. the first request runs and its answer is stored for your principal and that key;\n2. a retry with the same key and the same body returns the stored answer with `Idempotency-Replayed: true`, without running the operation again;\n3. the same key with another body answers `409 idempotency_conflict`;\n4. a retry while the first request still runs answers `409 operation_in_progress`.\n\nA failed request (non 2xx) releases the key, so it can be retried.\n\n## Rate limits and request size limits\n\nCounters use fixed one minute windows, shared by every replica when Redis is configured. Default budgets, which the operator may change:\n\n| Bucket | Default | Key |\n|---|---|---|\n| `principal` | 1200 requests per minute | tenant and principal, every `/v1` route |\n| `gateway` | 600 requests per minute | tenant and principal, `/v1/gateway/*` |\n| `anonymous` | 1200 requests per minute | client IP, requests without any credential |\n| `auth_failures` | 20 failures per minute | client IP; past it every attempt of that IP is refused until the window ends |\n\nOver the budget the API answers `429 rate_limited` with a `Retry-After` header and `details.bucket`, `details.limit_per_minute`, `details.retry_after_seconds`. Health and metrics routes are never limited.\n\nSize limits: at most 100 headers and 32 KiB of headers (`431`), a query string of at most 8192 characters (`414`), a body of at most 10 MiB, or 100 MiB on upload routes (`413 payload_too_large` with `details.max_bytes`), and JSON nested at most 64 levels (`400 json_too_deep`). The body limit applies whatever the transfer encoding.\n\n## Request IDs and tracing\n\nEvery response carries `X-Request-Id`. Send your own `X-Request-Id` (1 to 128 characters among letters, digits and `. _ : -`) to correlate your logs; any other value is replaced by a generated `req_<hex>` id. The same id is in the error envelope and in the access log.\n\nThe API follows W3C Trace Context: send a `traceparent` header and the request joins your trace; without it the API starts a new trace. The response returns the `traceparent` of the request, and audit events carry the same trace id, so `GET /v1/audit/correlations?trace_id=...` finds every event of one call chain. Outside staging and production a `Server-Timing` header gives the processing time.\n\n## Audit\n\nEvery change, every refused authorization and every sensitive read writes an Audit Event in the same transaction as the change: a rolled back change leaves no event. Events of a tenant form a hash chain (each hash covers the previous one), so a removed or modified event is detected by `GET /v1/audit/verify`. Each event records the actor (subject, tenant, authentication method), the action, the resource, the policy decision, the outcome, the trace id and, under a delegated execution context, the person the call acts on behalf of. Read events with `GET /v1/audit/events` and export them with `POST /v1/audit/export`.",
  "title": "Enterprise AI Platform - Control Plane",
  "version": "1.0.2",
  "x-contract-version": "1.0"
 },
 "openapi": "3.1.0",
 "paths": {
  "/healthz": {
   "get": {
    "description": "Liveness probe: always answers 200 with `status: ok` and the version of the Control Plane while the process serves requests. It checks no dependency. No authentication, no rate limit.",
    "operationId": "healthz_healthz_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Healthz Healthz Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Check that the process is alive",
    "tags": [
     "system"
    ]
   }
  },
  "/readyz": {
   "get": {
    "description": "Readiness probe: checks that the database answers and that the schema migrations were applied. Answers 200 `ready` when every check passes, else 503 `not_ready`, with the result of each check and a message in the language of the request. The Redis cache state is reported but never makes the instance not ready. No authentication, no rate limit.",
    "operationId": "readyz_readyz_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Check that the instance is ready",
    "tags": [
     "system"
    ]
   }
  },
  "/v1/a2a/inbox": {
   "get": {
    "description": "Returns the A2A messages addressed to `recipient`, oldest first, each with `verified` (the HMAC-SHA256 signature of the envelope matches the tenant key). Reading marks the returned messages as read. One page only (`next_cursor` is always null).",
    "operationId": "a2a_inbox_v1_a2a_inbox_get",
    "parameters": [
     {
      "description": "Party whose inbox is read: `agent:<name>` or `run:<id>` (at least 3 characters).",
      "in": "query",
      "name": "recipient",
      "required": true,
      "schema": {
       "minLength": 3,
       "title": "Recipient",
       "type": "string"
      }
     },
     {
      "description": "When true, only the messages not read yet. Default false.",
      "in": "query",
      "name": "unread",
      "required": false,
      "schema": {
       "default": false,
       "title": "Unread",
       "type": "boolean"
      }
     },
     {
      "description": "Maximum number of messages returned (default 50, capped at 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response A2A Inbox V1 A2A Inbox Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read an A2A inbox",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/a2a/messages": {
   "post": {
    "description": "Sends a signed agent to agent message (envelope `a2a.v1`, HMAC-SHA256 signature per tenant). Needs `tenant_admin`, `developer` or `agent`.\nSteps:\n1. `to` and `from` are resolved: `agent:<name>` or `run:<id>` (400 `invalid_request` otherwise). Without `from`, the sender is the calling principal.\n2. A `run:` sender must be a run created by the caller (or the caller is `tenant_admin`, else 403 `forbidden`) and not finished (409 `run_finished`).\n3. The policy `agent.a2a.send` is evaluated and the payload is screened as untrusted content; a prompt injection is refused with `prompt_injection_blocked` after the security event is recorded.\n4. The envelope is stored in the recipient inbox and audited as `a2a.send`.",
    "operationId": "send_a2a_v1_a2a_messages_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/A2AIn"
       }
      }
     },
     "description": "Recipient, message type, payload and optional conversation threading.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Send A2A V1 A2A Messages Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Send an A2A message",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/adapters": {
   "get": {
    "description": "Specialized adapters of the gateway (image generation, speech to text, text to speech, video generation...) with their modality, label in the language of the request and in both languages, status (`configured` when their address is set, else `not_configured`) and the controls applied to them. Requires a reader role.",
    "operationId": "adapters_list_v1_adapters_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the specialized adapters",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/agents": {
   "get": {
    "description": "Agents of the tenant, in name order, paginated with `cursor`. Any tenant principal may call it.",
    "operationId": "list_agents_v1_agents_get",
    "parameters": [
     {
      "description": "Only the agents with this status: `active`, `suspended` or `killed`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Agents V1 Agents Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the agents",
    "tags": [
     "agents"
    ]
   },
   "post": {
    "description": "Applies an Agent manifest: creates the agent, or adds a version to an existing one and makes it current. The manifest is validated against the v1 contract (422 `invalid_manifest`); risk level `unacceptable` is refused (422 `agent_risk_unacceptable`); the same version with other content is refused (409 `version_immutable`). `apply_status` in the answer is `created`, `version_added` or `unchanged`. Needs `tenant_admin`, `developer` or `application_owner`; the caller becomes ReBAC owner. Audited as `agent.apply`.",
    "operationId": "create_agent_v1_agents_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Manifest",
        "type": "object"
       }
      }
     },
     "description": "Agent manifest (`kind: Agent`, `metadata` with name, version and owner, `spec`).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Agent V1 Agents Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register an agent or a version",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/agents/{agent_id}": {
   "delete": {
    "description": "Deletes the agent and its versions. Needs the role `tenant_admin` and the ReBAC relation `owner` on the agent. Refused with 409 `agent_has_active_runs` while a run of the agent is still active (pending, running, waiting or suspended); 404 `agent_not_found` for an unknown agent. Audited as `agent.delete`.",
    "operationId": "delete_agent_v1_agents__agent_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an agent",
    "tags": [
     "agents"
    ]
   },
   "get": {
    "description": "Returns the agent, the manifest of its current version and `runs`, the number of its runs per state. Needs the ReBAC relation `viewer` on the agent. 404 `agent_not_found`.",
    "operationId": "get_agent_v1_agents__agent_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Agent V1 Agents  Agent Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an agent",
    "tags": [
     "agents"
    ]
   },
   "patch": {
    "description": "Changes the registry fields of the agent (owner, risk level, description, labels) without creating a version. Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor`. Invalid values answer 400 `invalid_request`. Audited as `agent.update` with the changed field names.",
    "operationId": "patch_agent_v1_agents__agent_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AgentPatch"
       }
      }
     },
     "description": "Fields to change; the omitted ones are kept.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Agent V1 Agents  Agent Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update an agent",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/agents/{agent_id}/kill": {
   "post": {
    "description": "Kill switch: every active run of the agent is cancelled with the error `killed` and the agent status becomes `killed` for good (it can never be resumed). Needs `tenant_admin` or `security_officer`. 409 `agent_killed` if already killed. The answer lists `affected_runs`. Audited as `agent.kill`.",
    "operationId": "kill_agent_v1_agents__agent_id__kill_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/eai__domains__agents__routes__StatusIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason, kept on the agent and in the audit trail."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Kill Agent V1 Agents  Agent Id  Kill Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Kill an agent",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/agents/{agent_id}/resume": {
   "post": {
    "description": "Opens a promotion approval to bring a suspended agent back to `active` and answers 202 with `approval_id` and `status: pending_approval`; approvers are `tenant_admin` or `security_officer`. Once approved, the runs suspended by the agent suspension resume. Needs `tenant_admin` or `security_officer`. Refused with 409 `agent_killed`, or 409 `kill_switch_active` while a SOC containment holds the agent (lifted only through `POST /v1/soc/recoveries`).",
    "operationId": "resume_agent_v1_agents__agent_id__resume_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/eai__domains__agents__routes__StatusIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason, shown to the approvers."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Resume Agent V1 Agents  Agent Id  Resume Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request the resumption of an agent",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/agents/{agent_id}/runs": {
   "post": {
    "description": "Creates a run and returns its Execution Contract (201). Needs `tenant_admin`, `developer` or `agent`, the scope `agents:run` and the ReBAC relation `can_invoke`.\nSteps:\n1. The agent must be `active` (else 409 `agent_not_active`, audited as a denial).\n2. The policy `agent.run` is evaluated with the agent risk, owner, purpose and the `data_classification` of the task (403 `policy_denied`).\n3. The budget is the manifest budget, tightened by `budgets` (a request can never loosen it; 422 `invalid_budget`).\n4. The delegation and workload identity are attached, the run is created in `pending` (or `running` with `start=true`) and audited as `run.create`.\nA repeated `Idempotency-Key` returns the first run; the same key for another agent answers 409 `idempotency_conflict`. An unknown `session_id` answers 404 `session_not_found`.",
    "operationId": "create_run_v1_agents__agent_id__runs_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     },
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__agents__routes__RunIn"
       }
      }
     },
     "description": "Task of the run, optional session, budget, retry policy and delegation.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Run V1 Agents  Agent Id  Runs Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start a run of an agent",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/agents/{agent_id}/suspend": {
   "post": {
    "description": "Kill switch, reversible: the agent status becomes `suspended`, its active runs move to `suspended` and new runs are refused. Needs `tenant_admin` or `security_officer`. 409 `agent_killed` for a killed agent. The answer lists `affected_runs`. Audited as `agent.suspend`.",
    "operationId": "suspend_agent_v1_agents__agent_id__suspend_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/eai__domains__agents__routes__StatusIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason, kept on the agent and in the audit trail."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Suspend Agent V1 Agents  Agent Id  Suspend Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Suspend an agent",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/agents/{agent_id}/versions": {
   "get": {
    "description": "Every registered version of the agent, newest first, with its manifest, digest, author and `current` (true for the version in use). Needs the ReBAC relation `viewer`. One page only.",
    "operationId": "agent_versions_v1_agents__agent_id__versions_get",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Agent Versions V1 Agents  Agent Id  Versions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the versions of an agent",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/api-keys": {
   "get": {
    "description": "Lists the API keys of the tenant, paginated by `limit` and `cursor`, ordered by identifier. Each item gives the name, the public prefix, roles, scopes, clearance, project, environment, creator, expiry and revocation state; never the secret nor its hash. `tenant_admin` and `security_officer` see every key, a `developer` only the keys they created.",
    "operationId": "list_api_keys_v1_api_keys_get",
    "parameters": [
     {
      "description": "Maximum number of API keys in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Api Keys V1 Api Keys Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the API keys",
    "tags": [
     "identity"
    ]
   },
   "post": {
    "description": "Creates an API key for scripts and services. Needs `tenant_admin` or `developer`. The answer (201) carries the full secret in `key`, shown only once: store it in a secret store right away.\n\nRules:\n\n1. the roles granted must be held by the caller, unless the caller is `tenant_admin`; `platform_admin` needs a platform administrator (403 `forbidden`);\n2. every scope must be held by the caller (403 `forbidden`, reason `scope_not_held`);\n3. `expires_in_days` sets `expires_at` when the latter is not given; without either the key never expires.\n\nSend the key as `X-API-Key: <key>` or `Authorization: Bearer <key>`. Writes the audit event `api_key.create` (name, prefix, scopes, roles; never the secret).",
    "operationId": "create_api_key_v1_api_keys_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ApiKeyIn"
       }
      }
     },
     "description": "Name, rights, binding and expiry of the new key.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Api Key V1 Api Keys Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an API key",
    "tags": [
     "identity"
    ]
   }
  },
  "/v1/api-keys/{key_id}": {
   "delete": {
    "description": "Revokes the key at once: every later request made with it answers 401 `api_key_revoked`. Revoking a key already revoked succeeds without change. Allowed to `tenant_admin`, `security_officer` and `developer`; a developer only revokes the keys they created, any other key answers 404 `not_found`. Writes the audit event `api_key.revoke`. Answers 204 without body.",
    "operationId": "revoke_api_key_v1_api_keys__key_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the API key.",
      "in": "path",
      "name": "key_id",
      "required": true,
      "schema": {
       "title": "Key Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke an API key",
    "tags": [
     "identity"
    ]
   }
  },
  "/v1/api-keys/{key_id}/rotate": {
   "post": {
    "description": "Issues a replacement key with the same name, roles, scopes, clearance, project and environment, and retires the old one. The new secret is in `key` of the 201 answer, shown once.\n\n1. Without `grace_seconds` (or with 0) the old key is revoked at once.\n2. With `grace_seconds` the old key keeps working until that delay ends (at most 7 days), so clients can switch without downtime.\n\nWho may rotate: `tenant_admin` and platform administrators any key of the tenant; `security_officer` any key without an administrator role; a `developer` only their own keys, within their own roles and scopes. A key holding `platform_admin` needs a platform administrator. A revoked key answers 409 `api_key_revoked`; an unknown key, or another developer's key, answers 404. Writes the audit event `api_key.rotate`.",
    "operationId": "rotate_api_key_v1_api_keys__key_id__rotate_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the API key.",
      "in": "path",
      "name": "key_id",
      "required": true,
      "schema": {
       "title": "Key Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/RotateIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional grace period of the old key. An empty body revokes the old key at once."
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rotate Api Key V1 Api Keys  Key Id  Rotate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Rotate an API key",
    "tags": [
     "identity"
    ]
   }
  },
  "/v1/applications": {
   "get": {
    "description": "Applications of the tenant in name order, with kind, origin, status, environments and granted resources. One page only.",
    "operationId": "list_applications_v1_applications_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Applications V1 Applications Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the applications",
    "tags": [
     "applications"
    ]
   },
   "post": {
    "description": "Creates the application (201). An `external_agent` is always of origin `third_party`. Owner defaults to the caller, project to the `X-Project` header. A name already used answers 409 `conflict`. Needs `tenant_admin`, `developer` or `application_owner`. Audited as `application.create`.",
    "operationId": "create_application_v1_applications_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ApplicationIn"
       }
      }
     },
     "description": "Name, kind, origin, owner, project, environments, risk level and granted resources.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Application V1 Applications Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register an application",
    "tags": [
     "applications"
    ]
   }
  },
  "/v1/applications/{app_id}": {
   "get": {
    "description": "Returns the application and its deployments, oldest first. 404 `application_not_found`.",
    "operationId": "get_application_v1_applications__app_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the application.",
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Application V1 Applications  App Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an application",
    "tags": [
     "applications"
    ]
   }
  },
  "/v1/applications/{app_id}/deployments": {
   "post": {
    "description": "Records a deployment of a version in one environment of the application and opens an `application_deployment` approval for `tenant_admin` or `security_officer` (201, the deployment carries `approval_id`). The environment must be declared by the application (400 `invalid_request`); the same version in the same environment answers 409 `conflict`; a suspended or retired application answers 409 `application_suspended`. Needs `tenant_admin`, `developer` or `application_owner`. Audited as `application.deployment.create`.",
    "operationId": "create_deployment_v1_applications__app_id__deployments_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the application.",
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeploymentIn"
       }
      }
     },
     "description": "Version, environment and reason shown to the approvers.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Deployment V1 Applications  App Id  Deployments Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request a deployment",
    "tags": [
     "applications"
    ]
   }
  },
  "/v1/applications/{app_id}/deployments/{deployment_id}/activate": {
   "post": {
    "description": "Activates the deployment once its approval is approved (separation of duties is enforced by the approvals domain; a missing approval is audited as a denial): the previous active deployment of the environment is retired and the application becomes `active`. 409 `application_suspended`; 404 `application_deployment_not_found`. Needs `tenant_admin`, `developer` or `application_owner`. Audited as `application.deployment.activate` with the approver.",
    "operationId": "activate_deployment_v1_applications__app_id__deployments__deployment_id__activate_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the application.",
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the deployment.",
      "in": "path",
      "name": "deployment_id",
      "required": true,
      "schema": {
       "title": "Deployment Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Activate Deployment V1 Applications  App Id  Deployments  Deployment Id  Activate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Activate an approved deployment",
    "tags": [
     "applications"
    ]
   }
  },
  "/v1/applications/{app_id}/external-agents": {
   "post": {
    "description": "Creates an API key with the role `agent`, bound to the application and its project, with the scopes `tools:invoke`, `models:invoke` plus the requested ones (201). The key is in `api_key` and is shown only once. Needs `tenant_admin`. Audited as `application.external_agent.register`.",
    "operationId": "register_external_agent_v1_applications__app_id__external_agents_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the application.",
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ExternalAgentIn"
       }
      }
     },
     "description": "Name of the identity and extra scopes.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Register External Agent V1 Applications  App Id  External Agents Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register a third party agent identity",
    "tags": [
     "applications"
    ]
   }
  },
  "/v1/applications/{app_id}/status": {
   "post": {
    "description": "Sets the application to `suspended` or `retired` and its active deployments too; every gateway call of its external agents is refused from then on. Needs `tenant_admin` or `security_officer`. Audited as `application.suspended` or `application.retired`.",
    "operationId": "application_status_v1_applications__app_id__status_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the application.",
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__applications__routes__StatusIn"
       }
      }
     },
     "description": "Target status and reason.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Application Status V1 Applications  App Id  Status Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Suspend or retire an application",
    "tags": [
     "applications"
    ]
   }
  },
  "/v1/approvals": {
   "get": {
    "description": "Lists the approval requests of the tenant, newest first, paginated, optionally filtered by status. Pending requests past their expiry are marked `expired` first. Each item carries its `decisions` and `approvals_count`. Open to any member of the tenant.",
    "operationId": "list_approvals_v1_approvals_get",
    "parameters": [
     {
      "description": "Only the requests in this status: `pending`, `approved`, `rejected`, `expired` or `cancelled`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Maximum number of requests in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Approvals V1 Approvals Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the approval requests",
    "tags": [
     "approvals"
    ]
   },
   "post": {
    "description": "Creates a pending approval request. Needs `tenant_admin`, `developer`, `agent`, `security_officer` or `finops`.\n\n- `run_id`, when given, must be a run of the tenant (404 otherwise); the run is resumed or failed when the request is decided.\n- The caller, and the person an agent acts on behalf of, are added to `payload.excluded_approvers`, with any subject already listed there.\n- Without `approver_roles`, approvers are `tenant_admin`, `security_officer`, `developer` and `business_owner`.\n- Without `expires_in_seconds`, the request expires after the platform default (24 hours).\n\nWith an `Idempotency-Key` already used, the existing request is returned unchanged. Writes the audit event `approval.request`. Answers 201 with the request.",
    "operationId": "create_approval_v1_approvals_post",
    "parameters": [
     {
      "description": "Client key of the request: the same key returns the request already created instead of a second one.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ApprovalIn"
       }
      }
     },
     "description": "Action, resource, quorum, approvers and expiry of the request.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Approval V1 Approvals Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request an approval",
    "tags": [
     "approvals"
    ]
   }
  },
  "/v1/approvals/{approval_id}": {
   "get": {
    "description": "Returns one approval request with its decisions (approver, decision, comment, date) and `approvals_count`. A pending request past its expiry is marked `expired` and its waiting run is failed. Open to any member of the tenant. Answers 404 `approval_not_found`.",
    "operationId": "get_approval_v1_approvals__approval_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the approval request.",
      "in": "path",
      "name": "approval_id",
      "required": true,
      "schema": {
       "title": "Approval Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Approval V1 Approvals  Approval Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an approval request",
    "tags": [
     "approvals"
    ]
   }
  },
  "/v1/approvals/{approval_id}/cancel": {
   "post": {
    "description": "Withdraws a pending request. Allowed to its requester, a `tenant_admin` or a `security_officer` (403 `forbidden` otherwise, the refusal being audited). The request ends `cancelled` and its subject reacts as to a refusal: a waiting run fails (`approval_cancelled`), a pending break glass grant or mandate is rejected. A request that is no longer pending answers 409 `approval_closed`. Writes the audit event `approval.cancel` with the reason. The answer carries `run_state` when a run is attached.",
    "operationId": "cancel_v1_approvals__approval_id__cancel_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the approval request.",
      "in": "path",
      "name": "approval_id",
      "required": true,
      "schema": {
       "title": "Approval Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__approvals__routes__CancelIn"
       }
      }
     },
     "description": "Reason of the cancellation.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Cancel V1 Approvals  Approval Id  Cancel Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Cancel an approval request",
    "tags": [
     "approvals"
    ]
   }
  },
  "/v1/approvals/{approval_id}/decide": {
   "post": {
    "description": "Records the decision of the caller on a pending request.\n\n1. The request must be pending (409 `approval_closed`, also when it has just expired).\n2. The caller must not be the requester nor an excluded approver (403 `separation_of_duties`, audited).\n3. The caller must hold one of `approver_roles` (403 `forbidden`) and not have decided already (409 `already_decided`).\n4. `reject` ends the request `rejected`; `approve` ends it `approved` once the approvals reach the quorum, otherwise it stays pending.\n\nOnce decided, the subject reacts: the attached run resumes or fails, an approved `promotion` is applied, a `break_glass` or `mandate` request is activated or refused. Writes the audit event `approval.decide`. The answer carries `run_state` when a run is attached.",
    "operationId": "decide_v1_approvals__approval_id__decide_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the approval request.",
      "in": "path",
      "name": "approval_id",
      "required": true,
      "schema": {
       "title": "Approval Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DecisionIn"
       }
      }
     },
     "description": "Decision and optional comment.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Decide V1 Approvals  Approval Id  Decide Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Approve or reject a request",
    "tags": [
     "approvals"
    ]
   }
  },
  "/v1/audit/correlations": {
   "get": {
    "description": "With `trace_id`, `run_id` or `session_id` (the first given wins), returns everything that shares that key: `audit_events`, LLM `usage_events`, `runs`, telemetry `spans`, `multimodal_jobs` (up to 1000 of each, 200 for runs and jobs), the `trace_ids` met and `counts`.\n\nWithout any key, returns `groups`: the most recent keys (trace, run, session) with their number of events, first and last date and actions, at most `limit`. Needs `auditor`, `security_officer` or `tenant_admin`.",
    "operationId": "correlations_v1_audit_correlations_get",
    "parameters": [
     {
      "description": "W3C trace id (32 hexadecimal characters) to correlate.",
      "in": "query",
      "name": "trace_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Trace Id"
      }
     },
     {
      "description": "Agent run identifier to correlate.",
      "in": "query",
      "name": "run_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Run Id"
      }
     },
     {
      "description": "Session identifier to correlate.",
      "in": "query",
      "name": "session_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Session Id"
      }
     },
     {
      "description": "Maximum number of groups when no key is given (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Correlations V1 Audit Correlations Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Correlate events by trace, run or session",
    "tags": [
     "audit"
    ]
   }
  },
  "/v1/audit/events": {
   "get": {
    "description": "Searches the audit events of the tenant, newest first (highest sequence first), paginated. All filters combine. Needs `auditor`, `security_officer` or `tenant_admin`. The search itself is recorded in the evidence access log (who, which query, how many results).",
    "operationId": "list_events_v1_audit_events_get",
    "parameters": [
     {
      "description": "Only the events of this actor id, for example a user subject or `apikey:<id>`.",
      "in": "query",
      "name": "actor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Actor"
      }
     },
     {
      "description": "Only this action, for example `api_key.create`. A final `*` matches a prefix: `approval.*`.",
      "in": "query",
      "name": "action",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Action"
      }
     },
     {
      "description": "Only this resource: `<type>` or `<type>:<id>`, for example `project:42`.",
      "in": "query",
      "name": "resource",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Resource"
      }
     },
     {
      "description": "Only this outcome: `success`, `failure` or `error`.",
      "in": "query",
      "name": "outcome",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Outcome"
      }
     },
     {
      "description": "Only the events of this W3C trace id.",
      "in": "query",
      "name": "trace_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Trace Id"
      }
     },
     {
      "description": "Events at or after this date and time (ISO 8601).",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "description": "Events at or before this date and time (ISO 8601).",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     },
     {
      "description": "Maximum number of events in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Events V1 Audit Events Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Search the audit events",
    "tags": [
     "audit"
    ]
   },
   "post": {
    "description": "Appends an application event to the tenant hash chain. The actor comes from the authentication; the sequence, the hashes and `occurred_at` from the server; the client `details` are kept under `evidence.details.attributes`, next to `stream: sdk`. The event is sealed and exported to the outbox and the SIEM like the platform events.\n\n1. Needs `tenant_admin`, `developer`, `agent`, `security_officer`, `application_owner` or `ai_platform_engineer`.\n2. `details` must stay under 16384 bytes once serialized (422 `audit_event_too_large`).\n3. The policy decides on `audit.record` first.\n4. `event_time` may not be more than the allowed clock skew ahead of the server (422 `audit_event_time_invalid`).\n\nThe answer (201) gives `event_id`, `sequence`, `hash`, `prev_hash`, `occurred_at`, `event_time`, `action`, `stream`, `actor` and `decision`.",
    "operationId": "record_event_v1_audit_events_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AppEventIn"
       }
      }
     },
     "description": "The application event. Fields other than those of the schema are refused.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Record Event V1 Audit Events Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Record an application audit event",
    "tags": [
     "audit"
    ]
   }
  },
  "/v1/audit/events/{event_id}": {
   "get": {
    "description": "Returns one audit event with its sequence, hashes, actor, resource, decision and evidence. Needs `auditor`, `security_officer` or `tenant_admin`. The read is recorded in the evidence access log. Answers 404 `not_found`.",
    "operationId": "get_event_v1_audit_events__event_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the audit event.",
      "in": "path",
      "name": "event_id",
      "required": true,
      "schema": {
       "title": "Event Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Event V1 Audit Events  Event Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an audit event",
    "tags": [
     "audit"
    ]
   }
  },
  "/v1/audit/export": {
   "post": {
    "description": "Writes the events of the period (bounds included) to write once storage, as NDJSON or CSV, with a manifest. Needs `auditor`, `security_officer` or `tenant_admin`.\n\n1. The events are read in sequence order and the chain is verified.\n2. The file is hashed (SHA-256) and the hash signed (OpenBao Transit, or HMAC outside production).\n3. File and manifest are stored with object lock for `retention_days`; with a storage profile of the tenant that verified object lock and retention, the export is `qualified` (409 `storage_capability_missing` when the profile lacks them).\n\nThe answer (201) is the manifest: `export_id`, `file`, `manifest_uri`, `format`, `count`, first and last sequence, `sha256`, `signature`, `chain`, period and `worm`. Writes the audit event `audit.export`.",
    "operationId": "export_v1_audit_export_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/ExportIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Period, retention and format of the export. An empty body exports everything as NDJSON kept 365 days."
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Export V1 Audit Export Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Export the audit trail",
    "tags": [
     "audit"
    ]
   }
  },
  "/v1/audit/verify": {
   "get": {
    "description": "Recomputes the hash chain of the tenant from the first event and returns `tenant_id`, `valid`, `count`, `last_hash`, `broken_at`, `reason` and `verified_at`. When the chain is broken, `broken_at` is the sequence of the first faulty event and `reason` says why: `sequence gap`, `prev_hash mismatch` or `hash mismatch`. Needs `auditor`, `security_officer` or `tenant_admin`. The verification is recorded in the evidence access log.",
    "operationId": "verify_v1_audit_verify_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Verify V1 Audit Verify Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Verify the audit chain",
    "tags": [
     "audit"
    ]
   }
  },
  "/v1/auth/login": {
   "post": {
    "description": "Opens a portal session for a local account. No credential is needed. The login is compared without case.\n\nAnswer 200: `token` (shown once), `token_type` (`Bearer`), `expires_at`, `must_change_password` and `user` (username, tenant, roles).\n\nErrors: 401 `invalid_credentials` for an unknown login or a wrong password (same answer and same cost, so the answer tells nothing about the login); 429 `account_locked` with `Retry-After` after too many wrong passwords; 401 `account_disabled`; 403 `tenant_suspended`; 403 `local_auth_disabled`; 429 `rate_limited` when the client IP exceeded its authentication failure budget. Every attempt writes the audit event `auth.login`.",
    "operationId": "login_v1_auth_login_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LoginIn"
       }
      }
     },
     "description": "Login and password of the local account.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Login V1 Auth Login Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Sign in with a login and a password",
    "tags": [
     "auth"
    ]
   }
  },
  "/v1/auth/logout": {
   "post": {
    "description": "Revokes the current portal session: its token is refused from now on (401 `session_revoked`). Only for a portal session (403 `password_session_required` with another credential). Writes the audit event `auth.logout`. Answers 204.",
    "operationId": "logout_v1_auth_logout_post",
    "responses": {
     "204": {
      "description": "Successful Response"
     }
    },
    "summary": "Sign out",
    "tags": [
     "auth"
    ]
   }
  },
  "/v1/auth/password": {
   "post": {
    "description": "Changes the password of the signed in local account. Only for a portal session (403 `password_session_required`).\n\n1. `current_password` must be right (403 `invalid_current_password`).\n2. `new_password` must pass the rules (422 `password_too_weak`, `details` lists the reasons): at least the configured length (12 by default), at most 256 characters, letters and non letters, not the login, not the current password, not a known or initial password.\n3. The other sessions of the account are revoked; the current one stays open and leaves the `must_change_password` restriction.\n\nWrites the audit event `auth.password.change`.",
    "operationId": "change_password_v1_auth_password_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PasswordIn"
       }
      }
     },
     "description": "Current and new password.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Change Password V1 Auth Password Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change the password",
    "tags": [
     "auth"
    ]
   }
  },
  "/v1/authz/check": {
   "post": {
    "description": "Tells whether `subject` holds `relation` on `object`, following inheritance. Up to 20 `contextual_tuples` are taken as true for this check only and never stored (an invalid one answers 422 `validation_error`). Open to any member of the tenant. The answer gives `allowed`, `engine`, `subject`, `relation` and `object`. Writes the audit event `authz.check` with the decision. When the engine cannot answer, the decision is a refusal, it is audited and the API answers 502 `authz_backend_error`.",
    "operationId": "check_v1_authz_check_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CheckIn"
       }
      }
     },
     "description": "Subject, relation, object and optional contextual tuples.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Check V1 Authz Check Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Check a relation",
    "tags": [
     "authz"
    ]
   }
  },
  "/v1/authz/tuples": {
   "delete": {
    "description": "Deletes one tuple (`{subject, relation, object}`) or up to 100 (`{\"tuples\": [...]}`). Needs `tenant_admin` or `security_officer`. Tuples that do not exist are ignored; the answer gives `deleted` (number removed) and `engine`. Writes the audit event `authz.delete`. 502 `authz_backend_error` when the engine cannot answer.",
    "operationId": "delete_tuples_v1_authz_tuples_delete",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Payload",
        "type": "object"
       }
      }
     },
     "description": "One tuple, or an object `tuples` with 1 to 100 tuples.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Tuples V1 Authz Tuples Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete authorization tuples",
    "tags": [
     "authz"
    ]
   },
   "get": {
    "description": "Lists the stored tuples of the tenant, ordered by object, relation and subject, at most 1000, optionally filtered by object and subject (exact match). Open to any member of the tenant. `next_cursor` is always null.",
    "operationId": "list_tuples_v1_authz_tuples_get",
    "parameters": [
     {
      "description": "Only the tuples on this object, `<type>:<id>` such as `project:42`.",
      "in": "query",
      "name": "object",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Object"
      }
     },
     {
      "description": "Only the tuples of this subject, such as `user:alice` or `group:fin#member`.",
      "in": "query",
      "name": "subject",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Subject"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Tuples V1 Authz Tuples Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List authorization tuples",
    "tags": [
     "authz"
    ]
   },
   "post": {
    "description": "Grants one tuple (`{subject, relation, object}`) or up to 100 (`{\"tuples\": [...]}`) in one transaction. Needs `tenant_admin` or `security_officer`. A wildcard subject (`user:*`) on a relation reserved to named subjects, such as `can_assume`, answers 422 `authz_wildcard_not_allowed`. The answer (201) gives `written` and `engine`. Writes the audit event `authz.write`. 502 `authz_backend_error` when the engine cannot answer.",
    "operationId": "write_tuples_v1_authz_tuples_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Payload",
        "type": "object"
       }
      }
     },
     "description": "One tuple, or an object `tuples` with 1 to 100 tuples.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Write Tuples V1 Authz Tuples Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Write authorization tuples",
    "tags": [
     "authz"
    ]
   }
  },
  "/v1/break-glass": {
   "get": {
    "description": "Lists break glass grants, newest first: all of them for `tenant_admin`, `security_officer` and `auditor`, otherwise those the caller requested or benefits from. Active grants past their expiry are marked `expired` (audited once). An unknown status answers 400.",
    "operationId": "list_break_glass_v1_break_glass_get",
    "parameters": [
     {
      "description": "Only `pending`, `active`, `expired`, `rejected` or `revoked` grants.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Maximum number of grants (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Break Glass V1 Break Glass Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the break glass grants",
    "tags": [
     "delegation"
    ]
   },
   "post": {
    "description": "Requests an exceptional, time bound elevation for the beneficiary (the caller by default). Open to any member of the tenant.\n\n1. Give tenant roles (never `platform_admin`) and/or scopes, a justification of at least 10 characters and a duration between 60 seconds and the platform maximum (3600 by default, 400 `break_glass_duration_exceeded`).\n2. An approval request is created (action `break_glass`, quorum 2, approvers `tenant_admin` or `security_officer`, requester and beneficiary excluded).\n3. Once approved, the grant is active for `duration_seconds` and expires on its own; delegations created by the beneficiary may use its scopes and never outlive it.\n\nWrites the audit events `break_glass.request`, then `break_glass.activate` or `break_glass.reject`. Answers 201 with the pending grant and its `approval_id`.",
    "operationId": "request_break_glass_v1_break_glass_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/BreakGlassIn"
       }
      }
     },
     "description": "Roles, scopes, reason, duration, beneficiary and incident reference.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Request Break Glass V1 Break Glass Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request a break glass elevation",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/break-glass/{grant_id}": {
   "get": {
    "description": "Returns one grant: requester, beneficiary, roles, scopes, reason, incident, duration, status, approval and dates. Visible to its requester and beneficiary and to `tenant_admin`, `security_officer` and `auditor`; anyone else gets 404 `break_glass_not_found`.",
    "operationId": "get_break_glass_v1_break_glass__grant_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the break glass grant.",
      "in": "path",
      "name": "grant_id",
      "required": true,
      "schema": {
       "title": "Grant Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Break Glass V1 Break Glass  Grant Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a break glass grant",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/break-glass/{grant_id}/context": {
   "post": {
    "description": "Returns a signed ExecutionContext carrying the active elevation, whose lifetime never exceeds the grant expiry. Only the beneficiary may ask (403 `forbidden`); the grant must be active (409 `break_glass_not_active`); each audience must be known (400 `context_wrong_audience`). Downstream services verify it like any execution context.",
    "operationId": "break_glass_context_v1_break_glass__grant_id__context_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the break glass grant.",
      "in": "path",
      "name": "grant_id",
      "required": true,
      "schema": {
       "title": "Grant Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/BreakGlassContextIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional audiences and lifetime of the context."
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Break Glass Context V1 Break Glass  Grant Id  Context Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an execution context for a break glass grant",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/break-glass/{grant_id}/revoke": {
   "post": {
    "description": "Ends a pending or active grant and revokes the delegations created under it. Allowed to the requester, a `tenant_admin` or a `security_officer` (403 `forbidden`). A grant already closed answers 409 `break_glass_closed`. Writes the audit event `break_glass.revoke`.",
    "operationId": "revoke_break_glass_v1_break_glass__grant_id__revoke_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the break glass grant.",
      "in": "path",
      "name": "grant_id",
      "required": true,
      "schema": {
       "title": "Grant Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/RevokeIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Revoke Break Glass V1 Break Glass  Grant Id  Revoke Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke a break glass grant",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/business-units": {
   "get": {
    "description": "Lists the business units of the tenant, paginated, optionally filtered by organization or by parent unit. Open to any member of the tenant.",
    "operationId": "list_business_units_v1_business_units_get",
    "parameters": [
     {
      "description": "Only the units of this organization.",
      "in": "query",
      "name": "organization_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Organization Id"
      }
     },
     {
      "description": "Only the direct children of this business unit.",
      "in": "query",
      "name": "parent_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Parent Id"
      }
     },
     {
      "description": "Maximum number of business units in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Business Units V1 Business Units Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the business units",
    "tags": [
     "tenancy"
    ]
   },
   "post": {
    "description": "Creates a business unit in an organization, optionally under a parent unit of the same organization (422 `invalid_hierarchy` otherwise). Needs `tenant_admin`. A slug already used answers 409 `conflict`. Writes the audit event `business_unit.create`.",
    "operationId": "create_business_unit_v1_business_units_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/BusinessUnitIn"
       }
      }
     },
     "description": "Organization, parent, slug, name and description of the unit.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Business Unit V1 Business Units Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a business unit",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/business-units/{business_unit_id}": {
   "patch": {
    "description": "Changes the name, description, status (`active` or `archived`) or metadata of a business unit. Its organization and parent cannot change. Needs `tenant_admin`. Send `expected_version` to detect a concurrent change (409 `version_conflict`). Writes the audit event `business_unit.update`.",
    "operationId": "patch_business_unit_v1_business_units__business_unit_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the business unit.",
      "in": "path",
      "name": "business_unit_id",
      "required": true,
      "schema": {
       "title": "Business Unit Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/BusinessUnitPatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Business Unit V1 Business Units  Business Unit Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a business unit",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/catalog/bricks": {
   "get": {
    "description": "Catalog of the platform bricks read from `bricks.yaml` of the catalog folder, in one page (`next_cursor` is always null). The file is loaded as safe YAML (no anchors or aliases, 2 MB at most). No authentication required.",
    "operationId": "list_bricks_v1_catalog_bricks_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Bricks V1 Catalog Bricks Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the platform bricks",
    "tags": [
     "system"
    ]
   }
  },
  "/v1/catalog/bricks/{brick_id}": {
   "get": {
    "description": "One brick of the catalog, matched on its `id` without regard to case. Answers 404 `not_found` when no brick has this id. No authentication required.",
    "operationId": "get_brick_v1_catalog_bricks__brick_id__get",
    "parameters": [
     {
      "description": "Identifier of the brick in the catalog, case insensitive.",
      "in": "path",
      "name": "brick_id",
      "required": true,
      "schema": {
       "title": "Brick Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Brick V1 Catalog Bricks  Brick Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get one platform brick",
    "tags": [
     "system"
    ]
   }
  },
  "/v1/channels": {
   "get": {
    "description": "Channels of the tenant in name order; `project` (id or slug) keeps the channels of that project only (404 `project_not_found`). One page only.",
    "operationId": "list_channels_v1_channels_get",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project whose channels are listed.",
      "in": "query",
      "name": "project",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Channels V1 Channels Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the channels",
    "tags": [
     "channels"
    ]
   },
   "post": {
    "description": "Applies a Channel manifest (`apply_status`: `created` or `updated`); `project` (id or slug, default the `X-Project` header) attaches it to a project, and a channel of another project is never taken over (409 `channel_project_conflict`). The `agent_ref` agent must exist (404 `agent_not_found`); `signed_webhook` needs `auth.secret_ref` (422 `invalid_manifest`). Needs `tenant_admin`, `developer` or `application_owner`. Audited as `channel.apply`.",
    "operationId": "create_channel_v1_channels_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project the channel belongs to. Default: the `X-Project` header.",
      "in": "query",
      "name": "project",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Manifest",
        "type": "object"
       }
      }
     },
     "description": "Channel manifest (`kind: Channel`, `metadata`, `spec` with type, agent, auth, limits, DLP and sessions).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Channel V1 Channels Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create or update a channel",
    "tags": [
     "channels"
    ]
   }
  },
  "/v1/channels/{name}": {
   "delete": {
    "description": "Deletes the channel. Needs `tenant_admin`. 404 `channel_not_found`. Audited as `channel.delete`.",
    "operationId": "delete_channel_v1_channels__name__delete",
    "parameters": [
     {
      "description": "Name of the channel.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a channel",
    "tags": [
     "channels"
    ]
   },
   "get": {
    "description": "Returns the channel with its manifest, type, agent, status, project and preset. 404 `channel_not_found`.",
    "operationId": "get_channel_v1_channels__name__get",
    "parameters": [
     {
      "description": "Name of the channel.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Channel V1 Channels  Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a channel",
    "tags": [
     "channels"
    ]
   },
   "patch": {
    "description": "Changes the status (`active` or `disabled`; a disabled channel refuses inbound messages) or the owner. Needs `tenant_admin`, `developer` or `application_owner`. Audited as `channel.update`.",
    "operationId": "patch_channel_v1_channels__name__patch",
    "parameters": [
     {
      "description": "Name of the channel.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ChannelPatch"
       }
      }
     },
     "description": "Fields to change; the omitted ones are kept.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Channel V1 Channels  Name  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a channel",
    "tags": [
     "channels"
    ]
   }
  },
  "/v1/channels/{name}/inbound": {
   "post": {
    "description": "Delivers a message from an end user (202) and returns `session_id`, `session_created`, `message_id`, `run_id` (or `run_skipped` when the agent is not active) and the DLP result. Needs `tenant_admin`, `developer` or `agent`.\nSteps:\n1. The channel must be active (409 `channel_disabled`); a `signed_webhook` channel checks `X-EAI-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.\" + raw body>`, 5 minute window; 401 `invalid_signature`).\n2. The policy `channel.inbound` is evaluated; size (413 `message_too_large`) and rate per user (429 `rate_limited`) are checked.\n3. Inbound DLP runs (default `detect`; `block` answers 403 `dlp_blocked`, `mask` stores the masked text).\n4. The open session of the user and conversation is reused, or a new one opened (429 `too_many_sessions`, 409 `session_closed` past `max_session_minutes`).\n5. The message is added and a run of the channel agent starts with trigger `channel`.",
    "operationId": "inbound_v1_channels__name__inbound_post",
    "parameters": [
     {
      "description": "Name of the channel.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "properties": {
         "conversation_id": {
          "anyOf": [
           {
            "maxLength": 300,
            "type": "string"
           },
           {
            "type": "null"
           }
          ],
          "title": "Conversation Id"
         },
         "metadata": {
          "additionalProperties": true,
          "title": "Metadata",
          "type": "object"
         },
         "text": {
          "maxLength": 1000000,
          "minLength": 1,
          "title": "Text",
          "type": "string"
         },
         "user": {
          "anyOf": [
           {
            "maxLength": 300,
            "type": "string"
           },
           {
            "type": "null"
           }
          ],
          "title": "User"
         }
        },
        "required": [
         "text"
        ],
        "title": "InboundIn",
        "type": "object"
       }
      }
     },
     "description": "JSON message: `text` (1 to 1000000 characters, required), `user` (external user id, up to 300 characters; default the caller), `conversation_id` (up to 300 characters; default the user) and `metadata` (kept with the message). The raw bytes are used for the signature check.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Inbound V1 Channels  Name  Inbound Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Post an inbound message",
    "tags": [
     "channels"
    ]
   }
  },
  "/v1/channels/{name}/sessions": {
   "get": {
    "description": "Sessions opened on the channel, most recently updated first, at most 500.",
    "operationId": "channel_sessions_v1_channels__name__sessions_get",
    "parameters": [
     {
      "description": "Name of the channel.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Channel Sessions V1 Channels  Name  Sessions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the sessions of a channel",
    "tags": [
     "channels"
    ]
   }
  },
  "/v1/checkpoints/{checkpoint_id}": {
   "get": {
    "description": "Returns one checkpoint: run, sequence number, step sequence at save time, label and saved state. 404 `checkpoint_not_found`.",
    "operationId": "get_checkpoint_v1_checkpoints__checkpoint_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the checkpoint.",
      "in": "path",
      "name": "checkpoint_id",
      "required": true,
      "schema": {
       "title": "Checkpoint Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Checkpoint V1 Checkpoints  Checkpoint Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a checkpoint",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/compliance/instances": {
   "get": {
    "description": "Activation records of the tenant, newest first, with status, sector, pack, deployment model, versions and owned resources (one page, `next_cursor` null). Filters: `status`, `project`, `sector`.",
    "operationId": "list_instances_v1_compliance_instances_get",
    "parameters": [
     {
      "description": "Only the instances in this status (draft, ready, failed, ...).",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 20,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only the instances of this project (identifier).",
      "in": "query",
      "name": "project",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 100,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project"
      }
     },
     {
      "description": "Only the instances of this sector (generic, banking, insurance, industry).",
      "in": "query",
      "name": "sector",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 20,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Sector"
      }
     },
     {
      "description": "Maximum number of instances returned (1 to 200, default 50).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "maximum": 200,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Instances V1 Compliance Instances Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the Compliance & Audit Agent instances",
    "tags": [
     "compliance"
    ]
   },
   "post": {
    "description": "Creates the activation record in `draft` (201) with its immutable `id` (given, for example the id chosen by the compliance runtime, or generated), its sector and its pack. Needs a tenant administrator or an owner of the project (403 `forbidden`); unknown project: 404 `compliance_project_not_found`; a name or an id already used: 409 `conflict`. With `Idempotency-Key` a retry replays the first answer. Audited as `compliance.create`.",
    "operationId": "create_instance_v1_compliance_instances_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ComplianceInstanceIn"
       }
      }
     },
     "description": "Name, project, organization and business unit, sector and pack, deployment model, generation and embedding models of the registry, optional version.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Instance V1 Compliance Instances Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a draft Compliance & Audit Agent instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}": {
   "delete": {
    "description": "Long operation (202, status `deleting` then `deleted`) from `draft`, `stopped` or `failed` (a ready instance is stopped first, else 409). Removes only what the instance owns, as recorded in `resources`: its knowledge base and its Qdrant points, the objects under its storage prefix, its agent memories and memory policy, its tuples, API key and secret, its agent; the governed application is retired. The shared runtime, a shared database, the Qdrant collection shared by the tenant knowledge bases and the storage profile are kept. Each step lists `deleted` and `kept`. Audited as `compliance.delete` and `compliance.delete.completed`.",
    "operationId": "delete_instance_v1_compliance_instances__instance_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Instance V1 Compliance Instances  Instance Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an instance",
    "tags": [
     "compliance"
    ]
   },
   "get": {
    "description": "The activation record with `serving` (true for `ready` and `degraded`), `sector`, `pack`, the current `operation` and `run`, `validation`, `last_error` and the `steps` of the current run in order (state, attempts, detail, logs, times). This is the route the compliance runtime reads at startup and on demand.",
    "operationId": "get_instance_v1_compliance_instances__instance_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance, the same in the Control Plane and in the compliance runtime.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Instance V1 Compliance Instances  Instance Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a Compliance & Audit Agent instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/backup": {
   "post": {
    "description": "Answers 501 `compliance_backup_not_supported` with `parts` and the reason of each one: the compliance runtime has no admin route to export the compliance schema rows of an instance, the knowledge domain has no export of a knowledge base. Nothing is pretended; the refusal is audited.",
    "operationId": "backup_instance_v1_compliance_instances__instance_id__backup_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Backup Instance V1 Compliance Instances  Instance Id  Backup Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Back up an instance (not supported)",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/branding": {
   "get": {
    "description": "The branding chosen in the activation journey, owned by the Control Plane: `agent_name`, `sidebar_color`, `navbar_color`, the text colours computed for them (`sidebar_text_color`, `navbar_text_color`, black or white, contrast 4.5:1 or more), `logo` (`content_type`, `sha256`, `size_bytes`, `url`) or null, `version`, `updated_at`, and `app_url` (the URL of the web application once known). A null field means the default of the runtime. The compliance runtime keeps a replica of it for its public login page and rewrites it when `version` is newer. Any principal of the tenant; another tenant's instance answers 404.",
    "operationId": "get_branding_v1_compliance_instances__instance_id__branding_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Branding V1 Compliance Instances  Instance Id  Branding Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the branding of an instance",
    "tags": [
     "compliance"
    ]
   },
   "put": {
    "description": "Writes the fields given (an absent field is kept, null brings it back to the default of the runtime) and answers the branding. Colours are `#RRGGBB` (stored in upper case); the text drawn on them is black or white, whichever contrasts most (WCAG 2.2 relative luminance), and a colour whose text would stay under 4.5:1 answers 422 `compliance_branding_contrast`. `app_url` must be an https URL without credentials (422 `compliance_app_url_invalid`). A change of the name, the colours or the logo increments `version`; `expected_version` different from the current one answers 409 `compliance_branding_version_conflict`. With an `Idempotency-Key`, a retry with the same body replays the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Needs a tenant administrator or an owner of the project (403 `forbidden`); refused while the instance is `deleting` or `deleted` (409). Audited as `compliance.branding.update`.",
    "operationId": "put_branding_v1_compliance_instances__instance_id__branding_put",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     },
     {
      "description": "Optional key (up to 200 characters), unique per instance: a retry with the same key and body replays the first answer.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 200,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ComplianceBrandingIn"
       }
      }
     },
     "description": "The branding fields to write.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Branding V1 Compliance Instances  Instance Id  Branding Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change the branding of an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/branding/logo": {
   "delete": {
    "description": "Back to the default logo of the runtime: the branding no longer points to an object, `version` is incremented and the stored object is removed. Without a logo, answers the branding unchanged. Same rights as the PUT; audited as `compliance.branding.logo.remove`.",
    "operationId": "delete_branding_logo_v1_compliance_instances__instance_id__branding_logo_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Branding Logo V1 Compliance Instances  Instance Id  Branding Logo Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Remove the logo of an instance",
    "tags": [
     "compliance"
    ]
   },
   "get": {
    "description": "The logo bytes, read from the storage domain and checked against the recorded sha256, with the Content-Type of the validated format (`image/png` or `image/jpeg`), `X-Content-Type-Options: nosniff`, a Content-Security-Policy starting with `default-src 'none'` and an `ETag`. 404 `compliance_logo_not_found` when the instance has no logo. Any principal of the tenant.",
    "operationId": "get_branding_logo_v1_compliance_instances__instance_id__branding_logo_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "image/jpeg": {},
       "image/png": {}
      },
      "description": "The logo bytes."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the logo of an instance",
    "tags": [
     "compliance"
    ]
   },
   "post": {
    "description": "Multipart `file` (with the optional text fields `filename` and `mime_type`). PNG or JPEG only: SVG and any other format are refused. The real signature, the declared Content-Type and the file extension must match; 32 to 1024 pixels a side, 512 KiB at most; else 422 `compliance_logo_invalid` with `details.reason` (`format_not_allowed`, `signature_invalid`, `signature_mismatch`, `extension_mismatch`, `dimensions_out_of_bounds`, `too_large`, `empty`). The file is then scanned by the file security domain, fail closed: a blocked file answers 422 `file_blocked`, a scanner down 503 `file_scan_unavailable`. It is stored through the storage domain in the documents storage profile of the tenant under `compliance-agent/<tenant>/<instance>/branding/` (409 `compliance_branding_storage_required` without such a profile, 503 `compliance_branding_storage_unavailable` when it cannot be reached); the replaced object is removed. Increments `version` and answers the branding. Same rights as the PUT; audited as `compliance.branding.logo.update` (a refusal is audited as a denial).",
    "operationId": "upload_branding_logo_v1_compliance_instances__instance_id__branding_logo_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "multipart/form-data": {
       "schema": {
        "properties": {
         "file": {
          "format": "binary",
          "type": "string"
         },
         "filename": {
          "type": "string"
         },
         "mime_type": {
          "type": "string"
         }
        },
        "required": [
         "file"
        ],
        "type": "object"
       }
      }
     },
     "description": "Multipart form with the logo in the `file` part.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upload Branding Logo V1 Compliance Instances  Instance Id  Branding Logo Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Upload the logo of an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/health": {
   "get": {
    "description": "Real checks: readiness URL of the runtime (`GET /readyz`), knowledge base (row, vector store qdrant, Qdrant `/readyz`) and model gateway (generation and embedding models in the registry, usable). `status` is `up`, `degraded` or `down` (runtime down); `instance_status` is the lifecycle status. Each check has `status`, `duration_ms` and `reason` when not up.",
    "operationId": "instance_health_v1_compliance_instances__instance_id__health_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Instance Health V1 Compliance Instances  Instance Id  Health Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Health of an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/provision": {
   "post": {
    "description": "Long operation (202, `Operation-Id`): status `provisioning` then `starting`, steps from `validation` to `activation` run by the worker. From a validated `draft` (else 409 `compliance_not_validated`) or after a failed provisioning, which resumes from the failed step. Repeated while provisioning or once ready: `changed: false`. Audited as `compliance.provision`, each step as `compliance.step`.",
    "operationId": "provision_instance_v1_compliance_instances__instance_id__provision_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Provision Instance V1 Compliance Instances  Instance Id  Provision Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Provision an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/restart": {
   "post": {
    "description": "Long operation (202): from `ready`, `degraded`, `stopped` or after a failed restart, steps `deployment` (Navin Manager restart for a dedicated instance), `health`, `smoke`, `activation`. A restart in progress: `changed: false`.",
    "operationId": "restart_instance_v1_compliance_instances__instance_id__restart_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Restart Instance V1 Compliance Instances  Instance Id  Restart Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Restart an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/restore": {
   "post": {
    "description": "Answers 501 `compliance_backup_not_supported` with the same `parts` as the backup: no backup of an instance can be made for real yet. Audited.",
    "operationId": "restore_instance_v1_compliance_instances__instance_id__restore_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ComplianceRestoreIn"
       }
      }
     },
     "description": "The backup to restore.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Restore Instance V1 Compliance Instances  Instance Id  Restore Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Restore an instance (not supported)",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/start": {
   "post": {
    "description": "Long operation (202): from `stopped` (or after a failed start or stop), steps `deployment` (Navin Manager start for a dedicated instance, status only for a shared one), `health`, `smoke`, `activation` (governed application active). Already starting or ready: `changed: false`.",
    "operationId": "start_instance_v1_compliance_instances__instance_id__start_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Start Instance V1 Compliance Instances  Instance Id  Start Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/stop": {
   "post": {
    "description": "Long operation (202): from `ready`, `degraded` or after a failed start, restart, upgrade or stop, steps `deployment` (Navin Manager stop for a dedicated instance, status only for a shared one) and `activation` (governed application suspended, reason `compliance_instance_stopped`); status `stopped`. Already stopping or stopped: `changed: false`.",
    "operationId": "stop_instance_v1_compliance_instances__instance_id__stop_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Stop Instance V1 Compliance Instances  Instance Id  Stop Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Stop an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/upgrade": {
   "post": {
    "description": "Long operation (202), status `updating`: a shared instance follows the shared runtime, so the deployment step reads the version of the runtime in its OpenAPI document (`GET /api/v1/compliance/openapi.json`) and checks that it is the requested one (else `shared_runtime_version_mismatch`); a dedicated one is reinstalled by the Navin Manager. Then `health`, `smoke`, `activation`; `deployed_version` becomes the version. The same version already deployed or in progress: `changed: false`.",
    "operationId": "upgrade_instance_v1_compliance_instances__instance_id__upgrade_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ComplianceUpgradeIn"
       }
      }
     },
     "description": "The version to deploy.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upgrade Instance V1 Compliance Instances  Instance Id  Upgrade Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Upgrade an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/instances/{instance_id}/validate": {
   "post": {
    "description": "Real checks before provisioning: the project exists and the caller may administer it, the generation model exists in the registry with the `chat` capability and a usable status, the embedding model resolves in the Model Gateway (capability `embeddings`), the quota of instances, Qdrant answers, the shared runtime answers (shared model) or the Navin Manager answers (dedicated model, an unpublished catalog service is a warning). From `draft` or after a failed validation. 200 with `validation` and status `draft`; 422 `compliance_validation_failed` with the failed checks (status `failed`, step `validation`). Audited as `compliance.validate` and `compliance.validate.completed`.",
    "operationId": "validate_instance_v1_compliance_instances__instance_id__validate_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Validate Instance V1 Compliance Instances  Instance Id  Validate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Validate an instance",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/compliance/packs": {
   "get": {
    "description": "Summary of the domain packs shipped with the product (read only; the frameworks are not applicable by default).",
    "operationId": "list_packs_v1_compliance_packs_get",
    "parameters": [
     {
      "in": "query",
      "name": "sector",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 20,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Sector"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Packs V1 Compliance Packs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List Packs",
    "tags": [
     "compliance"
    ]
   }
  },
  "/v1/connectors": {
   "get": {
    "description": "Connectors of the tenant in name order, each with the kinds of credentials configured (never their values). One page only.",
    "operationId": "list_connectors_v1_connectors_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Connectors V1 Connectors Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the connectors",
    "tags": [
     "connectors"
    ]
   },
   "post": {
    "description": "Applies a Connector manifest: creates or updates the connector (`apply_status`: `created` or `updated`). The URLs must be allowed by the egress policy; OAuth2 needs `auth.token_url`; unsigned webhooks are refused (422 `invalid_manifest`). Needs `tenant_admin`, `developer` or `application_owner`. Audited as `connector.apply`.",
    "operationId": "create_connector_v1_connectors_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Manifest",
        "type": "object"
       }
      }
     },
     "description": "Connector manifest (`kind: Connector`, `metadata`, `spec` with base URL, auth, resources, scopes, sync and webhooks).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Connector V1 Connectors Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register a connector",
    "tags": [
     "connectors"
    ]
   }
  },
  "/v1/connectors/{name}": {
   "delete": {
    "description": "Deletes the connector and its credentials in the secret store. Needs `tenant_admin`. 404 `connector_not_found`. Audited as `connector.delete`.",
    "operationId": "delete_connector_v1_connectors__name__delete",
    "parameters": [
     {
      "description": "Name of the connector.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a connector",
    "tags": [
     "connectors"
    ]
   },
   "get": {
    "description": "Returns the connector with its manifest, status, owner and configured credentials (kind, field names, update date). 404 `connector_not_found`.",
    "operationId": "get_connector_v1_connectors__name__get",
    "parameters": [
     {
      "description": "Name of the connector.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Connector V1 Connectors  Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a connector",
    "tags": [
     "connectors"
    ]
   },
   "patch": {
    "description": "Changes the status or the owner. Disabling a connector revokes its credential leases at once. Needs `tenant_admin`, `developer` or `application_owner`. Audited as `connector.update`.",
    "operationId": "patch_connector_v1_connectors__name__patch",
    "parameters": [
     {
      "description": "Name of the connector.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConnectorPatch"
       }
      }
     },
     "description": "Fields to change; the omitted ones are kept.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Connector V1 Connectors  Name  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a connector",
    "tags": [
     "connectors"
    ]
   }
  },
  "/v1/connectors/{name}/credentials": {
   "post": {
    "description": "Stores credentials in the secret store and returns only the kind and the field names (201). Needs `tenant_admin` or `security_officer`. Body: `kind` plus its fields:\n- `oauth2_client`: `client_id`, `client_secret`;\n- `oauth2_code`: `code`, `redirect_uri`, optional `code_verifier`; the code is exchanged at once at the token URL (needs a stored `oauth2_client`, else 409 `credential_unavailable`) and kept as `oauth2_token`;\n- `api_key`: `api_key`, optional `header`;\n- `service_account`: `private_key` or `token`, optional `client_email`, `client_id`;\n- `basic`: `username`, `password`;\n- `webhook_secret`: `secret`.\nUnknown kinds and missing fields answer 400 `invalid_request`. Audited as `connector.credentials.write`.",
    "operationId": "put_credentials_v1_connectors__name__credentials_post",
    "parameters": [
     {
      "description": "Name of the connector.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "Credential kind and its fields. Write only: values are never returned.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Credentials V1 Connectors  Name  Credentials Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Store connector credentials",
    "tags": [
     "connectors"
    ]
   }
  },
  "/v1/connectors/{name}/sync": {
   "post": {
    "description": "Queues a sync run (202) and publishes `connectors.<name>.sync` for the worker. The manifest must declare a sync mode (409 `sync_disabled`), the connector must be active (409 `connector_disabled`), resources must be readable (400 `invalid_request`) and no other run may be queued or running (409 `sync_in_progress`). An incremental sync starts from the cursor of the last successful run unless `full`. The policy `connector.sync` is evaluated. Needs `tenant_admin`, `developer` or `agent`. Audited as `connector.sync`.",
    "operationId": "sync_connector_v1_connectors__name__sync_post",
    "parameters": [
     {
      "description": "Name of the connector.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/SyncIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional resources and full flag."
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Sync Connector V1 Connectors  Name  Sync Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start a synchronisation",
    "tags": [
     "connectors"
    ]
   }
  },
  "/v1/connectors/{name}/sync-runs": {
   "get": {
    "description": "Synchronisation runs of the connector, newest first: mode, status, resources, cursor and dates.",
    "operationId": "sync_runs_v1_connectors__name__sync_runs_get",
    "parameters": [
     {
      "description": "Name of the connector.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     },
     {
      "description": "Maximum number of runs returned (default 50, capped at 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Sync Runs V1 Connectors  Name  Sync Runs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the sync runs of a connector",
    "tags": [
     "connectors"
    ]
   }
  },
  "/v1/connectors/{name}/test": {
   "post": {
    "description": "Builds the authentication headers from the stored credentials and, when the manifest has a base URL, sends a GET to it. Returns `ok`, `credentials`, `http_status`, `latency_ms` and an `error` code on failure (`egress_denied`, `upstream_unavailable`, credential errors); a failed test is a 200 with `ok: false`. The policy `connector.test` is evaluated. Needs `tenant_admin`, `developer` or `application_owner`. Audited as `connector.test`.",
    "operationId": "test_connector_v1_connectors__name__test_post",
    "parameters": [
     {
      "description": "Name of the connector.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Test Connector V1 Connectors  Name  Test Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Test a connector",
    "tags": [
     "connectors"
    ]
   }
  },
  "/v1/context/issue": {
   "post": {
    "description": "Builds and signs an ExecutionContext for the caller and returns `token`, `context_id`, `kid`, `alg`, `issued_at` and `expires_at` (201).\n- With `run_id`: the caller must have created the run, be its root principal or the user it acts for, or hold `agent`, `tenant_admin` or `security_officer` (403 `forbidden`); the delegation of the run is checked again and the agent manifest is included.\n- With `delegation_id`: the delegation must be valid and the caller one of its parties, or `agent` or `tenant_admin`.\nErrors: 400 `context_wrong_audience` for an audience the platform does not accept, 400 `context_ttl_exceeded`, 403 `delegation_expired`, 503 `context_authority_unavailable`. Audited as `context.issue`.",
    "operationId": "issue_v1_context_issue_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/IssueIn"
       }
      }
     },
     "description": "Audience, lifetime and the run or delegation the context is for.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Issue V1 Context Issue Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Issue a signed execution context",
    "tags": [
     "context"
    ]
   }
  },
  "/v1/context/jwks": {
   "get": {
    "description": "Public verification keys as a JWKS (active, and retired ones still inside their verification window), each with `kid`, `alg` (`ES256` or `EdDSA`) and `use: sig`. Any authenticated principal may read it. 503 `context_authority_unavailable` when the key registry cannot be read.",
    "operationId": "jwks_v1_context_jwks_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Jwks V1 Context Jwks Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the public verification keys",
    "tags": [
     "context"
    ]
   }
  },
  "/v1/context/keys": {
   "get": {
    "description": "Registry of the context signing keys: `kid`, algorithm, status, dates of use, retirement and revocation. Needs `security_officer` or `auditor`. 503 `context_authority_unavailable` when the registry cannot be read.",
    "operationId": "list_keys_v1_context_keys_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Keys V1 Context Keys Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the signing keys",
    "tags": [
     "context"
    ]
   }
  },
  "/v1/context/keys/{kid}/revoke": {
   "post": {
    "description": "Revokes a context signing key at once: the contexts it signed no longer verify. Needs `platform_admin`. 404 `signing_key_not_found`. Audited as `context.key.revoke` at platform level.",
    "operationId": "revoke_key_v1_context_keys__kid__revoke_post",
    "parameters": [
     {
      "description": "Key id, the RFC 7638 thumbprint of the public key.",
      "in": "path",
      "name": "kid",
      "required": true,
      "schema": {
       "title": "Kid",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RevokeKeyIn"
       }
      }
     },
     "description": "Reason of the revocation.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Revoke Key V1 Context Keys  Kid  Revoke Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke a signing key",
    "tags": [
     "context"
    ]
   }
  },
  "/v1/context/plan": {
   "post": {
    "description": "Context Manager dry run: computes the token budget of a model window (output, reasoning and safety reserves) and which segments are kept, compressed or dropped by priority. With `model`, the window and output reserve come from the registry. A window that is not a positive integer answers 422 `parameter_invalid`; segments that cannot fit answer 422 `context_overflow`. Requires a reader role.",
    "operationId": "context_plan_v1_context_plan_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`model` (or `model_id`), or `window` (tokens); `output` (reserved output tokens, default the model maximum capped at 4096), `reasoning` (reserved reasoning tokens), `safety` (margin) and `segments` (each with `type`, optional `segment_id`, `priority`, `classification` and its content).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Plan the context window",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/context/verify": {
   "post": {
    "description": "Checks a token and returns `valid`, `context_id`, `kid`, `alg`, the claims and the context document. Checks, in order: structure and canonical form (`context_malformed`), algorithm and signature (`context_invalid_signature`), known non revoked key (`context_unknown_key`), issuer (`context_wrong_issuer`), audience (`context_wrong_audience`), lifetime (`context_expired`), tenant of the caller (403 `context_tenant_mismatch`), issuance record (`context_revoked`), digest of the document and delegation chain (a revoked delegation gives `context_revoked`). Refusals answer 401 unless stated and are audited; a success binds the verified identity to the audit events of the request.",
    "operationId": "verify_v1_context_verify_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__context__routes__VerifyIn"
       }
      }
     },
     "description": "Token to verify and expected audience.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Verify V1 Context Verify Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Verify a signed execution context",
    "tags": [
     "context"
    ]
   }
  },
  "/v1/context/{context_id}/revoke": {
   "post": {
    "description": "Revokes an issued context before it expires; verifying it then answers `context_revoked`. Allowed for the principal that issued it, or `tenant_admin` or `security_officer` (403 `forbidden`). Revoking twice keeps the first date. 404 `context_not_found`. Audited as `context.revoke`.",
    "operationId": "revoke_context_v1_context__context_id__revoke_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the context, the `jti` claim of its token.",
      "in": "path",
      "name": "context_id",
      "required": true,
      "schema": {
       "title": "Context Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Revoke Context V1 Context  Context Id  Revoke Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke an execution context",
    "tags": [
     "context"
    ]
   }
  },
  "/v1/contracts": {
   "get": {
    "description": "Lists the published contracts with their `name`, `title`, `kind`, `type`, `file`, schema `id` and `description`. Open to any authenticated caller. `next_cursor` is always null.",
    "operationId": "list_contracts_v1_contracts_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Contracts V1 Contracts Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the contracts",
    "tags": [
     "contracts"
    ]
   }
  },
  "/v1/contracts/{name}": {
   "get": {
    "description": "Returns the JSON Schema of the contract as published. Open to any authenticated caller. An unknown name answers 404 `unknown_contract`.",
    "operationId": "get_contract_v1_contracts__name__get",
    "parameters": [
     {
      "description": "Name of the contract, for example `agent-manifest`.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Contract V1 Contracts  Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a contract",
    "tags": [
     "contracts"
    ]
   }
  },
  "/v1/contracts/{name}/validate": {
   "post": {
    "description": "Validates the body against the contract, formats included, without storing anything. The answer gives `contract`, `valid` and `errors`, each with the JSON `path` of the faulty value and a `message`. Open to any authenticated caller. An unknown contract answers 404 `unknown_contract`.",
    "operationId": "validate_contract_v1_contracts__name__validate_post",
    "parameters": [
     {
      "description": "Name of the contract, for example `agent-manifest`.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "title": "Document"
       }
      }
     },
     "description": "Any JSON document to validate.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Validate Contract V1 Contracts  Name  Validate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Validate a document against a contract",
    "tags": [
     "contracts"
    ]
   }
  },
  "/v1/credentials/broker/lease": {
   "post": {
    "description": "Issues a short lived lease on a connector instead of its secret (201): `lease_id`, `token` (shown once), `scopes`, `expires_at`, `ttl_seconds`. Requested scopes must be declared by the connector (403 `scope_not_allowed`; default: all of them); the connector must be active (409 `connector_disabled`). With `on_behalf_of`, the user must hold the relation `can_invoke` on the connector (403 `relation_required`). Needs `tenant_admin`, `developer` or `agent`. Audited as `credential.lease`.",
    "operationId": "lease_v1_credentials_broker_lease_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LeaseIn"
       }
      }
     },
     "description": "Connector, scopes, lifetime, run and user acted for.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Lease V1 Credentials Broker Lease Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Obtain a credential lease",
    "tags": [
     "connectors"
    ]
   }
  },
  "/v1/delegations": {
   "get": {
    "description": "Lists delegations, newest first, paginated: all of them for `tenant_admin`, `security_officer` and `auditor`, otherwise those the caller is the root, the creator or the person acted for. An unknown status answers 400.",
    "operationId": "list_delegations_v1_delegations_get",
    "parameters": [
     {
      "description": "`active` (not expired), `expired` or `revoked`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only the delegations rooted at this principal.",
      "in": "query",
      "name": "root_principal_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Root Principal Id"
      }
     },
     {
      "description": "Maximum number of delegations in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Delegations V1 Delegations Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the delegations",
    "tags": [
     "delegation"
    ]
   },
   "post": {
    "description": "Creates a root delegation from the caller to a delegate. Open to members of the tenant; an agent cannot create a root delegation by itself (403 `delegation_root_forbidden`).\n\nChecks: delegate format `agent:`, `app:`, `service:` or `subagent:` and existing agent (400, 404); scopes covered by the caller scopes, including those of an active break glass grant (403 `delegation_scope_exceeds`); classification at most the caller clearance (403 `delegation_classification_exceeds`); expiry in the future and within the platform maximum (24 hours by default, 400 `delegation_ttl_exceeded`). `redelegation_allowed` only applies when `max_depth` is above 0. Writes the audit event `delegation.create`. Answers 201 with the delegation.",
    "operationId": "create_delegation_v1_delegations_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DelegationIn"
       }
      }
     },
     "description": "Delegate, rights, limits and expiry of the delegation.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Delegation V1 Delegations Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a delegation",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/delegations/authorize": {
   "post": {
    "description": "Computes the effective permission of an action: user AND agent AND delegation AND resource restriction AND relationship (OpenFGA or the builtin tuples) AND policy (OPA or builtin). Give `delegation_id`, or `run_id` to use the delegation of a run (400 `invalid_request` without either; 403 `delegation_required` for a run without delegation).\n\nThe chain is verified first (403 `delegation_revoked`, `delegation_expired` or `delegation_invalid`; 404 `delegation_not_found`). The answer is the ActionContext of the decision: `allow` (true only when every layer allows) and the verdict of each layer. The decision is recorded in its own transactions, so a refusal is kept in the trail. Open to members of the tenant.",
    "operationId": "authorize_v1_delegations_authorize_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__delegation__routes__AuthorizeIn"
       }
      }
     },
     "description": "Action, delegation or run, and the scope, resource, relation, audience and classification to check.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Authorize V1 Delegations Authorize Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Authorize an action under a delegation",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/delegations/revoke-principal": {
   "post": {
    "description": "Revokes every active delegation rooted at a principal or acting for it, with their descendants and execution contexts, for example at user offboarding or after an account compromise. Needs `tenant_admin` or `security_officer`. Writes the audit event `delegation.revoke_principal`.",
    "operationId": "revoke_principal_v1_delegations_revoke_principal_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RevokePrincipalIn"
       }
      }
     },
     "description": "Principal and reason.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Revoke Principal V1 Delegations Revoke Principal Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke every delegation of a principal",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/delegations/{delegation_id}": {
   "get": {
    "description": "Returns the delegation with the verification of its chain from the root (every link active, not expired, same tenant, covered by its parent). Visible to its root, creator and the person acted for, and to `tenant_admin`, `security_officer`, `auditor` and `agent`; otherwise 404 `delegation_not_found`.",
    "operationId": "get_delegation_v1_delegations__delegation_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the delegation.",
      "in": "path",
      "name": "delegation_id",
      "required": true,
      "schema": {
       "title": "Delegation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Delegation V1 Delegations  Delegation Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a delegation",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/delegations/{delegation_id}/restrict": {
   "post": {
    "description": "Creates a child delegation, always covered by its parent: a sub-agent never gets wider rights. Allowed to the root or creator of the parent, an `agent`, a `tenant_admin` or a `security_officer` (403 `forbidden`).\n\nThe parent must be valid and allow redelegation (403 `delegation_not_redelegable`) with depth left (403 `delegation_depth_exceeded`). Omitted fields inherit the parent values; given ones must be covered by them (403 `delegation_scope_exceeds`, `delegation_classification_exceeds`, `delegation_expiry_exceeds`). Writes the audit event `delegation.restrict`. Answers 201 with the child delegation.",
    "operationId": "restrict_delegation_v1_delegations__delegation_id__restrict_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the parent delegation.",
      "in": "path",
      "name": "delegation_id",
      "required": true,
      "schema": {
       "title": "Delegation Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RestrictIn"
       }
      }
     },
     "description": "Sub-delegate and narrower rights.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Restrict Delegation V1 Delegations  Delegation Id  Restrict Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Restrict a delegation for a sub-delegate",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/delegations/{delegation_id}/revoke": {
   "post": {
    "description": "Revokes the delegation and every descendant; their execution contexts are revoked with them, effective at the next action. Allowed to its root, creator or the person acted for, and to `tenant_admin` and `security_officer` (403 `forbidden`). Writes the audit event `delegation.revoke`.",
    "operationId": "revoke_delegation_v1_delegations__delegation_id__revoke_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the delegation.",
      "in": "path",
      "name": "delegation_id",
      "required": true,
      "schema": {
       "title": "Delegation Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/RevokeIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Revoke Delegation V1 Delegations  Delegation Id  Revoke Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke a delegation",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/developer/kit": {
   "get": {
    "description": "Developer kit of an application, an agent or a project: values, states and actions, never a secret. Give exactly one of `application_id`, `agent_id` or `project` (400 `invalid_request` otherwise). The answer holds the `subject` (with the models, tools, MCP servers, knowledge bases and evaluation suites it uses), the nine `rows`, the `env` entries of an environment file (the API key is only a placeholder marked secret), a `summary` of ready rows and the `next_steps` (create a key, run the tests, run the red team). An unknown application or agent, or a project without application, answers 404 `not_found`. Requires a tenant principal (403 `tenant_required`) with `developer`, `application_owner` or `tenant_admin` (403 `forbidden`).",
    "operationId": "developer_kit_v1_developer_kit_get",
    "parameters": [
     {
      "description": "Identifier of the application the kit is built for, 200 characters at most. Exclusive with `agent_id` and `project`.",
      "in": "query",
      "name": "application_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 200,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Application Id"
      }
     },
     {
      "description": "Identifier of the agent the kit is built for, 200 characters at most; its resources come from the manifest of its current version. Exclusive with `application_id` and `project`.",
      "in": "query",
      "name": "agent_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 200,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Agent Id"
      }
     },
     {
      "description": "Name of the project, 200 characters at most: the kit merges the resources of every application of the project. Exclusive with `application_id` and `agent_id`.",
      "in": "query",
      "name": "project",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 200,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Developer Kit V1 Developer Kit Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the developer kit",
    "tags": [
     "developer"
    ]
   }
  },
  "/v1/dlp/inspect": {
   "post": {
    "description": "Runs DLP on the text with the tenant rules, in mode `detect` unless `mode` says otherwise. The answer gives `text`, `findings` (type, position, score, classification, short preview, action, rule), `action` (strongest action applied), `classification`, `mode`, `engine` (`builtin` or `presidio`), `blocked` and `count`. An unknown mode answers 400. Open to any member of the tenant. Writes the audit event `dlp.inspect` (counts and types only).",
    "operationId": "dlp_inspect_v1_dlp_inspect_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DlpIn"
       }
      }
     },
     "description": "Text, optional mode and language.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Dlp Inspect V1 Dlp Inspect Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Inspect a text for sensitive data",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/dlp/redact": {
   "post": {
    "description": "Same as inspect, in mode `mask` by default: each finding is replaced by `[TYPE]` (for example `[EMAIL]`), or tokenized or blocked when a tenant rule or `mode` says so; a blocked text comes back empty with `blocked: true`. Open to any member of the tenant. Writes the audit event `dlp.redact`.",
    "operationId": "dlp_redact_v1_dlp_redact_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DlpIn"
       }
      }
     },
     "description": "Text, optional mode and language.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Dlp Redact V1 Dlp Redact Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Redact sensitive data from a text",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/dlp/rules": {
   "get": {
    "description": "Lists the DLP rules of the tenant ordered by name. Open to any member of the tenant. `next_cursor` is always null.",
    "operationId": "list_rules_v1_dlp_rules_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Rules V1 Dlp Rules Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the DLP rules",
    "tags": [
     "privacy"
    ]
   },
   "post": {
    "description": "Creates the rule, or replaces the rule of the same name. A rule needs an `entity_type` or a `pattern` (a valid regular expression); errors answer 400 `invalid_request` (unknown action, invalid pattern or classification). Needs `tenant_admin` or `security_officer`. Writes the audit event `dlp.rule.upsert`. Answers 201 with the rule.",
    "operationId": "create_rule_v1_dlp_rules_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__privacy__RuleIn"
       }
      }
     },
     "description": "Name, entity type or pattern, action, classification and score of the rule.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Rule V1 Dlp Rules Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create or update a DLP rule",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/encryption/decrypt": {
   "post": {
    "description": "Decrypts an `eaienc1` ciphertext of the tenant with the key version it names, checking the same `aad` as at encryption. Returns `plaintext`, or `plaintext_base64` with `as_base64` or when the data is not UTF-8 text, and `key_version`. Old versions keep decrypting after a rotation. Open to any member of the tenant. Writes the audit event `encryption.decrypt`.",
    "operationId": "decrypt_v1_encryption_decrypt_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__privacy__DecryptIn"
       }
      }
     },
     "description": "Ciphertext, associated data and output format.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Decrypt V1 Encryption Decrypt Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Decrypt a ciphertext",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/encryption/encrypt": {
   "post": {
    "description": "Encrypts `plaintext` (UTF-8 text) or `plaintext_base64` (bytes) with the current version of the key, bound to `aad`. Returns `ciphertext` (`eaienc1:...`), `key_id` and `key_version`. One of the two inputs is required, and base64 must be valid (400 `invalid_request`); an unknown key answers 404 `key_not_found`. Open to any member of the tenant. Writes the audit event `encryption.encrypt` (size only).",
    "operationId": "encrypt_v1_encryption_encrypt_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EncryptIn"
       }
      }
     },
     "description": "Key, data to encrypt and associated data.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Encrypt V1 Encryption Encrypt Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Encrypt data with a tenant key",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/encryption/keys": {
   "get": {
    "description": "Lists the encryption keys of the tenant ordered by name: id, name, backend (`openbao-transit` or `local`), purpose, current version and dates. Never the key material. Open to any member of the tenant.",
    "operationId": "list_keys_v1_encryption_keys_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Keys V1 Encryption Keys Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the encryption keys",
    "tags": [
     "privacy"
    ]
   },
   "post": {
    "description": "Creates a named key with its first version; the data key is generated and wrapped by OpenBao Transit when configured, locally otherwise. The name must be lowercase letters, digits, `.`, `_` or `-`, at most 63 characters (400 `invalid_request`); a name already used answers 409 `conflict`. Needs `tenant_admin` or `security_officer`. Writes the audit event `encryption.key.create`.",
    "operationId": "create_key_v1_encryption_keys_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__privacy__KeyIn"
       }
      }
     },
     "description": "Name and purpose of the key.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Key V1 Encryption Keys Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an encryption key",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/encryption/keys/{key_id}/rotate": {
   "post": {
    "description": "Adds a new version to the key: new encryptions use it, older ciphertexts keep decrypting with their own version. Needs `tenant_admin` or `security_officer`. Answers 404 `key_not_found`. Writes the audit event `encryption.key.rotate`.",
    "operationId": "rotate_key_v1_encryption_keys__key_id__rotate_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the key.",
      "in": "path",
      "name": "key_id",
      "required": true,
      "schema": {
       "title": "Key Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rotate Key V1 Encryption Keys  Key Id  Rotate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Rotate an encryption key",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/evaluations/comparisons": {
   "get": {
    "description": "Lists the comparisons of the tenant, newest first, at most 200, optionally for one suite. Each gives baseline, candidate, both run ids, per metric deltas, tolerance and verdict. Needs `tenant_admin`, `developer`, `security_officer`, `auditor`, `viewer` or `finops`.",
    "operationId": "list_comparisons_v1_evaluations_comparisons_get",
    "parameters": [
     {
      "description": "Only the comparisons of this suite (UUID).",
      "in": "query",
      "name": "suite_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Suite Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Comparisons V1 Evaluations Comparisons Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the A/B comparisons",
    "tags": [
     "evaluation",
     "evaluation"
    ]
   },
   "post": {
    "description": "Runs one suite twice, on the `baseline` and on the `candidate` (each `{type, ref, version}`, type `model` by default, `agent` or `prompt`), and stores both runs, the per metric deltas and the verdict. Deltas are oriented by the comparator of each metric (`gte`: higher is better, `lte`: lower is better).\n\nVerdicts: `regression` (a metric worse by more than `tolerance`), `candidate_better` (no regression and at least one metric better by more than `tolerance`), `equivalent` (every delta within `tolerance`), `inconclusive` (a run ended in error).\n\nNeeds `tenant_admin`, `developer` or `security_officer`. Errors 422 `comparison_invalid` (`details.field`): missing `ref`, unknown type, same baseline and candidate, `tolerance` outside 0 to 1, `outputs` not an object. Writes the audit event `evaluation.comparison`.",
    "operationId": "create_comparison_v1_evaluations_comparisons_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "JSON object: `suite_id`, `baseline`, `candidate`, optional `tolerance` (0 to 1, default 0) and `outputs` (`{\"baseline\": [...], \"candidate\": [...]}`, precomputed outputs per case).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Comparison V1 Evaluations Comparisons Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Compare a candidate with a baseline",
    "tags": [
     "evaluation",
     "evaluation"
    ]
   }
  },
  "/v1/evaluations/comparisons/{comparison_id}": {
   "get": {
    "description": "Returns one comparison. Needs `tenant_admin`, `developer`, `security_officer`, `auditor`, `viewer` or `finops`. Answers 404 `comparison_not_found`.",
    "operationId": "get_comparison_v1_evaluations_comparisons__comparison_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the comparison.",
      "in": "path",
      "name": "comparison_id",
      "required": true,
      "schema": {
       "title": "Comparison Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Comparison V1 Evaluations Comparisons  Comparison Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an A/B comparison",
    "tags": [
     "evaluation",
     "evaluation"
    ]
   }
  },
  "/v1/evaluations/gates/check": {
   "post": {
    "description": "Checks that the latest finished run of every blocking suite of the target (for `target.version` when given, and limited to `suite_ids` when given) has passed. With `run_missing: true`, a suite without any run is run now; otherwise it counts as `missing`.\n\nPassed: 200 with `passed: true`, the target and one check per suite. Failed: 409 `gate_failed` with the failing checks in `details.failures`, so that a promotion pipeline stops. An unknown target type answers 400. Open to any member of the tenant. Writes the audit event `evaluation.gate.check`, a deny when the gate fails.",
    "operationId": "gate_check_v1_evaluations_gates_check_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/GateIn"
       }
      }
     },
     "description": "Target, optional suites and whether to run missing suites.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Gate Check V1 Evaluations Gates Check Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Check the quality gate of a target",
    "tags": [
     "evaluation"
    ]
   }
  },
  "/v1/evaluations/runs": {
   "get": {
    "description": "Lists the evaluation runs of the tenant, newest identifier first, paginated, optionally filtered by suite and status. Each item follows the Evaluation Contract (target, engine, dataset, metrics, results, status, cost) with `run_id`, `suite_id`, `trigger`, `case_results` and `error`. Open to any member of the tenant.",
    "operationId": "list_runs_v1_evaluations_runs_get",
    "parameters": [
     {
      "description": "Only the runs of this suite.",
      "in": "query",
      "name": "suite_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Suite Id"
      }
     },
     {
      "description": "Only this status: `running`, `passed`, `failed` or `error`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Maximum number of runs in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Runs V1 Evaluations Runs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the evaluation runs",
    "tags": [
     "evaluation"
    ]
   },
   "post": {
    "description": "Runs a suite now and returns the finished run (201). Needs `tenant_admin`, `developer`, `security_officer` or `ai_governance_officer` or `agent`.\n\n1. With `suite_id`: each case is sent to the target (the suite target, or `target` to evaluate another version), unless `outputs` gives the output of the case or the case has one.\n2. Each metric is scored and compared to its threshold; the run ends `passed`, `failed` or `error` (target or engine unavailable, metric without samples), with its cost from the usage events.\n3. With `trigger: promotion` and no `suite_id`, every suite of `target` with `run_on_promotion` runs; the answer gives `runs` and `passed` (all blocking suites passed).\n\nThe response carries `Operation-Id` and accepts `Idempotency-Key`. A missing `suite_id` answers 400; an unknown suite 404. Writes the audit event `evaluation.run`.",
    "operationId": "create_run_v1_evaluations_runs_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__evaluation__RunIn"
       }
      }
     },
     "description": "Suite, optional target, precomputed outputs and trigger.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Run V1 Evaluations Runs Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run an evaluation suite",
    "tags": [
     "evaluation"
    ]
   }
  },
  "/v1/evaluations/runs/{run_id}": {
   "get": {
    "description": "Returns one evaluation run with its results per metric and per case. Open to any member of the tenant. Answers 404 `not_found`.",
    "operationId": "get_run_v1_evaluations_runs__run_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the evaluation run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Run V1 Evaluations Runs  Run Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an evaluation run",
    "tags": [
     "evaluation"
    ]
   }
  },
  "/v1/evaluations/suites": {
   "get": {
    "description": "Lists the suites of the tenant ordered by name, paginated, as Evaluation Contract documents; `cases` gives the number of cases. Open to any member of the tenant.",
    "operationId": "list_suites_v1_evaluations_suites_get",
    "parameters": [
     {
      "description": "Maximum number of suites in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Suites V1 Evaluations Suites Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the evaluation suites",
    "tags": [
     "evaluation"
    ]
   },
   "post": {
    "description": "Creates a suite. Needs `tenant_admin`, `developer`, `security_officer` or `ai_governance_officer`. Errors 400 `invalid_request`: target type not in `model`, `agent`, `prompt`, `rag_pipeline`, `skill` or `tool`, unknown engine or kind, comparator other than `gte` or `lte`, or, for the `custom` engine, a metric other than `exact_match`, `contains`, `not_contains`, `json_valid`, `faithfulness`, `latency` or `refusal`. A name already used answers 409 `conflict`. The dataset gets its `size` and a SHA-256 `digest` of the cases. Writes the audit event `evaluation.suite.create`.",
    "operationId": "create_suite_v1_evaluations_suites_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SuiteIn"
       }
      }
     },
     "description": "Name, target, engine, kind, dataset, cases, metrics and gate options.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Suite V1 Evaluations Suites Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an evaluation suite",
    "tags": [
     "evaluation"
    ]
   }
  },
  "/v1/evaluations/suites/{suite_id}": {
   "get": {
    "description": "Returns one suite with its full list of cases and `run_on_promotion`. Open to any member of the tenant. Answers 404 `not_found`.",
    "operationId": "get_suite_v1_evaluations_suites__suite_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the suite.",
      "in": "path",
      "name": "suite_id",
      "required": true,
      "schema": {
       "title": "Suite Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Suite V1 Evaluations Suites  Suite Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an evaluation suite",
    "tags": [
     "evaluation"
    ]
   }
  },
  "/v1/events/publish": {
   "post": {
    "description": "Publishes an event (202): on NATS JetStream when configured, else in the platform outbox. The current W3C trace context is added to the headers. Every trigger whose subject and filter match starts a run of its agent (idempotent per event and trigger); the answer lists them in `triggered`, with `skipped` and an error code when a run could not start. Needs `tenant_admin`, `developer` or `agent`. 422 `invalid_subject`. Audited as `event.publish`.",
    "operationId": "publish_event_v1_events_publish_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EventIn"
       }
      }
     },
     "description": "Subject, payload and headers of the event.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Publish Event V1 Events Publish Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Publish an event",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/evidence/access-log": {
   "get": {
    "description": "Returns the latest accesses to the audit trail, newest first: actor, roles, kind (`read`, `search`, `verify`, `export`, `payload_decrypt`, `seal_read`), query, number of results, reason and the audit event written. Needs `auditor` or `security_officer`. Reading the log is itself recorded.",
    "operationId": "access_log_v1_evidence_access_log_get",
    "parameters": [
     {
      "description": "Maximum number of entries (default 200, maximum 1000).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 200,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Access Log V1 Evidence Access Log Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the audit access log",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/alerts": {
   "get": {
    "description": "Lists the integrity alerts of the tenant opened by the monitor: `chain_broken`, `sequence_gap`, `seal_invalid`, `outbox_missing` or `clock_skew`, refreshed while the problem persists. Needs `auditor`, `security_officer` or `tenant_admin`.",
    "operationId": "list_alerts_v1_evidence_alerts_get",
    "parameters": [
     {
      "description": "Only `open` or `acknowledged` alerts.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "open",
          "acknowledged"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Alerts V1 Evidence Alerts Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the integrity alerts",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/bundle": {
   "get": {
    "description": "Returns `bundle` (events, seals and public keys of the tenant) and `manifest` (format, counts, SHA-256 of the canonical bundle, `alg: Ed25519`, key id, public key and signature by the seal key). An external auditor verifies it offline with `python -m eai.domains.evidence.verify`. Needs `auditor` or `security_officer`. Answers 503 `audit_seal_key_unavailable` without signing key. The export is recorded in the access log.",
    "operationId": "export_bundle_v1_evidence_bundle_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Export Bundle V1 Evidence Bundle Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Export an offline evidence bundle",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/events/{event_id}/payload": {
   "post": {
    "description": "Returns the decrypted sensitive fields of one event in `payload`, with `access_event_id`, the audit event that records this access. Only `auditor` or `security_officer` held explicitly: `platform_admin` is not enough (403 `forbidden`). A `reason` is required. Errors: 404 `not_found` (no payload), 410 `audit_payload_purged` (expired or erased), 409 `audit_payload_tampered` (ciphertext digest mismatch), 503 `audit_payload_key_unavailable`.",
    "operationId": "decrypt_payload_v1_evidence_events__event_id__payload_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the audit event.",
      "in": "path",
      "name": "event_id",
      "required": true,
      "schema": {
       "title": "Event Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__evidence__routes__DecryptIn"
       }
      }
     },
     "description": "Reason of the decryption, written to the access log.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Decrypt Payload V1 Evidence Events  Event Id  Payload Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Decrypt the payload of an audit event",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/gateway": {
   "get": {
    "description": "Returns the delivery state of the audit events of the tenant to the SIEM: configured `targets`, `pending` and `delivered` counts, `max_attempts` of a pending event and `oldest_pending`. Needs `auditor`, `security_officer` or `tenant_admin`.",
    "operationId": "gateway_status_v1_evidence_gateway_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Gateway Status V1 Evidence Gateway Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the Audit Gateway status",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/holds": {
   "get": {
    "description": "Lists the legal holds of the tenant with their case, period, reason, status and release approvals. Needs `auditor`, `security_officer` or `tenant_admin`.",
    "operationId": "list_holds_v1_evidence_holds_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Holds V1 Evidence Holds Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the evidence legal holds",
    "tags": [
     "evidence"
    ]
   },
   "post": {
    "description": "Places a legal hold on the payloads of the tenant for a case and an optional period of event time: while it is active, the payload retention purge and erasures skip the events it covers. `time_to` must be after `time_from` (400 `invalid_request`). Needs `auditor`, `security_officer` or `tenant_admin`. Writes the audit event `audit.legal_hold.create`. Answers 201 with the hold.",
    "operationId": "create_hold_v1_evidence_holds_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/HoldIn"
       }
      }
     },
     "description": "Case, reason and optional period of the hold.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Hold V1 Evidence Holds Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Place an evidence legal hold",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/holds/{hold_id}/release": {
   "post": {
    "description": "Records one release approval with its reason. The hold is released at the second approval by a distinct approver; the same person twice answers 409 `audit_hold_same_approver`, a hold no longer active 409 `audit_hold_not_active`, an unknown hold 404. Needs `auditor`, `security_officer` or `tenant_admin`. Writes `audit.legal_hold.release_approve`, then `audit.legal_hold.release`.",
    "operationId": "release_hold_v1_evidence_holds__hold_id__release_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the legal hold.",
      "in": "path",
      "name": "hold_id",
      "required": true,
      "schema": {
       "title": "Hold Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReleaseIn"
       }
      }
     },
     "description": "Reason of the approval.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Release Hold V1 Evidence Holds  Hold Id  Release Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Approve the release of a legal hold",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/retention/evidence": {
   "get": {
    "description": "Lists the purge evidence records of the tenant: kind, cutoff, purged and held counts, purged sequences and the Merkle root of the purged ciphertext digests, never the contents. Needs `auditor`, `security_officer` or `tenant_admin`.",
    "operationId": "retention_evidence_v1_evidence_retention_evidence_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Retention Evidence V1 Evidence Retention Evidence Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the purge evidence",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/retention/run": {
   "post": {
    "description": "Deletes encrypted audit payloads; the events, the chain and the seals stay and keep verifying.\n\n1. `retention` (default): payloads of events older than `cutoff` (default: now minus the payload retention period of the platform).\n2. `erasure`: payloads of the listed `event_ids` (required, 400 otherwise), for a data subject request.\n\nPayloads under an active legal hold are skipped. A purge evidence record keeps counts, sequences and the Merkle root of the purged ciphertext digests. With `dry_run`, nothing is deleted. Needs `security_officer` or `tenant_admin`. Writes the audit event `audit.payload.retention` or `audit.payload.erasure`.",
    "operationId": "run_retention_v1_evidence_retention_run_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PurgeIn"
       }
      }
     },
     "description": "Kind of purge, cutoff, events and simulation flag.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Run Retention V1 Evidence Retention Run Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Purge expired audit payloads",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/runs/{run_id}/components": {
   "post": {
    "description": "Records, append only, the versions of the components used by an agent run, or by one step of it with `step_seq` (tool call, model call). Each report is audited with the `versions` field of the Audit Event. Needs `tenant_admin`, `agent_operator` or `developer`. Answers 201 with the recorded items, or 404 `not_found` for an unknown run.",
    "operationId": "record_components_v1_evidence_runs__run_id__components_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the agent run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ComponentsIn"
       }
      }
     },
     "description": "Optional step and 1 to 100 components.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Record Components V1 Evidence Runs  Run Id  Components Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Record the components of a run",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/runs/{run_id}/configuration": {
   "get": {
    "description": "Rebuilds the execution configuration of an agent run: agent version and manifest digest, components reported by kind (model, prompt, tool, skill, plugin) with their versions and digests, and the policy decisions recorded for the run. Needs `auditor`, `security_officer` or `tenant_admin`, `agent_operator` or `developer`. The read is recorded in the access log. Answers 404 `not_found` for an unknown run.",
    "operationId": "run_configuration_v1_evidence_runs__run_id__configuration_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the agent run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Run Configuration V1 Evidence Runs  Run Id  Configuration Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the execution configuration of a run",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/seals": {
   "get": {
    "description": "Lists the seals of the tenant chain: number, sequence range, Merkle root, first and last hashes, previous seal hash, key id, signature and date. Needs `auditor`, `security_officer` or `tenant_admin`. The read is recorded in the access log.",
    "operationId": "list_seals_v1_evidence_seals_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Seals V1 Evidence Seals Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the audit seals",
    "tags": [
     "evidence"
    ]
   },
   "post": {
    "description": "Writes a seal over the events written since the previous seal (up to the platform maximum per seal) and returns it (201). Needs `security_officer` or `auditor`. Answers 409 `audit_nothing_to_seal` when no event is waiting, 503 `audit_seal_key_unavailable` without signing key.",
    "operationId": "create_seal_v1_evidence_seals_post",
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Seal V1 Evidence Seals Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Seal the audit chain now",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/seals/{seal_id}/verify": {
   "get": {
    "description": "Recomputes the seal from the events it covers and the seals before it and checks its signature. Returns `seal`, `valid` and `failures`. Needs `auditor`, `security_officer` or `tenant_admin`. Answers 404 `not_found` for an unknown seal. The verification is recorded in the access log.",
    "operationId": "verify_seal_v1_evidence_seals__seal_id__verify_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the seal.",
      "in": "path",
      "name": "seal_id",
      "required": true,
      "schema": {
       "title": "Seal Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Verify Seal V1 Evidence Seals  Seal Id  Verify Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Verify an audit seal",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/evidence/verify": {
   "get": {
    "description": "Verifies the whole tenant chain and every seal and returns `tenant_id`, `valid`, `chain` (hash chain result), `seals` (count and failures), `clock` (timestamp failures) and `events` (number checked). Needs `auditor`, `security_officer` or `tenant_admin`. The verification is recorded in the access log.",
    "operationId": "verify_all_v1_evidence_verify_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Verify All V1 Evidence Verify Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Verify the chain and every seal",
    "tags": [
     "evidence"
    ]
   }
  },
  "/v1/file-security/policy": {
   "get": {
    "description": "Effective policy of the tenant: the locked rules, every editable rule (stored values over the defaults, the size never above the platform ceiling `EAI_FILE_SCAN_MAX_BYTES`), the known file types, and when and by whom it was last changed. Requires a tenant principal with `tenant_admin`, `security_officer` or `auditor` (403 `forbidden`).",
    "operationId": "get_policy_v1_file_security_policy_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Policy V1 File Security Policy Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the file security policy",
    "tags": [
     "file-security"
    ]
   },
   "put": {
    "description": "Changes the editable rules given in the body; the other rules keep their value. Sizes may only be tighter than the platform ceiling, and the locked rules never change (422 `file_security_rule_locked`). An unknown field, an unknown type or a value out of bounds answers 422 `invalid_request` with the field and the reason. Requires a tenant principal with `security_officer` or `tenant_admin` (403 `forbidden`). The change is audited (`file_security.policy.update`) with the values before and after; the answer is the new effective policy.",
    "operationId": "put_policy_v1_file_security_policy_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__file_security__PolicyIn"
       }
      }
     },
     "description": "Editable rules to change; omitted fields keep their value.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Policy V1 File Security Policy Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change the file security policy",
    "tags": [
     "file-security"
    ]
   }
  },
  "/v1/file-security/scans": {
   "get": {
    "description": "Scan records of the tenant, newest first; a principal without a reader role (`tenant_admin`, `security_officer`, `auditor`) only sees its own scans. Requires a tenant principal. An unknown status, verdict or source answers 400 `invalid_request`; a malformed cursor 400 `invalid_cursor`.",
    "operationId": "list_scans_v1_file_security_scans_get",
    "parameters": [
     {
      "description": "Only records in this status: `quarantined`, `released` or `blocked`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only records with this verdict: `clean`, `malware`, `suspicious`, `unscannable`, `scan_error` or `policy_violation`.",
      "in": "query",
      "name": "verdict",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Verdict"
      }
     },
     {
      "description": "Only files from this entry point: `knowledge`, `media`, `multimodal`, `transcription`, `connector`, `channel` or `api`.",
      "in": "query",
      "name": "source",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Source"
      }
     },
     {
      "description": "Maximum number of records in one page: 50 by default, capped at 500.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the newest records.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Scans V1 File Security Scans Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the scan records",
    "tags": [
     "file-security"
    ]
   },
   "post": {
    "description": "Scans a file without ingesting it and answers 201 with the record, `released` or `blocked` (a blocked file is not an error here). Any tenant principal may call it (403 `tenant_required` otherwise).\n\nSteps:\n\n1. The record is written as `quarantined`.\n2. Built in checks apply the tenant policy (size, type, archives, type mismatch, macros); a file over the size limit skips the engines.\n3. ClamAV and YARA-X scan the bytes; the verdict follows the precedence malware, suspicious, unscannable, policy violation, scan error.\n4. The record becomes `released` or `blocked`, a blocked file keeps an encrypted sample when the policy says so, and the scan is audited (`file_security.scan`), with a security event for a blocked file.\n\nErrors: 400 `invalid_request` for invalid JSON, missing `content_base64` or `file`, or invalid base64; 503 `file_scan_unavailable` when the analysis itself fails (the record stays quarantined).",
    "operationId": "create_scan_v1_file_security_scans_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "properties": {
         "content_base64": {
          "type": "string"
         },
         "filename": {
          "type": "string"
         },
         "mime_type": {
          "type": "string"
         }
        },
        "required": [
         "content_base64"
        ],
        "type": "object"
       }
      },
      "multipart/form-data": {
       "schema": {
        "properties": {
         "file": {
          "format": "binary",
          "type": "string"
         },
         "filename": {
          "type": "string"
         },
         "mime_type": {
          "type": "string"
         }
        },
        "required": [
         "file"
        ],
        "type": "object"
       }
      }
     },
     "description": "Either JSON `{content_base64, filename?, mime_type?}` or `multipart/form-data` with a `file` part and the optional `filename` and `mime_type` fields (they override the values of the part).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Scan V1 File Security Scans Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Scan a file without ingesting it",
    "tags": [
     "file-security"
    ]
   }
  },
  "/v1/file-security/scans/{scan_id}": {
   "get": {
    "description": "One scan record: status, verdict, reasons, source and its reference, file name, declared and detected type, size, SHA-256, answer of each engine, whether a sample is kept, the scan it rescans, creator and dates (creation, scan, sample expiry). Requires a tenant principal; a record of someone else is visible only to `tenant_admin`, `security_officer` and `auditor` (404 `not_found` otherwise).",
    "operationId": "get_scan_v1_file_security_scans__scan_id__get",
    "parameters": [
     {
      "description": "Identifier of the scan record.",
      "in": "path",
      "name": "scan_id",
      "required": true,
      "schema": {
       "title": "Scan Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Scan V1 File Security Scans  Scan Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a scan record",
    "tags": [
     "file-security"
    ]
   }
  },
  "/v1/file-security/scans/{scan_id}/rescan": {
   "post": {
    "description": "Scans the retained sample of a blocked file again, for example after a signature update, and answers 201 with a new record whose `rescan_of` names the original scan. The original upload is never released: a clean result only informs. Requires a tenant principal with `security_officer` or `tenant_admin` (403 `forbidden`). Without a retained sample: 409 `file_sample_unavailable`; unknown or invisible scan: 404 `not_found`.",
    "operationId": "rescan_v1_file_security_scans__scan_id__rescan_post",
    "parameters": [
     {
      "description": "Identifier of the blocked scan record whose sample is scanned again.",
      "in": "path",
      "name": "scan_id",
      "required": true,
      "schema": {
       "title": "Scan Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rescan V1 File Security Scans  Scan Id  Rescan Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Rescan the sample of a blocked file",
    "tags": [
     "file-security"
    ]
   }
  },
  "/v1/file-security/scans/{scan_id}/sample": {
   "delete": {
    "description": "Deletes the encrypted sample of a blocked file now, without waiting for the end of its retention, and answers `sample_retained: false`. The purge is audited (`file_security.sample.purge`) with the SHA-256 of the file. Requires a tenant principal with `security_officer` or `tenant_admin` (403 `forbidden`). A scan that is unknown or not visible to the caller answers 404 `not_found`.",
    "operationId": "purge_sample_v1_file_security_scans__scan_id__sample_delete",
    "parameters": [
     {
      "description": "Identifier of the scan record.",
      "in": "path",
      "name": "scan_id",
      "required": true,
      "schema": {
       "title": "Scan Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Purge Sample V1 File Security Scans  Scan Id  Sample Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Purge the sample of a blocked file",
    "tags": [
     "file-security"
    ]
   }
  },
  "/v1/file-security/stats": {
   "get": {
    "description": "Number of scans over the last `window_hours` hours, by status, by verdict and by source, with the time of the last blocked file. Readers (`tenant_admin`, `security_officer`, `auditor`) count every scan of the tenant, anyone else only its own. Requires a tenant principal. A window outside 1 to 8784 hours answers 400 `invalid_request`.",
    "operationId": "scan_stats_v1_file_security_stats_get",
    "parameters": [
     {
      "description": "Length of the window in hours, 1 to 8784 (366 days), default 24.",
      "in": "query",
      "name": "window_hours",
      "required": false,
      "schema": {
       "default": 24,
       "title": "Window Hours",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Scan Stats V1 File Security Stats Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the scan statistics",
    "tags": [
     "file-security"
    ]
   }
  },
  "/v1/file-security/status": {
   "get": {
    "description": "Mode (`enforce` or `dev`), readiness, pipeline and every ClamAV gateway and YARA-X worker, probed live: version, signature version, publication and age with a `stale` flag against the policy, rules version, hash, count and load time, latency. The instance is ready when each engine has at least one healthy endpoint (in enforce mode, or when it is configured). Requires `tenant_admin`, `security_officer` or `auditor` (403 `forbidden`).",
    "operationId": "file_security_status_v1_file_security_status_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response File Security Status V1 File Security Status Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the scan engines status",
    "tags": [
     "file-security"
    ]
   }
  },
  "/v1/finops/alerts": {
   "get": {
    "description": "Budget, quota and billing variance alerts of the tenant, newest first, with their message in the language of the request. One page only. Requires a reader role and a tenant principal.",
    "operationId": "get_alerts_v1_finops_alerts_get",
    "parameters": [
     {
      "description": "Only alerts of this kind: `budget`, `quota` or `variance`.",
      "in": "query",
      "name": "kind",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "budget",
          "quota",
          "variance"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Kind"
      }
     },
     {
      "description": "Maximum number of alerts: 50 by default, capped at 500.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Alerts V1 Finops Alerts Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the FinOps alerts",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/allocation-policies": {
   "get": {
    "description": "Policies that turn GPU samples into a cost (GPU hourly cost, energy, PUE, storage and overhead) per deployment pattern and GPU model. Requires a reader role.",
    "operationId": "list_allocation_policies_v1_finops_allocation_policies_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Allocation Policies V1 Finops Allocation Policies Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the GPU allocation policies",
    "tags": [
     "finops"
    ]
   },
   "post": {
    "description": "Creates a policy that prices the GPU samples of the matching deployments and answers 201. The most specific deployment pattern wins. Cost of one sample of `s` seconds at `P` watts: GPU `s / 3600 * gpu_hourly_cost`, energy `P * s / 3600 / 1000 * energy_kwh_price * pue`, storage `storage_gb * storage_gb_month_price * (s / 3600) / 730`, total multiplied by `1 + overhead_pct / 100`. Audited. Requires `platform_admin`.",
    "operationId": "create_allocation_policy_v1_finops_allocation_policies_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AllocationPolicyIn"
       }
      }
     },
     "description": "The new allocation policy.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Allocation Policy V1 Finops Allocation Policies Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a GPU allocation policy",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/estimate": {
   "post": {
    "description": "Prices a planned call with the price card in force (most specific model pattern and region first), converts it to the tenant currency and checks it against the matching quotas, without reserving anything. Reasoning tokens are added according to the billing mode of the card. No card answers 404 `price_card_not_found`; a missing FX rate 422 `fx_rate_missing`. Requires a usage or reader role and a tenant principal.",
    "operationId": "post_estimate_v1_finops_estimate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EstimateIn"
       }
      }
     },
     "description": "The planned call to price.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Post Estimate V1 Finops Estimate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Estimate the cost of a call",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/fx-rates": {
   "get": {
    "description": "Exchange rates (global ones and those of the tenant) by base, quote and newest date first, with their source. Requires a reader role.",
    "operationId": "get_fx_rates_v1_finops_fx_rates_get",
    "parameters": [
     {
      "description": "Only rates of this base currency (ISO 4217).",
      "in": "query",
      "name": "base",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Base"
      }
     },
     {
      "description": "Only rates of this quote currency (ISO 4217).",
      "in": "query",
      "name": "quote",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Quote"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Fx Rates V1 Finops Fx Rates Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the FX rates",
    "tags": [
     "finops"
    ]
   },
   "put": {
    "description": "Adds or replaces 1 to 1000 exchange rates (same base, quote and date: replaced) for the tenant, or global rates for a platform administrator without tenant, and answers the number updated with the full list. Conversions go through `USD` as pivot when no direct rate exists. Audited. Requires `finops` or `tenant_admin` (`platform_admin` for global rates).",
    "operationId": "put_fx_rates_v1_finops_fx_rates_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/FxRatesIn"
       }
      }
     },
     "description": "The rates to store.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Fx Rates V1 Finops Fx Rates Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set FX rates",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/gpu/allocation": {
   "get": {
    "description": "Cost of the local GPU deployments over the window, computed from the GPU samples and the allocation policies, and shared between tenants in proportion to the GPU seconds of their usage events on each deployment. A tenant sees its own share; a platform administrator without tenant sees every tenant. Requires a reader role.",
    "operationId": "get_gpu_allocation_v1_finops_gpu_allocation_get",
    "parameters": [
     {
      "description": "Start of the window, ISO 8601. Default: one day before `to`.",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "description": "End of the window, ISO 8601. Default: now.",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Gpu Allocation V1 Finops Gpu Allocation Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the GPU cost allocation",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/gpu/samples": {
   "post": {
    "description": "Stores GPU utilization samples (typically from DCGM), 1 to 10000 per call, used for the GPU cost allocation. One audit event per batch. Requires `platform_admin`.",
    "operationId": "post_gpu_samples_v1_finops_gpu_samples_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/GpuSamplesIn"
       }
      }
     },
     "description": "Batch of GPU samples.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Post Gpu Samples V1 Finops Gpu Samples Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ingest GPU samples",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/media-costs/estimate": {
   "post": {
    "description": "Prices up to 100 media items with the revision in force at their date (exact resource first, then the provider wide `*` revision). An item without price comes back with `amount: null`, `status: unavailable` and `reason: price_unknown`; `total` is given only when every item is priced in one currency (`complete: true`). Invalid items answer 422 `media_price_invalid` with the field. Requires a reader role or `agent`, and a tenant principal.",
    "operationId": "media_cost_estimate_v1_finops_media_costs_estimate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`items`: 1 to 100 objects with `unit` (`audio_second`, `image`, `video_second`, `gpu_second`, `storage_gb_month`), `provider`, `quantity` (positive number), optional `resource` (default `*`) and `at` (ISO 8601, default now).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Media Cost Estimate V1 Finops Media Costs Estimate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Estimate media costs",
    "tags": [
     "finops",
     "finops"
    ]
   }
  },
  "/v1/finops/media-prices": {
   "get": {
    "description": "Dated media price revisions of the tenant by unit, provider, resource and date, with the list of supported units. An unknown unit answers 422 `media_price_invalid`. Requires a reader role and a tenant principal.",
    "operationId": "media_price_list_v1_finops_media_prices_get",
    "parameters": [
     {
      "description": "Only prices of this unit: `audio_second`, `image`, `video_second`, `gpu_second` or `storage_gb_month`.",
      "in": "query",
      "name": "unit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Unit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Media Price List V1 Finops Media Prices Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the media prices",
    "tags": [
     "finops",
     "finops"
    ]
   },
   "post": {
    "description": "Adds a dated price revision for a media unit and answers 201. A revision never rewrites an older one. The same unit, provider, resource and start date answers 409 `media_price_exists`; an invalid field 422 `media_price_invalid`. Audited. Requires `finops` or `tenant_admin`, and a tenant principal.",
    "operationId": "media_price_create_v1_finops_media_prices_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`unit` (`audio_second`, `image`, `video_second`, `gpu_second`, `storage_gb_month`), `provider`, `unit_price` (number, at least 0), `currency` (ISO 4217), `source` (where the price comes from, required), optional `resource` (default `*`, the whole provider) and `effective_from` (ISO 8601, default now).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Media Price Create V1 Finops Media Prices Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add a media price revision",
    "tags": [
     "finops",
     "finops"
    ]
   }
  },
  "/v1/finops/price-cards": {
   "get": {
    "description": "Price cards visible to the caller (global and tenant ones), by provider, model pattern and start date. Only active cards unless `include_retired` or `at` is given. One page only. Requires a reader role.",
    "operationId": "list_price_cards_v1_finops_price_cards_get",
    "parameters": [
     {
      "description": "Only cards of this provider.",
      "in": "query",
      "name": "provider",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Provider"
      }
     },
     {
      "description": "Only cards whose model pattern matches this model id (case insensitive glob).",
      "in": "query",
      "name": "model",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Model"
      }
     },
     {
      "description": "Only cards in force at this date and time (ISO 8601), retired ones included.",
      "in": "query",
      "name": "at",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "At"
      }
     },
     {
      "description": "Include retired cards (default false).",
      "in": "query",
      "name": "include_retired",
      "required": false,
      "schema": {
       "default": false,
       "title": "Include Retired",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Price Cards V1 Finops Price Cards Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the price cards",
    "tags": [
     "finops"
    ]
   },
   "post": {
    "description": "Creates a price card for the tenant (or a global one for a platform administrator without tenant) and answers 201. The card in force for the same provider, model pattern, region and usage type is closed at the new start date; a card starting later in the new validity answers 409 `conflict`. Unknown price keys, negative prices or a card without any price answer 422 `price_card_invalid`. Audited. Requires `finops` or `tenant_admin` (`platform_admin` for a global card).",
    "operationId": "create_price_card_v1_finops_price_cards_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PriceCardIn"
       }
      }
     },
     "description": "The new price card.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Price Card V1 Finops Price Cards Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a price card",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/price-cards/{card_id}": {
   "get": {
    "description": "One price card with its prices, tiers, validity and status. Unknown id: 404 `not_found`. Requires a reader role.",
    "operationId": "get_price_card_v1_finops_price_cards__card_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the price card.",
      "in": "path",
      "name": "card_id",
      "required": true,
      "schema": {
       "title": "Card Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Price Card V1 Finops Price Cards  Card Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a price card",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/price-cards/{card_id}/retire": {
   "post": {
    "description": "Marks the card `retired` and ends its validity at `at` (default now) when it was still open after that date. Past usage keeps the price it was costed with. Unknown id: 404 `not_found`. Audited. Requires `finops` or `tenant_admin`.",
    "operationId": "retire_price_card_v1_finops_price_cards__card_id__retire_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the price card.",
      "in": "path",
      "name": "card_id",
      "required": true,
      "schema": {
       "title": "Card Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "Optional `{at}`: end of validity, ISO 8601 (default now)."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Retire Price Card V1 Finops Price Cards  Card Id  Retire Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Retire a price card",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/reconciliation/imports": {
   "get": {
    "description": "Billing exports imported by the tenant, with source, provider, file name, number of lines, total amount, currency and period. Requires a reader role and a tenant principal.",
    "operationId": "get_imports_v1_finops_reconciliation_imports_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Imports V1 Finops Reconciliation Imports Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the billing imports",
    "tags": [
     "finops"
    ]
   },
   "post": {
    "description": "Parses a billing export of a provider, converts every line to the tenant currency and stores it, then answers 201 with the import (line count, total, period). An export that cannot be read answers 422 `import_invalid` with the reason. Run the reconciliation afterwards. Audited. Requires `finops` or `tenant_admin`, and a tenant principal.",
    "operationId": "post_import_v1_finops_reconciliation_imports_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ImportIn"
       }
      }
     },
     "description": "The billing export and its format.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Post Import V1 Finops Reconciliation Imports Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Import a billing export",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/reconciliation/report": {
   "get": {
    "description": "Measured against billed cost over the period, with the variance, the unmatched billing lines and the last 100 variance alerts. A `from` after `to` answers 422 `validation_error`. Requires a reader role and a tenant principal.",
    "operationId": "get_recon_report_v1_finops_reconciliation_report_get",
    "parameters": [
     {
      "description": "First day of the period (ISO 8601 date). Default: the first day of the month of `to`.",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "description": "Last day of the period (ISO 8601 date). Default: today.",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Recon Report V1 Finops Reconciliation Report Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the reconciliation report",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/reconciliation/run": {
   "post": {
    "description": "Allocates the imported billed lines of the period to the usage events: a line with a `provider_request_id` goes to that event, other lines are split pro rata of the measured cost of the events of the same provider, model and day (evenly when nothing was measured); lines without candidate event are reported as unmatched. Variance alerts are raised over the tenant threshold. Audited. Requires `finops` or `tenant_admin`, and a tenant principal.",
    "operationId": "post_recon_run_v1_finops_reconciliation_run_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReconRunIn"
       }
      }
     },
     "description": "Period to reconcile; the body may be omitted."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Post Recon Run V1 Finops Reconciliation Run Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run the billing reconciliation",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/settings": {
   "get": {
    "description": "Currency, monthly budget, variance threshold and reservation lifetime of the tenant (defaults: `USD`, no budget, 10 percent, 900 seconds). Requires a reader role and a tenant principal.",
    "operationId": "get_settings__v1_finops_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Settings  V1 Finops Settings Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the FinOps settings",
    "tags": [
     "finops"
    ]
   },
   "put": {
    "description": "Changes the given settings of the tenant; omitted or null fields keep their value. Audited (`finops.settings.update`). Requires `finops` or `tenant_admin`, and a tenant principal.",
    "operationId": "put_settings_v1_finops_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SettingsIn"
       }
      }
     },
     "description": "Settings to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Settings V1 Finops Settings Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change the FinOps settings",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/summary": {
   "get": {
    "description": "Usage events of the tenant grouped by one dimension, per currency: number of events, tokens, GPU seconds, estimated, measured and billed amounts (billed is null when nothing was reconciled). An unknown grouping answers 400 `finops_group_by_invalid`. Requires a reader role and a tenant principal.",
    "operationId": "get_summary_v1_finops_summary_get",
    "parameters": [
     {
      "description": "Grouping: `model` (default), `tenant`, `project`, `agent`, `provider`, `usage_type` or `day`.",
      "in": "query",
      "name": "group_by",
      "required": false,
      "schema": {
       "default": "model",
       "title": "Group By",
       "type": "string"
      }
     },
     {
      "description": "Start of the period, ISO 8601 (included).",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "description": "End of the period, ISO 8601 (excluded).",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Summary V1 Finops Summary Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Summarize the spend",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/usage": {
   "get": {
    "description": "Usage events of the tenant with their units and their estimated, measured and billed costs, filtered and paginated. Requires a reader role and a tenant principal.",
    "operationId": "get_usage_v1_finops_usage_get",
    "parameters": [
     {
      "description": "Only events of this project.",
      "in": "query",
      "name": "project_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project Id"
      }
     },
     {
      "description": "Only events of this agent.",
      "in": "query",
      "name": "agent_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Agent Id"
      }
     },
     {
      "description": "Only events of this session.",
      "in": "query",
      "name": "session_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Session Id"
      }
     },
     {
      "description": "Only events of this agent run.",
      "in": "query",
      "name": "run_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Run Id"
      }
     },
     {
      "description": "Only events of this task.",
      "in": "query",
      "name": "task_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Task Id"
      }
     },
     {
      "description": "Only events of this model.",
      "in": "query",
      "name": "model_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Model Id"
      }
     },
     {
      "description": "Only events of this provider.",
      "in": "query",
      "name": "provider",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Provider"
      }
     },
     {
      "description": "Only events of this usage type of Usage Event v1, for example `llm`, `embeddings`, `image_generation`, `stt`, `tool` or `gpu_local`.",
      "in": "query",
      "name": "usage_type",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Usage Type"
      }
     },
     {
      "description": "Only events with this status.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only events of this local model deployment.",
      "in": "query",
      "name": "deployment_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Deployment Id"
      }
     },
     {
      "description": "Start of the period, ISO 8601.",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "description": "End of the period, ISO 8601.",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     },
     {
      "description": "Maximum number of events in one page: 50 by default, capped at 500.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Usage V1 Finops Usage Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the usage events",
    "tags": [
     "finops"
    ]
   },
   "post": {
    "description": "Validates a Usage Event v1, prices it (measured cost in the tenant currency) and stores it; answers 201, or 200 with `duplicate: true` when the same `event_id` was already stored. An invalid event answers 422 `usage_event_invalid` with the errors; an event of another tenant 403 `usage_tenant_mismatch`. One audit event per call, never the payload. Requires `finops`, `tenant_admin`, `agent` or `developer`, and a tenant principal.",
    "operationId": "ingest_usage_v1_finops_usage_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Event",
        "type": "object"
       }
      }
     },
     "description": "One Usage Event v1 (`event_id`, `tenant_id`, `occurred_at`, `usage_type`, `units`, `pricing`, scope identifiers...), as defined by the contract.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Ingest Usage V1 Finops Usage Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ingest a usage event",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/finops/usage/batch": {
   "post": {
    "description": "Ingests up to 1000 usage events, each in its own savepoint: the answer lists every event as `created`, `duplicate` or `error` (with code, message and details) and the counts. More than 1000 events answer 413 `batch_too_large`; a body without an `events` list 422 `validation_error`. One audit event per batch. Requires `finops`, `tenant_admin`, `agent` or `developer`, and a tenant principal.",
    "operationId": "ingest_usage_batch_v1_finops_usage_batch_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`{events: [...]}`: a list of Usage Event v1 objects.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Ingest Usage Batch V1 Finops Usage Batch Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ingest usage events in batch",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/gateway/audio/speech": {
   "post": {
    "description": "Text to speech through the TTS adapter, in the OpenAI `audio/speech` format; the audio comes back as is (`audio/*`). The tenant kill switch, data classification and caller clearance, secret isolation and audit apply, and the cost is reserved from the quotas by number of characters. Requires a tenant principal with the scope `models:invoke`. Without a configured adapter: 501 `adapter_not_available`; adapter unreachable: 502 `upstream_error`.",
    "operationId": "gateway_tts_v1_gateway_audio_speech_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "OpenAI speech request (`model`, `input`, `voice`, `response_format`...) plus the optional `eai` object (`data_classification`, `agent_id`, `run_id`).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Synthesize speech from text",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/gateway/audio/transcriptions": {
   "post": {
    "description": "Speech to text through the STT adapter, in the OpenAI `audio/transcriptions` format. Requires a tenant principal with the scope `models:invoke`.\n\nSteps:\n\n1. The body is read as multipart (`file` part) or JSON (`content_base64`); `model` is required and `timestamp_granularities` needs `response_format: verbose_json` (422 `parameter_invalid` otherwise).\n2. The audio goes through file security (quarantine, ClamAV, YARA-X, validation): a blocked file answers 422 `file_blocked`, an unavailable scan 503 `file_scan_unavailable`.\n3. The tenant kill switch, classification, DLP on the file and the cost reservation (by audio length) apply, then the adapter is called.\n4. The transcript (JSON `text` fields, or text, SRT and VTT answers) is scanned by the DLP of the tenant before it is returned; the call is audited with the SHA-256 of the file.",
    "operationId": "gateway_stt_v1_gateway_audio_transcriptions_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "properties": {
         "content_base64": {
          "type": "string"
         },
         "eai": {
          "type": "object"
         },
         "filename": {
          "type": "string"
         },
         "language": {
          "type": "string"
         },
         "mime_type": {
          "type": "string"
         },
         "model": {
          "type": "string"
         },
         "prompt": {
          "type": "string"
         },
         "response_format": {
          "enum": [
           "json",
           "text",
           "srt",
           "verbose_json",
           "vtt"
          ],
          "type": "string"
         },
         "temperature": {
          "maximum": 1.0,
          "minimum": 0.0,
          "type": "number"
         },
         "timestamp_granularities": {
          "description": "needs response_format verbose_json",
          "items": {
           "enum": [
            "word",
            "segment"
           ],
           "type": "string"
          },
          "type": "array"
         }
        },
        "required": [
         "content_base64",
         "model"
        ],
        "type": "object"
       }
      },
      "multipart/form-data": {
       "schema": {
        "properties": {
         "eai": {
          "description": "eai extension as a JSON object",
          "type": "string"
         },
         "file": {
          "format": "binary",
          "type": "string"
         },
         "language": {
          "type": "string"
         },
         "model": {
          "type": "string"
         },
         "prompt": {
          "type": "string"
         },
         "response_format": {
          "enum": [
           "json",
           "text",
           "srt",
           "verbose_json",
           "vtt"
          ],
          "type": "string"
         },
         "temperature": {
          "maximum": 1.0,
          "minimum": 0.0,
          "type": "number"
         },
         "timestamp_granularities": {
          "description": "needs response_format verbose_json",
          "items": {
           "enum": [
            "word",
            "segment"
           ],
           "type": "string"
          },
          "type": "array"
         }
        },
        "required": [
         "file",
         "model"
        ],
        "type": "object"
       }
      }
     },
     "description": "Multipart `file` plus `model`, `language`, `prompt`, `response_format` (`json`, `text`, `srt`, `verbose_json`, `vtt`), `temperature` (0 to 1), `timestamp_granularities` (`word`, `segment`) and `eai` (a JSON object as text); or JSON with `content_base64`, `mime_type`, `filename` and the same fields.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Transcribe an audio file",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/gateway/chat/completions": {
   "post": {
    "description": "OpenAI compatible chat completion through every control of the gateway; with `stream: true` the answer is Server-Sent Events, with the cost guardrails checked during the stream. Requires a tenant principal (403 `platform_only`) whose credential carries the scope `models:invoke`.\n\nSteps:\n\n1. Secret isolation: provider credentials or addresses in the body are refused (400 `credentials_not_allowed`).\n2. Kill switches, application grant, model status and allow lists, region, data classification against the model ceiling and the caller clearance, isolation mode (403 with a stable code such as `model_blocked`, `classification_exceeded`, `isolation_external_route`).\n3. DLP masks or blocks sensitive data (422 `dlp_blocked`), prompt injection screening (403 `prompt_injection_blocked` in block mode), context compression when the window is exceeded (422 `context_overflow` when impossible).\n4. Cost estimate against the per request limit and the monthly budget (429 `budget_exceeded`), then the policy decision `model.invoke` (403 `policy_denied`).\n5. Call through LiteLLM with the allowed fallbacks (502 `upstream_error` when all fail), response DLP, usage event and audit with hashes only.\n\nWarnings (deprecated model, masked data, compressed context) are returned with the answer; headers `X-EAI-Decision-Id`, `X-EAI-Model`, `X-EAI-Cost-Estimated`, `X-EAI-Cost-Measured` and `X-EAI-Injection-Risk` describe the call.",
    "operationId": "gateway_chat_v1_gateway_chat_completions_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "OpenAI chat request (`model` is the registry id, `messages`, `stream`, `max_tokens`, `tools`...) plus the optional `eai` object: `data_classification` (`public`, `internal` by default, `confidential`, `restricted`, `secret`), `agent_id`, `session_id`, `run_id`, `purpose`, `project_id`, `effort`, `max_cost`, `fallback_policy` and allow lists that can only narrow the tenant ones (`provider_allow`, `model_allow`, `region_allow`).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Call a chat model",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/gateway/embeddings": {
   "post": {
    "description": "OpenAI compatible embeddings through the same controls as chat (kill switches, allow lists, classification, DLP on each input, cost guardrails, policy decision, audit). The model must declare the embeddings capability and, when `dimensions` is given, support it (422 `capability_not_supported`, 422 `embedding_dimensions_invalid`). Requires a tenant principal with the scope `models:invoke`.",
    "operationId": "gateway_embeddings_v1_gateway_embeddings_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "OpenAI embeddings request (`model`, `input` as a text or a list, optional `dimensions`) plus the optional `eai` object.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Compute embeddings",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/gateway/estimate": {
   "post": {
    "description": "Runs every preflight control of the gateway without calling the model and returns the resolved model, decision id, input tokens, maximum output tokens, estimator, estimated cost, cost limit, fallbacks, warnings and context plan. A request refused by a control answers with the same error as the real call. Requires a tenant principal with the scope `models:invoke`.",
    "operationId": "gateway_estimate_v1_gateway_estimate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "The body of the call to estimate, with optional `kind` (`chat`, `embeddings` or `rerank`); without `kind` it is guessed from `input` (embeddings) or `query` (rerank), else chat.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Estimate a gateway call",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/gateway/images/generations": {
   "post": {
    "description": "Image generation through the image adapter in the OpenAI format. The prompt goes through the DLP of the tenant (422 `dlp_blocked`), the kill switch, classification, secret isolation and audit apply, and the cost is reserved by number of images; text fields of the answer (`revised_prompt`) are scanned too. Requires a tenant principal with the scope `models:invoke`. Without a configured adapter: 501 `adapter_not_available`.",
    "operationId": "gateway_images_v1_gateway_images_generations_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "OpenAI image request (`model`, `prompt`, `n`, `size`...) plus the optional `eai` object.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Generate images",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/gateway/rerank": {
   "post": {
    "description": "Reranks `documents` against a `query` through the same controls as chat (DLP on the query, cost guardrails, policy decision, audit). The model must declare the rerank capability (422 `capability_not_supported`). Requires a tenant principal with the scope `models:invoke`.",
    "operationId": "gateway_rerank_v1_gateway_rerank_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "Rerank request: `model`, `query`, `documents` (texts or objects), optional `top_n`, plus the optional `eai` object.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Rerank documents",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/gateway/video/generations": {
   "post": {
    "description": "Starts a video generation job on the video adapter, with the same kill switch, classification, DLP of the prompt, cost reservation and audit as the other adapters; read the job with `GET /v1/gateway/video/generations/{job_id}`. Requires a tenant principal with the scope `models:invoke`. Without a configured adapter: 501 `adapter_not_available`.",
    "operationId": "gateway_video_v1_gateway_video_generations_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "Video generation request of the adapter (`model`, `prompt` and its options) plus the optional `eai` object.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start a video generation",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/gateway/video/generations/{job_id}": {
   "get": {
    "description": "State and result of a video generation job, read from the video adapter with the same kill switch and audit as the other adapter calls. Requires a tenant principal (403 `platform_only` otherwise) whose credential carries the scope `models:invoke`. Without a configured video adapter: 501 `adapter_not_available`.",
    "operationId": "gateway_video_get_v1_gateway_video_generations__job_id__get",
    "parameters": [
     {
      "description": "Identifier of the job returned by `POST /v1/gateway/video/generations`.",
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
       "title": "Job Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a video generation job",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/governance/registry": {
   "get": {
    "description": "Inventory of agents, models, providers, tools, skills, plugins and connectors (5000 items per kind at most, by name), one list per kind (`agents`, `models`, ...), with a `summary` per kind: total, count by status, count by risk level (`unassessed` when none) and number of items without owner. `missing_sources` lists the tables not installed on this instance; their list is empty. Requires a tenant principal (403 `tenant_required`). An unknown kind answers 400 `invalid_request` with the allowed kinds.",
    "operationId": "registry_v1_governance_registry_get",
    "parameters": [
     {
      "description": "Comma separated kinds to return, among `agent`, `model`, `provider`, `tool`, `skill`, `plugin`, `connector`. Omit it for every kind.",
      "in": "query",
      "name": "kind",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Kind"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Registry V1 Governance Registry Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the governance registry",
    "tags": [
     "governance"
    ]
   }
  },
  "/v1/heartbeats": {
   "get": {
    "description": "Liveness of the runs expected to send heartbeats (`running` and `waiting_input`). By default only the stale ones (no heartbeat within the threshold) are returned, with `active`, `stale_count` and `stale_after_seconds`. With `format=prometheus` the answer is Prometheus exposition text (`eai_runs_total`, `eai_runs_active`, `eai_runs_stale`, `eai_heartbeat_stale_threshold_seconds`).",
    "operationId": "list_heartbeats_v1_heartbeats_get",
    "parameters": [
     {
      "description": "Threshold in seconds after which a run without heartbeat is stale (1 to 86400). Default: the platform setting, 300 seconds unless configured.",
      "in": "query",
      "name": "stale_after",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 86400,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Stale After"
      }
     },
     {
      "description": "When true, every active run is returned, stale or not. Default false.",
      "in": "query",
      "name": "all",
      "required": false,
      "schema": {
       "default": false,
       "title": "All",
       "type": "boolean"
      }
     },
     {
      "description": "Answer format: `json` (default) or `prometheus` (text/plain exposition format 0.0.4).",
      "in": "query",
      "name": "format",
      "required": false,
      "schema": {
       "default": "json",
       "enum": [
        "json",
        "prometheus"
       ],
       "title": "Format",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List run heartbeats",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/identity/group-mappings": {
   "get": {
    "description": "Lists every directory group mapping of the tenant with its group, project, role and quota profile. Needs `tenant_admin`, `security_officer` or `auditor` (403 `forbidden` otherwise). Not paginated: `next_cursor` is always null.",
    "operationId": "list_group_mappings_v1_identity_group_mappings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Group Mappings V1 Identity Group Mappings Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the group mappings",
    "tags": [
     "identity",
     "identity"
    ]
   },
   "post": {
    "description": "Maps a directory group to a project role and, optionally, a quota profile. Needs `tenant_admin`.\n\n1. Give the group name as it appears in the `groups` or `entra_groups` claim of the Keycloak token.\n2. Give the project by `project_id` or by `project` slug (one is required, 422 `validation_error` otherwise; unknown project: 404).\n3. Optionally give a quota profile by `quota_profile_id` or `quota_profile` name.\n\nAt the next OIDC sign in of each member, the platform adds the membership and the quota, and withdraws them when the group leaves the token. The same group, project and role twice answers 409 `conflict`. Writes the audit event `identity.group_mapping.create`.",
    "operationId": "create_group_mapping_v1_identity_group_mappings_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/GroupMappingIn"
       }
      }
     },
     "description": "Group, project, role and optional quota profile of the mapping.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Group Mapping V1 Identity Group Mappings Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a group mapping",
    "tags": [
     "identity",
     "identity"
    ]
   }
  },
  "/v1/identity/group-mappings/{mapping_id}": {
   "delete": {
    "description": "Deletes the mapping and withdraws what it granted (project memberships and quotas recorded as granted by this mapping); memberships granted by hand stay. Needs `tenant_admin`. Writes the audit event `identity.group_mapping.delete`. Answers 204, or 404 `not_found` for an unknown mapping.",
    "operationId": "delete_group_mapping_v1_identity_group_mappings__mapping_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the group mapping.",
      "in": "path",
      "name": "mapping_id",
      "required": true,
      "schema": {
       "title": "Mapping Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a group mapping",
    "tags": [
     "identity",
     "identity"
    ]
   },
   "get": {
    "description": "Returns one group mapping. Needs `tenant_admin`, `security_officer` or `auditor`. Answers 404 `not_found` for an unknown mapping.",
    "operationId": "get_group_mapping_v1_identity_group_mappings__mapping_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the group mapping.",
      "in": "path",
      "name": "mapping_id",
      "required": true,
      "schema": {
       "title": "Mapping Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Group Mapping V1 Identity Group Mappings  Mapping Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a group mapping",
    "tags": [
     "identity",
     "identity"
    ]
   },
   "patch": {
    "description": "Changes the group, project, role or quota profile of a mapping; only the fields sent change. `clear_quota_profile: true` detaches the profile. The new values apply at the next sign in of each member. Needs `tenant_admin`. A change that would duplicate another mapping answers 409 `conflict`; an unknown project or profile answers 404. Writes the audit event `identity.group_mapping.update`.",
    "operationId": "patch_group_mapping_v1_identity_group_mappings__mapping_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the group mapping.",
      "in": "path",
      "name": "mapping_id",
      "required": true,
      "schema": {
       "title": "Mapping Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/GroupMappingPatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Group Mapping V1 Identity Group Mappings  Mapping Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a group mapping",
    "tags": [
     "identity",
     "identity"
    ]
   }
  },
  "/v1/identity/quota-profiles": {
   "get": {
    "description": "Lists the quota profiles of the tenant (name, period, enforcement, cost and token limits, currency). Needs `tenant_admin`, `security_officer` or `auditor`.",
    "operationId": "list_quota_profiles_v1_identity_quota_profiles_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Quota Profiles V1 Identity Quota Profiles Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the quota profiles",
    "tags": [
     "identity",
     "identity"
    ]
   },
   "post": {
    "description": "Creates a reusable quota profile for group mappings. Needs `tenant_admin`. At least one of `limit_cost` and `limit_tokens` is required (422 `validation_error`). A name already used answers 409 `conflict`. Writes the audit event `identity.quota_profile.create`.",
    "operationId": "create_quota_profile_v1_identity_quota_profiles_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/QuotaProfileIn"
       }
      }
     },
     "description": "Name, period, enforcement and limits of the profile.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Quota Profile V1 Identity Quota Profiles Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a quota profile",
    "tags": [
     "identity",
     "identity"
    ]
   }
  },
  "/v1/identity/quota-profiles/{profile_id}": {
   "delete": {
    "description": "Deletes a quota profile. Needs `tenant_admin`. A profile still used by a group mapping cannot be deleted (409 `conflict`): detach it from the mappings first. Writes the audit event `identity.quota_profile.delete`. Answers 204, or 404 `not_found`.",
    "operationId": "delete_quota_profile_v1_identity_quota_profiles__profile_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the quota profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a quota profile",
    "tags": [
     "identity",
     "identity"
    ]
   },
   "patch": {
    "description": "Updates the period, enforcement or limits of a profile, and the user quotas already created from it through group mappings, in the same transaction. Needs `tenant_admin`. Writes the audit event `identity.quota_profile.update` with the number of quotas updated. Answers 404 `not_found` for an unknown profile.",
    "operationId": "patch_quota_profile_v1_identity_quota_profiles__profile_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the quota profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/QuotaProfilePatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Quota Profile V1 Identity Quota Profiles  Profile Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a quota profile",
    "tags": [
     "identity",
     "identity"
    ]
   }
  },
  "/v1/identity/whoami": {
   "get": {
    "description": "Returns the identity the platform resolved for this request, whatever the credential (OIDC token, portal session, API key, SPIFFE): `id`, `kind` (`user`, `service`, `agent`, `system`), `tenant_id`, `tenant_slug`, `roles`, `scopes`, `clearance`, `auth_method` and `display`. Read only, open to any authenticated caller, also while a local account must still change its password. Use it to check a new token or key.",
    "operationId": "whoami_v1_identity_whoami_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Whoami V1 Identity Whoami Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Show the calling identity",
    "tags": [
     "identity"
    ]
   }
  },
  "/v1/incidents": {
   "get": {
    "description": "Lists the incidents of the tenant, newest identifier first, paginated, optionally filtered by status and severity. Items do not carry the timeline nor the actions (read one incident for those). Open to any member of the tenant.",
    "operationId": "list_incidents_v1_incidents_get",
    "parameters": [
     {
      "description": "Only this status: `open`, `investigating`, `contained`, `resolved` or `closed`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only this severity: `sev1`, `sev2`, `sev3` or `sev4`.",
      "in": "query",
      "name": "severity",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Severity"
      }
     },
     {
      "description": "Maximum number of incidents in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Incidents V1 Incidents Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the incidents",
    "tags": [
     "incidents"
    ]
   },
   "post": {
    "description": "Opens an incident in status `open`, adds the `created` entry to the timeline and forwards it to the SIEM. Needs `tenant_admin`, `security_officer`, `developer` or `agent`. An unknown severity answers 400 `invalid_request`. Writes the audit event `incident.create`. The answer (201) carries the incident with its timeline.",
    "operationId": "create_incident_v1_incidents_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/IncidentIn"
       }
      }
     },
     "description": "Title, severity, description, category, resources and assignee.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Incident V1 Incidents Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Open an incident",
    "tags": [
     "incidents"
    ]
   }
  },
  "/v1/incidents/alerts": {
   "post": {
    "description": "Webhook receiver of Prometheus Alertmanager (payload version 4). Each alert is keyed by its `fingerprint`:\n\n1. a `firing` alert opens an incident of category `alert`, or updates the open incident with the same fingerprint;\n2. a `resolved` alert resolves it;\n3. the `severity` label gives the severity (`critical` or `page`: `sev1`, `high` or `error`: `sev2`, `warning`: `sev3`, `info` or `none`: `sev4`, default `sev3`).\n\nAuthentication: a service API key granted the scope `incidents:alerts` (or `incidents:*`) explicitly, or the role `alert_receiver`; the global scope `*` of an interactive session does not count (403 `forbidden`). Alerts land in the tenant of the key; a `tenant=<uuid>` label is honoured only for a key of a platform administrator. A status other than `firing` or `resolved` answers 400. Every change is audited (`incident.alert.open`, `incident.alert.update`, `incident.alert.resolve`) and forwarded to the SIEM. The answer gives `received` and one item per alert.",
    "operationId": "receive_alerts_v1_incidents_alerts_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AlertmanagerIn"
       }
      }
     },
     "description": "Alertmanager webhook payload, at most 500 alerts.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Receive Alerts V1 Incidents Alerts Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Receive Alertmanager alerts",
    "tags": [
     "incidents"
    ]
   }
  },
  "/v1/incidents/{incident_id}": {
   "get": {
    "description": "Returns the incident with its `timeline` (kind, message, data, actor, date) and its containment `actions` (action, target, status, result). Open to any member of the tenant. Answers 404 `not_found`.",
    "operationId": "get_incident_v1_incidents__incident_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the incident.",
      "in": "path",
      "name": "incident_id",
      "required": true,
      "schema": {
       "title": "Incident Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Incident V1 Incidents  Incident Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an incident",
    "tags": [
     "incidents"
    ]
   },
   "patch": {
    "description": "Changes the status, severity or assignee and optionally adds a note. Each change is added to the timeline and forwarded to the SIEM; moving to `resolved` or `closed` sets `resolved_at`. Needs `tenant_admin` or `security_officer`. An unknown status or severity answers 400 `invalid_request`. Writes the audit event `incident.update`.",
    "operationId": "patch_incident_v1_incidents__incident_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the incident.",
      "in": "path",
      "name": "incident_id",
      "required": true,
      "schema": {
       "title": "Incident Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/IncidentPatch"
       }
      }
     },
     "description": "Fields to change and an optional note.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Incident V1 Incidents  Incident Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update an incident",
    "tags": [
     "incidents"
    ]
   }
  },
  "/v1/incidents/{incident_id}/actions": {
   "post": {
    "description": "Runs a containment action through the domain that owns the target and records it on the incident. Needs `tenant_admin` or `security_officer`.\n\nActions: `suspend_agent`, `resume_agent`, `kill_agent` (target `id` or `name` of the agent); `suspend_model`, `disable_model` (target model, `scope: platform` for a shared model); `disable_provider`; `rotate_key`, `revoke_key` (target `kind`: `api_key` or `encryption_key`, and `grace_seconds` for an API key rotation).\n\nThe action status is `executed`, `failed` (the error is kept in the result) or `pending` with reason `requires_platform_admin` when a platform level model or provider is targeted by a tenant responder. An executed action moves an `open` or `investigating` incident to `contained`. A rotated API key returns its new secret once in `secret` (`shown_once: true`). An unknown action answers 400 `unknown_action`; a target without `id` or `name` 400 `invalid_request`. Writes the audit event `incident.action.<action>` and forwards it to the SIEM.",
    "operationId": "incident_action_v1_incidents__incident_id__actions_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the incident.",
      "in": "path",
      "name": "incident_id",
      "required": true,
      "schema": {
       "title": "Incident Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ActionIn"
       }
      }
     },
     "description": "Action, target and reason.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Incident Action V1 Incidents  Incident Id  Actions Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run a containment action",
    "tags": [
     "incidents"
    ]
   }
  },
  "/v1/knowledge-bases": {
   "get": {
    "description": "Knowledge bases of the tenant that the caller may read by their ACL, in name order, paginated with `cursor`.",
    "operationId": "list_kbs_v1_knowledge_bases_get",
    "parameters": [
     {
      "description": "Maximum number of knowledge bases in one page (default 50, capped at 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Kbs V1 Knowledge Bases Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the knowledge bases",
    "tags": [
     "knowledge"
    ]
   },
   "post": {
    "description": "Creates a knowledge base with its embedding model (default: the platform RAG embedding model), which must be approved, have the embeddings capability and accept the classification. `chunk_overlap` must be lower than `chunk_size` (400 `invalid_request`); an unknown classification answers 400. A name already used in the tenant answers 409 `conflict`. Needs `tenant_admin` or `developer`; the caller becomes ReBAC owner. Audited as `knowledge_base.create`.",
    "operationId": "create_kb_v1_knowledge_bases_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/KbIn"
       }
      }
     },
     "description": "Name, chunking, classification, ACL and embedding model of the knowledge base.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Kb V1 Knowledge Bases Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a knowledge base",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}": {
   "delete": {
    "description": "Deletes the knowledge base, its documents and their vectors in the vector store. Needs the ReBAC relation `owner`, and the caller must be `tenant_admin` or its creator (403 `forbidden`). 404 `not_found`; 503 `vector_store_unavailable`. Audited as `knowledge_base.delete`.",
    "operationId": "delete_kb_v1_knowledge_bases__kb_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a knowledge base",
    "tags": [
     "knowledge"
    ]
   },
   "get": {
    "description": "Returns the knowledge base with its document count, its ingestion and retrieval `pipeline`, the running `reindex` job if any and the `datasets` the caller may see. Needs the ReBAC relation `viewer` and read access by the ACL; otherwise 404 `not_found`.",
    "operationId": "get_kb_v1_knowledge_bases__kb_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Kb V1 Knowledge Bases  Kb Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a knowledge base",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/acl": {
   "put": {
    "description": "Replaces the readers and writers of the knowledge base. With `apply_to_documents`, the documents that inherit the knowledge base ACL (no readers of their own) and their chunks get the new readers; `documents_updated` gives their number. Needs the ReBAC relation `owner`, and the caller must be `tenant_admin`, `security_officer` or the creator. Audited as `knowledge_base.acl.update`; the retrieval cache is invalidated.",
    "operationId": "put_acl_v1_knowledge_bases__kb_id__acl_put",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AclIn"
       }
      }
     },
     "description": "The new ACL.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Acl V1 Knowledge Bases  Kb Id  Acl Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Replace the ACL of a knowledge base",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/documents": {
   "get": {
    "description": "Documents the caller may read (one of its identities in the document `readers`, classification within its clearance), paginated with `cursor`. Needs the ReBAC relation `viewer` and read access to the knowledge base.",
    "operationId": "list_documents_v1_knowledge_bases__kb_id__documents_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Maximum number of documents in one page (default 50, capped at 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Documents V1 Knowledge Bases  Kb Id  Documents Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the documents of a knowledge base",
    "tags": [
     "knowledge"
    ]
   },
   "post": {
    "description": "Ingests a document (201). Needs the ReBAC relation `editor` and write access by the ACL (403 `not_permitted_acl`).\nSteps:\n1. The content (`content` or `content_base64`, one is required, else 400) is scanned by ClamAV and YARA-X (422 `file_blocked`, 503 `file_scan_unavailable`), then the text is extracted by Docling (422 `unsupported_media`).\n2. Personal data detection may raise the classification; a `source_connector` must be active.\n3. A document with the same `uri` replaces the previous version (version + 1).\n4. The text is chunked, embedded and stored; the poisoning screening may put the document in quarantine (`status: quarantined`).\n409 `knowledge_base_reindexing` while a reindex runs; 409 `embedding_dimension_mismatch`; 503 `vector_store_unavailable`. Audited as `knowledge.document.ingest`.",
    "operationId": "add_document_v1_knowledge_bases__kb_id__documents_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DocIn"
       }
      }
     },
     "description": "Content, title, URI, classification, readers and metadata of the document.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Document V1 Knowledge Bases  Kb Id  Documents Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add a document",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/documents/uploads": {
   "post": {
    "description": "Checks the size (413 `payload_too_large`, limit `EAI_RAG_UPLOAD_MAX_BYTES`), the declared `mime_type` against the real signature of the bytes (PDF, DOCX, XLSX and PPTX as ZIP packages with the right content types, PNG, JPEG, TIFF; text formats must be valid UTF-8 without NUL) and the extension of `filename`: 422 `unsupported_format`, `format_mismatch`, `extension_mismatch` or `archive_refused` (archive bomb, nested archive, too large once decompressed). The bytes are stored in the quarantine prefix of the documents storage profile (409 `ingestion_storage_required` without one, 503 `ingestion_storage_unavailable`), the document version is recorded with `document_status` `uploaded` and a durable job is created. Answers 202 with `job_id`, `kb_id`, `document_id`, `document_key`, `version`, `state` (`uploaded`), `detected_format`, `size_bytes` and `sha256`, and a `Location` header. The worker job `knowledge_ingestion` then scans the file through the file security domain (fail closed), extracts, chunks, embeds and indexes it. The same `Idempotency-Key` replays the same answer (header `Idempotency-Replayed`); with another body it is refused with 409 `idempotency_conflict`. Needs the ReBAC relation `editor`.",
    "operationId": "upload_document_v1_knowledge_bases__kb_id__documents_uploads_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Optional key (up to 200 characters), unique per tenant: a retry with the same key and body replays the first answer.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 200,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UploadIn"
       }
      }
     },
     "description": "File bytes in base64, declared media type, file name, title, URI, classification, readers, metadata, collection and language.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Upload a document for asynchronous ingestion",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/documents/{doc_id}": {
   "delete": {
    "description": "Deletes the document and its vectors. Needs the ReBAC relation `editor` and write access by the ACL: `tenant_admin`, an identity listed in `writers`, or, when `writers` is empty, `developer` or `agent` (else 403 `not_permitted_acl`). 404 `not_found`. Audited as `knowledge.document.delete`.",
    "operationId": "delete_document_v1_knowledge_bases__kb_id__documents__doc_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the document.",
      "in": "path",
      "name": "doc_id",
      "required": true,
      "schema": {
       "title": "Doc Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a document",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/documents/{doc_id}/chunks": {
   "get": {
    "description": "Chunks of the current version of a document in position order, paginated with `cursor`: `chunk_id`, `ordinal`, `content` (decrypted for sealed chunks), classification, `sealed`, `active`, `generation`, `fts_config` (text search configuration) and `metadata` (`source_page`, `section_title`, `element_type`, `language`, `char_start`, `char_end`, `bbox`, `document_version`, `content_hash`, `embedding_model`, `token_count`, `structure` with the table split marks). Only the chunks whose readers and classification the caller passes are listed. A quarantined or rejected document is shown only to `tenant_admin`, `security_officer` or `data_steward` (403 `forbidden`). Needs the ReBAC relation `viewer`; 404 `not_found` for a document the caller cannot read.",
    "operationId": "list_chunks_v1_knowledge_bases__kb_id__documents__doc_id__chunks_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the current document.",
      "in": "path",
      "name": "doc_id",
      "required": true,
      "schema": {
       "title": "Doc Id",
       "type": "string"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "maximum": 500,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "When false, `content` is null (metadata only). Default true.",
      "in": "query",
      "name": "include_content",
      "required": false,
      "schema": {
       "default": true,
       "title": "Include Content",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Chunks V1 Knowledge Bases  Kb Id  Documents  Doc Id  Chunks Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the chunks of a document",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/documents/{doc_id}/review": {
   "post": {
    "description": "Releases (chunks searchable again, `status: active`) or rejects (`status: rejected`) a quarantined document. Needs `tenant_admin`, `security_officer` or `data_steward`; the policy `knowledge.document.review` is evaluated. 409 `document_not_quarantined`; 404 `not_found`. The decision is recorded and audited as `knowledge.document.release` or `knowledge.document.reject`.",
    "operationId": "review_document_v1_knowledge_bases__kb_id__documents__doc_id__review_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the document.",
      "in": "path",
      "name": "doc_id",
      "required": true,
      "schema": {
       "title": "Doc Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReviewIn"
       }
      }
     },
     "description": "Decision and reason.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Review Document V1 Knowledge Bases  Kb Id  Documents  Doc Id  Review Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Review a quarantined document",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/documents/{doc_id}/status": {
   "get": {
    "description": "Status of one document version: `document_id`, `document_key`, `version`, `version_state` (`current`, `superseded` or `deleted`), `document_status` (`uploaded`, `active`, `quarantined`, `rejected`, `failed`...), `searchable` (true only for the current active version), `chunks`, `extractor`, and `ingestion`, the last ingestion job (`job_id`, `state`, `attempts`, `last_error`, `updated_at`) or null for a synchronous ingestion. Needs the ReBAC relation `viewer`; 404 `not_found` for a document the caller cannot read.",
    "operationId": "document_status_v1_knowledge_bases__kb_id__documents__doc_id__status_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the document version, the `document_id` of the upload answer.",
      "in": "path",
      "name": "doc_id",
      "required": true,
      "schema": {
       "title": "Doc Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Document Status V1 Knowledge Bases  Kb Id  Documents  Doc Id  Status Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the status of a document",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/documents/{doc_id}/versions": {
   "get": {
    "description": "Version history of a document, newest first: `document_key` (stable across versions) and `items` with `document_id`, `version`, `state` (`current`, `superseded` or `deleted`), `searchable` (only the current active version is searched), title, URI, media type, classification, `content_hash`, size, chunk count, extractor, language, collection, `document_status`, creation, `superseded_by` and `superseded_at`, `deleted_at`, and the Docling `artifacts` (kind, storage profile, object key, size, SHA-256). `doc_id` may be the current document or any past version. A version is listed only when the caller is among its readers and its classification fits the clearance. Needs the ReBAC relation `viewer`; 404 `not_found` otherwise.",
    "operationId": "list_versions_v1_knowledge_bases__kb_id__documents__doc_id__versions_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the document or of one of its past versions.",
      "in": "path",
      "name": "doc_id",
      "required": true,
      "schema": {
       "title": "Doc Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Versions V1 Knowledge Bases  Kb Id  Documents  Doc Id  Versions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the versions of a document",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/ingestion-jobs/{job_id}": {
   "get": {
    "description": "An asynchronous ingestion job: `job_id`, `kb_id`, `document_id`, `document_key`, `version`, `state` (`uploaded`, `quarantined`, `scanning`, `rejected`, `extracting`, `normalizing`, `chunking`, `embedding`, `indexing`, `enriching_memory`, `ready`, `partially_ready`, `failed`, `reindexing`, `deleting` or `deleted`), `attempts`, `lease_owner`, `lease_expires_at`, `next_attempt_at`, `last_error`, title, file name, media type, `detected_format`, `size_bytes`, `sha256`, `scan_id`, `extractor` (the one that ran), `storage` (profile and `quarantine` or `permanent` location), creation, update and end, and `history`: every transition with `from_state`, `to_state`, `at` and `detail` (scan verdict, extractor, chunk count, retry with its backoff, OCR failure, memory `skipped`). Needs the ReBAC relation `viewer`; 404 `not_found` for a job of another knowledge base or a document the caller cannot read.",
    "operationId": "get_ingestion_job_v1_knowledge_bases__kb_id__ingestion_jobs__job_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the ingestion job, the `job_id` of the upload answer.",
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
       "title": "Job Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Ingestion Job V1 Knowledge Bases  Kb Id  Ingestion Jobs  Job Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read an ingestion job",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/ingestion-jobs/{job_id}/retry": {
   "post": {
    "description": "Puts a `failed` job back in the queue: to `extracting` when its scan already released the file (never scanned twice), else to `quarantined`; the attempts start again from zero. Any other state is refused with 409 `ingestion_job_not_failed` (a `rejected` file is never retried). Answers the job with its history. Audited `knowledge.ingestion.retry`. Needs the ReBAC relation `editor`.",
    "operationId": "retry_ingestion_job_v1_knowledge_bases__kb_id__ingestion_jobs__job_id__retry_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the failed ingestion job.",
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
       "title": "Job Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/RetryIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason of the retry."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Retry Ingestion Job V1 Knowledge Bases  Kb Id  Ingestion Jobs  Job Id  Retry Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Retry a failed ingestion job",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/quarantine": {
   "get": {
    "description": "Documents isolated by the poisoning screening (data steward review queue), oldest first, at most 200, each with the screening reasons in `quarantine`. Their chunks are not searchable. Needs `tenant_admin`, `security_officer` or `data_steward` and the ReBAC relation `viewer`.",
    "operationId": "list_quarantine_v1_knowledge_bases__kb_id__quarantine_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Quarantine V1 Knowledge Bases  Kb Id  Quarantine Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the quarantined documents",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/query": {
   "post": {
    "description": "Searches the knowledge base and returns `results` (chunk, score, injection risk, classification, provenance), `citations` and a `lineage_run_id`. Needs the ReBAC relation `can_invoke`.\nSteps:\n1. The policy `knowledge.query` is evaluated and a quota reservation is taken.\n2. The query is embedded with the model of the knowledge base; only chunks whose readers match the caller identities and whose classification fits its clearance are searched.\n3. Retrieved chunks are screened for prompt injection (dropped in block mode) and checked against active sources.\n4. `hybrid` re-scores the candidates with keyword overlap; `rerank` orders them with a rerank model (a refusal is reported in `warnings`, never hidden).\nA caller outside the ACL gets an empty result, audited as a denial. Audited as `knowledge.query`; usage is metered.\n\n**Search modes** (`mode`, default: the strategy of the knowledge base, else `vector`): `vector` or `dense` (cosine similarity of the query embedding), `lexical` (PostgreSQL full text search, each chunk parsed with the configuration of its language, `simple` as fallback, terms OR combined, ordered by `ts_rank_cd`), `hybrid` (reciprocal rank fusion of the dense and lexical lists, `sum(1 / (rrf_k + rank))`, or the former weighted re-score with `fusion: weighted`).\n**After the search**: near duplicate passages are dropped (`dedupe`), the final passages are read again with the ACL, the clearance and the document status (a passage that no longer passes is dropped), neighbour chunks are added within `token_budget` when `context_window` is above 0, and `signals.possible_conflicts` lists passages of different documents on the same topic with different numbers or a negation on one side only: a heuristic signal to compare them, never a verdict.\n**Answer**: each result carries `rank`, `score` with its kind in `score_kind` (`cosine_similarity`, `lexical_rank`, `rrf`, `weighted_overlap`; never a probability), `scores` (dense similarity and rank, lexical rank score and rank, rrf, rerank relevance), `metadata` (page, section, element type, language, offsets, bounding boxes, document version, hash, embedding model, token count, structure) and `context` (neighbours). Without any passage, `no_result` gives `code: no_passage_found` and the `reason` (`no_candidates`, `filters_matched_no_document`, `candidates_removed_by_checks`, `acl`). The diagnostics (timing per stage, candidate counts) are always recorded under `diagnostics_id` and returned with `diagnostics: true`.",
    "operationId": "query_kb_v1_knowledge_bases__kb_id__query_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "When true, the answer adds `filters`: the identities, clearance and vector generation used, and the filters applied. Default false.",
      "in": "query",
      "name": "explain",
      "required": false,
      "schema": {
       "default": false,
       "title": "Explain",
       "type": "boolean"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/QueryIn"
       }
      }
     },
     "description": "Query text and search options.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Query Kb V1 Knowledge Bases  Kb Id  Query Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Query a knowledge base",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/query-diagnostics": {
   "get": {
    "description": "Recorded diagnostics of the queries on the knowledge base, newest first, `diagnostics_id` of an answer to select one: mode, effective strategy, `stages` (stage name, duration in milliseconds, candidates in and out), `counts` (filtered documents, dense and lexical candidates, fused, screened, deduplicated, dropped by the revalidation, final, context neighbours, cache hit) and `results` (rank, chunk, document, named scores). The query text is not stored, only its SHA-256. A caller sees its own queries; `tenant_admin`, `security_officer`, `data_steward` and `auditor` see every query. Needs the ReBAC relation `viewer`; 404 `not_found` for a caller outside the ACL or a `diagnostics_id` it cannot see.",
    "operationId": "list_diagnostics_v1_knowledge_bases__kb_id__query_diagnostics_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of one recorded diagnostics, the `diagnostics_id` of a query answer. Optional.",
      "in": "query",
      "name": "diagnostics_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 64,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Diagnostics Id"
      }
     },
     {
      "description": "Maximum number of diagnostics returned (1 to 100, default 20).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 20,
       "maximum": 100,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Diagnostics V1 Knowledge Bases  Kb Id  Query Diagnostics Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the diagnostics of the queries",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/reindex": {
   "post": {
    "description": "Queues the move of the knowledge base to another embedding model (worker job `embeddings_reindex`) and answers 202 with the job. The model must be approved, have the embeddings capability and accept the highest classification of the knowledge base and its documents (422 otherwise). The new vectors form a new generation; the two spaces are never mixed. Needs `tenant_admin` or `developer`, the ReBAC relation `owner` and write access. 409 `knowledge_base_reindexing` if a job is already running. Audited as `knowledge_base.reindex.request`.",
    "operationId": "reindex_kb_v1_knowledge_bases__kb_id__reindex_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReindexIn"
       }
      }
     },
     "description": "Target embedding model and dimension.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Reindex Kb V1 Knowledge Bases  Kb Id  Reindex Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reindex with another embedding model",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/reindex-jobs": {
   "get": {
    "description": "Reindex jobs of the knowledge base: status, source and target model, dimensions and generation, progress in documents and chunks, attempts, error and dates. Needs the ReBAC relation `viewer` and read access.",
    "operationId": "list_reindex_jobs_v1_knowledge_bases__kb_id__reindex_jobs_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Reindex Jobs V1 Knowledge Bases  Kb Id  Reindex Jobs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the reindex jobs",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/knowledge-bases/{kb_id}/retrieval": {
   "put": {
    "description": "Replaces the retrieval strategy of the knowledge base: default mode, fusion and its `rrf_k`, candidates per result, reranking and its model, deduplication, context window and token budget, conflict signal. A field left out takes its default; the options of a query override the strategy for that query. Needs the ReBAC relation `owner` and write access by the ACL (403 `not_permitted_acl`); 404 `not_found` for a caller outside the ACL. Audited as `knowledge_base.retrieval.update`; the retrieval cache is invalidated. Answers the knowledge base with its `retrieval`.",
    "operationId": "put_retrieval_v1_knowledge_bases__kb_id__retrieval_put",
    "parameters": [
     {
      "description": "Identifier (UUID) of the knowledge base.",
      "in": "path",
      "name": "kb_id",
      "required": true,
      "schema": {
       "title": "Kb Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RetrievalIn"
       }
      }
     },
     "description": "The retrieval strategy.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Retrieval V1 Knowledge Bases  Kb Id  Retrieval Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the retrieval strategy",
    "tags": [
     "knowledge"
    ]
   }
  },
  "/v1/license": {
   "get": {
    "description": "Non sensitive licence status of the installation: state, edition, product, term, validity and grace dates, days remaining, whether a renewal is scheduled, the actions restricted now, the capabilities a licence never restricts, and the banner the portal shows (level `none`, `info`, `warning` or `critical`, with an English and French message). No customer identifier, support reference or token is returned. Any authenticated principal may call it, subject to the policy decision `license.read` (403 `policy_denied`).",
    "operationId": "license_status_v1_license_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response License Status V1 License Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the licence state",
    "tags": [
     "licensing"
    ]
   }
  },
  "/v1/license/activations": {
   "post": {
    "description": "Verifies a signed licence locally and stores it. Requires the role `platform_admin` and the policy decision `license.activate`.\n\nSteps:\n\n1. The token is checked: JWS compact, header `{alg: EdDSA, kid, typ}`, signature of a trusted publisher key, canonical JSON payload matching the License Entitlement v1 contract, term of 12 or 36 months with `valid_until` equal to `valid_from` plus the term, and no price, seat, quota, limit or counter field.\n2. The environment of the installation must be listed in the licence (422 `license_environment_not_included`).\n3. The first licence binds the installation group; a licence of another group answers 409 `license_group_mismatch`.\n4. The licence, its support contract, a history event and an audit event `license.activate` are written in one transaction.\n\nSending the same token again answers `activation: already_active`; another token with the same licence id answers 409 `license_conflict`. Verification errors answer 422 with a stable code: `license_invalid_token`, `license_unknown_key`, `license_signature_invalid`, `license_invalid_payload`, `license_invalid_term`, `license_forbidden_field`. Every refused activation is kept in the history and the audit chain.",
    "operationId": "activate_license_v1_license_activations_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__licensing__routes__ActivationIn"
       }
      }
     },
     "description": "The signed licence received from the publisher.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Activate License V1 License Activations Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Activate a licence",
    "tags": [
     "licensing"
    ]
   }
  },
  "/v1/license/history": {
   "get": {
    "description": "Licence history of the installation, newest event first: activations, rejected activations, actions refused after grace and expiry notices. The answer also gives the installation identity (installation id, installation group and when and by whom it was bound), every stored licence with its customer id, support reference and environments, and the support contracts. Requires the role `platform_admin` (403 `forbidden`) and the policy decision `license.history.read`. A malformed cursor answers 400 `invalid_cursor`.",
    "operationId": "license_history_v1_license_history_get",
    "parameters": [
     {
      "description": "Maximum number of history events in one page: 50 by default, capped at 500; a value below 1 answers 400 `invalid_request`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the newest events.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response License History V1 License History Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the licence history",
    "tags": [
     "licensing"
    ]
   }
  },
  "/v1/lineage/datasets/{dataset_id}": {
   "get": {
    "description": "Returns the dataset node, the jobs that produce it (`produced_by`), the jobs that consume it (`consumed_by`) and its upstream and downstream graphs up to `depth` hops. Open to any member of the tenant. Answers 404 `not_found` for an unknown dataset.",
    "operationId": "dataset_v1_lineage_datasets__dataset_id__get",
    "parameters": [
     {
      "description": "Dataset key, `dataset:<namespace>:<name>` or `<namespace>:<name>` (the prefix is added), URL encoded.",
      "in": "path",
      "name": "dataset_id",
      "required": true,
      "schema": {
       "title": "Dataset Id",
       "type": "string"
      }
     },
     {
      "description": "Number of hops followed upstream and downstream (default 2).",
      "in": "query",
      "name": "depth",
      "required": false,
      "schema": {
       "default": 2,
       "title": "Depth",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Dataset V1 Lineage Datasets  Dataset Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the lineage of a dataset",
    "tags": [
     "lineage"
    ]
   }
  },
  "/v1/lineage/events": {
   "post": {
    "description": "Accepts one OpenLineage RunEvent or `{\"events\": [RunEvent, ...]}`, in one transaction. Each event needs `run.runId` and `job.namespace` and `job.name`; `eventType` is one of `START`, `RUNNING`, `COMPLETE`, `ABORT`, `FAIL` or `OTHER` (default; any other answers 400); `eventTime` defaults to the reception time.\n\nFor each event the platform stores the raw event, creates or updates the job, run and dataset nodes and links them (`instance_of`, `input_to`, `produces`). An invalid event answers 422 `validation_error` and nothing is stored. The answer (201) gives `accepted` and, per event, `run_id`, `job` and `event_type`. Writes the audit event `lineage.ingest`.",
    "operationId": "post_events_v1_lineage_events_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "One OpenLineage RunEvent, or an object `events` holding a list of them.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Post Events V1 Lineage Events Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Send OpenLineage events",
    "tags": [
     "lineage"
    ]
   }
  },
  "/v1/lineage/graph": {
   "get": {
    "description": "Returns `nodes` and `edges`. With `node`, the graph is walked from that node in `direction` up to `depth` hops (404 `not_found` for an unknown node). Without `node`, returns up to `limit` job and dataset nodes ordered by key, and the edges between them. A `direction` other than `both`, `upstream` or `downstream` answers 400 `invalid_request`. Open to any member of the tenant.",
    "operationId": "graph_v1_lineage_graph_get",
    "parameters": [
     {
      "description": "Key of the start node, such as `dataset:warehouse:sales` or `job:etl:daily`, URL encoded. Omit it for the whole graph.",
      "in": "query",
      "name": "node",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Node"
      }
     },
     {
      "description": "Number of hops followed from `node`, 1 to 10 (default 3).",
      "in": "query",
      "name": "depth",
      "required": false,
      "schema": {
       "default": 3,
       "title": "Depth",
       "type": "integer"
      }
     },
     {
      "description": "`upstream`, `downstream` or `both` (default).",
      "in": "query",
      "name": "direction",
      "required": false,
      "schema": {
       "default": "both",
       "title": "Direction",
       "type": "string"
      }
     },
     {
      "description": "Maximum number of nodes without `node` (default 500, maximum 5000).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 500,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Graph V1 Lineage Graph Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the lineage graph",
    "tags": [
     "lineage"
    ]
   }
  },
  "/v1/litellm/config": {
   "get": {
    "description": "LiteLLM proxy configuration generated from the visible models and the enabled providers (a tenant provider wins over a shared one of the same type). It never holds a secret value: credentials are `os.environ/<NAME>` references resolved by the LiteLLM deployment. Requires `tenant_admin`, `platform_admin`, `ai_platform_engineer`, `security_officer` or `auditor`.",
    "operationId": "litellm_get_config_v1_litellm_config_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Generate the LiteLLM configuration",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/litellm/sync": {
   "post": {
    "description": "Makes the LiteLLM proxy hold exactly the generated model list: models created by the Control Plane and no longer wanted are removed, missing ones are added; models added by hand in LiteLLM are left alone. Without `EAI_LITELLM_URL` nothing is pushed (`mode: in_process`). A transport error answers 502 `upstream_error`. Audited (`litellm.sync`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "litellm_sync_v1_litellm_sync_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Push the configuration to LiteLLM",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/llm/categories": {
   "get": {
    "description": "Model categories visible to the caller (predefined, shared and tenant ones) with their label and description in English and French, icon, order and number of models using them. One page only. Requires a reader role.",
    "operationId": "categories_list_v1_llm_categories_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the model categories",
    "tags": [
     "llm"
    ]
   },
   "post": {
    "description": "Creates a category for the tenant, or a shared one with `scope: platform` (`platform_admin` only, 403 `platform_only`), and answers 201. A slug already used answers 409 `category_exists`; invalid fields 422 `parameter_invalid`. Audited. Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "categories_create_v1_llm_categories_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`slug` (lowercase letters, digits, dashes and underscores, 1 to 40 characters, required), `label` (text or `{en, fr}`, 80 characters at most, required), `description` (500 characters at most), `icon`, `sort_order` (0 to 10000, default 100), `scope` (`platform` for a shared category).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a model category",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/llm/categories/{slug}": {
   "delete": {
    "description": "Deletes a category created by the tenant or the platform and answers 204. A predefined category cannot be deleted (409 `category_builtin`), nor a category still used by a model (409 `category_in_use`); a shared category needs `platform_admin` (403 `platform_only`). Audited. Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "categories_delete_v1_llm_categories__slug__delete",
    "parameters": [
     {
      "description": "Slug of the category: lowercase letters, digits, dashes and underscores, 1 to 40 characters.",
      "in": "path",
      "name": "slug",
      "required": true,
      "schema": {
       "title": "Slug",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a model category",
    "tags": [
     "llm"
    ]
   },
   "get": {
    "description": "One model category with its number of models. Unknown slug: 404 `category_not_found`. Requires a reader role.",
    "operationId": "categories_get_v1_llm_categories__slug__get",
    "parameters": [
     {
      "description": "Slug of the category.",
      "in": "path",
      "name": "slug",
      "required": true,
      "schema": {
       "title": "Slug",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a model category",
    "tags": [
     "llm"
    ]
   },
   "patch": {
    "description": "Changes the label, description, icon or order of a category; the slug never changes. A predefined category answers 409 `category_builtin`; a shared category needs `platform_admin`. Invalid values answer 422 `parameter_invalid`. Audited. Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "categories_patch_v1_llm_categories__slug__patch",
    "parameters": [
     {
      "description": "Slug of the category.",
      "in": "path",
      "name": "slug",
      "required": true,
      "schema": {
       "title": "Slug",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "Fields to change: `label` and `description` (a text, or `{en, fr}`; label 80 characters at most, description 500), `icon` (lowercase name of 1 to 48 characters, or null), `sort_order` (0 to 10000).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a model category",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/llm/isolation": {
   "get": {
    "description": "Effective isolation mode for the tenant or one of its projects: the project setting when present, else the tenant setting, else `connected`, with the declared internal hosts. Requires a tenant principal (400 `tenant_required`) with `tenant_admin`, `platform_admin`, `security_officer`, `finops`, `developer`, `auditor` or `viewer`.",
    "operationId": "isolation_get_v1_llm_isolation_get",
    "parameters": [
     {
      "description": "Project whose mode is read. Omit it for the tenant mode.",
      "in": "query",
      "name": "project_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the isolation mode",
    "tags": [
     "llm",
     "llm"
    ]
   },
   "put": {
    "description": "Sets the isolation mode of the tenant or of one project. In `local_only` or `air_gapped`, only local providers (vLLM, Ollama, LM Studio) and the declared internal hosts are reachable: an external route is refused in preflight (403 `isolation_external_route`) and the outbound call is checked again (403 `isolation_egress_denied`). Audited (`llm.isolation.set`). Requires a tenant principal with `tenant_admin`, `platform_admin` or `security_officer`.",
    "operationId": "isolation_put_v1_llm_isolation_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`mode` (`connected`, `local_only` or `air_gapped`), optional `project_id` (empty for the whole tenant) and `internal_hosts` (host names, optionally with a port, lowercase letters, digits, dots and dashes).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the isolation mode",
    "tags": [
     "llm",
     "llm"
    ]
   }
  },
  "/v1/llm/management/status": {
   "get": {
    "description": "LiteLLM admin configuration without any secret value: whether it is configured, the admin address, whether the master key is present and where it is read from (setting, environment reference or OpenBao reference), the settings still missing, and a liveness probe (`reachable`) when it is configured. `error_code` is `litellm_not_configured`, `litellm_unreachable` or null. Requires `tenant_admin` or `platform_admin`.",
    "operationId": "management_status_v1_llm_management_status_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Check the LiteLLM admin connection",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/llm/projects": {
   "get": {
    "description": "LLM projects of the tenant by name, each with its effective models (explicit ids plus the registry models of its categories), quota, LiteLLM team and sync state, FinOps quotas and number of keys that are not revoked. One page only (`next_cursor` is always null). Requires `tenant_admin` or `platform_admin`.",
    "operationId": "projects_list_v1_llm_projects_get",
    "parameters": [
     {
      "description": "Only projects in this status: `active`, `suspended` or `archived`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "active",
          "suspended",
          "archived"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the LLM projects",
    "tags": [
     "llm-management"
    ]
   },
   "post": {
    "description": "Creates an LLM project in the caller's tenant and answers 201 with the project. Requires `tenant_admin` or `platform_admin`.\n\nSteps:\n\n1. The tenant project given in `project_id` is resolved (404 `tenant_project_not_found`) and the name must be free in the tenant (409 `llm_project_exists`).\n2. The project and its quota are stored, the FinOps quotas are created when it is linked and active, and the creation is audited (`llm_project.create`).\n3. The project is pushed to LiteLLM as a team; a failure does not fail the request but is shown in `sync_status` (`pending` or `failed`) and can be retried with `POST .../sync`.",
    "operationId": "projects_create_v1_llm_projects_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__llm_management__ProjectIn"
       }
      }
     },
     "description": "The new LLM project. Unknown fields are refused.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an LLM project",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/llm/projects/{project_id}": {
   "delete": {
    "description": "Deletes the project, its LiteLLM team and its FinOps quotas, and answers 204. Refused with 409 `llm_project_has_keys` while the project has keys that are not revoked. A LiteLLM error while deleting the team stops the deletion. Audited (`llm_project.delete`). Requires `tenant_admin` or `platform_admin`; unknown id: 404 `llm_project_not_found`.",
    "operationId": "projects_delete_v1_llm_projects__project_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an LLM project",
    "tags": [
     "llm-management"
    ]
   },
   "get": {
    "description": "One LLM project with its effective models, quota, LiteLLM team, sync status and error, FinOps quotas and key count. Requires `tenant_admin` or `platform_admin`; unknown id: 404 `llm_project_not_found`.",
    "operationId": "projects_get_v1_llm_projects__project_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an LLM project",
    "tags": [
     "llm-management"
    ]
   },
   "patch": {
    "description": "Changes the given fields of the project, rebuilds its FinOps quotas (removed when the project is no longer active or no longer linked) and pushes it to LiteLLM again; a LiteLLM failure does not fail the request but is shown in `sync_status` and `sync_error`. Another project with the new name answers 409 `llm_project_exists`; an unknown tenant project 404 `tenant_project_not_found`. Audited (`llm_project.update`). Requires `tenant_admin` or `platform_admin`.",
    "operationId": "projects_update_v1_llm_projects__project_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__llm_management__ProjectPatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value. The quota is changed with `PUT .../quota`.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update an LLM project",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/llm/projects/{project_id}/keys": {
   "get": {
    "description": "Keys of a project, newest first, with their alias, display prefix, models, limits, status, spend and expiry; never the clear key. With `refresh`, the spend of up to 50 keys that are not revoked is read again from LiteLLM and stored; `usage_source` is then `litellm`, or `stored` with `litellm_error` when LiteLLM did not answer. Requires `tenant_admin` or `platform_admin`.",
    "operationId": "keys_list_v1_llm_projects__project_id__keys_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Read the current spend from LiteLLM before answering (default true); false returns the stored values only.",
      "in": "query",
      "name": "refresh",
      "required": false,
      "schema": {
       "default": true,
       "title": "Refresh",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the keys of a project",
    "tags": [
     "llm-management"
    ]
   },
   "post": {
    "description": "Generates a LiteLLM key for the project and answers 201 with the key record plus `key` (the clear key) and `key_shown_once: true`, with `Cache-Control: no-store`. The clear key is in this answer only: it is never stored nor audited. Requires `tenant_admin` or `platform_admin`.\n\nSteps:\n\n1. The project must be `active` (409 `llm_project_inactive`).\n2. The limits are checked against the project (422 `llm_key_limit_exceeds_project`, 422 `llm_key_model_not_allowed`); without models, the key gets every model of a restricted project. The alias must be free (409 `invalid_field`); without alias one is generated.\n3. The LiteLLM team is created first if the project has none, then LiteLLM generates the key.\n4. The hash, alias, 7 character prefix, limits and expiry are stored and audited (`llm_key.create`). If storing fails, the key is deleted in LiteLLM so that no unknown key stays usable.",
    "operationId": "keys_create_v1_llm_projects__project_id__keys_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__llm_management__KeyIn"
       }
      }
     },
     "description": "Name, alias, models and limits of the new key. Unknown fields are refused.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Generate a project key",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/llm/projects/{project_id}/keys/{key_id}": {
   "delete": {
    "description": "Revokes a key: it is deleted in LiteLLM and kept here with status `revoked` and its revocation time, for the history. A revoked key cannot be changed again (409 `llm_key_revoked`). Audited (`llm_key.revoke`). Requires `tenant_admin` or `platform_admin`; unknown key: 404 `llm_key_not_found`.",
    "operationId": "keys_revoke_v1_llm_projects__project_id__keys__key_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the key in the platform (not the LiteLLM token).",
      "in": "path",
      "name": "key_id",
      "required": true,
      "schema": {
       "title": "Key Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke a project key",
    "tags": [
     "llm-management"
    ]
   },
   "patch": {
    "description": "Changes the name, models and limits of a key, first in LiteLLM then here. The merged limits are checked against the project: a wider limit answers 422 `llm_key_limit_exceeds_project`, a model the project does not allow 422 `llm_key_model_not_allowed`. A revoked key answers 409 `llm_key_revoked`. Audited (`llm_key.update`). Requires `tenant_admin` or `platform_admin`.",
    "operationId": "keys_update_v1_llm_projects__project_id__keys__key_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the key in the platform.",
      "in": "path",
      "name": "key_id",
      "required": true,
      "schema": {
       "title": "Key Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/KeyPatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value, a limit sent as null removes it.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a project key",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/llm/projects/{project_id}/keys/{key_id}/block": {
   "post": {
    "description": "Blocks the key in LiteLLM: calls with it are refused until it is unblocked. The status becomes `blocked`. A revoked key answers 409 `llm_key_revoked`. Audited (`llm_key.block`). Requires `tenant_admin` or `platform_admin`.",
    "operationId": "keys_block_v1_llm_projects__project_id__keys__key_id__block_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the key in the platform.",
      "in": "path",
      "name": "key_id",
      "required": true,
      "schema": {
       "title": "Key Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Block a project key",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/llm/projects/{project_id}/keys/{key_id}/unblock": {
   "post": {
    "description": "Unblocks the key in LiteLLM; the status becomes `active` again. A revoked key answers 409 `llm_key_revoked`. Audited (`llm_key.unblock`). Requires `tenant_admin` or `platform_admin`.",
    "operationId": "keys_unblock_v1_llm_projects__project_id__keys__key_id__unblock_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the key in the platform.",
      "in": "path",
      "name": "key_id",
      "required": true,
      "schema": {
       "title": "Key Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Unblock a project key",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/llm/projects/{project_id}/quota": {
   "put": {
    "description": "Replaces the whole quota of the project (omitted fields take their default), rebuilds its FinOps quotas and pushes it to LiteLLM. With `hard_stop` false, LiteLLM gets no maximum budget (alert only) and the FinOps quotas are soft. An invalid quota answers 422 `invalid_quota`. Audited (`llm_project.quota`). Requires `tenant_admin` or `platform_admin`.",
    "operationId": "projects_quota_v1_llm_projects__project_id__quota_put",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__llm_management__QuotaIn"
       }
      }
     },
     "description": "The complete new quota of the project.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the quota of a project",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/llm/projects/{project_id}/sync": {
   "post": {
    "description": "Pushes the project to LiteLLM again (team created or updated) and answers the project with its new `sync_status`. Unlike the other changes, a failure is returned: 503 `litellm_not_configured`, 502 `litellm_unreachable` or 502 `litellm_rejected`. Audited (`llm_project.sync`). Requires `tenant_admin` or `platform_admin`.",
    "operationId": "projects_sync_v1_llm_projects__project_id__sync_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the LLM project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Push a project to LiteLLM again",
    "tags": [
     "llm-management"
    ]
   }
  },
  "/v1/mandates": {
   "get": {
    "description": "Lists the mandates of the tenant, newest first, optionally for one agent, with their effective status (`pending`, `approved`, `rejected`, `revoked` or `expired`). Open to any member of the tenant.",
    "operationId": "list_mandates_v1_mandates_get",
    "parameters": [
     {
      "description": "Only the mandates of this agent (name).",
      "in": "query",
      "name": "agent",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Agent"
      }
     },
     {
      "description": "Maximum number of mandates (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Mandates V1 Mandates Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the mandates",
    "tags": [
     "delegation"
    ]
   },
   "post": {
    "description": "Requests a mandate so that an agent (optionally one of its schedules) runs autonomously under a service identity. Needs `tenant_admin`, `developer` or `security_officer`.\n\nChecks: active service identity (404 `service_identity_not_found`, 409 `service_identity_disabled`); scopes covered by those of the identity (403 `delegation_scope_exceeds`); classification within its clearance (403 `delegation_classification_exceeds`); schedule of that agent (404 `schedule_not_found`); lifetime within the platform maximum (365 days by default, 400 `mandate_ttl_exceeded`).\n\nAn approval request is created (action `mandate`, approvers `tenant_admin` or `security_officer`, requester excluded). Writes the audit event `mandate.request`, then `mandate.approve` or `mandate.reject`. Answers 201 with the pending mandate.",
    "operationId": "create_mandate_v1_mandates_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MandateIn"
       }
      }
     },
     "description": "Agent, service identity, schedule, rights, purpose and lifetime of the mandate.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Mandate V1 Mandates Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request a mandate for an agent",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/mandates/{mandate_id}": {
   "get": {
    "description": "Returns one mandate: agent, schedule, service identity, scopes, audience, resources, classification ceiling, depth, purpose, status, approval and expiry. Open to any member of the tenant. Answers 404 `mandate_not_found`.",
    "operationId": "get_mandate_v1_mandates__mandate_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the mandate.",
      "in": "path",
      "name": "mandate_id",
      "required": true,
      "schema": {
       "title": "Mandate Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Mandate V1 Mandates  Mandate Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a mandate",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/mandates/{mandate_id}/revoke": {
   "post": {
    "description": "Revokes the mandate and the delegations rooted at it: the next scheduled run of the agent is refused (`mandate_required`). Allowed to the requester, a `tenant_admin` or a `security_officer` (403 `forbidden`). A revoked or rejected mandate answers 409 `mandate_closed`. Writes the audit event `mandate.revoke`.",
    "operationId": "revoke_mandate_v1_mandates__mandate_id__revoke_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the mandate.",
      "in": "path",
      "name": "mandate_id",
      "required": true,
      "schema": {
       "title": "Mandate Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/RevokeIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Revoke Mandate V1 Mandates  Mandate Id  Revoke Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke a mandate",
    "tags": [
     "delegation"
    ]
   }
  },
  "/v1/manifests/apply": {
   "post": {
    "description": "Creates or updates the object described by a manifest, in one transaction. Needs `tenant_admin` or `developer`.\n\n1. The manifest is validated against the contract of its `kind` (422 `unknown_kind`, or 422 `invalid_manifest` with the errors).\n2. `metadata.tenant`, when given, must be the slug of the caller tenant (403 `tenant_mismatch`).\n3. The policy decides on `manifest.apply` (403 `policy_denied` when denied).\n4. The document is stored and the registry of the kind applies it.\n\nThe answer gives `kind`, `name`, `version` (default `1.0.0`), `status` (`created`, `updated` or the status set by the registry) and the fields returned by the registry, such as `id`. Writes the audit event `manifest.apply`.",
    "operationId": "apply_manifest_v1_manifests_apply_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Manifest",
        "type": "object"
       }
      }
     },
     "description": "Manifest document with `kind`, `metadata` and the specification of the object.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Apply Manifest V1 Manifests Apply Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Apply a manifest",
    "tags": [
     "contracts"
    ]
   }
  },
  "/v1/manifests/{kind}/{name}": {
   "get": {
    "description": "Returns the current manifest of an object of the tenant: built by the registry of the kind when it can export, otherwise the last applied document. Open to any member of the tenant. An unknown kind answers 422 `unknown_kind` (with the supported kinds); an unknown object 404 `not_found`.",
    "operationId": "export_manifest_v1_manifests__kind___name__get",
    "parameters": [
     {
      "description": "Kind of manifest, without case: `Agent`, `Model`, `Tool`, `Skill`, `Plugin`, `Connector` or `Channel`.",
      "in": "path",
      "name": "kind",
      "required": true,
      "schema": {
       "title": "Kind",
       "type": "string"
      }
     },
     {
      "description": "Name of the object, the `metadata.name` of its manifest.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Export Manifest V1 Manifests  Kind   Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Export a manifest",
    "tags": [
     "contracts"
    ]
   }
  },
  "/v1/marketplace/changes": {
   "get": {
    "description": "Change requests of the tenant, newest first, at most 200, optionally filtered by kind, reference and stage. Any tenant principal may call it.",
    "operationId": "list_changes_v1_marketplace_changes_get",
    "parameters": [
     {
      "description": "Only this kind: `prompt`, `skill`, `connector`, `rule`, `model`, `policy`, `tool`, `agent` or `pack`.",
      "in": "query",
      "name": "kind",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Kind"
      }
     },
     {
      "description": "Only the changes of this object name.",
      "in": "query",
      "name": "ref",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Ref"
      }
     },
     {
      "description": "Only the changes at this stage: `draft`, `test`, `security_review`, `business_approval`, `staging`, `production`, `monitoring` or `rejected`.",
      "in": "query",
      "name": "stage",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Stage"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Changes V1 Marketplace Changes Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the change requests",
    "tags": [
     "marketplace"
    ]
   },
   "post": {
    "description": "Opens a change of a prompt, skill, connector, rule, model, policy, tool, agent or pack at stage `draft`. Needs `tenant_admin` or `developer`; the policy `change.create` is evaluated. Audited as `change.create`.",
    "operationId": "create_change_v1_marketplace_changes_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ChangeIn"
       }
      }
     },
     "description": "Kind, object name, version and title of the change.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Change V1 Marketplace Changes Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Open a change request",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/changes/{change_id}": {
   "get": {
    "description": "Returns the change with its stage, evidence, pending approval and `history` (one entry per transition with actor and time). 404 `change_not_found`.",
    "operationId": "get_change_v1_marketplace_changes__change_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the change request.",
      "in": "path",
      "name": "change_id",
      "required": true,
      "schema": {
       "title": "Change Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Change V1 Marketplace Changes  Change Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a change request",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/changes/{change_id}/advance": {
   "post": {
    "description": "Moves the change to the next stage. Needs `tenant_admin`, `developer` or `security_officer`. Gates per target stage:\n1. `test`: only the author (or `tenant_admin`) leaves `draft` (403 `change_not_author`).\n2. `security_review`: `evidence.tests` must pass (`passed` > 0, no `failed`, no `errors`), else 422 `change_evidence_missing`.\n3. `business_approval`: approval `change.security_review` by a `security_officer`.\n4. `staging`: approval `change.business_approval` by a `tenant_admin`.\n5. `production`: passing `staging_smoke`, then approval `change.production` with a quorum of two.\n6. `monitoring`: passing `production_smoke`.\nWithout `approval_id`, a gated stage answers 202 with the approval to obtain; call again with the approved id to get 200. The author never approves. A closed change answers 409 `change_closed`.",
    "operationId": "advance_change_v1_marketplace_changes__change_id__advance_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the change request.",
      "in": "path",
      "name": "change_id",
      "required": true,
      "schema": {
       "title": "Change Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AdvanceIn"
       }
      }
     },
     "description": "Evidence to add and the approved request, when the stage needs one.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "title": "Response Advance Change V1 Marketplace Changes  Change Id  Advance Post"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Advance a change to the next stage",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/changes/{change_id}/reject": {
   "post": {
    "description": "Closes the change at stage `rejected` from any open stage, with the reason kept in `history`. Needs `tenant_admin` or `security_officer`. 409 `change_closed` if already closed. Audited as `change.reject`.",
    "operationId": "reject_change_v1_marketplace_changes__change_id__reject_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the change request.",
      "in": "path",
      "name": "change_id",
      "required": true,
      "schema": {
       "title": "Change Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RejectIn"
       }
      }
     },
     "description": "Reason of the rejection.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Reject Change V1 Marketplace Changes  Change Id  Reject Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reject a change request",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations": {
   "get": {
    "description": "Installations of the tenant, oldest first, each with package, version and created assets. One page only.",
    "operationId": "list_installations_v1_marketplace_installations_get",
    "parameters": [
     {
      "description": "Only the installations of this environment: `dev`, `test`, `staging` or `prod`.",
      "in": "query",
      "name": "environment",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "dev",
          "test",
          "staging",
          "prod"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Environment"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Installations V1 Marketplace Installations Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the installations",
    "tags": [
     "marketplace"
    ]
   },
   "post": {
    "description": "Opens an installation request and answers 202 with the installation, the `approval_id`, the `quorum` and the preflight report. Needs `tenant_admin`.\nSteps:\n1. The preflight runs (see `POST /v1/marketplace/preflight`); a failure answers 403 `permission_unsafe`, 422 `config_invalid`, 422 `permission_not_requested`, 409 `package_suspended` or 422 `preflight_failed`.\n2. An approval `marketplace.install` is opened for `tenant_admin` or `security_officer`: quorum 1 by default, at least 2 when a sensitive permission is granted or the environment is `prod`.\n3. Once approved, call `POST .../installations/{id}/apply`.\n409 `installation_exists` when the package is already installed or suspended in this environment.",
    "operationId": "request_install_v1_marketplace_installations_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__marketplace__routes__InstallIn"
       }
      }
     },
     "description": "Package, version, environment, granted permissions, configuration and secret references.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Request Install V1 Marketplace Installations Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request the installation of a pack",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}": {
   "get": {
    "description": "Returns the installation: status, package and version, granted and suspended permissions, configuration, last preflight and smoke results, created objects and assets. 404 `installation_not_found`.",
    "operationId": "get_installation_v1_marketplace_installations__installation_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Installation V1 Marketplace Installations  Installation Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an installation",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}/apply": {
   "post": {
    "description": "Executes the pending install or upgrade once its approval is approved: the policy and the preflight are checked again, the objects of the pack are created inside a savepoint, the objects of the former version that are no longer part of it are removed and a smoke test runs. A failed smoke test rolls everything back and answers 422 `smoke_failed`. Needs `tenant_admin`. 409 `installation_state` when nothing is pending. Audited as `marketplace.install` or `marketplace.upgrade`.",
    "operationId": "apply_v1_marketplace_installations__installation_id__apply_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Apply V1 Marketplace Installations  Installation Id  Apply Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Apply an approved installation",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}/authorize": {
   "post": {
    "description": "Runtime permission check used by the pack MCP servers and connectors: allowed only when the installation is `installed`, the permission was granted, is not suspended and is not an external export denied by the data protection settings. Otherwise 403 with `permission_not_granted`, `permission_suspended`, `installation_suspended` or `external_export_denied`, recorded as an `authorize_denied` event. Needs `tenant_admin`, `developer`, `agent` or `service`.",
    "operationId": "authorize_v1_marketplace_installations__installation_id__authorize_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__marketplace__routes__AuthorizeIn"
       }
      }
     },
     "description": "Permission scope to check.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Authorize V1 Marketplace Installations  Installation Id  Authorize Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Check a runtime permission",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}/events": {
   "get": {
    "description": "Lifecycle history of the installation, oldest first: requests, installs, upgrades, rollbacks, failed smoke tests, suspensions, resumptions, refused authorizations, with versions, outcome and actor. One page only.",
    "operationId": "installation_events_v1_marketplace_installations__installation_id__events_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Installation Events V1 Marketplace Installations  Installation Id  Events Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the events of an installation",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}/rollback": {
   "post": {
    "description": "Reinstalls the previous version with its previous grant, inside a savepoint with a smoke test (422 `smoke_failed` keeps the current version). Needs `tenant_admin`. 409 `installation_state` unless `installed`; 409 `rollback_unavailable` when there is no previous version. Audited as `marketplace.rollback`.",
    "operationId": "rollback_v1_marketplace_installations__installation_id__rollback_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rollback V1 Marketplace Installations  Installation Id  Rollback Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Roll back to the previous version",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}/status": {
   "post": {
    "description": "Needs `tenant_admin` or `security_officer`.\n- `status: suspended`: immediate. Without `permissions`, the whole installation is suspended (tools blocked, agents suspended, MCP servers disabled, assets suspended); with `permissions`, only those granted capabilities (422 `permission_not_granted` for others). Answers 200.\n- `status: installed`: resume. Without `approval_id`, opens a `marketplace.resume` approval with a quorum of two and answers 202; with the approved id, lifts the suspension and answers 200. Refused with 409 `package_suspended` while the package kill switch is on.\n409 `installation_state` for a state that does not allow the change.",
    "operationId": "installation_status_v1_marketplace_installations__installation_id__status_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__marketplace__routes__StatusIn"
       }
      }
     },
     "description": "Target status, reason, capabilities to suspend and approval for a resumption.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "title": "Response Installation Status V1 Marketplace Installations  Installation Id  Status Post"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Suspend or resume an installation",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}/supervision": {
   "get": {
    "description": "Activity, quality, costs and incidents of an installed pack, aggregated from the objects it created: tool invocations and runs per state, refused authorizations, evaluation results, last smoke result, run success rate, run costs per currency, and the incidents naming its objects (50 most recent).",
    "operationId": "installation_supervision_v1_marketplace_installations__installation_id__supervision_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Installation Supervision V1 Marketplace Installations  Installation Id  Supervision Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Supervise an installed pack",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}/uninstall": {
   "post": {
    "description": "Removes every object and asset the installation created and sets it to `uninstalled` (grants, suspensions and previous version cleared). Allowed from `installed`, `failed`, `pending_approval` or `suspended` (else 409 `installation_state`). Needs `tenant_admin`; the policy `marketplace.uninstall` is evaluated. The answer lists `removed`. Audited as `marketplace.uninstall`.",
    "operationId": "uninstall_v1_marketplace_installations__installation_id__uninstall_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Uninstall V1 Marketplace Installations  Installation Id  Uninstall Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Uninstall a pack",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/installations/{installation_id}/upgrade": {
   "post": {
    "description": "Opens an upgrade request to a higher version (202 with approval, quorum and preflight), then apply it with `POST .../apply` once approved. The installation must be `installed` and the version strictly higher (else 409 `installation_state`). Configuration and secret references default to the current ones. Needs `tenant_admin`. Preflight failures answer as for an installation request.",
    "operationId": "request_upgrade_v1_marketplace_installations__installation_id__upgrade_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the installation.",
      "in": "path",
      "name": "installation_id",
      "required": true,
      "schema": {
       "title": "Installation Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UpgradeIn"
       }
      }
     },
     "description": "Target version, granted permissions, configuration and secret references.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Request Upgrade V1 Marketplace Installations  Installation Id  Upgrade Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request the upgrade of an installation",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/packages": {
   "get": {
    "description": "Packages of the catalogue in name order, with status, latest version, publisher and category. One page only.",
    "operationId": "list_packages_v1_marketplace_packages_get",
    "parameters": [
     {
      "description": "Only the packages of this business domain.",
      "in": "query",
      "name": "domain",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Domain"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Packages V1 Marketplace Packages Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the packages",
    "tags": [
     "marketplace"
    ]
   },
   "post": {
    "description": "Publishes a pack archive as a new version (201). Needs `tenant_admin` or `developer`; the policy `marketplace.publish` is evaluated.\nSteps:\n1. The archive is decoded (422 `marketplace_archive_invalid`) and scanned by ClamAV and YARA-X before unpacking (422 `file_blocked`, 503 `file_scan_unavailable`).\n2. Every gate runs: schema, signature, SBOM, vulnerability scan, tests, evaluations, licence, permissions, documentation, secrets, provenance, privacy, security, approvals, configuration, resilience. Any failure answers 422 `publication_gate_failed` with the result of each gate.\n3. The package is created on first publication. 409 `package_suspended` when its kill switch is on, 409 `marketplace_version_exists` for a version already published.\nAudited as `marketplace.publish`.",
    "operationId": "publish_v1_marketplace_packages_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PublishIn"
       }
      }
     },
     "description": "The pack archive and its supply chain evidence.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Publish V1 Marketplace Packages Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Publish a package version",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/packages/{name}": {
   "get": {
    "description": "Returns the package and every version, oldest first, with gate results and a vulnerability summary. 404 `marketplace_package_not_found`.",
    "operationId": "get_package_v1_marketplace_packages__name__get",
    "parameters": [
     {
      "description": "Name of the package.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Package V1 Marketplace Packages  Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a package and its versions",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/packages/{name}/status": {
   "post": {
    "description": "Needs `tenant_admin` or `security_officer`.\n- `status: suspended`: immediate. Every installed installation of the package is suspended; installs, upgrades, publications and promotions are refused. Answers 200 with `suspended_installations`.\n- `status: active`: lifts the kill switch. Without `approval_id`, opens a `marketplace.package.resume` approval with a quorum of two (202); with the approved id, the package and the installations it suspended resume (200 with `resumed_installations`).\n409 `installation_state` when lifting a package that is not suspended.",
    "operationId": "package_status_v1_marketplace_packages__name__status_post",
    "parameters": [
     {
      "description": "Name of the package.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PackageStatusIn"
       }
      }
     },
     "description": "Target status, reason and approval for a lifting.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "title": "Response Package Status V1 Marketplace Packages  Name  Status Post"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the kill switch of a package",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/packages/{name}/versions/{version}": {
   "get": {
    "description": "Returns one version: manifest, digest, file digests, signature and its status, licence, OCI reference, gate results, provenance status and production approval. The archive and the SBOM are not included. 404 `marketplace_version_not_found`.",
    "operationId": "get_version_v1_marketplace_packages__name__versions__version__get",
    "parameters": [
     {
      "description": "Name of the package.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     },
     {
      "description": "Semantic version, for example `1.2.0`.",
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "title": "Version",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Version V1 Marketplace Packages  Name  Versions  Version  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a package version",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/packages/{name}/versions/{version}/production": {
   "post": {
    "description": "Production gate, required to install a version in `prod`. Needs `tenant_admin` or `security_officer`.\nSteps:\n1. Without `approval_id`: every stored gate must have passed, the signature must still verify and an OCI artifact digest must be attached (else 422 `publication_gate_failed`); then a `marketplace.promote` approval is opened with a quorum of at least two and the answer is 202 with the checks.\n2. With the approved `approval_id`: the version becomes `production` (200).\nA version already in production answers 200 at once; 409 `package_suspended` while the kill switch is on.",
    "operationId": "promote_v1_marketplace_packages__name__versions__version__production_post",
    "parameters": [
     {
      "description": "Name of the package.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     },
     {
      "description": "Semantic version, for example `1.2.0`.",
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "title": "Version",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ProductionIn"
       }
      }
     },
     "description": "Approved request, on the second call.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "title": "Response Promote V1 Marketplace Packages  Name  Versions  Version  Production Post"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Promote a version to production",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/packages/{name}/versions/{version}/sbom": {
   "get": {
    "description": "Returns the software bill of materials stored at publication, its digest and the vulnerability scan report.",
    "operationId": "get_sbom_v1_marketplace_packages__name__versions__version__sbom_get",
    "parameters": [
     {
      "description": "Name of the package.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     },
     {
      "description": "Semantic version, for example `1.2.0`.",
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "title": "Version",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Sbom V1 Marketplace Packages  Name  Versions  Version  Sbom Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the SBOM of a version",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/preflight": {
   "post": {
    "description": "Dry run of the installation checks, nothing is installed: package active, environment, configuration against the pack `configSchema`, version available (and in production for `prod`), platform compatibility, dependencies installed, archive digest, signature, permissions requested and safe, secret references of the connectors, approved model, no name conflict. Returns `passed`, every check, the granted, not granted and sensitive permissions, the approvals required and the data protection applied. Needs `tenant_admin` or `security_officer`. Audited as `marketplace.preflight`.",
    "operationId": "preflight_v1_marketplace_preflight_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__marketplace__routes__InstallIn"
       }
      }
     },
     "description": "Same body as an installation request.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Preflight V1 Marketplace Preflight Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Dry run the installation checks",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/publishers": {
   "get": {
    "description": "Trusted signing keys, by name: algorithm, status (`active` or `revoked`) and `scope` (`platform` for a key shared by every tenant, `tenant` for a key of this tenant). Public keys are not returned.",
    "operationId": "list_publishers_v1_marketplace_publishers_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Publishers V1 Marketplace Publishers Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the publishers",
    "tags": [
     "marketplace"
    ]
   },
   "post": {
    "description": "Registers a public signing key for the tenant; pack signatures are verified against the active keys. Needs `tenant_admin` or `security_officer`. An unreadable key answers 422 `publisher_invalid_key`. Audited as `marketplace.publisher.add`.",
    "operationId": "add_publisher_v1_marketplace_publishers_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PublisherIn"
       }
      }
     },
     "description": "Publisher name and public key.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Publisher V1 Marketplace Publishers Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add a trusted publisher key",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/marketplace/publishers/{name}/revoke": {
   "post": {
    "description": "Revokes every key of the tenant registered under this name; signatures made with them no longer verify. Needs `tenant_admin` or `security_officer`. 404 `publisher_not_found`. Platform keys cannot be revoked here. Audited as `marketplace.publisher.revoke`.",
    "operationId": "revoke_publisher_v1_marketplace_publishers__name__revoke_post",
    "parameters": [
     {
      "description": "Name of the publisher.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Revoke Publisher V1 Marketplace Publishers  Name  Revoke Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke a publisher",
    "tags": [
     "marketplace"
    ]
   }
  },
  "/v1/mcp/catalog": {
   "get": {
    "description": "Catalogue: tools, input and output schemas, versions, scopes and approval status (`approved`, `pending_approval`, `rejected`), for the servers the request may see only, as `GET /v1/mcp/servers`.",
    "operationId": "mcp_catalog_v1_mcp_catalog_get",
    "parameters": [
     {
      "description": "Only the catalogue of this server (UUID or name).",
      "in": "query",
      "name": "server",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Server"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Mcp Catalog V1 Mcp Catalog Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the MCP tool catalogue",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/mcp/gateway/{server_id}": {
   "post": {
    "description": "JSON-RPC 2.0 proxy. The body is one request or a batch (at most 50 are handled). Needs `tenant_admin`, `developer` or `agent` and the ReBAC relation `can_invoke`. Refusals are answered as JSON-RPC errors with HTTP 200, and audited.\nChecks, in order: valid JSON-RPC 2.0; server `active`; project isolation (`mcp_server_project_mismatch`); allowed callers (`mcp_principal_not_allowed`); a sleeping hosted instance is woken up; a third party application must be active and granted the server; method allowed; for `tools/call`: tool in `allowed_tools`, scope `tools:invoke`, DLP on the arguments; policy `mcp.call`; quota reservation; for `resources/read`: URI in `allowed_resources`.\nThen the call is forwarded with the upstream credentials; `tools/list` and `resources/list` are filtered by the allow lists, `tools/call` results are masked by DLP and screened for prompt injection, and the call is metered as a tool usage.",
    "operationId": "mcp_gateway_v1_mcp_gateway__server_id__post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the MCP server.",
      "in": "path",
      "name": "server_id",
      "required": true,
      "schema": {
       "title": "Server Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "title": "Message"
       }
      }
     },
     "description": "A JSON-RPC 2.0 request (`jsonrpc`, `id`, `method`, `params`) or an array of requests.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "title": "Response Mcp Gateway V1 Mcp Gateway  Server Id  Post"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Call an MCP server through the gateway",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/mcp/hosted/sync": {
   "post": {
    "description": "Publishes the MCP servers hosted by the Navin Manager (service mcp-host) in their project: token kept in the Credential Broker, server of the project created or updated, servers no longer hosted disabled. `project` (id or slug, default the request project) limits the synchronisation to one project; a project other than the request one answers 403 `mcp_project_forbidden`. Needs `tenant_admin` and a tenant (403 `tenant_required`).",
    "operationId": "sync_hosted_v1_mcp_hosted_sync_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the only project to synchronise. Default: the project of the request.",
      "in": "query",
      "name": "project",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Sync Hosted V1 Mcp Hosted Sync Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Publish the MCP servers hosted by the Navin Manager",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/mcp/runtime/jwks": {
   "get": {
    "description": "Public verification keys of the tokens the MCP Gateway gives the ToolHive proxies (no secret: public keys only, as any OIDC JWKS). Read without authentication by the MCPOIDCConfig `eai-mcp-runtime` of every project namespace. 503 `context_authority_unavailable` when the key registry cannot be read.",
    "operationId": "runtime_jwks_v1_mcp_runtime_jwks_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Runtime Jwks V1 Mcp Runtime Jwks Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the MCP runtime verification keys",
    "tags": [
     "mcp-runtime"
    ]
   }
  },
  "/v1/mcp/servers": {
   "get": {
    "description": "Servers the request may see: `project` (id or slug) keeps the servers of that project; a request made in a project (`X-Project` header or an API key bound to a project) sees the servers of its project and those shared by the tenant, never those of another project (403 `mcp_project_forbidden`). Upstream secrets are never returned, only their references.",
    "operationId": "list_servers_v1_mcp_servers_get",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project whose servers are listed.",
      "in": "query",
      "name": "project",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Servers V1 Mcp Servers Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the MCP servers",
    "tags": [
     "mcp"
    ]
   },
   "post": {
    "description": "Registers an upstream server (201). The URL must be http(s) on an internal host allowed by the MCP egress policy (403 `mcp_online_forbidden` otherwise); `bearer`, `api_key` and `query_param` need an `openbao://` or `env://` `credential_ref`, `query_param` needs `param`, `connector` needs `connector` (400 `invalid_request`). A name already used answers 409 `conflict`. The project (default `X-Project`) must be the request project (403 `mcp_project_forbidden`). Needs `tenant_admin`, `developer` or `application_owner`; the caller becomes ReBAC owner. Audited as `mcp.server.create`.",
    "operationId": "create_server_v1_mcp_servers_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ServerIn"
       }
      }
     },
     "description": "Name, URL, transport, upstream authentication, allow lists, owner and project.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Server V1 Mcp Servers Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register an MCP server",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/mcp/servers/{server_id}": {
   "delete": {
    "description": "Removes the server from the registry. Needs `tenant_admin`, the ReBAC relation `owner` and access to the project of the server. 404 `mcp_server_not_found`. Audited as `mcp.server.delete`.",
    "operationId": "delete_server_v1_mcp_servers__server_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the MCP server.",
      "in": "path",
      "name": "server_id",
      "required": true,
      "schema": {
       "title": "Server Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an MCP server",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/mcp/servers/{server_id}/access": {
   "put": {
    "description": "MCP Gateway access control: which users and agents may call this server; an empty list lets every member of its project call it. Principal ids are letters, digits and `:._@/-` (up to 128 characters, 400 `invalid_request`). The access of a hosted instance is managed by the MCP runtime (409 `mcp_instance_access_managed`). Needs `tenant_admin`, `developer` or `application_owner` and access to the project of the server. Audited as `mcp.server.access`.",
    "operationId": "put_access_v1_mcp_servers__server_id__access_put",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the MCP server.",
      "in": "path",
      "name": "server_id",
      "required": true,
      "schema": {
       "title": "Server Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AccessIn"
       }
      }
     },
     "description": "The allowed principals.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Access V1 Mcp Servers  Server Id  Access Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set who may call an MCP server",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/mcp/servers/{server_id}/discover": {
   "post": {
    "description": "MCP protocol discovery (`initialize`, `tools/list`): every new or changed tool schema becomes a catalogue version waiting for approval (`mcp_tool_version`, approvers `tenant_admin` or `security_officer`). Returns the versions created with their approval ids. Needs `tenant_admin`, `developer` or `application_owner`, the ReBAC relation `editor` and access to the project of the server.",
    "operationId": "discover_server_v1_mcp_servers__server_id__discover_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the MCP server.",
      "in": "path",
      "name": "server_id",
      "required": true,
      "schema": {
       "title": "Server Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Discover Server V1 Mcp Servers  Server Id  Discover Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Discover the tools of an MCP server",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/mcp/servers/{server_id}/status": {
   "post": {
    "description": "`active` goes through a promotion: an approval is opened and the answer is 202 with `approval_id`. `disabled` applies at once (every gateway call is then refused) and is audited as `mcp.server.status`. Needs `tenant_admin` or `security_officer`, the ReBAC relation `editor` and access to the project of the server.",
    "operationId": "server_status_v1_mcp_servers__server_id__status_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the MCP server.",
      "in": "path",
      "name": "server_id",
      "required": true,
      "schema": {
       "title": "Server Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ServerStatusIn"
       }
      }
     },
     "description": "Target status and reason.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "title": "Response Server Status V1 Mcp Servers  Server Id  Status Post"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Enable or disable an MCP server",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/mcp/servers/{server_id}/tools": {
   "get": {
    "description": "Calls `tools/list` on the server through the gateway and returns the tools allowed by `allowed_tools`. Needs the ReBAC relation `can_invoke` and access to the project of the server. An upstream error answers 502 `upstream_error`.",
    "operationId": "server_tools_v1_mcp_servers__server_id__tools_get",
    "parameters": [
     {
      "description": "Identifier (UUID) or name of the MCP server.",
      "in": "path",
      "name": "server_id",
      "required": true,
      "schema": {
       "title": "Server Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Server Tools V1 Mcp Servers  Server Id  Tools Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the tools of an MCP server",
    "tags": [
     "mcp"
    ]
   }
  },
  "/v1/me": {
   "get": {
    "description": "Who the caller is: principal id, kind, tenant, clearance, project, environment, authentication method and display name, with its roles and scopes. When the principal belongs to a tenant, the tenant (id, slug, name, status, data residency) is returned too. Requires authentication (401 otherwise).",
    "operationId": "me_v1_me_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Me V1 Me Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the current principal",
    "tags": [
     "system"
    ]
   }
  },
  "/v1/media": {
   "get": {
    "description": "Tenant media (Multimodal Contract documents), keyset paginated with `cursor`, filtered by `media_type` and `classification` (400 `invalid_request` for an unknown value).",
    "operationId": "list_media_v1_media_get",
    "parameters": [
     {
      "description": "Only this type: `image`, `audio`, `video` or `document`.",
      "in": "query",
      "name": "media_type",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Media Type"
      }
     },
     {
      "description": "Only this classification: `public`, `internal`, `confidential`, `restricted` or `secret`.",
      "in": "query",
      "name": "classification",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Classification"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Media V1 Media Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the media",
    "tags": [
     "multimodal"
    ]
   },
   "post": {
    "description": "Stores a media (201) from JSON `{content_base64, mime_type, filename?, operation?, dlp_mode?, retention_days?, classification?}` or multipart/form-data with a `file` part and the same fields. Any tenant principal may call it.\nSteps:\n1. Size checked against the platform maximum (50 MiB unless configured; 413 `media_too_large`).\n2. File scan by ClamAV and YARA-X (422 `file_blocked`, 503 `file_scan_unavailable`).\n3. Text extraction and DLP with `dlp_mode` (default `detect`; `block` answers 422 `dlp_blocked` when personal data is found); the classification is raised accordingly.\n4. The content is encrypted with a tenant key and stored. Returns the Multimodal Contract document.",
    "operationId": "upload_media_v1_media_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "properties": {
         "classification": {
          "enum": [
           "public",
           "internal",
           "confidential",
           "restricted",
           "secret"
          ],
          "type": "string"
         },
         "content_base64": {
          "type": "string"
         },
         "dlp_mode": {
          "enum": [
           "detect",
           "mask",
           "tokenize",
           "block"
          ],
          "type": "string"
         },
         "filename": {
          "type": "string"
         },
         "mime_type": {
          "type": "string"
         },
         "operation": {
          "enum": [
           "vision_understanding",
           "image_generation",
           "image_edit",
           "video_processing",
           "video_generation",
           "stt",
           "diarization",
           "tts",
           "voice_live",
           "ocr",
           "document_extraction"
          ],
          "type": "string"
         },
         "retention_days": {
          "minimum": 0,
          "type": "integer"
         }
        },
        "required": [
         "content_base64",
         "mime_type"
        ],
        "type": "object"
       }
      },
      "multipart/form-data": {
       "schema": {
        "properties": {
         "classification": {
          "enum": [
           "public",
           "internal",
           "confidential",
           "restricted",
           "secret"
          ],
          "type": "string"
         },
         "dlp_mode": {
          "enum": [
           "detect",
           "mask",
           "tokenize",
           "block"
          ],
          "type": "string"
         },
         "file": {
          "format": "binary",
          "type": "string"
         },
         "filename": {
          "type": "string"
         },
         "mime_type": {
          "type": "string"
         },
         "operation": {
          "enum": [
           "vision_understanding",
           "image_generation",
           "image_edit",
           "video_processing",
           "video_generation",
           "stt",
           "diarization",
           "tts",
           "voice_live",
           "ocr",
           "document_extraction"
          ],
          "type": "string"
         },
         "retention_days": {
          "minimum": 0,
          "type": "integer"
         }
        },
        "required": [
         "file"
        ],
        "type": "object"
       }
      }
     },
     "description": "The file (JSON with base64 content, or multipart with a `file` part) and its options: `operation` the media is meant for, `dlp_mode` (`detect`, `mask`, `tokenize`, `block`), `retention_days` (0 or more), `classification`.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upload Media V1 Media Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Upload a media",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/media/{media_id}": {
   "delete": {
    "description": "Deletes the media and its stored content. Allowed for its creator, `tenant_admin` or `security_officer` (403 `forbidden`). A media under legal hold answers 409 `legal_hold`. Audited as `media.delete`.",
    "operationId": "delete_media_v1_media__media_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the media.",
      "in": "path",
      "name": "media_id",
      "required": true,
      "schema": {
       "title": "Media Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Media V1 Media  Media Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a media",
    "tags": [
     "multimodal"
    ]
   },
   "get": {
    "description": "Returns the Multimodal Contract document of the media. With `include_content=true` the answer is `{media, content_base64}` with the decrypted content; this needs a clearance at least equal to the media classification (403 `policy_denied`) and is audited as `media.read`.",
    "operationId": "get_media_v1_media__media_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the media.",
      "in": "path",
      "name": "media_id",
      "required": true,
      "schema": {
       "title": "Media Id",
       "type": "string"
      }
     },
     {
      "description": "When true, also return the decrypted content, base64 encoded. Default false.",
      "in": "query",
      "name": "include_content",
      "required": false,
      "schema": {
       "default": false,
       "title": "Include Content",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Media V1 Media  Media Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a media",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/members": {
   "get": {
    "description": "Lists the memberships of the tenant, paginated: user subject, email, display name, role, clearance, project and creation date. Open to any member of the tenant.",
    "operationId": "list_members_v1_members_get",
    "parameters": [
     {
      "description": "Maximum number of members in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Members V1 Members Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the members",
    "tags": [
     "tenancy"
    ]
   },
   "post": {
    "description": "Gives a user (OIDC subject) a role and a clearance in the tenant, or in one project with `project_id`. The user record is created when unknown; an existing membership for the same user and project is updated. Needs `tenant_admin`; granting `platform_admin` needs a platform administrator (403 `forbidden`). Writes the audit event `member.assign`.",
    "operationId": "add_member_v1_members_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemberIn"
       }
      }
     },
     "description": "User, role, clearance and optional project of the membership.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Member V1 Members Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add a member",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/members/{member_id}": {
   "delete": {
    "description": "Removes the membership: the user loses the role it gave at the next request. Needs `tenant_admin`. Writes the audit event `member.remove`. Answers 204, or 404 `not_found`.",
    "operationId": "delete_member_v1_members__member_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the membership.",
      "in": "path",
      "name": "member_id",
      "required": true,
      "schema": {
       "title": "Member Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Remove a member",
    "tags": [
     "tenancy"
    ]
   },
   "patch": {
    "description": "Changes the role or the clearance of a membership. Needs `tenant_admin`; granting `platform_admin` needs a platform administrator (403 `forbidden`). Writes the audit event `member.update`. Answers 404 `not_found` for an unknown membership.",
    "operationId": "patch_member_v1_members__member_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the membership.",
      "in": "path",
      "name": "member_id",
      "required": true,
      "schema": {
       "title": "Member Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemberPatch"
       }
      }
     },
     "description": "New role and/or clearance.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Member V1 Members  Member Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a member",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/memory": {
   "get": {
    "description": "Items the caller may read (listed in `readers`, classification within its clearance, not expired, not deleted), as Memory Contract documents, paginated with `cursor`.",
    "operationId": "list_memory_v1_memory_get",
    "parameters": [
     {
      "description": "Only this scope type: `session`, `agent`, `user`, `project` or `tenant`.",
      "in": "query",
      "name": "scope_type",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Scope Type"
      }
     },
     {
      "description": "Only this scope id.",
      "in": "query",
      "name": "scope_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Scope Id"
      }
     },
     {
      "description": "Only this kind: `episodic`, `semantic`, `procedural`, `preference` or `fact`.",
      "in": "query",
      "name": "kind",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Kind"
      }
     },
     {
      "description": "Maximum number of items in one page (default 50, capped at 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Memory V1 Memory Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the memory items",
    "tags": [
     "memory"
    ]
   },
   "post": {
    "description": "Creates an item, or a new version of `memory_id` (201, Memory Contract document).\nSteps:\n1. `kind` and `scope.type` are checked (400 `invalid_request`); `content` or `content_ref` is required.\n2. Personal data detection may raise the classification; a classification above the caller clearance answers 403 `policy_denied`; the policy `memory.write` is evaluated.\n3. For an update, the caller must be a writer or owner (403 `not_permitted_acl`) before the content is sent to the embedding model.\n4. The content is embedded and stored. A new item defaults to the caller as reader, writer and owner, and to the `user` scope of the caller.\nAudited as `memory.create` or `memory.update`.",
    "operationId": "write_memory_v1_memory_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryIn"
       }
      }
     },
     "description": "The memory item to write.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Write Memory V1 Memory Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Write a memory item",
    "tags": [
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/knowledge": {
   "post": {
    "description": "Adds texts to the Cognee dataset of one scope (Cognee `POST /api/v1/add`, then `POST /api/v1/cognify` when `build_graph`), only when the policy enables `knowledge_graph` and the engine is `cognee` or `hybrid` (else 403 or 422 `memory_capability_unsupported`). Same DLP, classification, retention and isolation checks as a memory; relation `editor` on the agent. 201 with `dataset`, `items` and `graph`. Accepts an `Idempotency-Key` header. Audited as `memory.knowledge.create` without the content.",
    "operationId": "ingest_knowledge_v1_memory_agents__agent_id__knowledge_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryKnowledgeIn"
       }
      }
     },
     "description": "Texts to ingest and their scope.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Ingest Knowledge V1 Memory Agents  Agent Id  Knowledge Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ingest knowledge",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/knowledge/datasets": {
   "get": {
    "description": "Datasets the caller may read through this agent, paginated with `cursor`.",
    "operationId": "list_datasets_v1_memory_agents__agent_id__knowledge_datasets_get",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     },
     {
      "description": "Only this isolation level: `agent`, `shared_agents`, `project`, `team`, `organization` or `global`.",
      "in": "query",
      "name": "scope",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "agent",
          "shared_agents",
          "project",
          "team",
          "organization",
          "global"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Scope"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Datasets V1 Memory Agents  Agent Id  Knowledge Datasets Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the knowledge datasets",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/knowledge/datasets/{dataset_id}": {
   "delete": {
    "description": "Deletes the dataset in Cognee (`DELETE /api/v1/datasets/{dataset_id}`) and its index entries. 409 `legal_hold` when the dataset or one of its items is held. Audited as `memory.knowledge.delete`.",
    "operationId": "delete_knowledge_dataset_v1_memory_agents__agent_id__knowledge_datasets__dataset_id__delete",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the Navin index entry of the dataset.",
      "in": "path",
      "name": "dataset_id",
      "required": true,
      "schema": {
       "title": "Dataset Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Knowledge Dataset V1 Memory Agents  Agent Id  Knowledge Datasets  Dataset Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a knowledge dataset",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/knowledge/datasets/{dataset_id}/relations": {
   "get": {
    "description": "Nodes and edges of the knowledge graph of one readable dataset (Cognee `GET /api/v1/datasets/{dataset_id}/graph`), screened for prompt injection and returned as untrusted data. 404 for a dataset the caller may not read. Audited as `memory.provider.read`.",
    "operationId": "knowledge_relations_v1_memory_agents__agent_id__knowledge_datasets__dataset_id__relations_get",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the Navin index entry of the dataset.",
      "in": "path",
      "name": "dataset_id",
      "required": true,
      "schema": {
       "title": "Dataset Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Knowledge Relations V1 Memory Agents  Agent Id  Knowledge Datasets  Dataset Id  Relations Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the relations of a dataset",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/knowledge/graph": {
   "post": {
    "description": "Runs Cognee `POST /api/v1/cognify` on readable datasets of the instance of the agent (all of them by default). Relation `editor` on the agent. Audited as `memory.knowledge.build`.",
    "operationId": "build_knowledge_graph_v1_memory_agents__agent_id__knowledge_graph_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryGraphBuildIn"
       }
      }
     },
     "description": "Datasets to process.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Build Knowledge Graph V1 Memory Agents  Agent Id  Knowledge Graph Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Build the knowledge graph",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/knowledge/search": {
   "post": {
    "description": "Cognee `POST /api/v1/search`, one readable dataset per call so every passage is attributed to its dataset; results are screened and returned as untrusted data with `framed_content`. The policy decision `memory.search` is evaluated. Audited as `memory.provider.read`.",
    "operationId": "search_knowledge_v1_memory_agents__agent_id__knowledge_search_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryGraphSearchIn"
       }
      }
     },
     "description": "Query, datasets, number of results and search type.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Search Knowledge V1 Memory Agents  Agent Id  Knowledge Search Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Search the knowledge graph",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/memories": {
   "get": {
    "description": "Index entries of the memories the caller may read through this agent (readable scopes of the policy, classification within the clearance, not expired), paginated with `cursor`. With `include_content=true` (at most 100 per page) the content is read from the engine and returned as untrusted data. Audited as `memory.provider.read`.",
    "operationId": "list_memories_v1_memory_agents__agent_id__memories_get",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     },
     {
      "description": "Only this isolation level: `session`, `user`, `agent`, `shared_agents`, `project`, `team`, `organization` or `global`.",
      "in": "query",
      "name": "scope",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "session",
          "user",
          "agent",
          "shared_agents",
          "project",
          "team",
          "organization",
          "global"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Scope"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Also read the content from the engine (default false).",
      "in": "query",
      "name": "include_content",
      "required": false,
      "schema": {
       "default": false,
       "title": "Include Content",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Memories V1 Memory Agents  Agent Id  Memories Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the memories of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   },
   "post": {
    "description": "Writes one memory through the engine of the agent policy (session scope: always the builtin store; `hybrid`: Mem0). 201 with `items` (index entries, without content), `engine` and `engine_instance`.\nThe context (tenant, organization, project, user, agent, session) is derived server side from the authenticated principal, the agent registry and the verified session, never from the body. Checks, each refusal audited: an agent only uses its own memory (403 `memory_agent_mismatch`), the scope and the kind must be allowed by the policy (403), shared scopes need `editor` on the agent, the engine must announce `remember` (422 `memory_capability_unsupported`) and guarantee the required isolation (409), secrets, passwords, tokens and keys are refused (422 `memory_secret_refused`), personal data when the policy forbids it (422), a classification above the policy or the clearance (403), a retention above the policy (422). Accepts an `Idempotency-Key` header. Audited as `memory.provider.create` without the content.",
    "operationId": "remember_v1_memory_agents__agent_id__memories_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryRememberIn"
       }
      }
     },
     "description": "The memory to remember.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Remember V1 Memory Agents  Agent Id  Memories Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Remember through the engine of the agent",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/memories/export": {
   "post": {
    "description": "Exports at most 1000 readable memories with their content (untrusted data). Refused to agents (403). Audited as `memory.export` without the content.",
    "operationId": "export_memories_v1_memory_agents__agent_id__memories_export_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryExportIn"
       }
      }
     },
     "description": "Scopes to export (default: every readable scope).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Export Memories V1 Memory Agents  Agent Id  Memories Export Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Export the memories of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/memories/purge": {
   "post": {
    "description": "Deletes every memory and dataset of one scope of the caller (Mem0 `DELETE /memories` with the identifiers of the scope, Cognee dataset deletion, builtin soft delete). `confirm` must be true (400). 409 `legal_hold` when an item of the scope is held. Audited as `memory.provider.purge`.",
    "operationId": "purge_memories_v1_memory_agents__agent_id__memories_purge_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryPurgeIn"
       }
      }
     },
     "description": "The scope to purge and the confirmation.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Purge Memories V1 Memory Agents  Agent Id  Memories Purge Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Purge one scope of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/memories/search": {
   "post": {
    "description": "Same search as `recall` for a person who consults the memories (no `context_segments`); shared scopes need `editor` on the agent. Results are untrusted data. Audited as `memory.provider.read`.",
    "operationId": "search_memories_v1_memory_agents__agent_id__memories_search_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryRecallIn"
       }
      }
     },
     "description": "Query, scopes, number of results and session.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Search Memories V1 Memory Agents  Agent Id  Memories Search Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Search the memories of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/memories/{item_id}": {
   "delete": {
    "description": "Deletes the memory in its engine (Mem0 `DELETE /memories/{memory_id}`, Cognee data item deletion, builtin soft delete) and marks the index entry deleted. 409 `legal_hold`; only the owner agent of a shared memory (403). Audited as `memory.provider.delete`.",
    "operationId": "forget_memory_item_v1_memory_agents__agent_id__memories__item_id__delete",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the Navin index entry.",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Forget Memory Item V1 Memory Agents  Agent Id  Memories  Item Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Forget a memory of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   },
   "get": {
    "description": "Index entry and content (read from the engine, untrusted data) of one memory. An item of a scope the caller may not read answers 404, never 403, so its existence is not disclosed. Audited as `memory.provider.read`.",
    "operationId": "get_memory_item_v1_memory_agents__agent_id__memories__item_id__get",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the Navin index entry.",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Memory Item V1 Memory Agents  Agent Id  Memories  Item Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a memory of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   },
   "patch": {
    "description": "Replaces the content of a memory in its engine (Mem0 `PUT /memories/{memory_id}`, builtin new version) after the same DLP checks as a creation; the version increases. Only the owner agent of a shared memory may change it (403); a held item answers 409 `legal_hold`. Audited as `memory.provider.update`.",
    "operationId": "update_memory_item_v1_memory_agents__agent_id__memories__item_id__patch",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the Navin index entry.",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryUpdateIn"
       }
      }
     },
     "description": "The new content.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Update Memory Item V1 Memory Agents  Agent Id  Memories  Item Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a memory of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/policy": {
   "get": {
    "description": "Engine choice (`builtin`, `mem0`, `cognee`, `hybrid`), instances, modes, scopes, memorization limits, retention, sharing and required isolation of the agent, with `version`, `configured` (false: defaults, builtin engine) and `engines` (per purpose `memory` or `knowledge`: instance, provider, isolation and capabilities). Relation `viewer` on the agent, or the agent itself.",
    "operationId": "get_agent_policy_v1_memory_agents__agent_id__policy_get",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Agent Policy V1 Memory Agents  Agent Id  Policy Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the memory policy of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   },
   "put": {
    "description": "Replaces the memory policy of the agent (new `version`, the former one is kept for a restore).\nChecks: roles `tenant_admin`, `developer` or `application_owner` and relation `editor` on the agent (403); `global_access` needs `tenant_admin`; `default_scope` must be a write scope and `shared_with` existing agents (400); the chosen instances must exist, match the provider and guarantee `required_isolation` (409 `memory_isolation_unsatisfied`: a dedicated instance installed by the Navin Manager is required). The policy decision `memory.policy.update` is enforced.\n`shared_with` writes or deletes the OpenFGA relation `memory_reader` of each agent on this one. Audited as `memory.policy.update`, plus `memory.engine.change` when the engine or an instance changes and `memory.share` when the sharing changes.",
    "operationId": "put_agent_policy_v1_memory_agents__agent_id__policy_put",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AgentMemoryPolicyIn"
       }
      }
     },
     "description": "Engine choice, instances and memory policy of the agent.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Agent Policy V1 Memory Agents  Agent Id  Policy Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the memory policy of an agent",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/policy/restore": {
   "post": {
    "description": "Applies a former version again as a new version, with the same checks as `PUT .../policy`. 404 for an unknown version. Audited as `memory.policy.restore`.",
    "operationId": "restore_agent_policy_v1_memory_agents__agent_id__policy_restore_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryPolicyRestoreIn"
       }
      }
     },
     "description": "The version to restore.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Restore Agent Policy V1 Memory Agents  Agent Id  Policy Restore Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Restore a version of the memory policy",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/policy/versions": {
   "get": {
    "description": "Former versions of the memory policy of the agent, newest first (at most 200), each with its engine, instances, policy, author and date. Relation `viewer` on the agent.",
    "operationId": "agent_policy_versions_v1_memory_agents__agent_id__policy_versions_get",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Agent Policy Versions V1 Memory Agents  Agent Id  Policy Versions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the versions of the memory policy",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/agents/{agent_id}/recall": {
   "post": {
    "description": "Searches the readable scopes on the engines of the policy (hybrid: Mem0 and Cognee, merged and deduplicated by content, every source kept in `sources`), keeps only the results indexed by Navin for a readable scope and within the clearance (permission check before anything reaches the LLM), screens them for prompt injection (blocked items dropped) and returns them as untrusted data: `framed_content` wrapped in the untrusted markers and `context_segments` of type `memory` for the Context Manager, never instructions. The policy decision `memory.search` is evaluated. Audited as `memory.provider.read` with counts only.",
    "operationId": "recall_v1_memory_agents__agent_id__recall_post",
    "parameters": [
     {
      "description": "Name or identifier of the agent.",
      "in": "path",
      "name": "agent_id",
      "required": true,
      "schema": {
       "title": "Agent Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryRecallIn"
       }
      }
     },
     "description": "Query, scopes, number of results and session.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Recall V1 Memory Agents  Agent Id  Recall Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Recall memories for the LLM",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/engines": {
   "get": {
    "description": "Memory engines the tenant may use (Navin Memory Provider): `builtin` (the Memory Manager store), the platform instances `mem0` and `cognee` rendered by the Navin Manager from its bindings (only when configured), and the instances declared by the platform administrator (shared ones and those dedicated to this tenant; a dedicated instance of another tenant is never listed). Each entry gives `provider`, `base_url`, `origin` (`builtin`, `manager_binding`, `declared`), `dedicated`, `credential_bound` (the credential itself is never returned), `isolation` (`logical`, `backend` or `dedicated_instance`: the separation this instance guarantees for the tenant) and `capabilities`. Navin Enterprise never installs nor configures an engine: the Navin Manager does.",
    "operationId": "list_engines_v1_memory_engines_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Engines V1 Memory Engines Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the memory engines",
    "tags": [
     "memory",
     "memory"
    ]
   },
   "post": {
    "description": "Declares an instance of Mem0 or Cognee installed and operated by the Navin Manager, for example one dedicated to a tenant (`tenant_id`: physical separation, as a bank requires). Only `platform_admin` (403 otherwise). The credential is a reference only (`openbao://<path>` or `env://EAI_CRED_<NAME>`), resolved server side. 409 `conflict` when the id exists or is reserved (`builtin`, `mem0`, `cognee`), 404 for an unknown tenant. Accepts an `Idempotency-Key` header. Audited as `memory.engine.declare`.",
    "operationId": "declare_engine_v1_memory_engines_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryEngineIn"
       }
      }
     },
     "description": "The engine instance to declare.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Declare Engine V1 Memory Engines Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Declare a memory engine instance",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/engines/{engine_id}": {
   "delete": {
    "description": "Removes a declared instance and the tenant credentials bound to it. Only `platform_admin`. 409 `memory_engine_in_use` while an agent policy or a memory still uses it; 404 `memory_engine_not_found`. Audited as `memory.engine.delete`.",
    "operationId": "delete_engine_v1_memory_engines__engine_id__delete",
    "parameters": [
     {
      "description": "Identifier of the engine instance.",
      "in": "path",
      "name": "engine_id",
      "required": true,
      "schema": {
       "title": "Engine Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Engine V1 Memory Engines  Engine Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Remove a declared memory engine instance",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/engines/{engine_id}/capabilities": {
   "get": {
    "description": "Declarative capability set of the engine: only what its provider really executes. `memory`: among `remember`, `recall`, `search`, `update`, `forget`, `list`, `get`, `purge`, `get_health`, `get_capabilities`; `knowledge`: among `ingest_knowledge`, `build_graph`, `search_graph`, `get_relations`, `delete_dataset`. An operation outside this set answers 422 `memory_capability_unsupported`. Also gives `isolation` for the tenant and `session_memory` (true for `builtin` only: session memory never goes to an external engine). Nothing is sent to the engine.",
    "operationId": "engine_capabilities_v1_memory_engines__engine_id__capabilities_get",
    "parameters": [
     {
      "description": "Identifier of the engine instance (`builtin`, `mem0`, `cognee` or a declared id).",
      "in": "path",
      "name": "engine_id",
      "required": true,
      "schema": {
       "title": "Engine Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Engine Capabilities V1 Memory Engines  Engine Id  Capabilities Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the capabilities of a memory engine",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/engines/{engine_id}/credential": {
   "delete": {
    "description": "Removes the credential of this tenant on the instance; the credential of the instance is used again. Role `tenant_admin`. Audited as `memory.engine.change`.",
    "operationId": "delete_engine_credential_v1_memory_engines__engine_id__credential_delete",
    "parameters": [
     {
      "description": "Identifier of the engine instance.",
      "in": "path",
      "name": "engine_id",
      "required": true,
      "schema": {
       "title": "Engine Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Engine Credential V1 Memory Engines  Engine Id  Credential Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Unbind the credential of the tenant",
    "tags": [
     "memory",
     "memory"
    ]
   },
   "put": {
    "description": "Binds the credential of this tenant on a shared instance (`openbao://<path>` reference to a secret of the tenant). On a Cognee instance with backend access control, it is the API key of the Cognee user of the tenant: its datasets and permissions are then enforced by Cognee itself (`isolation` becomes `backend`). On Mem0 a key does not separate the memories (`logical` stays). Role `tenant_admin`. Audited as `memory.engine.change`.",
    "operationId": "put_engine_credential_v1_memory_engines__engine_id__credential_put",
    "parameters": [
     {
      "description": "Identifier of the engine instance.",
      "in": "path",
      "name": "engine_id",
      "required": true,
      "schema": {
       "title": "Engine Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MemoryEngineCredentialIn"
       }
      }
     },
     "description": "Reference to the credential of the tenant.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Engine Credential V1 Memory Engines  Engine Id  Credential Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Bind the credential of the tenant on an engine",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/engines/{engine_id}/health": {
   "get": {
    "description": "Calls the engine with the credential of the tenant: Mem0 `GET /auth/setup-status` then `GET /configure/providers`, Cognee `GET /health` then `GET /api/v1/datasets`. Answers `status` `up` (or `degraded`), or `down` with `error` and `reason` (never a secret). Roles `tenant_admin`, `developer`, `security_officer` or `auditor`.",
    "operationId": "engine_health_v1_memory_engines__engine_id__health_get",
    "parameters": [
     {
      "description": "Identifier of the engine instance.",
      "in": "path",
      "name": "engine_id",
      "required": true,
      "schema": {
       "title": "Engine Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Engine Health V1 Memory Engines  Engine Id  Health Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Check the health of a memory engine",
    "tags": [
     "memory",
     "memory"
    ]
   }
  },
  "/v1/memory/search": {
   "post": {
    "description": "Scores the visible items (at most the 2000 most recently updated ones with content) and returns the best `top_k` with `score`, `keyword_score` and `vector_score`. `keyword`: share of query terms found; `vector`: cosine similarity with the query embedding (only items embedded with the current model); `hybrid` (default): half of each. Recalled content is screened for prompt injection; blocked items are dropped. The policy `memory.search` is evaluated. 400 `invalid_request` for an unknown mode. Audited as `memory.search`.",
    "operationId": "search_memory_v1_memory_search_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SearchIn"
       }
      }
     },
     "description": "Query, optional scope and kind, number of results and mode.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Search Memory V1 Memory Search Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Search the memory",
    "tags": [
     "memory"
    ]
   }
  },
  "/v1/memory/{memory_id}": {
   "delete": {
    "description": "Erases the content, the reference, the vector and the former versions of the item and marks it deleted. Allowed for a writer or owner of the item, or `tenant_admin` (else 403 `not_permitted_acl`). An item under legal hold answers 409 `legal_hold` (the refusal is audited); a non deletable item answers 409 `conflict` unless the caller is `tenant_admin`. 404 `not_found`. Audited as `memory.delete`.",
    "operationId": "delete_memory_v1_memory__memory_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the memory item.",
      "in": "path",
      "name": "memory_id",
      "required": true,
      "schema": {
       "title": "Memory Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Memory V1 Memory  Memory Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a memory item",
    "tags": [
     "memory"
    ]
   },
   "get": {
    "description": "Returns the item as a Memory Contract document with its `history` (former version numbers and dates). An expired item, or one the caller may not read by ACL or clearance, answers 404 `not_found`.",
    "operationId": "get_memory_v1_memory__memory_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the memory item.",
      "in": "path",
      "name": "memory_id",
      "required": true,
      "schema": {
       "title": "Memory Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Memory V1 Memory  Memory Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a memory item",
    "tags": [
     "memory"
    ]
   }
  },
  "/v1/meta": {
   "get": {
    "description": "Name, version and API version of the instance, supported locales and default locale, loaded domains, and the features enabled by the configuration: OIDC, API key, SPIFFE and development authentication, OpenBao, OpenFGA, OPA and LiteLLM (true when their address is set). No authentication required.",
    "operationId": "meta_v1_meta_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Meta V1 Meta Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Describe the Control Plane instance",
    "tags": [
     "system"
    ]
   }
  },
  "/v1/models": {
   "get": {
    "description": "Models visible to the caller (shared models with the tenant overrides applied, and the tenant models), optionally filtered. One page only (`next_cursor` is always null). Requires a reader role.",
    "operationId": "models_list_v1_models_get",
    "parameters": [
     {
      "description": "Only models in this status: `approved`, `restricted`, `deprecated` or `blocked`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only models of this provider type, for example `openai` or `vllm` (aliases are accepted).",
      "in": "query",
      "name": "provider",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Provider"
      }
     },
     {
      "description": "Only models declaring this capability, for example `chat`, `embeddings` or `reasoning`.",
      "in": "query",
      "name": "capability",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Capability"
      }
     },
     {
      "description": "Only models of this category slug.",
      "in": "query",
      "name": "category",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Category"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the registered models",
    "tags": [
     "llm"
    ]
   },
   "post": {
    "description": "Registers a model for the tenant, or a shared one with `scope: platform` (`platform_admin` only), and answers 201. The body is a Model Manifest v1 or a bare spec; it must be valid (422 `invalid_manifest`) and its category must exist. A model id already registered in the same scope answers 409 `model_exists`. Audited (`model.create`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "models_create_v1_models_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "A Model Manifest v1 (`kind: Model`, `metadata`, `spec`) or the spec alone (`model_id`, `provider`, `provider_model_id`, `capabilities`, `context_window`, `status`...), with the sheet fields, optional `pricing` and `scope`.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register a model",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/models/import": {
   "post": {
    "description": "Registers the models chosen in a discovery. Idempotent: the ones already registered (same id, or same provider and provider model id) are skipped and listed with `already_registered`. Every item is checked first; one invalid item refuses the whole import with 422 `import_invalid` and the problem of each item. Each model and the import are audited. Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "models_import_v1_models_import_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`provider_id` (provider id or name, required), `models` (1 to 200 objects from the discovery: `provider_model_id` and the optional registry id, category and sheet fields), optional `scope` (`platform`).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Import discovered models",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/models/resolve": {
   "post": {
    "description": "Capability Resolver: translates normalized call parameters (for example the reasoning effort `none`, `low`, `medium`, `high`, `max`) into the native parameters of the model, from what its manifest declares. An unsupported value is rejected with an explicit code or adjusted with a warning in the answer, never silently. Unknown model: 404 `model_not_found`. Requires a reader role.",
    "operationId": "models_resolve_v1_models_resolve_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`model` (or `model_id`) and the normalized parameters, either in `params` or at the top level of the body.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Resolve the native call parameters",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}": {
   "delete": {
    "description": "Deletes the tenant entry of the model (an override of a shared model brings the shared entry back), or the shared entry when there is no tenant entry; the shared entry needs `platform_admin` (403 `platform_only`). Answers 204; audited (`model.delete`). Unknown model: 404 `model_not_found`. Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "models_delete_v1_models__model_id__delete",
    "parameters": [
     {
      "description": "Registry identifier of the model (not the provider model id).",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a model from the registry",
    "tags": [
     "llm"
    ]
   },
   "get": {
    "description": "One model of the registry, or its Model Manifest v1 with `format=manifest`. Unknown model: 404 `model_not_found`. Requires a reader role.",
    "operationId": "models_get_v1_models__model_id__get",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     },
     {
      "description": "`manifest` returns the Model Manifest v1 (without the sheet fields); omit it for the full registry entry.",
      "in": "query",
      "name": "format",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Format"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a registered model",
    "tags": [
     "llm"
    ]
   },
   "patch": {
    "description": "Changes fields of the model spec, the sheet (`category`, `display_name`, `knowledge_cutoff`) or the prices; the model id never changes. A tenant change of a shared model creates a tenant override. The merged spec must stay a valid Model Manifest v1 (422 `invalid_manifest`) and the category must exist. Audited (`model.update`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "models_patch_v1_models__model_id__patch",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "Spec fields to change, sheet fields and `pricing` (per million tokens: `input_per_mtok`, `output_per_mtok`, `cached_input_per_mtok`, `cache_write_per_mtok`; per unit: `per_image`, `per_second`, `per_character`; with a currency). Use `POST .../status` to change the status.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a registered model",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}/disable": {
   "post": {
    "description": "Kill switch of the model for the tenant: the gateway refuses it at once (403 `model_disabled`). On a shared model this creates a tenant override. Audited (`model.disable`). Requires `tenant_admin`, `platform_admin`, `ai_platform_engineer` or `security_officer`.",
    "operationId": "models_disable_v1_models__model_id__disable_post",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Disable a model (kill switch)",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}/enable": {
   "post": {
    "description": "Lifts the kill switch of the model for the tenant. Audited (`model.enable`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "models_enable_v1_models__model_id__enable_post",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Enable a disabled model",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}/rollback": {
   "post": {
    "description": "During a canary, aborts it: the active version keeps all the traffic. Otherwise, restores the version that was active before the last full publication. The version left becomes `rolled_back`, the step is added to the rollout history and audited (`model.rollout.rollback`). Nothing to roll back: 409 `model_rollback_unavailable`. Requires a tenant principal with `tenant_admin` or `platform_admin`.",
    "operationId": "versions_rollback_v1_models__model_id__rollback_post",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "additionalProperties": true,
          "type": "object"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional `{reason}` written to the rollout history and the audit trail."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Roll back a model version",
    "tags": [
     "llm",
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}/rollout": {
   "get": {
    "description": "Active version, canary version and canary share of the model in the tenant, with the whole rollout history (publish, canary, rollback, actor, reason, approval). Requires a tenant principal with `tenant_admin`, `platform_admin`, `security_officer`, `finops`, `developer`, `auditor` or `viewer`.",
    "operationId": "rollout_get_v1_models__model_id__rollout_get",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the rollout of a model",
    "tags": [
     "llm",
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}/status": {
   "post": {
    "description": "Sets the status to `approved`, `restricted`, `deprecated` or `blocked` (422 `status_invalid` otherwise). For a tenant, a promotion to `approved` is not applied at once: an approval request is opened and the answer is 202 with it; the status changes once it is approved. Other changes apply at once and are audited (`model.status`, with the previous and new status). Requires `tenant_admin`, `platform_admin`, `ai_platform_engineer` or `security_officer`.",
    "operationId": "models_status_v1_models__model_id__status_post",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`status` (`approved`, `restricted`, `deprecated` or `blocked`) and an optional `reason`.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change the status of a model",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}/versions": {
   "get": {
    "description": "Versions of the model in the tenant, oldest first, with licence, weights source, digest and size, capabilities, status (`draft`, `pending_approval`, `canary`, `active`, `superseded`, `rolled_back`) and approval. Requires a tenant principal with `tenant_admin`, `platform_admin`, `security_officer`, `finops`, `developer`, `auditor` or `viewer`.",
    "operationId": "versions_list_v1_models__model_id__versions_get",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the versions of a model",
    "tags": [
     "llm",
     "llm"
    ]
   },
   "post": {
    "description": "Registers a version of the model in the tenant with status `draft` and answers 201. The version needs a licence (SPDX expression, or terms reference starting with `https://` or `LicenseRef-`) and the weights provenance; invalid fields answer 422 `model_version_invalid` with their names, an existing version 409 `model_version_exists`. Audited (`model.version.create`). Requires a tenant principal with `tenant_admin` or `platform_admin`.",
    "operationId": "versions_create_v1_models__model_id__versions_post",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`version` (1 to 64 characters: letters, digits, dots, dashes, underscores, plus), `licence_spdx` or `licence_terms_ref`, `weights` with `source` (`https://`, `oci://`, `hf://`, `s3://` or `registry://`), `digest` (`sha256:` and 64 hex characters) and `size_bytes` (positive integer), optional `capabilities` (list of texts).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register a model version",
    "tags": [
     "llm",
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}/versions/{version}/approval": {
   "post": {
    "description": "Opens an approval request (action `model_version_activation`) for a `draft` version and answers 202 with its id; the version becomes `pending_approval`. The approvers are `tenant_admin` and `security_officer`, and the requester cannot approve its own request (separation of duties). A version that is not a draft answers 409 `model_version_state`. Audited. Requires a tenant principal with `tenant_admin` or `platform_admin`.",
    "operationId": "versions_request_approval_v1_models__model_id__versions__version__approval_post",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     },
     {
      "description": "Version to approve, as registered.",
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "title": "Version",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "additionalProperties": true,
          "type": "object"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional `{reason}` shown to the approvers."
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request the approval of a version",
    "tags": [
     "llm",
     "llm"
    ]
   }
  },
  "/v1/models/{model_id}/versions/{version}/rollout": {
   "post": {
    "description": "Publishes an approved version fully (`canary_percent` 100, default) or as a canary for 1 to 99 percent of the traffic, picked deterministically from the caller (same session or principal, same version). Requires a tenant principal with `tenant_admin` or `platform_admin`.\n\nSteps:\n\n1. The approval of the version must be granted for this model and version (403 `model_version_not_approved`); the approver and decision time are copied onto the version.\n2. A full publication makes the version `active` and the previous one `superseded`; a canary needs an active version to compare with (409 `model_rollout_no_baseline`).\n3. The step is added to the rollout history and audited (`model.rollout.publish` or `model.rollout.canary`).\n\nPublishing the version already active answers 409 `model_version_state`; an invalid share 422 `parameter_invalid`.",
    "operationId": "versions_rollout_v1_models__model_id__versions__version__rollout_post",
    "parameters": [
     {
      "description": "Registry identifier of the model.",
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "string"
      }
     },
     {
      "description": "Approved version to publish.",
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "title": "Version",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`canary_percent` (integer 1 to 100, default 100) and an optional `reason`.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Publish a model version",
    "tags": [
     "llm",
     "llm"
    ]
   }
  },
  "/v1/multimodal/diarize": {
   "post": {
    "description": "Starts a diarization job (who spoke when) on an audio media or inline audio (201, the job). Only `min_speakers` and `max_speakers` apply here (`word_timestamps` answers 422 `parameter_unsupported`); `min_speakers` must not exceed `max_speakers` (422 `parameter_invalid`); an option the configured provider cannot honour answers 422 `parameter_unsupported`. Needs `tenant_admin`, `developer` or `agent`.",
    "operationId": "diarize_v1_multimodal_diarize_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SttIn"
       }
      }
     },
     "description": "Audio input and speaker bounds.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Diarize V1 Multimodal Diarize Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Diarize an audio",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/dlp": {
   "post": {
    "description": "Inspects `text`, the extracted text of a stored media, or inline content (scanned first), with the tenant DLP rules. Returns `source`, `extracted_text_chars`, the processed `text`, `findings`, `action` and `classification`. Nothing is stored. Any tenant principal may call it. Audited as `multimodal.dlp`.",
    "operationId": "multimodal_dlp_v1_multimodal_dlp_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MultimodalDlpIn"
       }
      }
     },
     "description": "Text, stored media or inline content, and the DLP mode.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Multimodal Dlp V1 Multimodal Dlp Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run the DLP on a text or a media",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/images/edit": {
   "post": {
    "description": "Starts an image edition job from an image media or inline image and a prompt (201, the job). The input must be an image (422 `unsupported_media`). Needs `tenant_admin`, `developer` or `agent`.",
    "operationId": "images_edit_v1_multimodal_images_edit_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ImageEditIn"
       }
      }
     },
     "description": "Input image, prompt, number of images, size and model.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Images Edit V1 Multimodal Images Edit Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Edit an image",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/images/generate": {
   "post": {
    "description": "Starts an image generation job (201, the job). The prompt is inspected by the DLP in block mode first: personal data answers 422 `dlp_blocked`. Usage is counted per image. Needs `tenant_admin`, `developer` or `agent`.",
    "operationId": "images_generate_v1_multimodal_images_generate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ImageGenIn"
       }
      }
     },
     "description": "Prompt, number of images, size and model.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Images Generate V1 Multimodal Images Generate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Generate images",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/jobs": {
   "get": {
    "description": "Jobs of the tenant, newest first, paginated with `cursor`, optionally filtered by status and operation.",
    "operationId": "list_jobs_v1_multimodal_jobs_get",
    "parameters": [
     {
      "description": "Only this status: `queued`, `running`, `succeeded`, `failed` or `cancelled`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only this operation, for example `stt` or `image_generation`.",
      "in": "query",
      "name": "operation",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Operation"
      }
     },
     {
      "description": "Maximum number of jobs in one page (default 50, capped at 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Jobs V1 Multimodal Jobs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the multimodal jobs",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/jobs/{job_id}": {
   "get": {
    "description": "Returns the job: operation, status, input parameters, output, error, adapter, units and cost. 404 `not_found`.",
    "operationId": "get_job_v1_multimodal_jobs__job_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the job.",
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
       "title": "Job Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Job V1 Multimodal Jobs  Job Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a multimodal job",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/jobs/{job_id}/complete": {
   "post": {
    "description": "Called by GPU workers (agent or service identities) to report a queued job result: status `running`, `succeeded`, `failed` or `cancelled` (else 400 `invalid_request`), with output, error and measured units; the quota reservation is committed or released. A finished job answers 409 `conflict`. Needs `agent` or `tenant_admin`. 404 `not_found`.",
    "operationId": "complete_job_v1_multimodal_jobs__job_id__complete_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the job.",
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
       "title": "Job Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/JobCompleteIn"
       }
      }
     },
     "description": "Status, output, error and measured units of the job.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Complete Job V1 Multimodal Jobs  Job Id  Complete Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Report the result of a queued job",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/stt": {
   "post": {
    "description": "Starts a speech to text job on an audio media or inline audio (201, the job). The transcript goes through the DLP with `dlp_mode`. Only `word_timestamps` applies here (speaker bounds answer 422 `parameter_unsupported`). Usage is counted in audio seconds (`duration_seconds`, or read from a WAV header). Needs `tenant_admin`, `developer` or `agent`.",
    "operationId": "stt_v1_multimodal_stt_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SttIn"
       }
      }
     },
     "description": "Audio input, language, model, DLP mode and options.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Stt V1 Multimodal Stt Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Transcribe speech to text",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/tts": {
   "post": {
    "description": "Starts a text to speech job (201, the job). The text is inspected by the DLP with `dlp_mode` (default `block`: personal data answers 422 `dlp_blocked`; `mask` speaks the masked text). Usage is counted in characters. Needs `tenant_admin`, `developer` or `agent`.",
    "operationId": "tts_v1_multimodal_tts_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TtsIn"
       }
      }
     },
     "description": "Text, voice, model and DLP mode.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Tts V1 Multimodal Tts Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Synthesize speech from text",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/video/generate": {
   "post": {
    "description": "Starts a video generation job and answers 202 with the job; follow it with `GET /v1/multimodal/jobs/{job_id}`. Usage is counted in video seconds. Needs `tenant_admin`, `developer` or `agent`.",
    "operationId": "video_generate_v1_multimodal_video_generate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/VideoGenIn"
       }
      }
     },
     "description": "Prompt, duration, size and model.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Video Generate V1 Multimodal Video Generate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Generate a video",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/video/process": {
   "post": {
    "description": "Extracts frames and/or the audio track of a video media or inline video (201, the job; queued when ffmpeg is not available). `operations` accepts `frames` and `audio` only (400 `invalid_request`). Needs `tenant_admin`, `developer` or `agent`.",
    "operationId": "video_process_v1_multimodal_video_process_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/VideoProcessIn"
       }
      }
     },
     "description": "Input video, operations, frame rate and audio sample rate.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Video Process V1 Multimodal Video Process Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Process a video",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/multimodal/vision": {
   "post": {
    "description": "Starts a vision understanding job on an image media or inline image with a prompt (201, the job). The answer goes through the DLP with `dlp_mode`. `detail` answers 422 `parameter_unsupported` when the configured provider cannot honour it; a non image input answers 422 `unsupported_media`. Needs `tenant_admin`, `developer` or `agent`.",
    "operationId": "vision_v1_multimodal_vision_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/VisionIn"
       }
      }
     },
     "description": "Input image, prompt, model, DLP mode and detail level.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Vision V1 Multimodal Vision Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Understand an image",
    "tags": [
     "multimodal"
    ]
   }
  },
  "/v1/navin-library": {
   "get": {
    "description": "Version of the vendored navin package, counts per kind and the rule files read from a repository. 503 `navin_library_unavailable` when the catalogue is not packaged.",
    "operationId": "navin_library_v1_navin_library_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Navin Library V1 Navin Library Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the library summary",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/navin-library/{kind}": {
   "get": {
    "description": "Items of one kind: skills, plugins, commands, agents, mcp-presets or channels (`q` searches name and description, `category` filters skills, plugins and MCP presets). An unknown kind answers 404 `navin_library_kind_unknown`.",
    "operationId": "navin_library_items_v1_navin_library__kind__get",
    "parameters": [
     {
      "description": "Kind of item: `skills`, `plugins`, `commands`, `agents`, `mcp-presets` or `channels`.",
      "in": "path",
      "name": "kind",
      "required": true,
      "schema": {
       "title": "Kind",
       "type": "string"
      }
     },
     {
      "description": "Text searched in the name and the description.",
      "in": "query",
      "name": "q",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Q"
      }
     },
     {
      "description": "Only this category (skills, plugins and MCP presets).",
      "in": "query",
      "name": "category",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Category"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Navin Library Items V1 Navin Library  Kind  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the library items of a kind",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/navin-library/{kind}/{name}": {
   "get": {
    "description": "One item with its content (SKILL.md and files of a skill, plugin.json and README of a plugin, Markdown of a command or an agent, full MCP preset or channel contract). 404 `navin_library_item_not_found`.",
    "operationId": "navin_library_item_v1_navin_library__kind___name__get",
    "parameters": [
     {
      "description": "Kind of item: `skills`, `plugins`, `commands`, `agents`, `mcp-presets` or `channels`.",
      "in": "path",
      "name": "kind",
      "required": true,
      "schema": {
       "title": "Kind",
       "type": "string"
      }
     },
     {
      "description": "Name of the item.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Navin Library Item V1 Navin Library  Kind   Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a library item",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/operations/{operation_id}": {
   "get": {
    "description": "The operation (kind, state `pending` or `accepted`, method, path, HTTP status, idempotency key, tracked resource, creator and dates), its accepted answer and the live state of the tracked resource. The resource is read with the caller's credentials through the resource route, so the resource authorization applies: when that read fails, `result` stays null and `result_error.http_status` gives the status. `status` is `pending` while the request runs, then the `status` or `state` of the resource. Requires a tenant principal (403 `tenant_required`); an operation created by someone else answers 404 `not_found` unless the caller holds `tenant_admin`, `platform_admin`, `auditor` or `security_officer`.",
    "operationId": "get_operation_v1_operations__operation_id__get",
    "parameters": [
     {
      "description": "Identifier of the operation, as returned in the `Operation-Id` header.",
      "in": "path",
      "name": "operation_id",
      "required": true,
      "schema": {
       "title": "Operation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Operation V1 Operations  Operation Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Follow a long operation",
    "tags": [
     "operations"
    ]
   }
  },
  "/v1/organizations": {
   "get": {
    "description": "Lists the organizations of the tenant, paginated. Open to any member of the tenant.",
    "operationId": "list_organizations_v1_organizations_get",
    "parameters": [
     {
      "description": "Maximum number of organizations in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Organizations V1 Organizations Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the organizations",
    "tags": [
     "tenancy"
    ]
   },
   "post": {
    "description": "Creates an organization in the tenant. Needs `tenant_admin`. A slug already used answers 409 `conflict`. Writes the audit event `organization.create`.",
    "operationId": "create_organization_v1_organizations_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OrganizationIn"
       }
      }
     },
     "description": "Slug, name, description and metadata of the organization.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Organization V1 Organizations Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an organization",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/organizations/{organization_id}": {
   "patch": {
    "description": "Changes the name, description, status (`active` or `archived`) or metadata of an organization. Needs `tenant_admin`. Send `expected_version` to detect a concurrent change (409 `version_conflict`). Writes the audit event `organization.update`.",
    "operationId": "patch_organization_v1_organizations__organization_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the organization.",
      "in": "path",
      "name": "organization_id",
      "required": true,
      "schema": {
       "title": "Organization Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OrganizationPatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Organization V1 Organizations  Organization Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update an organization",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/platform-manager/backup/backups": {
   "get": {
    "description": "Backup artefacts with SHA-256, size and the outcome of their last verification, relayed from the Manager (`backup:read` there). Requires `platform_admin`.",
    "operationId": "list_backups_v1_platform_manager_backup_backups_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Backups V1 Platform Manager Backup Backups Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the backup artefacts",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/backup/jobs": {
   "get": {
    "description": "Backup jobs of the Manager with their status, relayed on behalf of the user (`backup:read` there). Requires `platform_admin`.",
    "operationId": "list_backup_jobs_v1_platform_manager_backup_jobs_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Backup Jobs V1 Platform Manager Backup Jobs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the backup jobs",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/backup/plans": {
   "get": {
    "description": "Backup policies (scope, interval, retention, immutability) and the late or failed alerts of the Manager. Requires `platform_admin`.",
    "operationId": "list_backup_plans_v1_platform_manager_backup_plans_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Backup Plans V1 Platform Manager Backup Plans Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the backup plans",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/backup/restores": {
   "get": {
    "description": "Restore plans with their status and approval count (two approvers other than the requester). Requires `platform_admin`.",
    "operationId": "list_restores_v1_platform_manager_backup_restores_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Restores V1 Platform Manager Backup Restores Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the restore plans",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Plans a restore of one artefact and answers 201 with the plan; the plan always precedes an execution and needs two approvers other than the requester. The Manager compares the target versions with the artefact. Executing the restore stays in the Manager console. Audited (`platform_manager.restore.plan`), allowed or refused. Requires `platform_admin`.",
    "operationId": "plan_restore_v1_platform_manager_backup_restores_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RestorePlanIn"
       }
      }
     },
     "description": "Artefact to restore and target environment.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Plan Restore V1 Platform Manager Backup Restores Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Plan a restore",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/backup/restores/{plan_id}/approve": {
   "post": {
    "description": "Adds the approval of the user to a restore plan; the Manager refuses a self approval and counts two distinct approvers. Audited (`platform_manager.restore.approve`) with the new status and approval count. Requires `platform_admin`.",
    "operationId": "approve_restore_v1_platform_manager_backup_restores__plan_id__approve_post",
    "parameters": [
     {
      "description": "Identifier of the restore plan in the Manager.",
      "in": "path",
      "name": "plan_id",
      "required": true,
      "schema": {
       "title": "Plan Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Approve Restore V1 Platform Manager Backup Restores  Plan Id  Approve Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Approve a restore plan",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/catalog": {
   "get": {
    "description": "Services of the Manager catalog (stack name, version and categories) with their display names, category, version, components, modes, methods, requirements, delivery (`install`, `connect`, `job`, `package`), layer and licence. Requires `platform_admin`.",
    "operationId": "list_catalog_v1_platform_manager_catalog_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Catalog V1 Platform Manager Catalog Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the Manager catalog",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/catalog/{service}": {
   "get": {
    "description": "Install descriptor of one catalog service: modes with their components and cardinalities, methods, requirements, sections and parameters with their defaults. A secret parameter never carries a default and says whether it is generated; templates and artefacts never leave the bridge. Requires `platform_admin`.",
    "operationId": "get_catalog_service_v1_platform_manager_catalog__service__get",
    "parameters": [
     {
      "description": "Name of the catalog service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Catalog Service V1 Platform Manager Catalog  Service  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the install descriptor of a service",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters": {
   "get": {
    "description": "Clusters (environments) of the Navin Manager visible to the user. Requires `platform_admin`.",
    "operationId": "list_clusters_v1_platform_manager_clusters_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Clusters V1 Platform Manager Clusters Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the clusters",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Creates a cluster (environment) in the Manager and answers 201; the delegated user needs `clusters:create`. Audited (`platform_manager.cluster_create`), allowed or refused. Requires `platform_admin`.",
    "operationId": "create_cluster_v1_platform_manager_clusters_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ClusterIn"
       }
      }
     },
     "description": "Name, mode, description and profile of the cluster.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Cluster V1 Platform Manager Clusters Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a cluster",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/enrollment-tokens": {
   "get": {
    "description": "Bootstrap tokens of a cluster: prefix, expiry, uses and revocation (the token itself is never listed). Requires `platform_admin`.",
    "operationId": "list_enrollment_tokens_v1_platform_manager_clusters__cluster_id__enrollment_tokens_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Enrollment Tokens V1 Platform Manager Clusters  Cluster Id  Enrollment Tokens Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the enrollment tokens",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Bootstrap token of the node agent and the register command to run on each machine, answered with 201; shown once, the token and the command are never written to the audit (only its id and expiry). Needs `hosts:manage` in the Manager. Requires `platform_admin`.",
    "operationId": "create_enrollment_token_v1_platform_manager_clusters__cluster_id__enrollment_tokens_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EnrollmentTokenIn"
       }
      }
     },
     "description": "Lifetime and number of uses of the token.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Enrollment Token V1 Platform Manager Clusters  Cluster Id  Enrollment Tokens Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an enrollment token",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/enrollment-tokens/{token_id}": {
   "delete": {
    "description": "Revokes a bootstrap token of the node agent in the Manager (`hosts:manage` there) and answers 204; machines already enrolled are not affected. Audited (`platform_manager.enrollment_token_revoke`), allowed or refused. Requires `platform_admin`.",
    "operationId": "revoke_enrollment_token_v1_platform_manager_clusters__cluster_id__enrollment_tokens__token_id__delete",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier of the enrollment token, as listed.",
      "in": "path",
      "name": "token_id",
      "required": true,
      "schema": {
       "title": "Token Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke an enrollment token",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/hosts/ssh-bootstrap": {
   "post": {
    "description": "Installs the node agent on machines over SSH (Manager operation `host.ssh_bootstrap`, `hosts:manage` there) and answers 202 with the operation to follow. The private key is relayed to the Manager, which keeps it in memory for the bootstrap tasks only; the Control Plane never stores nor audits it (the audit keeps hosts, user, port, sudo and fingerprints). Requires `platform_admin`.",
    "operationId": "ssh_bootstrap_v1_platform_manager_clusters__cluster_id__hosts_ssh_bootstrap_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SshBootstrapIn"
       }
      }
     },
     "description": "Machines, SSH account and host key fingerprints.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Ssh Bootstrap V1 Platform Manager Clusters  Cluster Id  Hosts Ssh Bootstrap Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Install the node agent over SSH",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/nodes": {
   "get": {
    "description": "Hosts of the cluster as the Manager knows them (state, facts, agent). Requires `platform_admin`.",
    "operationId": "list_nodes_v1_platform_manager_clusters__cluster_id__nodes_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Nodes V1 Platform Manager Clusters  Cluster Id  Nodes Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the machines of a cluster",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/operations": {
   "get": {
    "description": "Operations of the Manager on the cluster (install, start, stop, preflight, bootstrap...) with their target and status. Requires `platform_admin`.",
    "operationId": "list_operations_v1_platform_manager_clusters__cluster_id__operations_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Operations V1 Platform Manager Clusters  Cluster Id  Operations Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the operations of a cluster",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services": {
   "get": {
    "description": "Services of the cluster with the five state fields (desired, observed, health, operation, security), the administrative state and its reason, the running and total instance counts, `drift` (observed differs from desired), the delivery and the connection of a connected service. Requires `platform_admin`.",
    "operationId": "list_services_v1_platform_manager_clusters__cluster_id__services_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Services V1 Platform Manager Clusters  Cluster Id  Services Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the services of a cluster",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Installs catalog services on the chosen hosts, on behalf of the user, and answers 202 with the operation id; the Manager checks `services:install`, the modes, methods, placements and configuration, then starts the install operation. The audit keeps services, modes, methods, hosts and configured keys, never the configuration values. Requires `platform_admin`.",
    "operationId": "install_services_v1_platform_manager_clusters__cluster_id__services_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__platform_manager__InstallIn"
       }
      }
     },
     "description": "Services to install and install options.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Install Services V1 Platform Manager Clusters  Cluster Id  Services Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Install catalog services",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/connect": {
   "post": {
    "description": "Registers an existing service of the customer on behalf of the user and answers 201; the Manager checks `services:install` and the connect section of the descriptor, then health checks it. A connected service is never installed, started or stopped by the Manager. Secret fields are relayed and sealed by the Manager; the audit keeps the endpoint, TLS, method and field names only. Requires `platform_admin`.",
    "operationId": "connect_service_v1_platform_manager_clusters__cluster_id__services_connect_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConnectIn"
       }
      }
     },
     "description": "The service to connect.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Connect Service V1 Platform Manager Clusters  Cluster Id  Services Connect Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Connect an existing service",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/connect/validate": {
   "post": {
    "description": "Dry run of a connect by the Manager: answers `ok`, the errors (service, field, code, messages in both languages) and the health check result; nothing is stored. Requires `platform_admin`.",
    "operationId": "validate_connect_v1_platform_manager_clusters__cluster_id__services_connect_validate_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConnectIn"
       }
      }
     },
     "description": "The service to connect, as for the real connect.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Validate Connect V1 Platform Manager Clusters  Cluster Id  Services Connect Validate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Validate a service connection",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/validate": {
   "post": {
    "description": "Dry run of an install by the Manager planner: answers `ok`, the errors (service, field, code, messages in both languages) and the plan it would run; nothing is installed. Requires `platform_admin`.",
    "operationId": "validate_install_v1_platform_manager_clusters__cluster_id__services_validate_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__platform_manager__InstallIn"
       }
      }
     },
     "description": "The install to check, as for the real install.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Validate Install V1 Platform Manager Clusters  Cluster Id  Services Validate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Validate a services install",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/{service}": {
   "get": {
    "description": "One service with its state fields and instance counts, its security state (TLS, number of secrets set out of the total) and the full sheet of the Manager. Requires `platform_admin`.",
    "operationId": "get_service_v1_platform_manager_clusters__cluster_id__services__service__get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Service V1 Platform Manager Clusters  Cluster Id  Services  Service  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a service sheet",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/{service}/config": {
   "get": {
    "description": "Current configuration version of a service as the Manager shows it (secret values masked), with recommendations, groups and stale hosts. Needs `configs:read` in the Manager; editing stays in the Manager console. Requires `platform_admin`.",
    "operationId": "service_config_v1_platform_manager_clusters__cluster_id__services__service__config_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Service Config V1 Platform Manager Clusters  Cluster Id  Services  Service  Config Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the configuration of a service",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/{service}/config/diff": {
   "get": {
    "description": "Changed parameters between two configuration versions of a service, one entry per parameter; a secret parameter only says whether it is set in each version, never its value. Requires `platform_admin`.",
    "operationId": "config_diff_v1_platform_manager_clusters__cluster_id__services__service__config_diff_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     },
     {
      "description": "Older configuration version, integer of at least 1 (required).",
      "in": "query",
      "name": "from",
      "required": true,
      "schema": {
       "minimum": 1,
       "title": "From",
       "type": "integer"
      }
     },
     {
      "description": "Newer configuration version, integer of at least 1 (required).",
      "in": "query",
      "name": "to",
      "required": true,
      "schema": {
       "minimum": 1,
       "title": "To",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Config Diff V1 Platform Manager Clusters  Cluster Id  Services  Service  Config Diff Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Compare two configuration versions",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/{service}/config/versions": {
   "get": {
    "description": "Configuration version history of a service in the Manager (`configs:read` there). Requires `platform_admin`.",
    "operationId": "service_config_versions_v1_platform_manager_clusters__cluster_id__services__service__config_versions_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Service Config Versions V1 Platform Manager Clusters  Cluster Id  Services  Service  Config Versions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the configuration versions",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/{service}/connection": {
   "delete": {
    "description": "Forgets a connected service (the service itself is untouched); the Manager refuses while a consumer uses it. Audited (`platform_manager.disconnect`), allowed or refused. Requires `platform_admin`.",
    "operationId": "disconnect_service_v1_platform_manager_clusters__cluster_id__services__service__connection_delete",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the connected service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Disconnect Service V1 Platform Manager Clusters  Cluster Id  Services  Service  Connection Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Disconnect a connected service",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/{service}/dashboard": {
   "get": {
    "description": "Monitoring dashboard of a service relayed from the Manager (`cluster:read` there): instances, health and latest checks, availability, the machines it detected with their components and metrics, alerts, operations, configuration and, for a connected service, its connection. Requires `platform_admin`.",
    "operationId": "service_dashboard_v1_platform_manager_clusters__cluster_id__services__service__dashboard_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     },
     {
      "description": "Start of the window, ISO 8601, 64 characters at most. Default: one hour ago.",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 64,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "description": "End of the window, ISO 8601, 64 characters at most. Default: now.",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 64,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     },
     {
      "description": "Resolution of the metric series in seconds, 10 to 86400, default 60.",
      "in": "query",
      "name": "step",
      "required": false,
      "schema": {
       "default": 60,
       "maximum": 86400,
       "minimum": 10,
       "title": "Step",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Service Dashboard V1 Platform Manager Clusters  Cluster Id  Services  Service  Dashboard Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the dashboard of a service",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/{service}/mode": {
   "post": {
    "description": "Operating mode of a service (drain, scale to zero, security suspension, emergency stop, disable, quarantine, maintenance, enable), forwarded on behalf of the user; the Manager enforces the state it leaves behind and may require an approval. Audited (`platform_manager.mode.<mode>`) with the operation id and the resulting administrative state, allowed or refused. Requires `platform_admin`.",
    "operationId": "set_mode_v1_platform_manager_clusters__cluster_id__services__service__mode_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ModeIn"
       }
      }
     },
     "description": "The mode to apply and its options.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Set Mode V1 Platform Manager Clusters  Cluster Id  Services  Service  Mode Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the operating mode of a service",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/services/{service}/operations": {
   "post": {
    "description": "Forwards an operation (start, stop, restart, rolling restart, reinstall) with the user's identity and answers 202 with the operation id; the Manager decides (RBAC, approvals, stop rules). Audited (`platform_manager.<action>`), allowed or refused. Requires `platform_admin`.",
    "operationId": "request_operation_v1_platform_manager_clusters__cluster_id__services__service__operations_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the service.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OperationIn"
       }
      }
     },
     "description": "The operation and its scope.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Request Operation V1 Platform Manager Clusters  Cluster Id  Services  Service  Operations Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request a service operation",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/clusters/{cluster_id}/support-bundles": {
   "get": {
    "description": "Sanitized support bundles of a cluster; a bundle is downloaded from the Manager console, never through the Control Plane. Requires `platform_admin`.",
    "operationId": "list_support_bundles_v1_platform_manager_clusters__cluster_id__support_bundles_get",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Support Bundles V1 Platform Manager Clusters  Cluster Id  Support Bundles Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the support bundles",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Asks the Manager for a sanitized support bundle (`cluster:manage` there) and answers 202 with the operation to follow and the bundle id; the bundle is downloaded from the Manager console. Audited (`platform_manager.support_bundle`), allowed or refused. Requires `platform_admin`.",
    "operationId": "request_support_bundle_v1_platform_manager_clusters__cluster_id__support_bundles_post",
    "parameters": [
     {
      "description": "Identifier of the cluster in the Navin Manager.",
      "in": "path",
      "name": "cluster_id",
      "required": true,
      "schema": {
       "title": "Cluster Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Request Support Bundle V1 Platform Manager Clusters  Cluster Id  Support Bundles Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request a support bundle",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/connections": {
   "get": {
    "description": "Existing connections of the types the portal binds (PostgreSQL, Redis, OIDC), filtered by type when given; the secret only says whether it is set. Needs `connections:read` in the Manager. Requires `platform_admin`.",
    "operationId": "list_connections_v1_platform_manager_connections_get",
    "parameters": [
     {
      "description": "Only connections of this type: `postgresql`, `redis` or `oidc`.",
      "in": "query",
      "name": "type",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "pattern": "^(postgresql|redis|oidc)$",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Type"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Connections V1 Platform Manager Connections Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the connections",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Saves an existing PostgreSQL, Redis or OIDC issuer as a Manager connection and answers 201 (the secret is sealed by the Manager and never returned). Install forms then bind a service to it. Needs `connections:manage` in the Manager. The audit keeps name, type, parameter keys and whether a secret was given. Requires `platform_admin`.",
    "operationId": "create_connection_v1_platform_manager_connections_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConnectionIn"
       }
      }
     },
     "description": "The connection to save.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Connection V1 Platform Manager Connections Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Save a connection",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/connections/validate": {
   "post": {
    "description": "Real protocol test of a connection before it is saved: answers `ok`, latency in milliseconds, server version, error code and messages; nothing is stored and the secret is never sent back. Audited without the secret. Requires `platform_admin`.",
    "operationId": "validate_connection_v1_platform_manager_connections_validate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConnectionTestIn"
       }
      }
     },
     "description": "Type, parameters and secret of the connection to test.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Validate Connection V1 Platform Manager Connections Validate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Test a connection before saving it",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/connections/{connection_id}": {
   "delete": {
    "description": "Forgets a connection and answers 204; the Manager refuses (409 `platform_manager_connection_in_use`) while a service is bound to it. Needs `connections:manage` in the Manager. Audited, allowed or refused. Requires `platform_admin`.",
    "operationId": "delete_connection_v1_platform_manager_connections__connection_id__delete",
    "parameters": [
     {
      "description": "Identifier of the connection in the Manager.",
      "in": "path",
      "name": "connection_id",
      "required": true,
      "schema": {
       "title": "Connection Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a connection",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/connections/{connection_id}/test": {
   "post": {
    "description": "Runs the protocol test of a saved connection now (its sealed secret stays in the Manager). Audited. Requires `platform_admin`.",
    "operationId": "test_connection_v1_platform_manager_connections__connection_id__test_post",
    "parameters": [
     {
      "description": "Identifier of the connection in the Manager.",
      "in": "path",
      "name": "connection_id",
      "required": true,
      "schema": {
       "title": "Connection Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Test Connection V1 Platform Manager Connections  Connection Id  Test Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Test a saved connection",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/console": {
   "get": {
    "description": "Whether the Manager is configured, the base address of its console (`EAI_PLATFORM_MANAGER_CONSOLE_URL`, else `EAI_PLATFORM_MANAGER_URL`) and the operator consoles (Opik, Grafana, Keycloak, LiteLLM, OpenSearch Dashboards): from their setting when set (source `setting`), else from the service of the same name the Manager installed or connected (source `manager`). A console address that is not https or that carries credentials is never returned (`problem` says why). Requires `platform_admin`.",
    "operationId": "console_v1_platform_manager_console_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Console V1 Platform Manager Console Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the console links",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/dr/exercises": {
   "get": {
    "description": "DR exercises with the observed RPO and RTO and whether each target was met (null when not measured). Requires `platform_admin`.",
    "operationId": "list_dr_exercises_v1_platform_manager_dr_exercises_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Dr Exercises V1 Platform Manager Dr Exercises Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the DR exercises",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Requests a DR exercise of a DR plan and answers 201; the Manager applies its approval rule (`dr:manage` there). Completing the exercise and a real failover stay in the Manager console. Audited (`platform_manager.dr.exercise.request`), allowed or refused. Requires `platform_admin`.",
    "operationId": "request_dr_exercise_v1_platform_manager_dr_exercises_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ExerciseIn"
       }
      }
     },
     "description": "The DR plan to exercise.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Request Dr Exercise V1 Platform Manager Dr Exercises Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request a DR exercise",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/dr/exercises/{exercise_id}/approve": {
   "post": {
    "description": "Adds the approval of the user to a DR exercise; the Manager refuses a self approval. Audited (`platform_manager.dr.exercise.approve`) with the new status. Requires `platform_admin`.",
    "operationId": "approve_dr_exercise_v1_platform_manager_dr_exercises__exercise_id__approve_post",
    "parameters": [
     {
      "description": "Identifier of the DR exercise in the Manager.",
      "in": "path",
      "name": "exercise_id",
      "required": true,
      "schema": {
       "title": "Exercise Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Approve Dr Exercise V1 Platform Manager Dr Exercises  Exercise Id  Approve Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Approve a DR exercise",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/dr/plans": {
   "get": {
    "description": "DR plans: mode, primary and secondary sites, the client's RPO and RTO targets (null until set). Requires `platform_admin`.",
    "operationId": "list_dr_plans_v1_platform_manager_dr_plans_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Dr Plans V1 Platform Manager Dr Plans Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the DR plans",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/hosts/{host_id}": {
   "get": {
    "description": "One machine with its facts (operating system, resources, agent version, last heartbeat). Requires `platform_admin`.",
    "operationId": "get_host_v1_platform_manager_hosts__host_id__get",
    "parameters": [
     {
      "description": "Identifier of the machine in the Manager.",
      "in": "path",
      "name": "host_id",
      "required": true,
      "schema": {
       "title": "Host Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Host V1 Platform Manager Hosts  Host Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a machine",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/hosts/{host_id}/decommission": {
   "post": {
    "description": "Decommissions a machine without components (agent stopped, certificate revoked) and answers 202 with the operation id. Audited (`platform_manager.decommission`), allowed or refused. Requires `platform_admin`.",
    "operationId": "decommission_host_v1_platform_manager_hosts__host_id__decommission_post",
    "parameters": [
     {
      "description": "Identifier of the machine in the Manager.",
      "in": "path",
      "name": "host_id",
      "required": true,
      "schema": {
       "title": "Host Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Decommission Host V1 Platform Manager Hosts  Host Id  Decommission Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Decommission a machine",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/hosts/{host_id}/facts/refresh": {
   "post": {
    "description": "Asks the node agent to collect the facts of the machine again (operating system, resources...) and answers 202 with the operation id. Audited (`platform_manager.facts_refresh`), allowed or refused. Requires `platform_admin`.",
    "operationId": "refresh_facts_v1_platform_manager_hosts__host_id__facts_refresh_post",
    "parameters": [
     {
      "description": "Identifier of the machine in the Manager.",
      "in": "path",
      "name": "host_id",
      "required": true,
      "schema": {
       "title": "Host Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Refresh Facts V1 Platform Manager Hosts  Host Id  Facts Refresh Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Refresh the facts of a machine",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/hosts/{host_id}/preflight": {
   "get": {
    "description": "Results of the last preflight checks of a machine (check, status, message in both languages). Requires `platform_admin`.",
    "operationId": "preflight_results_v1_platform_manager_hosts__host_id__preflight_get",
    "parameters": [
     {
      "description": "Identifier of the machine in the Manager.",
      "in": "path",
      "name": "host_id",
      "required": true,
      "schema": {
       "title": "Host Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Preflight Results V1 Platform Manager Hosts  Host Id  Preflight Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the preflight results",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Runs the preflight checks of a machine (Manager operation `host.preflight`, `hosts:manage` there) and answers 202 with the operation id; read the results with `GET .../preflight`. Audited, allowed or refused. Requires `platform_admin`.",
    "operationId": "run_preflight_v1_platform_manager_hosts__host_id__preflight_post",
    "parameters": [
     {
      "description": "Identifier of the machine in the Manager.",
      "in": "path",
      "name": "host_id",
      "required": true,
      "schema": {
       "title": "Host Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Run Preflight V1 Platform Manager Hosts  Host Id  Preflight Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run the preflight checks",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/setup": {
   "get": {
    "description": "Getting started status, never a secret and never an error because the Manager is absent. `core`: API, PostgreSQL, migrations, Redis (optional) and Keycloak (optional), each with a state (`ok`, `missing`, `down`, `error`), the setting to fix and messages in English and French. `manager`: address and token reference set, credential found, Manager reachable, delegated user known, number of clusters, the suggested token reference and the permissions the Manager API token needs (changes need a restart). Requires `platform_admin`.",
    "operationId": "setup_status_v1_platform_manager_setup_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Setup Status V1 Platform Manager Setup Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the setup status",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/summary": {
   "get": {
    "description": "Real counts per cluster (environment): services total, healthy, warning, failed; hosts; alerts; operations. Requires `platform_admin`.",
    "operationId": "summary_v1_platform_manager_summary_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Summary V1 Platform Manager Summary Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the platform summary",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/vault/entries": {
   "get": {
    "description": "Services of the IT vault by name, with URL, login, source (`manual` or `installed:<service>`) and whether a password and a key are set (`has_password`, `has_api_key`), never their values. Requires `platform_admin`.",
    "operationId": "list_entries_v1_platform_manager_vault_entries_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Entries V1 Platform Manager Vault Entries Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the vault entries",
    "tags": [
     "platform-manager"
    ]
   },
   "post": {
    "description": "Adds a service to the IT vault (source `manual`) and answers 201 without the password nor the key. URL, login, password and key are sealed together with AES-256-GCM (key derived from the platform master key, entry id as associated data); only the name is stored in clear. A name already used answers 409 `it_vault_name_taken`; an empty name 422 `validation_failed`. Audited (`it_vault.create`, name only). Requires `platform_admin`.",
    "operationId": "create_entry_v1_platform_manager_vault_entries_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EntryIn"
       }
      }
     },
     "description": "The service to add. Unknown fields are refused.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Entry V1 Platform Manager Vault Entries Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add a vault entry",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/vault/entries/{entry_id}": {
   "delete": {
    "description": "Deletes a service of the IT vault and answers 204. An entry pre-filled from the platform settings comes back at the next import. Audited (`it_vault.delete`, name only). Unknown id: 404 `it_vault_entry_not_found`. Requires `platform_admin`.",
    "operationId": "delete_entry_v1_platform_manager_vault_entries__entry_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the vault entry.",
      "in": "path",
      "name": "entry_id",
      "required": true,
      "schema": {
       "title": "Entry Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a vault entry",
    "tags": [
     "platform-manager"
    ]
   },
   "get": {
    "description": "One service of the vault without its password nor key (use `POST .../reveal` for them). Unknown id: 404 `it_vault_entry_not_found`. Requires `platform_admin`.",
    "operationId": "get_entry_v1_platform_manager_vault_entries__entry_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the vault entry.",
      "in": "path",
      "name": "entry_id",
      "required": true,
      "schema": {
       "title": "Entry Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Entry V1 Platform Manager Vault Entries  Entry Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a vault entry",
    "tags": [
     "platform-manager"
    ]
   },
   "patch": {
    "description": "Changes the given fields of a vault entry and seals them again (AES-256-GCM). A name used by another entry (case insensitive) answers 409 `it_vault_name_taken`; an empty name 422 `validation_failed`. Audited (`it_vault.update`, name and changed field names only). Requires `platform_admin`.",
    "operationId": "update_entry_v1_platform_manager_vault_entries__entry_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the vault entry.",
      "in": "path",
      "name": "entry_id",
      "required": true,
      "schema": {
       "title": "Entry Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EntryPatch"
       }
      }
     },
     "description": "Fields to change. Unknown fields are refused.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Update Entry V1 Platform Manager Vault Entries  Entry Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a vault entry",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/vault/entries/{entry_id}/reveal": {
   "post": {
    "description": "Password and key of one service in clear (show and copy in the console). Each reveal is audited (`it_vault.reveal`) with the service name, never the values. Unknown id: 404 `it_vault_entry_not_found`. Requires `platform_admin`.",
    "operationId": "reveal_entry_v1_platform_manager_vault_entries__entry_id__reveal_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the vault entry.",
      "in": "path",
      "name": "entry_id",
      "required": true,
      "schema": {
       "title": "Entry Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Reveal Entry V1 Platform Manager Vault Entries  Entry Id  Reveal Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reveal the secrets of a vault entry",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/platform-manager/vault/import": {
   "post": {
    "description": "Pre-fills the vault with the services the platform is configured with (PostgreSQL, Redis, Keycloak, OpenBao, OpenFGA, OPA, LiteLLM, Qdrant, NATS, Temporal, LiveKit, Opik, ClickHouse, S3, Platform Manager, installer account of the portal), from the `EAI_*` settings. Only missing services are added: an entry is never overwritten, a deleted one comes back. Answers the created and skipped names. Audited (`it_vault.import`). The same import runs at each API start. Requires `platform_admin`.",
    "operationId": "import_entries_v1_platform_manager_vault_import_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Import Entries V1 Platform Manager Vault Import Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Import the configured services into the vault",
    "tags": [
     "platform-manager"
    ]
   }
  },
  "/v1/plugins": {
   "get": {
    "description": "Plugins of the tenant in name order, with version, digest, verification and status. One page only.",
    "operationId": "list_plugins_v1_plugins_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Plugins V1 Plugins Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the plugins",
    "tags": [
     "plugins"
    ]
   },
   "post": {
    "description": "Applies a Plugin manifest: creates the plugin or updates it (back to `registered`, a blocked plugin stays `blocked`), with the signature verified and stored. Refused: 422 `pack_requires_marketplace` for a pack, 422 `invalid_manifest` when the `oci_ref` digest differs from `artifact.digest`, an allow list is missing for `egress_allowlist` or the limits exceed the platform maximum (4 CPU, 8Gi memory, 3600 s, 1 GPU); 409 `plugin_installed` while installed. Needs `tenant_admin`, `developer` or `application_owner`; the caller becomes ReBAC owner. Audited as `plugin.apply`.",
    "operationId": "create_plugin_v1_plugins_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Manifest",
        "type": "object"
       }
      }
     },
     "description": "Plugin manifest (`kind: Plugin`, `metadata`, `spec` with description, artifact, signature and sandbox).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Plugin V1 Plugins Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register a plugin",
    "tags": [
     "plugins"
    ]
   }
  },
  "/v1/plugins/{name}": {
   "get": {
    "description": "Returns the plugin with its manifest, verification result and rendered deployment. Needs the ReBAC relation `viewer`. 404 `plugin_not_found`.",
    "operationId": "get_plugin_v1_plugins__name__get",
    "parameters": [
     {
      "description": "Name of the plugin.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Plugin V1 Plugins  Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a plugin",
    "tags": [
     "plugins"
    ]
   }
  },
  "/v1/plugins/{name}/install": {
   "post": {
    "description": "Installs the plugin in its sandbox. Needs `tenant_admin` and the ReBAC relation `owner`.\nSteps:\n1. A `blocked` plugin answers 403 `plugin_blocked`; an installed one is returned as is.\n2. The signature is verified again (403 `plugin_unsigned` when it fails, audited as a denial).\n3. The Deployment (runtime class of the sandbox, read-only root file system by default) and the NetworkPolicy are rendered, then applied when Kubernetes is configured (`status: failed` with the error if the apply fails).\nReturns the runtime status. Audited as `plugin.install`.",
    "operationId": "install_plugin_v1_plugins__name__install_post",
    "parameters": [
     {
      "description": "Name of the plugin.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Install Plugin V1 Plugins  Name  Install Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Install a plugin",
    "tags": [
     "plugins"
    ]
   }
  },
  "/v1/plugins/{name}/status": {
   "get": {
    "description": "Runtime view: status, verified flag, digest, install date, runtime class, whether the objects were `rendered` or `applied` to Kubernetes, the Deployment and NetworkPolicy and the last error. Needs the ReBAC relation `viewer`.",
    "operationId": "plugin_status_v1_plugins__name__status_get",
    "parameters": [
     {
      "description": "Name of the plugin.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Plugin Status V1 Plugins  Name  Status Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the runtime status of a plugin",
    "tags": [
     "plugins"
    ]
   }
  },
  "/v1/plugins/{name}/uninstall": {
   "post": {
    "description": "Deletes the Deployment and the NetworkPolicy from Kubernetes when configured (502 `upstream_error` on failure) and sets the plugin to `uninstalled`. Only an `installed`, `installing` or `failed` plugin (else 409 `plugin_not_installed`). Needs `tenant_admin` and the ReBAC relation `owner`. Audited as `plugin.uninstall`.",
    "operationId": "uninstall_plugin_v1_plugins__name__uninstall_post",
    "parameters": [
     {
      "description": "Name of the plugin.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Uninstall Plugin V1 Plugins  Name  Uninstall Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Uninstall a plugin",
    "tags": [
     "plugins"
    ]
   }
  },
  "/v1/policies": {
   "get": {
    "description": "Lists the policies of the tenant in evaluation order (priority, then name), with their rules or Rego. Open to any member of the tenant. `next_cursor` is always null.",
    "operationId": "list_policies_v1_policies_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Policies V1 Policies Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the policies",
    "tags": [
     "policies"
    ]
   },
   "post": {
    "description": "Creates a policy of the tenant and appends its first revision. An `opa` policy needs `rego` (422 `validation_error`) and, unless OPA loads signed bundles, is pushed to OPA at once (503 `policy_engine_unavailable` when OPA cannot be reached). A name already used answers 409 `conflict`. Needs `tenant_admin` or `security_officer`. Writes the audit event `policy.create`.",
    "operationId": "create_policy_v1_policies_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__policies__PolicyIn"
       }
      }
     },
     "description": "Name, engine, rules or Rego, priority and status of the policy.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Policy V1 Policies Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a policy",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/bundles": {
   "get": {
    "description": "Lists the OPA bundles published for the tenant: revision, SHA-256, signature state, policies included and date. Needs `tenant_admin`, `security_officer` or `auditor`.",
    "operationId": "list_bundles_v1_policies_bundles_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Bundles V1 Policies Bundles Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the OPA bundles",
    "tags": [
     "policies"
    ]
   },
   "post": {
    "description": "Packs the `opa` policies of the tenant into a signed OPA bundle and stores it as the new `current` revision. Active policies are decided by OPA; draft ones ship as libraries; disabled ones are left out. No `opa` policy answers 409 `policy_bundle_empty`; no signing key in production 503 `policy_bundle_signing_unavailable`. Needs `tenant_admin` or `security_officer`. Writes the audit event `policy.bundle_publish`. Answers 201 with the bundle record.",
    "operationId": "publish_bundle_v1_policies_bundles_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/BundleIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional revision name and `data.json` content. An empty body generates the revision."
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Publish Bundle V1 Policies Bundles Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Publish an OPA bundle",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/bundles/{revision}/bundle.tar.gz": {
   "get": {
    "description": "Returns the bundle OPA polls, as `application/gzip`: Rego modules, optional `data.json`, `.manifest` and `.signatures.json` (RS256 JWT over the SHA-256 of every file). The `ETag` header is its SHA-256 and `X-Bundle-Revision` its revision. Needs `tenant_admin`, `security_officer` or `auditor`. Answers 404 `not_found` for an unknown revision.",
    "operationId": "download_bundle_v1_policies_bundles__revision__bundle_tar_gz_get",
    "parameters": [
     {
      "description": "Revision of the bundle, or `current` for the latest published one.",
      "in": "path",
      "name": "revision",
      "required": true,
      "schema": {
       "title": "Revision",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Download an OPA bundle",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/decisions": {
   "get": {
    "description": "Lists the decisions of the tenant, newest first, paginated: subject, action, resource, context, allow, policy and version, reasons, obligations, engine and date. Needs `tenant_admin`, `security_officer` or `auditor`.",
    "operationId": "list_decisions_v1_policies_decisions_get",
    "parameters": [
     {
      "description": "Maximum number of decisions in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Only the decisions on this action, for example `model.invoke`.",
      "in": "query",
      "name": "action",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Action"
      }
     },
     {
      "description": "`true` for allowed decisions only, `false` for denied ones only.",
      "in": "query",
      "name": "allow",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Allow"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Decisions V1 Policies Decisions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the policy decisions",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/engines": {
   "get": {
    "description": "Returns the policy services (builtin engine, OPA, OpenFGA) and the policy version or bundle revision each one really runs, read from the engine itself. Needs `tenant_admin`, `security_officer` or `auditor`.",
    "operationId": "engines_status_v1_policies_engines_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Engines Status V1 Policies Engines Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the policy engines status",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/evaluate": {
   "post": {
    "description": "Returns the decision for a Policy Contract request. The body is a Policy Contract (`{schema_version, request}`) or just its `request` object (`subject`, `action`, `resource`, `context`); it is validated against the `policy-contract` contract (422 `validation_error`).\n\n1. Without `subject`, the request is evaluated for the caller: SDK helpers and gateway middleware only send the action, the resource and the context.\n2. The subject is always the caller, except that `tenant_admin` and `security_officer` may evaluate on behalf of another subject of their own tenant (what if simulation; `platform_admin` is removed from its roles). Such an evaluation writes the audit event `policy.simulate`.\n\nThe answer gives `schema_version`, `request` and `decision` (allow, reasons, obligations, policy and version, decision id). The decision is stored in the decision log.",
    "operationId": "evaluate_policy_v1_policies_evaluate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Document",
        "type": "object"
       }
      }
     },
     "description": "Policy Contract document, or its `request` object alone.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Evaluate Policy V1 Policies Evaluate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Evaluate a policy request",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/simulate": {
   "post": {
    "description": "Compares, input by input, the decisions of the active policies with those of the same set where the candidate replaces `policy_id` (or is added). Nothing is changed.\n\nInputs are the given Policy Contract requests plus, with `recorded`, the last N recorded decisions replayed. Each result gives `current`, `candidate` and `changed`; `summary` counts the total, the changed decisions and the `allow_to_deny` and `deny_to_allow` flips. Only `builtin` candidates can be simulated (422 `simulation_engine_unsupported`). Needs `tenant_admin`, `security_officer` or `developer`. Writes the audit event `policy.simulate`.",
    "operationId": "simulate_policy_v1_policies_simulate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SimulateIn"
       }
      }
     },
     "description": "Candidate policy, policy replaced, inputs and number of recorded decisions to replay.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Simulate Policy V1 Policies Simulate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Simulate a candidate policy",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/{policy_id}": {
   "delete": {
    "description": "Deletes the policy and appends a `delete` revision. An OPA policy pushed directly to OPA is removed from it too (503 `policy_engine_unavailable` when OPA cannot be reached). Needs `tenant_admin` or `security_officer`. Writes the audit event `policy.delete`. Answers 204, or 404 `not_found`.",
    "operationId": "delete_policy_v1_policies__policy_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the policy.",
      "in": "path",
      "name": "policy_id",
      "required": true,
      "schema": {
       "title": "Policy Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a policy",
    "tags": [
     "policies"
    ]
   },
   "get": {
    "description": "Returns one policy. Open to any member of the tenant. Answers 404 `not_found`.",
    "operationId": "get_policy_v1_policies__policy_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the policy.",
      "in": "path",
      "name": "policy_id",
      "required": true,
      "schema": {
       "title": "Policy Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Policy V1 Policies  Policy Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a policy",
    "tags": [
     "policies"
    ]
   },
   "put": {
    "description": "Replaces every field of the policy and appends an `update` revision. Same validation as at creation (`rego` for `opa`, unique name). An `opa` policy is pushed to OPA unless OPA loads bundles. Needs `tenant_admin` or `security_officer`. Writes the audit event `policy.update`. Answers 404 `not_found` for an unknown policy.",
    "operationId": "put_policy_v1_policies__policy_id__put",
    "parameters": [
     {
      "description": "Identifier (UUID) of the policy.",
      "in": "path",
      "name": "policy_id",
      "required": true,
      "schema": {
       "title": "Policy Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__policies__PolicyIn"
       }
      }
     },
     "description": "Full new content of the policy.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Policy V1 Policies  Policy Id  Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Replace a policy",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/{policy_id}/revisions": {
   "get": {
    "description": "Lists the immutable revisions of the policy (one per create, update and delete, written in the same transaction), with their number, operation, author, date and content. Needs `tenant_admin`, `security_officer`, `auditor` or `developer`. Answers 404 `not_found`.",
    "operationId": "list_revisions_v1_policies__policy_id__revisions_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the policy.",
      "in": "path",
      "name": "policy_id",
      "required": true,
      "schema": {
       "title": "Policy Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Revisions V1 Policies  Policy Id  Revisions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the revisions of a policy",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/policies/{policy_id}/revisions/diff": {
   "get": {
    "description": "Returns the differences between two revisions of the policy. Defaults: the previous revision against the latest one. The policy is looked up first (404 `not_found`), then the revisions (404 `not_found`). Needs `tenant_admin`, `security_officer`, `auditor` or `developer`.",
    "operationId": "diff_revisions_v1_policies__policy_id__revisions_diff_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the policy.",
      "in": "path",
      "name": "policy_id",
      "required": true,
      "schema": {
       "title": "Policy Id",
       "type": "string"
      }
     },
     {
      "description": "Older revision number (1 or more). Default: the one before `to_revision`.",
      "in": "query",
      "name": "from_revision",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "From Revision"
      }
     },
     {
      "description": "Newer revision number (1 or more). Default: the latest.",
      "in": "query",
      "name": "to_revision",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "To Revision"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Diff Revisions V1 Policies  Policy Id  Revisions Diff Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Compare two revisions of a policy",
    "tags": [
     "policies"
    ]
   }
  },
  "/v1/privacy/classify": {
   "post": {
    "description": "With `text`, detects the entities with the tenant rules and returns `classification`, `findings` and `engine`, without changing the text. With `media_id`, returns the classification, findings and DLP result already computed for that media (404 `not_found` for an unknown media). One of the two is required (400 `invalid_request`). Open to any member of the tenant.",
    "operationId": "classify_v1_privacy_classify_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ClassifyIn"
       }
      }
     },
     "description": "Text or media to classify, and language.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Classify V1 Privacy Classify Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Classify a text or a media",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/projects": {
   "get": {
    "description": "Lists the projects of the tenant ordered by slug, paginated, optionally filtered by organization or business unit. Open to any member of the tenant.",
    "operationId": "list_projects_v1_projects_get",
    "parameters": [
     {
      "description": "Maximum number of projects in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Only the projects attached to this organization.",
      "in": "query",
      "name": "organization_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Organization Id"
      }
     },
     {
      "description": "Only the projects attached to this business unit.",
      "in": "query",
      "name": "business_unit_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Business Unit Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Projects V1 Projects Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the projects",
    "tags": [
     "tenancy"
    ]
   },
   "post": {
    "description": "Creates a project in the tenant of the caller. Needs `tenant_admin`.\n\n1. The project may be attached to an organization and one of its business units (422 `invalid_hierarchy` when they do not match).\n2. The environments listed in `environments` are created at the same time.\n3. The caller receives the ReBAC relation `owner` on the project.\n\nA slug already used answers 409 `conflict`. Writes the audit event `project.create`. The answer carries the project and its environments.",
    "operationId": "create_project_v1_projects_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__tenancy__ProjectIn"
       }
      }
     },
     "description": "Slug, name, settings, environments and attachment of the project.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Project V1 Projects Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a project",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/projects/{project_id}": {
   "delete": {
    "description": "Deletes the project and its environments. Needs `tenant_admin` and the relation `owner` on the project (403 `relation_required`). Objects that still reference the project may block the deletion (409 `conflict`). Writes the audit event `project.delete`. Answers 204.",
    "operationId": "delete_project_v1_projects__project_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a project",
    "tags": [
     "tenancy"
    ]
   },
   "get": {
    "description": "Returns the project with its environments. Needs the relation `viewer` on the project (403 `relation_required`, audited). Answers 404 `not_found` for an unknown project.",
    "operationId": "get_project_v1_projects__project_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Project V1 Projects  Project Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a project",
    "tags": [
     "tenancy"
    ]
   },
   "patch": {
    "description": "Changes the name, description, settings, metadata or attachment of a project. Sending `organization_id` or `business_unit_id` as null detaches the project. The unit must belong to the organization (422 `invalid_hierarchy`). Needs `tenant_admin` and the relation `editor` on the project. Send `expected_version` to detect a concurrent change (409 `version_conflict`). Writes the audit event `project.update`.",
    "operationId": "patch_project_v1_projects__project_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__tenancy__ProjectPatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Project V1 Projects  Project Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a project",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/projects/{project_id}/environments": {
   "get": {
    "description": "Lists the environments of the project, ordered by name. Needs the relation `viewer` on the project. Not paginated: `next_cursor` is always null.",
    "operationId": "list_environments_v1_projects__project_id__environments_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Environments V1 Projects  Project Id  Environments Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the environments of a project",
    "tags": [
     "tenancy"
    ]
   },
   "post": {
    "description": "Adds an environment (`dev`, `test`, `staging` or `prod`) to the project. Needs `tenant_admin` and the relation `editor` on the project. An environment that already exists answers 409 `conflict`. Writes the audit event `environment.create`.",
    "operationId": "create_environment_v1_projects__project_id__environments_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EnvironmentIn"
       }
      }
     },
     "description": "Name and settings of the environment.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Environment V1 Projects  Project Id  Environments Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an environment",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/projects/{project_id}/mcp/instances": {
   "get": {
    "description": "Returns `enabled` (whether the MCP Runtime runs on this platform), the project `policy` (defaults when not configured), the catalogue state, the `templates` and the instances, newest first, at most 500: its own for a user, every one for `tenant_admin` and `security_officer`. Needs the ReBAC relation `viewer` on the project.",
    "operationId": "list_instances_v1_projects__project_id__mcp_instances_get",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Only the instances in this state: `provisioning`, `ready`, `sleeping`, `failed`, `terminating` or `terminated`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "provisioning",
          "ready",
          "sleeping",
          "failed",
          "terminating",
          "terminated"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Instances V1 Projects  Project Id  Mcp Instances Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the MCP instances of a project",
    "tags": [
     "mcp-runtime"
    ]
   },
   "post": {
    "description": "Starts an isolated MCP instance of the caller in the project (202): ToolHive MCPServer of its own, credentials of its own, ready when ToolHive reports it Ready (GET the instance to follow it). Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor` on the project.\nChecks: the MCP Runtime is enabled (409 `mcp_runtime_disabled`); the template, its hosts and database roles are allowed by the project policy (403 `mcp_template_not_allowed`, `mcp_host_not_allowed`, `mcp_database_role_not_allowed`); a template with personal credentials needs `credential_ref` (422 `mcp_credential_required`); agents, tools and name are valid (422); quotas per user and per project (409 `mcp_instance_quota`); no other instance of the caller with the same name (409 `mcp_instance_exists`). A failed provisioning destroys the instance and returns the error. Audited as `mcp.instance.create`.",
    "operationId": "create_instance_v1_projects__project_id__mcp_instances_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/InstanceIn"
       }
      }
     },
     "description": "Template, name, parameters, personal credential, agents, allowed tools and idle time.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Instance V1 Projects  Project Id  Mcp Instances Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start an MCP instance",
    "tags": [
     "mcp-runtime"
    ]
   }
  },
  "/v1/projects/{project_id}/mcp/instances/{instance_id}": {
   "delete": {
    "description": "Destroys the instance at the end of the task: credentials revoked, resources deleted, gateway entry disabled, journal kept. Allowed for its owner, or `tenant_admin` and `security_officer` (recorded as an administrator destruction). Needs the ReBAC relation `viewer` on the project. Returns the instance and its journal. 404 `mcp_instance_not_found`.",
    "operationId": "delete_instance_v1_projects__project_id__mcp_instances__instance_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Instance V1 Projects  Project Id  Mcp Instances  Instance Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Destroy an MCP instance",
    "tags": [
     "mcp-runtime"
    ]
   },
   "get": {
    "description": "The instance (its state read again from ToolHive while it is provisioning or ready) and its lifecycle journal in `events`. `credential_active` tells whether credentials are currently issued. Visible to its owner, `tenant_admin` and `security_officer`; needs the ReBAC relation `viewer` on the project. 404 `mcp_instance_not_found`.",
    "operationId": "get_instance_v1_projects__project_id__mcp_instances__instance_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Instance V1 Projects  Project Id  Mcp Instances  Instance Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get an MCP instance",
    "tags": [
     "mcp-runtime"
    ]
   }
  },
  "/v1/projects/{project_id}/mcp/instances/{instance_id}/start": {
   "post": {
    "description": "Starts a sleeping or failed instance again now (failure count reset): template and project policy checked again, new generation and credentials; ready when ToolHive reports it Ready (GET the instance to follow it). 409 `mcp_instance_busy` while another lifecycle operation runs. Allowed for its owner, `tenant_admin` and `security_officer`; needs the ReBAC relation `viewer` on the project. Returns the instance and its journal (202).",
    "operationId": "start_instance_v1_projects__project_id__mcp_instances__instance_id__start_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Start Instance V1 Projects  Project Id  Mcp Instances  Instance Id  Start Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start a sleeping or failed instance",
    "tags": [
     "mcp-runtime"
    ]
   }
  },
  "/v1/projects/{project_id}/mcp/instances/{instance_id}/stop": {
   "post": {
    "description": "Stops the instance now (credentials revoked, resources deleted): it sleeps, its gateway entry stays and its next call recreates it. Allowed for its owner, `tenant_admin` and `security_officer`; needs the ReBAC relation `viewer` on the project. Returns the instance and its journal.",
    "operationId": "stop_instance_v1_projects__project_id__mcp_instances__instance_id__stop_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Stop Instance V1 Projects  Project Id  Mcp Instances  Instance Id  Stop Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Put an MCP instance to sleep",
    "tags": [
     "mcp-runtime"
    ]
   }
  },
  "/v1/projects/{project_id}/mcp/policy": {
   "put": {
    "description": "Replaces the policy of the MCP Runtime of the project: templates, hosts, database roles, idle time, lifetime and quotas. Unknown templates, invalid host patterns or role names answer 422 `mcp_policy_invalid`. New and woken instances follow it. Needs `tenant_admin` and the ReBAC relation `editor` on the project. Audited as `mcp.runtime.policy`.",
    "operationId": "put_policy_v1_projects__project_id__mcp_policy_put",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__mcp_runtime__routes__PolicyIn"
       }
      }
     },
     "description": "The complete policy; omitted fields take their default.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Policy V1 Projects  Project Id  Mcp Policy Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the MCP runtime policy of a project",
    "tags": [
     "mcp-runtime"
    ]
   }
  },
  "/v1/projects/{project_id}/navin-library": {
   "get": {
    "description": "Library version, activations of the project with counts per kind, and the MCP servers and channels of the project (with the preset they come from). Needs the ReBAC relation `viewer` on the project.",
    "operationId": "project_library_v1_projects__project_id__navin_library_get",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Project Library V1 Projects  Project Id  Navin Library Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get what a project uses from the library",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/projects/{project_id}/navin-library/activations": {
   "post": {
    "description": "Activates a skill, a plugin (with its skills, commands and agents), a command or an agent for the project (201). A skill is registered in the Skill Registry, verified by its library digest; a skill name already used by a skill not from the library answers 409 `navin_skill_name_taken`. Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor`. 422 `navin_library_kind_not_activable`; 404 `navin_library_item_not_found`. Audited as `navin_library.activate`.",
    "operationId": "activate_v1_projects__project_id__navin_library_activations_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__navin_library__routes__ActivationIn"
       }
      }
     },
     "description": "Kind and name of the item to activate.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Activate V1 Projects  Project Id  Navin Library Activations Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Activate a library item",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/projects/{project_id}/navin-library/activations/{activation_id}": {
   "delete": {
    "description": "Removes an activation from the project; a plugin takes the skills, commands and agents it brought with it. Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor`. 404 `navin_library_activation_not_found`. Audited as `navin_library.deactivate`.",
    "operationId": "deactivate_v1_projects__project_id__navin_library_activations__activation_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the activation.",
      "in": "path",
      "name": "activation_id",
      "required": true,
      "schema": {
       "title": "Activation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Deactivate V1 Projects  Project Id  Navin Library Activations  Activation Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Deactivate a library item",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/projects/{project_id}/navin-library/channels/{name}/install": {
   "post": {
    "description": "Creates a channel of the project from a Navin channel adapter (201). The setup contract of the adapter is checked: unknown, secret or read-only fields in `settings` and non secret fields in `secret_refs` answer 422 `channel_field_invalid`, a wrong value kind also, missing requirements 422 `channel_field_missing`; secrets are `openbao://` or `env://` references only (422 `channel_secret_ref_required`). Defaults: auth `api_key`, limits 65536 bytes per message and 60 per minute, DLP `detect` inbound and `mask` outbound. Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor`. Audited as `navin_library.channel_install`.",
    "operationId": "install_channel_v1_projects__project_id__navin_library_channels__name__install_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the Navin channel adapter.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ChannelInstallIn"
       }
      }
     },
     "description": "Channel name, agent, settings, secret references, authentication, limits and DLP.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Install Channel V1 Projects  Project Id  Navin Library Channels  Name  Install Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Install a channel from the library",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/projects/{project_id}/navin-library/mcp-presets/{name}/install": {
   "post": {
    "description": "Registers an MCP server of the project in the MCP gateway from a Navin preset (201), over streamable HTTP or SSE. A stdio preset runs where its command runs (the MCP page of the Navin Manager): give its HTTP endpoint in `url`; its environment and argument fields are returned in `bridge_fields`. Errors: 409 `mcp_preset_not_installable`, 409 `mcp_preset_needs_endpoint`, 422 `mcp_preset_field_unknown`, 422 `mcp_preset_field_missing`, 422 `mcp_preset_secret_ref_required` (a secret field must be an `openbao://` or `env://` reference), 422 `mcp_preset_unsupported`. Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor`. Audited as `navin_library.mcp_install`.",
    "operationId": "install_mcp_v1_projects__project_id__navin_library_mcp_presets__name__install_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the MCP preset.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/McpInstallIn"
       }
      }
     },
     "description": "Server name, endpoint, transport, preset fields, secret references and allowed tools.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Install Mcp V1 Projects  Project Id  Navin Library Mcp Presets  Name  Install Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Install an MCP server from a preset",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/projects/{project_id}/rules": {
   "get": {
    "description": "Rules of the project by mode then name, each with source, source path, description, globs, content, digest and size in bytes. Needs the ReBAC relation `viewer`.",
    "operationId": "list_rules_v1_projects__project_id__rules_get",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Rules V1 Projects  Project Id  Rules Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the project rules",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/projects/{project_id}/rules/import": {
   "post": {
    "description": "Imports the rule files of a repository (`.navin/rules`, `.cursor/rules/*.mdc` with their frontmatter, `.cursorrules`, `.clinerules`, `.windsurfrules`, `.github/copilot-instructions.md`); each recognised file creates or replaces a rule. Other files are reported in `skipped` with a reason (`not_a_rule_file`, `empty`, `too_large`). At most 200 files (400 `invalid_request`). Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor`.",
    "operationId": "import_rules_v1_projects__project_id__rules_import_post",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RulesImportIn"
       }
      }
     },
     "description": "The files to import, path and content.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Import Rules V1 Projects  Project Id  Rules Import Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Import the rule files of a repository",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/projects/{project_id}/rules/prompt": {
   "get": {
    "description": "The prompt section every run of the project receives: always on rules inlined (each clipped at 8000 characters), conditional ones listed with their description and globs. Returns `prompt`, the `always` and `conditional` counts and the `digest` of the text (empty when the project has no rule). Needs the ReBAC relation `viewer`.",
    "operationId": "rules_prompt_v1_projects__project_id__rules_prompt_get",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rules Prompt V1 Projects  Project Id  Rules Prompt Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get the rules prompt section",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/projects/{project_id}/rules/{name}": {
   "delete": {
    "description": "Deletes the rule; runs of the project no longer receive it. Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor`. 404 `rule_not_found`. Audited as `project.rule.delete`.",
    "operationId": "delete_rule_v1_projects__project_id__rules__name__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the rule.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a project rule",
    "tags": [
     "navin-library"
    ]
   },
   "put": {
    "description": "Creates (201) or replaces (200) a rule of the project. The name has 1 to 64 letters, digits, `.`, `_` or `-` (a `.md` suffix is dropped, `readme` is refused; 422 `rule_name_invalid`). Empty content answers 422 `rule_empty`, more than 64 KiB 413 `rule_too_large`; a conditional rule needs globs or a description (422 `rule_scope_required`). Needs `tenant_admin`, `developer` or `application_owner` and the ReBAC relation `editor`. Audited as `project.rule.put`.",
    "operationId": "put_rule_v1_projects__project_id__rules__name__put",
    "parameters": [
     {
      "description": "Identifier (UUID) or slug of the project.",
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
       "title": "Project Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the rule.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__navin_library__routes__RuleIn"
       }
      }
     },
     "description": "Content, mode, description, globs and source of the rule.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Rule V1 Projects  Project Id  Rules  Name  Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create or replace a project rule",
    "tags": [
     "navin-library"
    ]
   }
  },
  "/v1/prompts": {
   "get": {
    "description": "Prompts of the tenant in name order with their latest version number, paginated with `cursor`.",
    "operationId": "list_prompts_v1_prompts_get",
    "parameters": [
     {
      "description": "Maximum number of prompts in one page (default 50, capped at 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Prompts V1 Prompts Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the prompts",
    "tags": [
     "prompts"
    ]
   },
   "post": {
    "description": "Creates a prompt, or publishes a new version when the name exists; identical templates and variables are not duplicated (the current version is returned). The name is lowercase letters, digits, `.`, `_`, `-` (1 to 128 characters, 400 `invalid_request` otherwise). An unbalanced placeholder, an unknown variable type or a placeholder not declared in `variables` answers 422 `template_error`. Needs `tenant_admin` or `developer`. Audited as `prompt.publish`.",
    "operationId": "create_prompt_v1_prompts_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PromptIn"
       }
      }
     },
     "description": "Name, template, description, variables and model hint.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Prompt V1 Prompts Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Publish a prompt version",
    "tags": [
     "prompts"
    ]
   }
  },
  "/v1/prompts/{name}/render": {
   "post": {
    "description": "Fills the template of a version (default: the latest) with the given values and returns `text`, `chars` and `estimated_tokens` (characters divided by 4). Missing required values, wrong types, values outside `enum`, values over `max_length` and, with `strict`, unknown variables answer 422 `missing_variables` with one entry per problem. 404 `not_found` for an unknown prompt or version. Nothing is stored.",
    "operationId": "render_prompt_v1_prompts__name__render_post",
    "parameters": [
     {
      "description": "Name of the prompt.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RenderIn"
       }
      }
     },
     "description": "Values of the variables, version and strict mode.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Render Prompt V1 Prompts  Name  Render Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Render a prompt",
    "tags": [
     "prompts"
    ]
   }
  },
  "/v1/prompts/{name}/versions": {
   "get": {
    "description": "The prompt and every version, newest first, with template, variables, model hint, digest and author. 404 `not_found`.",
    "operationId": "versions_v1_prompts__name__versions_get",
    "parameters": [
     {
      "description": "Name of the prompt.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Versions V1 Prompts  Name  Versions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the versions of a prompt",
    "tags": [
     "prompts"
    ]
   }
  },
  "/v1/providers": {
   "get": {
    "description": "Shared providers and the providers of the caller's tenant, with their type, address, configuration, regions, retention, state and last test; credentials are never returned (only the names of the fields that are set). Requires a reader role.",
    "operationId": "providers_list_v1_providers_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the configured providers",
    "tags": [
     "llm"
    ]
   },
   "post": {
    "description": "Creates a provider for the tenant, or a shared one with `scope: platform` (`platform_admin` only), and answers 201 without the credentials. Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.\n\nSteps:\n\n1. The type must exist in the catalog (422 `missing_provider_type`, 422 `unknown_provider_type`) and the required fields and credentials must be given (422 with the field).\n2. A remote address must use TLS (422 `tls_required`) and pass the outbound address rules.\n3. The provider is stored (409 `provider_exists` for the same name in the same scope), then its credentials are written to the secret store and only their field names are kept. Audited (`provider.create`).",
    "operationId": "providers_create_v1_providers_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`provider_type` (or `type`, a catalog type or alias), optional `name` (default the type), `api_base` (or `base_url`), `config`, `credentials` (secret fields), `regions`, `retention`, `scope` (`platform` for a shared provider).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a model provider",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/providers/catalog": {
   "get": {
    "description": "Every provider type the platform supports, with the fields and credentials it needs, labels in the language of the request, the configured providers of each type, and how its models are found (`api`: listing API, `manual_only`: typed by the administrator). Requires a reader role.",
    "operationId": "providers_catalog_v1_providers_catalog_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the provider catalog",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/providers/{pid}": {
   "delete": {
    "description": "Deletes the provider and answers 204; a shared provider needs `platform_admin` (403 `platform_only`). Audited (`provider.delete`). Unknown or invisible provider: 404 `provider_not_found`. Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "providers_delete_v1_providers__pid__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the provider.",
      "in": "path",
      "name": "pid",
      "required": true,
      "schema": {
       "title": "Pid",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a model provider",
    "tags": [
     "llm"
    ]
   },
   "get": {
    "description": "One provider without its credentials. A provider of another tenant, or an id that is not a UUID, answers 404 `provider_not_found`. Requires a reader role.",
    "operationId": "providers_get_v1_providers__pid__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the provider.",
      "in": "path",
      "name": "pid",
      "required": true,
      "schema": {
       "title": "Pid",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a configured provider",
    "tags": [
     "llm"
    ]
   },
   "patch": {
    "description": "Changes the configuration, address, regions, retention or credentials of a provider. New credentials are written to the secret store and reset the connection state until the next test. A remote address must use TLS (422 `tls_required`) and pass the outbound address rules; an unknown credential field answers 422. A shared provider needs `platform_admin`. Audited (`provider.update`, without values). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "providers_patch_v1_providers__pid__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the provider.",
      "in": "path",
      "name": "pid",
      "required": true,
      "schema": {
       "title": "Pid",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "Fields to change: `config`, `api_base` (or `base_url`), `credentials` (secret fields; a secret field sent in `config` is moved to them), `regions`, `retention`.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a model provider",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/providers/{pid}/disable": {
   "post": {
    "description": "Kill switch of the provider: the gateway refuses its models at once (403 `provider_disabled`) and discovery is refused (409). A shared provider needs `platform_admin`. Audited (`provider.disable`). Requires `tenant_admin`, `platform_admin`, `ai_platform_engineer` or `security_officer`.",
    "operationId": "providers_disable_v1_providers__pid__disable_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the provider.",
      "in": "path",
      "name": "pid",
      "required": true,
      "schema": {
       "title": "Pid",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Disable a provider (kill switch)",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/providers/{pid}/enable": {
   "post": {
    "description": "Lifts the kill switch of the provider. A shared provider needs `platform_admin`. Audited (`provider.enable`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "providers_enable_v1_providers__pid__enable_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the provider.",
      "in": "path",
      "name": "pid",
      "required": true,
      "schema": {
       "title": "Pid",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Enable a disabled provider",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/providers/{pid}/models/discover": {
   "post": {
    "description": "Models the configured provider really serves, from its own listing API with the stored credentials and through the outbound guard (never a made up list). Each candidate carries what the provider returns (context window, maximum output, modalities, prices) completed with platform hints, a suggested registry id and category, and whether it is already registered; up to 1000 candidates. Providers without a listing API answer `manual_only`. A disabled provider answers 409 `provider_disabled`. Audited (`provider.discover`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "providers_discover_v1_providers__pid__models_discover_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the provider.",
      "in": "path",
      "name": "pid",
      "required": true,
      "schema": {
       "title": "Pid",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Discover the models of a provider",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/providers/{pid}/test": {
   "post": {
    "description": "Calls the listing endpoint of the provider with its stored credentials (for signed protocols such as Bedrock and Vertex, checks that the credential set is complete) and answers `ok`, the HTTP status, a detail and the models seen. The result is stored as the connection state and audited (`provider.test`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "providers_test_v1_providers__pid__test_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the provider.",
      "in": "path",
      "name": "pid",
      "required": true,
      "schema": {
       "title": "Pid",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Test a provider connection",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/quotas": {
   "get": {
    "description": "Quotas of the tenant by name, including those mirrored from the LLM projects (`llm-project:...`). One page only. Requires a reader role and a tenant principal.",
    "operationId": "list_quotas_v1_quotas_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Quotas V1 Quotas Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the quotas",
    "tags": [
     "finops"
    ]
   },
   "post": {
    "description": "Creates a quota of the tenant and answers 201. A cost or token limit is required, and `scope_value` is required unless `scope_type` is `tenant` (422 `validation_error`). Without currency, the tenant currency applies. Audited. Requires `finops` or `tenant_admin`, and a tenant principal.",
    "operationId": "create_quota_v1_quotas_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__finops__QuotaIn"
       }
      }
     },
     "description": "The new quota.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Quota V1 Quotas Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a quota",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/quotas/reserve": {
   "post": {
    "description": "Reserves an amount on every enabled quota matching the scope (tenant quotas always match; a user principal adds its own user scope) and answers 201 with the reservation, its items per quota and window, the soft quotas exceeded and its expiry. A hard quota that would be exceeded answers 429 `quota_exceeded` with `Retry-After: 60`, and nothing is reserved. Expired reservations are released first. Audited. Requires `finops`, `tenant_admin`, `agent` or `developer`, and a tenant principal.",
    "operationId": "reserve_quota_v1_quotas_reserve_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReserveIn"
       }
      }
     },
     "description": "Amount, scope and lifetime of the reservation.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Reserve Quota V1 Quotas Reserve Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reserve cost and tokens",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/quotas/usage": {
   "get": {
    "description": "Each quota of the tenant with its current window and the cost and tokens used and reserved in it. Run quotas need `run` to find their window. Requires a reader role and a tenant principal.",
    "operationId": "quota_usage_v1_quotas_usage_get",
    "parameters": [
     {
      "description": "Project used to resolve the windows.",
      "in": "query",
      "name": "project",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project"
      }
     },
     {
      "description": "Agent used to resolve the windows.",
      "in": "query",
      "name": "agent",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Agent"
      }
     },
     {
      "description": "Agent run whose `run` quota windows are read.",
      "in": "query",
      "name": "run",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Run"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Quota Usage V1 Quotas Usage Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the quota consumption",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/quotas/{quota_id}": {
   "delete": {
    "description": "Deletes a quota of the tenant and answers 204. Unknown id: 404 `quota_not_found`. Audited (`finops.quota.delete`). Requires `finops` or `tenant_admin`.",
    "operationId": "delete_quota_v1_quotas__quota_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the quota.",
      "in": "path",
      "name": "quota_id",
      "required": true,
      "schema": {
       "title": "Quota Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a quota",
    "tags": [
     "finops"
    ]
   },
   "put": {
    "description": "Replaces every field of a quota (same rules as on creation; without currency, the current one is kept). Unknown id: 404 `quota_not_found`. Audited. Requires `finops` or `tenant_admin`, and a tenant principal.",
    "operationId": "update_quota_v1_quotas__quota_id__put",
    "parameters": [
     {
      "description": "Identifier (UUID) of the quota.",
      "in": "path",
      "name": "quota_id",
      "required": true,
      "schema": {
       "title": "Quota Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__finops__QuotaIn"
       }
      }
     },
     "description": "The complete quota.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Update Quota V1 Quotas  Quota Id  Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Replace a quota",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/quotas/{reservation_id}/commit": {
   "post": {
    "description": "Replaces the reserved amount by the measured one on every quota window of the reservation and checks the alert thresholds. A closed reservation answers 409 `reservation_closed`; an unknown one 404 `reservation_not_found`. Audited. Requires `finops`, `tenant_admin`, `agent` or `developer`, and a tenant principal.",
    "operationId": "commit_quota_v1_quotas__reservation_id__commit_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the reservation returned by `POST /v1/quotas/reserve`.",
      "in": "path",
      "name": "reservation_id",
      "required": true,
      "schema": {
       "title": "Reservation Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CommitIn"
       }
      }
     },
     "description": "Measured cost and tokens of the call.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Commit Quota V1 Quotas  Reservation Id  Commit Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Commit a reservation",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/quotas/{reservation_id}/release": {
   "post": {
    "description": "Gives the reserved amount back to every quota window of the reservation without consuming anything (the call failed or was not made). A closed reservation answers 409 `reservation_closed`; an unknown one 404 `reservation_not_found`. Audited. Requires `finops`, `tenant_admin`, `agent` or `developer`, and a tenant principal.",
    "operationId": "release_quota_v1_quotas__reservation_id__release_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the reservation.",
      "in": "path",
      "name": "reservation_id",
      "required": true,
      "schema": {
       "title": "Reservation Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Release Quota V1 Quotas  Reservation Id  Release Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Release a reservation",
    "tags": [
     "finops"
    ]
   }
  },
  "/v1/rag-agent/instances": {
   "get": {
    "description": "Activation records of the tenant, newest first, with status, deployment model, versions and owned resources (one page, `next_cursor` null). Filters: `status`, `project`.",
    "operationId": "list_instances_v1_rag_agent_instances_get",
    "parameters": [
     {
      "description": "Only the instances in this status (draft, ready, failed, ...).",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 20,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only the instances of this project (identifier).",
      "in": "query",
      "name": "project",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 100,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Project"
      }
     },
     {
      "description": "Maximum number of instances returned (1 to 200, default 50).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "maximum": 200,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Instances V1 Rag Agent Instances Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the RAG Agent instances",
    "tags": [
     "rag-agent"
    ]
   },
   "post": {
    "description": "Creates the activation record in `draft` (201) with its immutable `id` (given, for example the id chosen by the RAG runtime, or generated). Needs a tenant administrator or an owner of the project (403 `forbidden`); unknown project: 404 `rag_agent_project_not_found`; a name or an id already used: 409 `conflict`. With `Idempotency-Key` a retry replays the first answer. Audited as `rag_agent.create`.",
    "operationId": "create_instance_v1_rag_agent_instances_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RagAgentInstanceIn"
       }
      }
     },
     "description": "Name, project, organization and business unit, deployment model, generation and embedding models of the registry, optional version.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Instance V1 Rag Agent Instances Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a draft RAG Agent instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}": {
   "delete": {
    "description": "Long operation (202, status `deleting` then `deleted`) from `draft`, `stopped` or `failed` (a ready instance is stopped first, else 409). Removes only what the instance owns, as recorded in `resources`: its knowledge base and its Qdrant points, the objects under its storage prefix, its agent memories and memory policy, its tuples, API key and secret, its agent; the governed application is retired. The shared runtime, a shared database, the Qdrant collection shared by the tenant knowledge bases and the storage profile are kept. Each step lists `deleted` and `kept`. Audited as `rag_agent.delete` and `rag_agent.delete.completed`.",
    "operationId": "delete_instance_v1_rag_agent_instances__instance_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Instance V1 Rag Agent Instances  Instance Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an instance",
    "tags": [
     "rag-agent"
    ]
   },
   "get": {
    "description": "The activation record with `serving` (true for `ready` and `degraded`), the current `operation` and `run`, `validation`, `last_error` and the `steps` of the current run in order (state, attempts, detail, logs, times). This is the route the RAG runtime reads at startup and on demand.",
    "operationId": "get_instance_v1_rag_agent_instances__instance_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance, the same in the Control Plane and in the RAG runtime.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Instance V1 Rag Agent Instances  Instance Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a RAG Agent instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/backup": {
   "post": {
    "description": "Answers 501 `rag_agent_backup_not_supported` with `parts` and the reason of each one: the RAG runtime has no admin route to export the rag schema rows of an instance, the knowledge domain has no export of a knowledge base. Nothing is pretended; the refusal is audited.",
    "operationId": "backup_instance_v1_rag_agent_instances__instance_id__backup_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Backup Instance V1 Rag Agent Instances  Instance Id  Backup Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Back up an instance (not supported)",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/branding": {
   "get": {
    "description": "The branding chosen in the activation journey, owned by the Control Plane: `agent_name`, `sidebar_color`, `navbar_color`, the text colours computed for them (`sidebar_text_color`, `navbar_text_color`, black or white, contrast 4.5:1 or more), `logo` (`content_type`, `sha256`, `size_bytes`, `url`) or null, `version`, `updated_at`, and `app_url` (the URL of the web application once known). A null field means the default of the runtime. The RAG runtime keeps a replica of it for its public login page and rewrites it when `version` is newer. Any principal of the tenant; another tenant's instance answers 404.",
    "operationId": "get_branding_v1_rag_agent_instances__instance_id__branding_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Branding V1 Rag Agent Instances  Instance Id  Branding Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the branding of an instance",
    "tags": [
     "rag-agent"
    ]
   },
   "put": {
    "description": "Writes the fields given (an absent field is kept, null brings it back to the default of the runtime) and answers the branding. Colours are `#RRGGBB` (stored in upper case); the text drawn on them is black or white, whichever contrasts most (WCAG 2.2 relative luminance, the rule of the RAG frontend), and a colour whose text would stay under 4.5:1 answers 422 `rag_agent_branding_contrast`. `app_url` must be an https URL without credentials (422 `rag_agent_app_url_invalid`). A change of the name, the colours or the logo increments `version`; `expected_version` different from the current one answers 409 `rag_agent_branding_version_conflict`. With an `Idempotency-Key`, a retry with the same body replays the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Needs a tenant administrator or an owner of the project (403 `forbidden`); refused while the instance is `deleting` or `deleted` (409). Audited as `rag_agent.branding.update`.",
    "operationId": "put_branding_v1_rag_agent_instances__instance_id__branding_put",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     },
     {
      "description": "Optional key (up to 200 characters), unique per instance: a retry with the same key and body replays the first answer.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 200,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RagAgentBrandingIn"
       }
      }
     },
     "description": "The branding fields to write.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Branding V1 Rag Agent Instances  Instance Id  Branding Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change the branding of an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/branding/logo": {
   "delete": {
    "description": "Back to the default logo of the runtime: the branding no longer points to an object, `version` is incremented and the stored object is removed. Without a logo, answers the branding unchanged. Same rights as the PUT; audited as `rag_agent.branding.logo.remove`.",
    "operationId": "delete_branding_logo_v1_rag_agent_instances__instance_id__branding_logo_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Branding Logo V1 Rag Agent Instances  Instance Id  Branding Logo Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Remove the logo of an instance",
    "tags": [
     "rag-agent"
    ]
   },
   "get": {
    "description": "The logo bytes, read from the storage domain and checked against the recorded sha256, with the Content-Type of the validated format (`image/png` or `image/jpeg`), `X-Content-Type-Options: nosniff`, a Content-Security-Policy starting with `default-src 'none'` and an `ETag`. 404 `rag_agent_logo_not_found` when the instance has no logo. Any principal of the tenant.",
    "operationId": "get_branding_logo_v1_rag_agent_instances__instance_id__branding_logo_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "image/jpeg": {},
       "image/png": {}
      },
      "description": "The logo bytes."
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the logo of an instance",
    "tags": [
     "rag-agent"
    ]
   },
   "post": {
    "description": "Multipart `file` (with the optional text fields `filename` and `mime_type`). PNG or JPEG only: SVG and any other format are refused. The real signature, the declared Content-Type and the file extension must match; 32 to 1024 pixels a side, 512 KiB at most; else 422 `rag_agent_logo_invalid` with `details.reason` (`format_not_allowed`, `signature_invalid`, `signature_mismatch`, `extension_mismatch`, `dimensions_out_of_bounds`, `too_large`, `empty`). The file is then scanned by the file security domain, fail closed: a blocked file answers 422 `file_blocked`, a scanner down 503 `file_scan_unavailable`. It is stored through the storage domain in the documents storage profile of the tenant under `rag-agent/<tenant>/<instance>/branding/` (409 `rag_agent_branding_storage_required` without such a profile, 503 `rag_agent_branding_storage_unavailable` when it cannot be reached); the replaced object is removed. Increments `version` and answers the branding. Same rights as the PUT; audited as `rag_agent.branding.logo.update` (a refusal is audited as a denial).",
    "operationId": "upload_branding_logo_v1_rag_agent_instances__instance_id__branding_logo_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "multipart/form-data": {
       "schema": {
        "properties": {
         "file": {
          "format": "binary",
          "type": "string"
         },
         "filename": {
          "type": "string"
         },
         "mime_type": {
          "type": "string"
         }
        },
        "required": [
         "file"
        ],
        "type": "object"
       }
      }
     },
     "description": "Multipart form with the logo in the `file` part.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upload Branding Logo V1 Rag Agent Instances  Instance Id  Branding Logo Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Upload the logo of an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/health": {
   "get": {
    "description": "Real checks: readiness URL of the runtime (`GET /readyz`), knowledge base (row, vector store qdrant, Qdrant `/readyz`) and model gateway (generation and embedding models in the registry, usable). `status` is `up`, `degraded` or `down` (runtime down); `instance_status` is the lifecycle status. Each check has `status`, `duration_ms` and `reason` when not up.",
    "operationId": "instance_health_v1_rag_agent_instances__instance_id__health_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Instance Health V1 Rag Agent Instances  Instance Id  Health Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Health of an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/provision": {
   "post": {
    "description": "Long operation (202, `Operation-Id`): status `provisioning` then `starting`, steps from `validation` to `activation` run by the worker. From a validated `draft` (else 409 `rag_agent_not_validated`) or after a failed provisioning, which resumes from the failed step. Repeated while provisioning or once ready: `changed: false`. Audited as `rag_agent.provision`, each step as `rag_agent.step`.",
    "operationId": "provision_instance_v1_rag_agent_instances__instance_id__provision_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Provision Instance V1 Rag Agent Instances  Instance Id  Provision Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Provision an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/restart": {
   "post": {
    "description": "Long operation (202): from `ready`, `degraded`, `stopped` or after a failed restart, steps `deployment` (Navin Manager restart for a dedicated instance), `health`, `smoke`, `activation`. A restart in progress: `changed: false`.",
    "operationId": "restart_instance_v1_rag_agent_instances__instance_id__restart_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Restart Instance V1 Rag Agent Instances  Instance Id  Restart Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Restart an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/restore": {
   "post": {
    "description": "Answers 501 `rag_agent_backup_not_supported` with the same `parts` as the backup: no backup of an instance can be made for real yet. Audited.",
    "operationId": "restore_instance_v1_rag_agent_instances__instance_id__restore_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RagAgentRestoreIn"
       }
      }
     },
     "description": "The backup to restore.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Restore Instance V1 Rag Agent Instances  Instance Id  Restore Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Restore an instance (not supported)",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/start": {
   "post": {
    "description": "Long operation (202): from `stopped` (or after a failed start or stop), steps `deployment` (Navin Manager start for a dedicated instance, status only for a shared one), `health`, `smoke`, `activation` (governed application active). Already starting or ready: `changed: false`.",
    "operationId": "start_instance_v1_rag_agent_instances__instance_id__start_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Start Instance V1 Rag Agent Instances  Instance Id  Start Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Start an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/stop": {
   "post": {
    "description": "Long operation (202): from `ready`, `degraded` or after a failed start, restart, upgrade or stop, steps `deployment` (Navin Manager stop for a dedicated instance, status only for a shared one) and `activation` (governed application suspended, reason `rag_instance_stopped`); status `stopped`. Already stopping or stopped: `changed: false`.",
    "operationId": "stop_instance_v1_rag_agent_instances__instance_id__stop_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Stop Instance V1 Rag Agent Instances  Instance Id  Stop Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Stop an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/upgrade": {
   "post": {
    "description": "Long operation (202), status `updating`: a shared instance follows the shared runtime, so the deployment step checks that the runtime runs the requested version (else `shared_runtime_version_mismatch`); a dedicated one is reinstalled by the Navin Manager. Then `health`, `smoke`, `activation`; `deployed_version` becomes the version. The same version already deployed or in progress: `changed: false`.",
    "operationId": "upgrade_instance_v1_rag_agent_instances__instance_id__upgrade_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RagAgentUpgradeIn"
       }
      }
     },
     "description": "The version to deploy.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upgrade Instance V1 Rag Agent Instances  Instance Id  Upgrade Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Upgrade an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/rag-agent/instances/{instance_id}/validate": {
   "post": {
    "description": "Real checks before provisioning: the project exists and the caller may administer it, the generation model exists in the registry with the `chat` capability and a usable status, the embedding model resolves in the Model Gateway (capability `embeddings`), the quota of instances, Qdrant answers, the shared runtime answers (shared model) or the Navin Manager answers (dedicated model, an unpublished catalog service is a warning). From `draft` or after a failed validation. 200 with `validation` and status `draft`; 422 `rag_agent_validation_failed` with the failed checks (status `failed`, step `validation`). Audited as `rag_agent.validate` and `rag_agent.validate.completed`.",
    "operationId": "validate_instance_v1_rag_agent_instances__instance_id__validate_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the instance.",
      "in": "path",
      "name": "instance_id",
      "required": true,
      "schema": {
       "title": "Instance Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Validate Instance V1 Rag Agent Instances  Instance Id  Validate Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Validate an instance",
    "tags": [
     "rag-agent"
    ]
   }
  },
  "/v1/realtime/sessions": {
   "post": {
    "description": "Opens a session (201) and returns it with `session_id`, `livekit` (`url`, `token`, `room`, `configured`) and the WebSocket access (`ws_url`, `ws_token`, `ws_token_expires_at`). Needs `tenant_admin`, `developer` or `agent`.\nChecks: `pipeline` is `echo` or `stt` (400 `invalid_request`); `config.vad` and `config.dlp_mode` are valid (422 `parameter_invalid`); an agent caller acts for `on_behalf_of`, a user may only open a session for itself (403 `identity_mismatch`); LiveKit credentials are configured; the policy `realtime.session.create` is evaluated. The room defaults to a name derived from the tenant and the session. Audited as `realtime.session.create`.",
    "operationId": "create_session_v1_realtime_sessions_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__realtime__SessionIn"
       }
      }
     },
     "description": "Room, pipeline, token lifetime, configuration, agent and user acted for.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Session V1 Realtime Sessions Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Open a realtime session",
    "tags": [
     "realtime"
    ]
   }
  },
  "/v1/realtime/sessions/{session_id}": {
   "get": {
    "description": "Returns the session: room, identities, agent, pipeline, configuration, status, audio seconds, tokens and usage. 404 `not_found`.",
    "operationId": "get_session_v1_realtime_sessions__session_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the realtime session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Session V1 Realtime Sessions  Session Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a realtime session",
    "tags": [
     "realtime"
    ]
   }
  },
  "/v1/realtime/sessions/{session_id}/consents": {
   "get": {
    "description": "Consents recorded for the session, in capture order, with their revocation when revoked. One page only.",
    "operationId": "list_consents_v1_realtime_sessions__session_id__consents_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the realtime session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Consents V1 Realtime Sessions  Session Id  Consents Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the consents of a session",
    "tags": [
     "realtime"
    ]
   },
   "post": {
    "description": "Consent of one participant (purpose, recording, transcription, retention, method), captured by the caller (201). The participant defaults to the participant of the session. The method must be `verbal`, `click`, `written` or `api` (422 `parameter_invalid`); the session must not be ended (409 `session_ended`); the policy `realtime.consent.record` is evaluated. Needs `tenant_admin`, `developer` or `agent`. Audited as `realtime.consent.record`.",
    "operationId": "record_consent_v1_realtime_sessions__session_id__consents_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the realtime session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConsentIn"
       }
      }
     },
     "description": "The consent of the participant.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Record Consent V1 Realtime Sessions  Session Id  Consents Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Record a participant consent",
    "tags": [
     "realtime"
    ]
   }
  },
  "/v1/realtime/sessions/{session_id}/consents/{consent_id}/revoke": {
   "post": {
    "description": "Revocation takes effect on the next audio event: transcription and recording are refused again. A consent already revoked or unknown answers 404 `not_found`. Needs `tenant_admin`, `developer` or `agent`. Audited as `realtime.consent.revoke`.",
    "operationId": "revoke_consent_v1_realtime_sessions__session_id__consents__consent_id__revoke_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the realtime session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the consent.",
      "in": "path",
      "name": "consent_id",
      "required": true,
      "schema": {
       "title": "Consent Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Revoke Consent V1 Realtime Sessions  Session Id  Consents  Consent Id  Revoke Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Revoke a consent",
    "tags": [
     "realtime"
    ]
   }
  },
  "/v1/realtime/sessions/{session_id}/end": {
   "post": {
    "description": "Ends the session and records its usage event (`voice_live`: audio seconds, input and output tokens, measured cost). Ending a session already ended returns it unchanged. Needs `tenant_admin`, `developer` or `agent`. Audited as `realtime.session.end`.",
    "operationId": "end_session_v1_realtime_sessions__session_id__end_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the realtime session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response End Session V1 Realtime Sessions  Session Id  End Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "End a realtime session",
    "tags": [
     "realtime"
    ]
   }
  },
  "/v1/realtime/sessions/{session_id}/token": {
   "post": {
    "description": "New single use WebSocket token for an open session (reconnection), read under RLS: `ws_url`, `ws_token`, `ws_token_expires_at`. 409 `session_ended`; 404 `not_found`. Needs `tenant_admin`, `developer` or `agent`. Audited as `realtime.session.token`.",
    "operationId": "session_token_v1_realtime_sessions__session_id__token_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the realtime session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Session Token V1 Realtime Sessions  Session Id  Token Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a new WebSocket token",
    "tags": [
     "realtime"
    ]
   }
  },
  "/v1/realtime/sessions/{session_id}/transcripts": {
   "get": {
    "description": "Stored transcripts, already filtered by the DLP (the raw transcript is never stored), with turn, consent, participant, DLP findings and expiry. Needs `tenant_admin`, `developer`, `auditor` or `security_officer`.",
    "operationId": "list_transcripts_v1_realtime_sessions__session_id__transcripts_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the realtime session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Transcripts V1 Realtime Sessions  Session Id  Transcripts Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the transcripts of a session",
    "tags": [
     "realtime"
    ]
   }
  },
  "/v1/realtime/sessions/{session_id}/turns": {
   "get": {
    "description": "Turns with the participant, the user, the agent, the trace id, the status (a barge-in records `cancelled`) and the measured latency, in order. One page only.",
    "operationId": "list_turns_v1_realtime_sessions__session_id__turns_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the realtime session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Turns V1 Realtime Sessions  Session Id  Turns Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the turns of a session",
    "tags": [
     "realtime"
    ]
   }
  },
  "/v1/redteam/runs": {
   "get": {
    "description": "Lists the red team runs of the tenant, newest identifier first, paginated, and `probes`: the builtin probes (id and category), the garak probe families and whether garak is installed. Open to any member of the tenant.",
    "operationId": "list_redteam_v1_redteam_runs_get",
    "parameters": [
     {
      "description": "Maximum number of runs in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Redteam V1 Redteam Runs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the red team runs",
    "tags": [
     "evaluation"
    ]
   },
   "post": {
    "description": "Sends adversarial probes to the target and stores the findings. Needs `tenant_admin`, `developer`, `security_officer` or `ai_governance_officer`.\n\n- Engine `builtin` (default): the builtin probes (all by default), each judged on the answer of the target (leak of a canary secret, of the system prompt, missing refusal...).\n- Engine `garak`: garak probe families (`promptinject` and `dan` by default), when garak is installed.\n\nThe run ends `passed` when the attack success rate (vulnerable findings over total) is at most `max_attack_success_rate`, `failed` above, `error` when the target or garak is unavailable. Unknown probes or engine answer 400 `invalid_request` with the available ones. The response carries `Operation-Id`. Writes the audit event `redteam.run`.",
    "operationId": "create_redteam_v1_redteam_runs_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RedTeamIn"
       }
      }
     },
     "description": "Target, engine, probes and accepted attack success rate.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Redteam V1 Redteam Runs Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run a red team campaign",
    "tags": [
     "evaluation"
    ]
   }
  },
  "/v1/redteam/runs/{run_id}": {
   "get": {
    "description": "Returns one red team run: target, engine, probes, status, summary (total, vulnerable, attack success rate, threshold, per category) and findings. Open to any member of the tenant. Answers 404 `not_found`.",
    "operationId": "get_redteam_v1_redteam_runs__run_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the red team run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Redteam V1 Redteam Runs  Run Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a red team run",
    "tags": [
     "evaluation"
    ]
   }
  },
  "/v1/retention/erase": {
   "post": {
    "description": "Deletes the data held on one subject, in one transaction. Needs `tenant_admin`, `security_officer` or `data_steward`.\n\n1. A subject under legal hold is not erased: `status` is `blocked_legal_hold`.\n2. Memory items, media, sessions and ended realtime sessions of the subject are deleted, and documents with `include_documents`; held items are skipped.\n3. Opik traces and ClickHouse analytics of the subject are deleted when those stores are configured.\n\n`status` is `completed`, `dry_run`, or `incomplete` when an external store failed (retry the erasure). The answer gives `request_id`, `deleted` and `skipped_legal_hold` per resource, `external` per store and `retained` (audit events and usage records, kept by legal obligation). Writes the audit event `retention.erase`, a failure when incomplete.",
    "operationId": "erase_v1_retention_erase_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EraseIn"
       }
      }
     },
     "description": "Subject, scope and reason of the erasure.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Erase V1 Retention Erase Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Erase a data subject",
    "tags": [
     "retention"
    ]
   }
  },
  "/v1/retention/legal-hold": {
   "post": {
    "description": "Without `hold_id`, places a new hold on a subject (`subject_id`) or on one resource (`resource_type` and `resource_id`); `reason` is required (400 `invalid_request` otherwise). With `hold_id`, activates or releases that hold with `active` (404 `not_found` for an unknown hold).\n\nThe legal hold flag of the memory items and media concerned is updated at once; held items are skipped by retention runs and erasures until every hold on them is released. Needs `tenant_admin`, `security_officer` or `data_steward`. Writes the audit event `retention.legal_hold`. Answers 201 with the hold.",
    "operationId": "legal_hold_v1_retention_legal_hold_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LegalHoldIn"
       }
      }
     },
     "description": "New hold, or the identifier of a hold to activate or release.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Legal Hold V1 Retention Legal Hold Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Place or release a legal hold",
    "tags": [
     "retention"
    ]
   }
  },
  "/v1/retention/policies": {
   "get": {
    "description": "Returns the retention policies of the tenant ordered by resource type in `items`, and the active legal holds in `legal_holds`. Open to any member of the tenant. `next_cursor` is always null.",
    "operationId": "list_policies_v1_retention_policies_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Policies V1 Retention Policies Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the retention policies",
    "tags": [
     "retention"
    ]
   },
   "post": {
    "description": "Sets the retention policy of one resource type, replacing the existing one. Needs `tenant_admin`, `security_officer` or `data_steward`. An unknown resource type or an action other than `erase` or `archive` answers 400 `invalid_request`. The policy takes effect at the next retention run. Writes the audit event `retention.policy.upsert`. Answers 201 with the policy.",
    "operationId": "upsert_policy_v1_retention_policies_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__retention__PolicyIn"
       }
      }
     },
     "description": "Resource type, lifetime and action of the policy.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upsert Policy V1 Retention Policies Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create or update a retention policy",
    "tags": [
     "retention"
    ]
   }
  },
  "/v1/retention/run": {
   "post": {
    "description": "Applies the enabled policies now, to every resource type or to `resource_types`. Memory items and media past their own expiry are purged even without a policy; realtime transcripts and recordings follow the retention period of the participant consent. Items under legal hold are skipped.\n\nWith `dry_run: true`, nothing is deleted and the report gives what would be. The answer gives `run_id`, `dry_run`, `created_at` and `report` with, per resource type, `processed` and `skipped_legal_hold`. Needs `tenant_admin`, `security_officer` or `data_steward`. An unknown resource type answers 400 `invalid_request`. Writes the audit event `retention.run`.",
    "operationId": "run_v1_retention_run_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/eai__domains__retention__RunIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional simulation flag and resource types. An empty body runs every policy for real."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Run V1 Retention Run Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run the retention policies",
    "tags": [
     "retention"
    ]
   }
  },
  "/v1/risk/assessments": {
   "get": {
    "description": "Lists the assessments of the tenant, newest first, at most 500, optionally for one target. Each item gives the target, `eu_ai_act_category` (also as `risk_level`), use cases, answers, rationale, obligations, status and owner. Open to any member of the tenant. `next_cursor` is always null.",
    "operationId": "list_assessments_v1_risk_assessments_get",
    "parameters": [
     {
      "description": "Only the assessments of this target reference, for example an agent name.",
      "in": "query",
      "name": "target_ref",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Target Ref"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Assessments V1 Risk Assessments Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the risk assessments",
    "tags": [
     "risk"
    ]
   },
   "post": {
    "description": "Classifies the target under the EU AI Act and records the assessment. Needs `tenant_admin`, `security_officer`, `developer` or `ai_governance_officer`; the status `approved` needs `tenant_admin`, `security_officer` or `ai_governance_officer` (403 `forbidden`).\n\n1. Use cases and answers set to true are matched first against the Article 5 prohibited practices (`unacceptable`), then the Annex III areas (`high`), then the Article 50 triggers (`limited`); otherwise `minimal`.\n2. The rationale and the obligations of the category are stored with the assessment, with the evidence given.\n3. For a target of type `agent`, the risk level of the agent is updated in the registry (`registry_synced`).\n\nA status other than `draft`, `submitted`, `approved` or `rejected` answers 400 `invalid_request`. Writes the audit event `risk.assessment.create`.",
    "operationId": "create_assessment_v1_risk_assessments_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AssessmentIn"
       }
      }
     },
     "description": "Target, use cases, answers, owner, status and evidence of the assessment.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Assessment V1 Risk Assessments Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Assess the risk of an AI system",
    "tags": [
     "risk"
    ]
   }
  },
  "/v1/risk/controls": {
   "get": {
    "description": "Lists the controls adopted by the tenant, ordered by code, each with `evidence_count`, its `exceptions` and `active_exceptions`, and the builtin `catalog` with `adopted` telling which ones the tenant uses. Open to any member of the tenant.",
    "operationId": "list_controls_v1_risk_controls_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Controls V1 Risk Controls Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the controls",
    "tags": [
     "risk"
    ]
   },
   "post": {
    "description": "Creates or updates the control of the given `code`. For a catalogue code, the title and frameworks default to the catalogue ones. Needs `tenant_admin` or `security_officer`. Errors 400 `invalid_request`: status other than `planned`, `implemented`, `partially_implemented` or `not_applicable`; no title for a custom code; a framework other than `iso_42001`, `nist_ai_rmf`, `gdpr` or `eu_ai_act`. Evidence given is added. Writes the audit event `risk.control.upsert`.",
    "operationId": "upsert_control_v1_risk_controls_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ControlIn"
       }
      }
     },
     "description": "Code, title, frameworks, status, owner and evidence of the control.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upsert Control V1 Risk Controls Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Adopt or update a control",
    "tags": [
     "risk"
    ]
   }
  },
  "/v1/risk/evidence": {
   "get": {
    "description": "Returns the evidence recorded on controls and assessments, newest first, plus evidence collected automatically from the platform and mapped to the catalogue controls: counts of agents, tools, models, assessments, enabled DLP rules and retention policies, keys, audit events and exports with the state of the audit chain, evaluations, red team runs, incidents and approvals. Open to any member of the tenant.",
    "operationId": "evidence_v1_risk_evidence_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Evidence V1 Risk Evidence Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the compliance evidence",
    "tags": [
     "risk"
    ]
   }
  },
  "/v1/risk/exceptions": {
   "get": {
    "description": "Lists the exceptions of the tenant ordered by expiry, each with its computed `status`: `active`, `expired` or `revoked`. Open to any member of the tenant. `next_cursor` is always null.",
    "operationId": "list_exceptions_v1_risk_exceptions_get",
    "parameters": [
     {
      "description": "Only the exceptions in this status: `active`, `expired` or `revoked`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Exceptions V1 Risk Exceptions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the exceptions",
    "tags": [
     "risk"
    ]
   },
   "post": {
    "description": "Records a time limited exception on a control (`control_id` or `control_code`) or on a target (`target_ref`). Needs `tenant_admin`, `security_officer` or `developer`.\n\nChecks: `expires_at` in the future and at most 365 days ahead (422 `invalid_exception`); the approver is not the requester (409 `separation_of_duties`); the control exists (404 `not_found`); a control or a target is given (400 `invalid_request`). Writes the audit event `risk.exception.create`. The answer carries the exception with its status.",
    "operationId": "create_exception_v1_risk_exceptions_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ExceptionIn"
       }
      }
     },
     "description": "Control or target, reason, compensating controls, approver and expiry.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Exception V1 Risk Exceptions Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request a control exception",
    "tags": [
     "risk"
    ]
   }
  },
  "/v1/roadmap": {
   "get": {
    "description": "Roadmap read from `roadmap.yaml` of the catalog folder, always with a `phases` list (empty when the file is missing). Loaded as safe YAML. No authentication required.",
    "operationId": "roadmap_v1_roadmap_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Roadmap V1 Roadmap Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the product roadmap",
    "tags": [
     "system"
    ]
   }
  },
  "/v1/routes": {
   "get": {
    "description": "Routing rules of the tenant by priority then name, each with its match, strategy, candidates, fallbacks, constraints and `target_model` (the first candidate). Requires a reader role.",
    "operationId": "routes_list_v1_routes_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the routing rules",
    "tags": [
     "llm"
    ]
   },
   "post": {
    "description": "Creates a routing rule of the tenant and answers 201. A platform principal without tenant answers 403 `platform_only`; an unknown strategy 422 `parameter_invalid`. Audited (`route.create`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "routes_create_v1_routes_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "`name` (default `default`), `match` (request fields the rule applies to, a value or a list of values), `strategy` (`priority` by default, `cost`, `latency`, `quality`), `candidates` (model ids, or a single `target_model`), `fallbacks`, `constraints`, `priority` (default 100, lower first), `enabled` (default true).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a routing rule",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/routes/simulate": {
   "post": {
    "description": "Shows which model a request would be routed to, without calling it: the rule given by `route_id` or the first enabled rule that matches, the tenant allow and deny lists (narrowed by the request), the classification and the fallback policy. Answers the selected model, fallbacks, rejected candidates with their reason and the rule used; no eligible model answers 422 `no_eligible_model`. Restricted models are only allowed for `tenant_admin` and `security_officer` with `allow_restricted`. Requires a reader role.",
    "operationId": "routes_simulate_v1_routes_simulate_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "Request to simulate: `model`, `candidates`, `strategy`, `purpose`, `capabilities`, `data_classification` (default `internal`), `region_allow`, `provider_allow`, `model_allow`, `allow_restricted`, `fallback_policy` (default `allowed`), optional `route_id`, and any field the rules match on.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Simulate the routing of a request",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/routes/{rid}": {
   "delete": {
    "description": "Deletes a routing rule of the tenant and answers 204. Unknown rule: 404 `route_not_found`. Audited (`route.delete`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "routes_delete_v1_routes__rid__delete",
    "parameters": [
     {
      "description": "Identifier of the routing rule.",
      "in": "path",
      "name": "rid",
      "required": true,
      "schema": {
       "title": "Rid",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a routing rule",
    "tags": [
     "llm"
    ]
   },
   "put": {
    "description": "Replaces the match, strategy, candidates, fallbacks, constraints, priority and enabled flag of a rule of the tenant (omitted fields take their default; the name is kept). Unknown rule: 404 `route_not_found`. Audited (`route.update`). Requires `tenant_admin`, `platform_admin` or `ai_platform_engineer`.",
    "operationId": "routes_update_v1_routes__rid__put",
    "parameters": [
     {
      "description": "Identifier of the routing rule.",
      "in": "path",
      "name": "rid",
      "required": true,
      "schema": {
       "title": "Rid",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "The complete rule: same fields as on creation except `name`.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Replace a routing rule",
    "tags": [
     "llm"
    ]
   }
  },
  "/v1/runs": {
   "get": {
    "description": "Runs of the tenant, newest first, paginated with `cursor`. Filters: `agent_id` (id or name; `agent` is an alias), `state`, `session_id`, `parent_run_id`. An unknown state or a malformed UUID answers 400 `invalid_request`.",
    "operationId": "list_runs_v1_runs_get",
    "parameters": [
     {
      "description": "Only the runs of this agent (UUID or name).",
      "in": "query",
      "name": "agent_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Agent Id"
      }
     },
     {
      "description": "Alias of `agent_id`, used when `agent_id` is absent.",
      "in": "query",
      "name": "agent",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Agent"
      }
     },
     {
      "description": "Only the runs in this state: `pending`, `running`, `waiting_approval`, `waiting_input`, `suspended`, `succeeded`, `failed`, `cancelled` or `timed_out`.",
      "in": "query",
      "name": "state",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "State"
      }
     },
     {
      "description": "Only the runs of this session (UUID).",
      "in": "query",
      "name": "session_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Session Id"
      }
     },
     {
      "description": "Only the sub-agent runs started by this parent run (UUID).",
      "in": "query",
      "name": "parent_run_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Parent Run Id"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Runs V1 Runs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the runs",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}": {
   "get": {
    "description": "Returns the Execution Contract v1 of the run: agent and version, task, state, steps, budget limits and consumption, errors, retry policy, resume information and trace. 404 `run_not_found`.",
    "operationId": "get_run_v1_runs__run_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Run V1 Runs  Run Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a run",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}/cancel": {
   "post": {
    "description": "Moves the run to `cancelled` with the error `cancelled`; its active sub-agent runs are cancelled too. Needs `tenant_admin`, `developer`, `agent` or `security_officer`. A run already terminal answers 409 `invalid_transition`. Audited as `run.transition`.",
    "operationId": "cancel_run_v1_runs__run_id__cancel_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/eai__domains__agents__routes__CancelIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason of the cancellation."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Cancel Run V1 Runs  Run Id  Cancel Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Cancel a run",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}/checkpoints": {
   "get": {
    "description": "Checkpoints of the run in sequence order. One page only. 404 `run_not_found`.",
    "operationId": "list_checkpoints_v1_runs__run_id__checkpoints_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Checkpoints V1 Runs  Run Id  Checkpoints Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the checkpoints of a run",
    "tags": [
     "agents"
    ]
   },
   "post": {
    "description": "Saves a state of the run with the next sequence number and the current step sequence, so the run can later resume from it. Needs `tenant_admin`, `developer` or `agent`. Refused with 409 `run_finished` on a run `succeeded` or `cancelled`. Emits `checkpoint.created`; audited as `run.checkpoint`.",
    "operationId": "create_checkpoint_v1_runs__run_id__checkpoints_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CheckpointIn"
       }
      }
     },
     "description": "State to save and optional label.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Checkpoint V1 Runs  Run Id  Checkpoints Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Save a checkpoint",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}/events": {
   "get": {
    "description": "Server-Sent Events stream (`text/event-stream`) of the run events: `run.created`, `run.state`, `step.recorded`, `checkpoint.created`, `subagent.spawned`. Each message carries `id`, `event` and `data` (`type`, `data`, `at`).\nSteps:\n1. The events already recorded after `Last-Event-ID` are sent.\n2. Without `follow` the stream ends at once; with `follow=true` it polls every second.\n3. The stream ends with an `end` event carrying the run `state` when the run is terminal, when `timeout` has elapsed or when the client disconnects.\n404 `run_not_found`.",
    "operationId": "run_events_v1_runs__run_id__events_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     },
     {
      "description": "When true, keep the stream open and send new events until the run ends or `timeout` elapses. Default false.",
      "in": "query",
      "name": "follow",
      "required": false,
      "schema": {
       "default": false,
       "title": "Follow",
       "type": "boolean"
      }
     },
     {
      "description": "Maximum duration of a followed stream, in seconds (1 to 300, default 30).",
      "in": "query",
      "name": "timeout",
      "required": false,
      "schema": {
       "default": 30,
       "maximum": 300,
       "minimum": 1,
       "title": "Timeout",
       "type": "integer"
      }
     },
     {
      "description": "Numeric id of the last event received; the stream restarts after it. Standard SSE reconnection header.",
      "in": "header",
      "name": "Last-Event-ID",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Last-Event-Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Stream the events of a run",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}/heartbeat": {
   "post": {
    "description": "Records that the runtime is alive and tells it whether to go on: `action` is `continue`, or `stop` with a `reason` (`run_cancelled`, `run_terminal`, `run_suspended`, `agent_killed`, `agent_suspended`). The answer also gives `stale_after_seconds`. A terminal run is not updated. Needs `tenant_admin`, `developer` or `agent`. Audited only for the first heartbeat of a run and when the runtime is told to stop.",
    "operationId": "heartbeat_v1_runs__run_id__heartbeat_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/HeartbeatIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional progress information."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Heartbeat V1 Runs  Run Id  Heartbeat Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Send a run heartbeat",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}/replay": {
   "get": {
    "description": "Returns the full history of a run for review: its Execution Contract, steps, checkpoints, the audit events that name it and a single `timeline` sorted by time (run events and audit events). Needs `tenant_admin`, `developer`, `agent`, `auditor` or `security_officer`. Read only: nothing is re-executed.",
    "operationId": "replay_v1_runs__run_id__replay_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Replay V1 Runs  Run Id  Replay Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Replay a run",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}/resume": {
   "post": {
    "description": "Moves a `suspended`, `failed`, `timed_out` or `waiting_input` run back to `running` (else 409 `invalid_transition`). Needs `tenant_admin`, `developer` or `agent`; the agent must be active (409 `agent_not_active`).\nStrategies:\n1. `from_last_checkpoint` (default, except for `waiting_input`): resume from `checkpoint_id` or the last checkpoint (409 `no_checkpoint` if none).\n2. `restart_step` (default for `waiting_input`): replay the current step.\n3. `restart_run`: start over with the budget consumption reset.\nA run that failed on `budget_exceeded`, `max_steps_exceeded`, `killed` or `approval_rejected` can only use `restart_run` (409 `run_not_resumable`). Returns the run and the checkpoint used.",
    "operationId": "resume_run_v1_runs__run_id__resume_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/ResumeIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional checkpoint and resume strategy."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Resume Run V1 Runs  Run Id  Resume Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Resume a run",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}/steps": {
   "get": {
    "description": "Steps of the run in order, each with `seq`, kind, state, attempt, tokens, cost and error when present. One page only. 404 `run_not_found`.",
    "operationId": "list_steps_v1_runs__run_id__steps_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Steps V1 Runs  Run Id  Steps Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the steps of a run",
    "tags": [
     "agents"
    ]
   },
   "post": {
    "description": "Records one step reported by the runtime and returns the decision of the Loop Controller: `run_state`, `next_kind`, `retry`, `backoff_seconds`, `error`, `approval_id` and the budgets. Needs `tenant_admin`, `developer` or `agent`.\nSteps:\n1. The Kill Switch Registry and, for a sensitive step, the delegation chain, session and policy are checked.\n2. A `pending` run moves to `running`; any other state than `running` answers 409 `run_not_running`.\n3. Usage and cost are added to the budget consumption (cost in the run currency, else 400 `invalid_request`).\n4. A step matching `autonomy.human_approval_for` without `approval_id` stays `pending`, an approval is opened and the run moves to `waiting_approval`; a step of kind `approval` with state `pending` opens an approval with `quorum`.\n5. Budgets, max steps and retries decide the next state (`failed` or `timed_out` when exceeded).",
    "operationId": "add_step_v1_runs__run_id__steps_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StepIn"
       }
      }
     },
     "description": "The step: kind, state, usage, cost, error and run state hints.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Step V1 Runs  Run Id  Steps Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Report a step of a run",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/runs/{run_id}/subagents": {
   "get": {
    "description": "Summaries of the child runs started by this run, oldest first. One page only. 404 `run_not_found`.",
    "operationId": "list_subagents_v1_runs__run_id__subagents_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the parent run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Subagents V1 Runs  Run Id  Subagents Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the sub-agent runs",
    "tags": [
     "agents"
    ]
   },
   "post": {
    "description": "Starts a child run from a `pending` or `running` parent (else 409 `run_not_running`) and returns its Execution Contract. Needs `tenant_admin`, `developer` or `agent` and the scope `agents:run`.\nChecks, in order: the Kill Switch Registry; the depth against `autonomy.max_depth` (default 1, 409 `subagent_depth_exceeded`); the number of children against `autonomy.max_subagents` (default 3, 409 `subagent_count_exceeded`); the child agent against the `subagents` list of the parent manifest (403 `subagent_not_allowed`); the parent delegation. The child budget cannot exceed what the parent has left, the child joins the parent session, and a running parent records a `subagent` step.",
    "operationId": "spawn_subagent_v1_runs__run_id__subagents_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the parent run.",
      "in": "path",
      "name": "run_id",
      "required": true,
      "schema": {
       "title": "Run Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SubagentIn"
       }
      }
     },
     "description": "Child agent, task and budget.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Spawn Subagent V1 Runs  Run Id  Subagents Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Spawn a sub-agent run",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/sandbox/executions": {
   "post": {
    "description": "Creates a sandbox execution: the image and command run as a Kubernetes Job with the runtime class of the profile (gVisor, Kata, Wasm) when Kubernetes is configured (`status: submitted`, or `failed` if the submission fails). Needs `tenant_admin`, `developer` or `agent`; the profile `none` needs `tenant_admin` (403). Invalid profile, image or limits answer 422 `invalid_sandbox`. The usage is metered and the request audited as `sandbox.execute`.",
    "operationId": "create_sandbox_execution_v1_sandbox_executions_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SandboxIn"
       }
      }
     },
     "description": "Profile, image, command, environment and resource limits.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Sandbox Execution V1 Sandbox Executions Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run a command in a sandbox",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/sandbox/executions/{execution_id}": {
   "get": {
    "description": "Returns the sandbox execution: profile, image, command, limits, generated Kubernetes Job spec, status, executor and result. 404 `sandbox_execution_not_found`.",
    "operationId": "get_sandbox_execution_v1_sandbox_executions__execution_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the sandbox execution.",
      "in": "path",
      "name": "execution_id",
      "required": true,
      "schema": {
       "title": "Execution Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Sandbox Execution V1 Sandbox Executions  Execution Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a sandbox execution",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/schedules": {
   "get": {
    "description": "Cron schedules of the tenant, oldest first, optionally for one agent. One page only.",
    "operationId": "list_schedules_v1_schedules_get",
    "parameters": [
     {
      "description": "Only the schedules of this agent (UUID or name). 404 `agent_not_found` if unknown.",
      "in": "query",
      "name": "agent",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Agent"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Schedules V1 Schedules Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the schedules",
    "tags": [
     "agents"
    ]
   },
   "post": {
    "description": "Schedules runs of an agent from a cron expression evaluated in a time zone; the first `next_run_at` is computed (422 `invalid_cron`). When Temporal is configured the schedule is created there (503 `scheduler_unavailable` on failure). Needs `tenant_admin`, `developer` or `application_owner`. 404 `agent_not_found`. Audited as `schedule.create`.",
    "operationId": "create_schedule_v1_schedules_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ScheduleIn"
       }
      }
     },
     "description": "Agent, cron expression, time zone, run input and enabled flag.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Schedule V1 Schedules Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a schedule",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/schedules/{schedule_id}": {
   "delete": {
    "description": "Deletes the schedule; no new run is started by it. Needs `tenant_admin`, `developer` or `application_owner`. When the schedule is held by Temporal, it is deleted there too (503 `scheduler_unavailable` if Temporal cannot be reached). 404 `schedule_not_found`. Audited as `schedule.delete`.",
    "operationId": "delete_schedule_v1_schedules__schedule_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the schedule.",
      "in": "path",
      "name": "schedule_id",
      "required": true,
      "schema": {
       "title": "Schedule Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a schedule",
    "tags": [
     "agents"
    ]
   },
   "patch": {
    "description": "Changes the cron expression, time zone, input or enabled flag. The next run time is computed again (422 `invalid_cron` for a bad expression or time zone) and the Temporal schedule is updated when Temporal holds it (503 `scheduler_unavailable`). Needs `tenant_admin`, `developer` or `application_owner`. Audited as `schedule.update`.",
    "operationId": "patch_schedule_v1_schedules__schedule_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the schedule.",
      "in": "path",
      "name": "schedule_id",
      "required": true,
      "schema": {
       "title": "Schedule Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SchedulePatch"
       }
      }
     },
     "description": "Fields to change; the omitted ones are kept.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Schedule V1 Schedules  Schedule Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a schedule",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/secrets": {
   "get": {
    "description": "Lists the metadata of the tenant secrets ordered by path: `id`, `path`, `backend` (`openbao` or `local`), `version`, `created_by`, `created_at`, `updated_at`. Never the value. Open to any member of the tenant. `next_cursor` is always null.",
    "operationId": "list_secrets_v1_secrets_get",
    "parameters": [
     {
      "description": "Only the paths that start with this text, for example `connectors/`.",
      "in": "query",
      "name": "prefix",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Prefix"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Secrets V1 Secrets Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the secrets",
    "tags": [
     "secrets"
    ]
   },
   "post": {
    "description": "Creates the secret, or replaces its value when the path exists (the `version` grows by one). Needs `tenant_admin`, `security_officer` or `developer`; a developer only overwrites the secrets they wrote (403 `forbidden`). A path with a `..` segment answers 400 `invalid_request`. The answer (201) gives the metadata, never the value. Writes the audit event `secret.write`. 502 `secret_backend_error` when the vault cannot be reached.",
    "operationId": "create_secret_v1_secrets_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SecretIn"
       }
      }
     },
     "description": "Path and value of the secret.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Secret V1 Secrets Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Write a secret",
    "tags": [
     "secrets"
    ]
   }
  },
  "/v1/secrets/{path}": {
   "delete": {
    "description": "Deletes the secret and, with OpenBao, its value in the vault. Needs `tenant_admin`, `security_officer` or `developer`; a developer only deletes the secrets they wrote (403 `forbidden`). Objects that still refer to the path stop working. Writes the audit event `secret.delete`. Answers 204, 404 `not_found`, or 502 `secret_backend_error` when the vault cannot be reached.",
    "operationId": "delete_secret_v1_secrets__path__delete",
    "parameters": [
     {
      "description": "Path of the secret, slashes included, for example `connectors/crm/password`.",
      "in": "path",
      "name": "path",
      "required": true,
      "schema": {
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a secret",
    "tags": [
     "secrets"
    ]
   }
  },
  "/v1/security/posture": {
   "get": {
    "description": "Returns `environment`, `generated_at`, `protections` (authentication methods and other protections in force), `checks` (each with its status `pass`, `warn` or `fail`, severity and message) and `summary` (number of checks per status). For a caller with a tenant, also `tenant` with the security settings of the tenant, which some checks take into account. Needs `security_officer` or `tenant_admin`. Read only.",
    "operationId": "get_posture_v1_security_posture_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Posture V1 Security Posture Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the security posture",
    "tags": [
     "security"
    ]
   }
  },
  "/v1/security/settings": {
   "get": {
    "description": "Returns `tenant_id` and `settings`: the security settings of the tenant, defaults included. Needs `tenant_admin` or `security_officer` and a tenant (403 `tenant_required`).",
    "operationId": "get_security_settings_v1_security_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Security Settings V1 Security Settings Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the security settings",
    "tags": [
     "security"
    ]
   },
   "put": {
    "description": "Partial update: only the settings sent change, the others keep their value. Needs `tenant_admin` or `security_officer` and a tenant.\n\nValidation (422 `validation_error` with `details.field`): unknown setting, `prompt_injection_mode` not in `off`, `detect`, `block`, `untrusted_content_wrapping` not a boolean, `output_links` not in `allow`, `strip_untrusted`, a host list longer than 200 or holding a value that is not a public host name (`*.` prefix allowed). Host names are lowercased and deduplicated.\n\nThe answer gives the full settings after the change. Writes the audit event `security.settings.update` with the changed settings.",
    "operationId": "put_security_settings_v1_security_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "JSON object with the settings to change, for example `{\"prompt_injection_mode\": \"block\"}`.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Security Settings V1 Security Settings Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update the security settings",
    "tags": [
     "security"
    ]
   }
  },
  "/v1/service-identities": {
   "get": {
    "description": "Lists the service identities of the tenant, ordered by name, with their SPIFFE ID, roles, scopes and clearance. Open to any member of the tenant. Not paginated: `next_cursor` is always null.",
    "operationId": "list_service_identities_v1_service_identities_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Service Identities V1 Service Identities Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the service identities",
    "tags": [
     "identity"
    ]
   },
   "post": {
    "description": "Registers a workload identity of the tenant with its SPIFFE ID, roles, scopes and clearance. Needs `tenant_admin` or `security_officer`; the roles and scopes granted follow the same rules as API keys (only what the caller holds). A SPIFFE ID already registered answers 409 `conflict`. Writes the audit event `service_identity.create`. Assuming the identity also needs the explicit relation `can_assume` (see the assume route).",
    "operationId": "create_service_identity_v1_service_identities_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ServiceIdentityIn"
       }
      }
     },
     "description": "Name, SPIFFE ID and rights of the identity.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Service Identity V1 Service Identities Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a service identity",
    "tags": [
     "identity"
    ]
   }
  },
  "/v1/service-identities/{identity_id}": {
   "delete": {
    "description": "Deletes the service identity; it can no longer be assumed nor authenticate with its SPIFFE ID. Needs `tenant_admin` or `security_officer`. Writes the audit event `service_identity.delete`. Answers 204, or 404 `not_found`.",
    "operationId": "delete_service_identity_v1_service_identities__identity_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the service identity.",
      "in": "path",
      "name": "identity_id",
      "required": true,
      "schema": {
       "title": "Identity Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a service identity",
    "tags": [
     "identity"
    ]
   }
  },
  "/v1/service-identities/{identity_id}/assume": {
   "post": {
    "description": "Returns a signed, short lived ExecutionContext whose subject is the service identity, for the caller. It is not an API credential: downstream services verify it (`POST /v1/context/verify` or the JWKS) and the caller revokes it with `POST /v1/context/{context_id}/revoke`.\n\nChecks, in order:\n\n1. the caller holds the OpenFGA relation `can_assume` on `service_identity:<id>`, written explicitly: it is never implied by a tenant role, an administrator included, nor granted to a wildcard subject (403 `relation_required`, audited; 502 `authz_backend_error` when OpenFGA cannot answer);\n2. the identity is enabled (409 `service_identity_disabled`) and each requested audience is known (400 `context_wrong_audience`);\n3. the requested scopes are granted by the identity and held by the caller (403 `service_identity_scope_exceeds`);\n4. the policy allows `service_identity.assume`.\n\nThe effective rights never exceed the caller's: roles held by both (never `platform_admin`), the scopes above and the lower of the two clearances. The caller stays `on_behalf_of` in the signed document and is the actor of the audit events `service_identity.assume` and `context.issue`.",
    "operationId": "assume_service_identity_v1_service_identities__identity_id__assume_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the service identity.",
      "in": "path",
      "name": "identity_id",
      "required": true,
      "schema": {
       "title": "Identity Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AssumeIn"
       }
      }
     },
     "description": "Purpose, audiences, lifetime and scopes of the requested context.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Assume Service Identity V1 Service Identities  Identity Id  Assume Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Assume a service identity",
    "tags": [
     "identity"
    ]
   }
  },
  "/v1/sessions": {
   "get": {
    "description": "Sessions, newest first, paginated with `cursor`. A caller sees its own sessions; `tenant_admin`, `auditor` and `security_officer` see every session of the tenant.",
    "operationId": "list_sessions_v1_sessions_get",
    "parameters": [
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Only the sessions opened on this channel.",
      "in": "query",
      "name": "channel",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Channel"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Sessions V1 Sessions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the sessions",
    "tags": [
     "agents"
    ]
   },
   "post": {
    "description": "Opens a conversation session, owned by `user_id` or by the caller. Opening a session for another user needs `tenant_admin` or `agent` (403 `forbidden`). Needs `tenant_admin`, `developer` or `agent`. 404 `agent_not_found` for an unknown `agent_id`. Audited as `session.create`.",
    "operationId": "create_session_v1_sessions_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__agents__routes__SessionIn"
       }
      }
     },
     "description": "Agent, owner, channel, title, metadata and lifetime of the session.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Session V1 Sessions Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Open a session",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/sessions/{session_id}": {
   "delete": {
    "description": "Deletes the session and its messages. Needs `tenant_admin`, `developer` or `agent`, and the caller must see the session (its owner, or `tenant_admin`, `auditor`, `security_officer`, `agent`); otherwise 404 `session_not_found`. Audited as `session.delete`.",
    "operationId": "delete_session_v1_sessions__session_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a session",
    "tags": [
     "agents"
    ]
   },
   "get": {
    "description": "Returns one session. Visible to its owner, to `tenant_admin`, `auditor`, `security_officer` and to the `agent` role; otherwise 404 `session_not_found`.",
    "operationId": "get_session_v1_sessions__session_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Session V1 Sessions  Session Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a session",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/sessions/{session_id}/messages": {
   "get": {
    "description": "Messages in order, paginated with `cursor`. `after` (message id or timestamp) lets a runtime poll the new messages only; an unknown message id or a malformed timestamp answers 400 `invalid_request`.",
    "operationId": "list_messages_v1_sessions__session_id__messages_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Message id or ISO 8601 timestamp: only newer messages.",
      "in": "query",
      "name": "after",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "message id or ISO 8601 timestamp: only newer messages",
       "title": "After"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Messages V1 Sessions  Session Id  Messages Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the messages of a session",
    "tags": [
     "agents"
    ]
   },
   "post": {
    "description": "Appends a message with the next sequence number. The session must be open and not expired (409 `session_closed`). Needs `tenant_admin`, `developer` or `agent`. The audit event `session.message.add` keeps the role and the length only, never the content.",
    "operationId": "add_message_v1_sessions__session_id__messages_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MessageIn"
       }
      }
     },
     "description": "Role, content and metadata of the message.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Message V1 Sessions  Session Id  Messages Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add a message to a session",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/skills": {
   "get": {
    "description": "Skills of the tenant in name order, with version, owner, digest, verification result and status. One page only.",
    "operationId": "list_skills_v1_skills_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Skills V1 Skills Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the skills",
    "tags": [
     "skills"
    ]
   },
   "post": {
    "description": "Applies a Skill manifest: creates the skill or replaces it (a replaced skill goes back to `draft`, a blocked one stays `blocked`). The digest and the signature are verified at once: the skill becomes `approved` when they verify. A Git or OCI artifact needs `artifact.digest` (422 `invalid_manifest`). `apply_status` is `created` or `updated`. Needs `tenant_admin`, `developer` or `application_owner`; the caller becomes ReBAC owner. Audited as `skill.apply`.",
    "operationId": "create_skill_v1_skills_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Manifest",
        "type": "object"
       }
      }
     },
     "description": "Skill manifest (`kind: Skill`, `metadata` with name, version and owner, `spec` with description, instructions, permissions, signature and optional artifact).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Skill V1 Skills Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register a skill",
    "tags": [
     "skills"
    ]
   }
  },
  "/v1/skills/{name}": {
   "get": {
    "description": "Returns the skill with its manifest, content, digest, signature and verification. Needs the ReBAC relation `viewer`. 404 `skill_not_found`.",
    "operationId": "get_skill_v1_skills__name__get",
    "parameters": [
     {
      "description": "Name of the skill.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Skill V1 Skills  Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a skill",
    "tags": [
     "skills"
    ]
   }
  },
  "/v1/skills/{name}/load": {
   "get": {
    "description": "Skill Loader: returns what a runtime needs to use the skill (instructions of an inline skill, artifact, entrypoint, permissions, dependencies, signer). Needs the ReBAC relation `can_invoke`. Refusals, each audited as `skill.load` denied:\n- 403 `skill_blocked`: the skill is `blocked` or `deprecated`;\n- 409 `skill_digest_mismatch`: the content no longer matches its digest;\n- 403 `skill_unsigned`: the signature does not verify;\n- 403 `skill_not_granted`: with `agent`, the skill is not listed in the agent manifest;\n- 403 `skill_permission_denied`: the skill asks for scopes the agent lacks, or its classification ceiling is below the agent one.",
    "operationId": "load_skill_v1_skills__name__load_get",
    "parameters": [
     {
      "description": "Name of the skill.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     },
     {
      "description": "Agent (UUID or name) that loads the skill; its manifest grants and permissions are checked.",
      "in": "query",
      "name": "agent",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Agent"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Load Skill V1 Skills  Name  Load Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Load a skill for an agent",
    "tags": [
     "skills"
    ]
   }
  },
  "/v1/skills/{name}/status": {
   "post": {
    "description": "`approved` goes through a promotion: an approval is opened for `tenant_admin` or `security_officer` and the answer is 202 with `approval_id` and `status: pending_approval`. The other statuses (`draft`, `restricted`, `deprecated`, `blocked`) apply at once (200). Needs `tenant_admin` or `security_officer` and the ReBAC relation `editor`. Audited as `skill.status`.",
    "operationId": "skill_status_v1_skills__name__status_post",
    "parameters": [
     {
      "description": "Name of the skill.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SkillStatusIn"
       }
      }
     },
     "description": "Target status and reason.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "title": "Response Skill Status V1 Skills  Name  Status Post"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change the status of a skill",
    "tags": [
     "skills"
    ]
   }
  },
  "/v1/skills/{name}/verify": {
   "post": {
    "description": "Checks again the content digest and the signature against the trusted keys and stores the result: `verified`, `method`, `signer`, `reason`. A verified skill becomes `approved`, otherwise `draft` (a blocked skill stays `blocked`). Needs `tenant_admin`, `developer`, `application_owner` or `security_officer` and the ReBAC relation `editor`. Audited as `skill.verify`.",
    "operationId": "verify_skill_v1_skills__name__verify_post",
    "parameters": [
     {
      "description": "Name of the skill.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Verify Skill V1 Skills  Name  Verify Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Verify a skill signature",
    "tags": [
     "skills"
    ]
   }
  },
  "/v1/soc/catalog": {
   "get": {
    "description": "Returns the allowlists: `reactions`, the target types allowed per reaction (`targets`), the detection kinds with their base severity and playbook (`detections`), the limits of the proportionality guard (`response`: minimum confidence, maximum automatic blast radius, blast radius needing a manual approval, reactions always needing approval) and the SOC roles. Open to any member of the tenant.",
    "operationId": "soc_catalog_v1_soc_catalog_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Soc Catalog V1 Soc Catalog Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get the SOC catalogue",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/detections": {
   "get": {
    "description": "Lists the detections of the tenant, newest first, optionally for one incident or one kind. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`. The read is audited.",
    "operationId": "list_detections_v1_soc_detections_get",
    "parameters": [
     {
      "description": "Only the detections correlated into this incident.",
      "in": "query",
      "name": "incident_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Incident Id"
      }
     },
     {
      "description": "Only this detection kind, for example `prompt_injection`.",
      "in": "query",
      "name": "kind",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Kind"
      }
     },
     {
      "description": "Maximum number of detections (default 100, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Detections V1 Soc Detections Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the detections",
    "tags": [
     "soc"
    ]
   },
   "post": {
    "description": "Ingests a detection. Needs a credential granted the scope `soc:detections` explicitly (the global `*` does not count), or `security_officer`, `agent` or `soc_analyst`.\n\n1. The detection is normalized: closed vocabularies of kinds and sources (400 `unknown_detection_kind`, 400 `invalid_request`), severity `sev1` to `sev4` (default: the base severity of the kind), confidence 0 to 1.\n2. It is scored by the risk engine and correlated (same user, else same agent, else tenant level) into an incident within the correlation window, then sealed as incident evidence.\n3. Its playbook of typed reactions is submitted to the Response Policy Engine; automatic orders run only within the guard limits.\n\nAnswers 201 with the detection, its incident and the orders created.",
    "operationId": "report_detection_v1_soc_detections_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DetectionIn"
       }
      }
     },
     "description": "The detection to ingest.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Report Detection V1 Soc Detections Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Report a detection",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/incidents/{incident_id}/custody": {
   "get": {
    "description": "Returns the custody log of the incident evidence (who sealed, read or exported what, and when) with the verification of both hash chains. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`. The read itself is added to the custody log. Answers 404 `not_found` for an unknown incident.",
    "operationId": "read_custody_v1_soc_incidents__incident_id__custody_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the incident.",
      "in": "path",
      "name": "incident_id",
      "required": true,
      "schema": {
       "title": "Incident Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Read Custody V1 Soc Incidents  Incident Id  Custody Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the chain of custody",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/incidents/{incident_id}/evidence": {
   "get": {
    "description": "Returns the sealed evidence records of the incident (detections, orders, receipts, notes), the verification of their chain and `custody_seq`, the custody entry this read created. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`. Answers 404 `not_found`.",
    "operationId": "read_evidence_v1_soc_incidents__incident_id__evidence_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the incident.",
      "in": "path",
      "name": "incident_id",
      "required": true,
      "schema": {
       "title": "Incident Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Read Evidence V1 Soc Incidents  Incident Id  Evidence Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the evidence of an incident",
    "tags": [
     "soc"
    ]
   },
   "post": {
    "description": "Appends a sealed record to the evidence chain of the incident: the content hash and the hash of the previous record, so that a removed, reordered or modified record breaks the chain. Records can never be updated nor deleted. Needs `security_officer`, `soc_analyst` or `tenant_admin`. Writes the audit event `soc.evidence.seal` and a custody entry. Answers 201 with `seq`, `kind`, `content_sha256`, `prev_hash`, `hash`, `sealed_by` and `sealed_at`.",
    "operationId": "seal_evidence_v1_soc_incidents__incident_id__evidence_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the incident.",
      "in": "path",
      "name": "incident_id",
      "required": true,
      "schema": {
       "title": "Incident Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__soc__EvidenceIn"
       }
      }
     },
     "description": "Kind and content of the evidence.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Seal Evidence V1 Soc Incidents  Incident Id  Evidence Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Seal evidence on an incident",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/incidents/{incident_id}/evidence/export": {
   "post": {
    "description": "Returns the incident, its evidence records, both chains verified and the custody log. The bundle is scanned for credentials before any byte leaves: when one is found the export is refused with 422 `secret_detected`, the refusal is recorded in the custody log and a `secret_leak` detection is raised. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`.",
    "operationId": "export_evidence_v1_soc_incidents__incident_id__evidence_export_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the incident.",
      "in": "path",
      "name": "incident_id",
      "required": true,
      "schema": {
       "title": "Incident Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Export Evidence V1 Soc Incidents  Incident Id  Evidence Export Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Export the evidence of an incident",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/kill-switches": {
   "get": {
    "description": "Lists the kill switches of the tenant, newest first, at most 500: by default only those whose desired state is `SUSPENDED`. Each gives reaction, target, desired and observed state, last receipt and release. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`. The read is audited.",
    "operationId": "list_kill_switches_v1_soc_kill_switches_get",
    "parameters": [
     {
      "description": "`active` (default, suspended only) or `all`.",
      "in": "query",
      "name": "state",
      "required": false,
      "schema": {
       "default": "active",
       "title": "State",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Kill Switches V1 Soc Kill Switches Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the kill switches",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/kill-switches/{switch_id}/verify": {
   "post": {
    "description": "Runs the Containment Verifier probe of the switch: on success the observed state becomes `SUSPENDED_VERIFIED`. Cluster reactions (`ISOLATE_NETWORK`, `TERMINATE_WORKLOAD`) are verified only by a signed in-cluster receipt. Needs `security_officer`, `soc_analyst` or `tenant_admin`. Writes the audit event `soc.kill_switch.verify`. Answers 404 `not_found`.",
    "operationId": "verify_kill_switch_v1_soc_kill_switches__switch_id__verify_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the kill switch.",
      "in": "path",
      "name": "switch_id",
      "required": true,
      "schema": {
       "title": "Switch Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Verify Kill Switch V1 Soc Kill Switches  Switch Id  Verify Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Verify a kill switch",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/orders": {
   "get": {
    "description": "Lists the containment orders of the tenant, newest first, optionally by status (`pending_approval`, `applied`, `rejected`...) or incident. Each gives reaction, target, blast radius, confidence, severity, mode (`manual` or automatic), status and the decision of the Response Policy Engine. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`.",
    "operationId": "list_orders_v1_soc_orders_get",
    "parameters": [
     {
      "description": "Only the orders in this status, for example `pending_approval`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only the orders of this incident.",
      "in": "query",
      "name": "incident_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Incident Id"
      }
     },
     {
      "description": "Maximum number of orders (default 100, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Orders V1 Soc Orders Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the containment orders",
    "tags": [
     "soc"
    ]
   },
   "post": {
    "description": "Creates a manual containment order. Needs `security_officer`, `soc_analyst` or `tenant_admin`.\n\n1. The reaction must be allowlisted (400 `unknown_reaction`; `RECOVER` goes through the recovery workflow, 422 `recover_requires_workflow`) and accept the target type (400 `target_not_allowed`).\n2. The blast radius is computed and the Response Policy Engine decides: allowed and applied, waiting for a SOC lead (`pending_approval`, always for `SUSPEND_TENANT` and `EMERGENCY_LOCKDOWN`, or above the blast radius limits), or rejected (409 `containment_refused` with the reasons).\n3. An applied order writes the kill switch (desired state `SUSPENDED`) and runs its enforcement adapter, which maps the reaction to a fixed code path.\n\nAnswers 201 with the order.",
    "operationId": "create_order_v1_soc_orders_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OrderIn"
       }
      }
     },
     "description": "Reaction, target, incident, reason, parameters and limits of the order.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Order V1 Soc Orders Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Order a containment",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/orders/{order_id}": {
   "get": {
    "description": "Returns the order with its latest kill switch and the receipts received for it. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`. Answers 404 `not_found`.",
    "operationId": "get_order_v1_soc_orders__order_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the containment order.",
      "in": "path",
      "name": "order_id",
      "required": true,
      "schema": {
       "title": "Order Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Order V1 Soc Orders  Order Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a containment order",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/orders/{order_id}/approve": {
   "post": {
    "description": "Approves an order waiting for a second person and applies it (kill switch written, adapter run). Needs `security_officer` or `tenant_admin` (SOC lead), who is not the requester (409 `separation_of_duties`). An order that is not pending answers 409 `order_not_pending`; an unknown one 404.",
    "operationId": "approve_order_v1_soc_orders__order_id__approve_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the containment order.",
      "in": "path",
      "name": "order_id",
      "required": true,
      "schema": {
       "title": "Order Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Approve Order V1 Soc Orders  Order Id  Approve Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Approve a containment order",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/orders/{order_id}/reject": {
   "post": {
    "description": "Rejects an order waiting for approval, with an optional reason. Needs `security_officer` or `tenant_admin` (SOC lead). An order that is not pending answers 409 `order_not_pending`; an unknown one 404.",
    "operationId": "reject_order_v1_soc_orders__order_id__reject_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the containment order.",
      "in": "path",
      "name": "order_id",
      "required": true,
      "schema": {
       "title": "Order Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DecisionNoteIn"
       }
      }
     },
     "description": "Optional reason of the decision.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Reject Order V1 Soc Orders  Order Id  Reject Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reject a containment order",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/receipts": {
   "post": {
    "description": "Receipt sent from the cluster (Cilium policy observed, workload scaled to zero) for a cluster reaction: JSON `{kill_switch_id, verified, adapter, evidence}`. Signed like the platform webhooks: `X-EAI-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.\" + body)>`, a 5 minute replay window, `X-EAI-Delivery` for deduplication and `X-EAI-Tenant` (tenant slug). Without the configured SOC webhook secret every delivery is refused. Every delivery, accepted or not, is recorded and audited. A verified receipt moves the observed state to `SUSPENDED_VERIFIED`; a receipt for a reaction that expects none answers 409 `receipt_not_expected`. No user credential is needed: the signature authenticates the sender. Answers 202 with the kill switch.",
    "operationId": "containment_receipt_v1_soc_receipts_post",
    "requestBody": {
     "content": {
      "application/octet-stream": {
       "schema": {
        "format": "binary",
        "type": "string"
       }
      }
     },
     "description": "Raw signed JSON body of the receipt (`application/octet-stream`), verified byte for byte.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Receive an in-cluster containment receipt",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/recoveries": {
   "get": {
    "description": "Lists the recovery requests of the tenant, newest first, at most 500, optionally by status, with their approvals. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`.",
    "operationId": "list_recoveries_v1_soc_recoveries_get",
    "parameters": [
     {
      "description": "Only the requests in this status, for example `pending`, `approved` or `recovered`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Recoveries V1 Soc Recoveries Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the recovery requests",
    "tags": [
     "soc"
    ]
   },
   "post": {
    "description": "Opens a four eyes recovery request for one active kill switch. Needs `security_officer`, `soc_analyst` or `tenant_admin`. An unknown switch answers 404, a switch no longer suspended 409 `kill_switch_not_active`, a switch with an open request 409 `recovery_already_open`. Answers 201 with the request.",
    "operationId": "request_recovery_v1_soc_recoveries_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RecoveryIn"
       }
      }
     },
     "description": "Kill switch and reason.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Request Recovery V1 Soc Recoveries Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Request the recovery of a kill switch",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/recoveries/{recovery_id}/approve": {
   "post": {
    "description": "Records one approval of a pending recovery; two distinct SOC leads are required, neither being the requester (409 `separation_of_duties`), each approving once (409 `already_approved`). Needs `security_officer` or `tenant_admin` (SOC lead). A request that is not pending answers 409 `recovery_not_pending`.",
    "operationId": "approve_recovery_v1_soc_recoveries__recovery_id__approve_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the recovery request.",
      "in": "path",
      "name": "recovery_id",
      "required": true,
      "schema": {
       "title": "Recovery Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DecisionNoteIn"
       }
      }
     },
     "description": "Optional note of the approval.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Approve Recovery V1 Soc Recoveries  Recovery Id  Approve Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Approve a recovery",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/recoveries/{recovery_id}/reauthorize": {
   "post": {
    "description": "Final step of a recovery, by one of the approvers (403 `reauthorization_by_approver` otherwise) once both approvals are in (409 `recovery_not_approved`). The switch is released, the target is re-evaluated by the policy, which must allow it (403 `reauthorization_denied`, everything rolled back), and only then the owning plane is restored, for example an agent resumed. A revoked API key stays revoked: issue a new one. Needs `security_officer` or `tenant_admin` (SOC lead).",
    "operationId": "reauthorize_recovery_v1_soc_recoveries__recovery_id__reauthorize_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the recovery request.",
      "in": "path",
      "name": "recovery_id",
      "required": true,
      "schema": {
       "title": "Recovery Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Reauthorize Recovery V1 Soc Recoveries  Recovery Id  Reauthorize Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Re-authorize and recover",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/transactions": {
   "get": {
    "description": "Lists the side effecting tool and connector calls of the tenant, newest first, at most 500: idempotency key, operation, status (`in_flight`, `committed`, `interrupted`, `reconciled`, `compensating`, `compensated`...) and reconciliation. Needs `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`.",
    "operationId": "list_transactions_v1_soc_transactions_get",
    "parameters": [
     {
      "description": "Only the transactions in this status, for example `interrupted`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only the transactions of this agent run.",
      "in": "query",
      "name": "run_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Run Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Transactions V1 Soc Transactions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the side effecting transactions",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/transactions/{transaction_id}/reconcile": {
   "post": {
    "description": "Records the real outcome of a side effecting call whose result is unknown (interrupted by a kill, a crash or a timeout): `committed` (it happened at the provider) or `not_executed`. A retry with the same idempotency key then returns the stored result instead of calling the provider again. Needs `security_officer` or `tenant_admin` (SOC lead). An unknown outcome answers 400, a transaction that cannot be reconciled 409 `transaction_not_reconcilable`, an unknown one 404.",
    "operationId": "reconcile_transaction_v1_soc_transactions__transaction_id__reconcile_post",
    "parameters": [
     {
      "description": "Identifier of the side effecting transaction.",
      "in": "path",
      "name": "transaction_id",
      "required": true,
      "schema": {
       "title": "Transaction Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReconcileIn"
       }
      }
     },
     "description": "Outcome, provider reference and note.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Reconcile Transaction V1 Soc Transactions  Transaction Id  Reconcile Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reconcile a transaction",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/soc/webhooks/{source}": {
   "post": {
    "description": "Webhook of external detectors: Falco, Tetragon or OpenSearch Security Analytics. The body is one event or a list (at most 200 processed), normalized into detections (Falco priorities and `eai_*` tags mapped to kinds and severities) and ingested like `POST /v1/soc/detections`. Signed like the platform webhooks: `X-EAI-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.\" + body)>`, a 5 minute replay window, `X-EAI-Delivery` for deduplication and `X-EAI-Tenant` (tenant slug). Without the configured SOC webhook secret every delivery is refused. Every delivery, accepted or not, is recorded and audited. An unknown source answers 404. Answers 202 with `received` and the detections.",
    "operationId": "detection_webhook_v1_soc_webhooks__source__post",
    "parameters": [
     {
      "description": "Detector: `falco`, `tetragon` or `opensearch`.",
      "in": "path",
      "name": "source",
      "required": true,
      "schema": {
       "title": "Source",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/octet-stream": {
       "schema": {
        "format": "binary",
        "type": "string"
       }
      }
     },
     "description": "Raw signed JSON body (`application/octet-stream`): one event or a list of events of the detector.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Receive external security findings",
    "tags": [
     "soc"
    ]
   }
  },
  "/v1/storage/profiles": {
   "get": {
    "description": "Storage profiles visible to the caller, ordered by scope then name, each with its `needed_capabilities` (required capabilities plus those its purposes need). One page only: `next_cursor` is always null. Requires `platform_admin`, or a tenant principal with `tenant_admin`, `security_officer`, `developer` or `auditor`.",
    "operationId": "list_profiles_v1_storage_profiles_get",
    "parameters": [
     {
      "description": "Only profiles of this scope: `tenant` or `platform`.",
      "in": "query",
      "name": "scope",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "tenant",
          "platform"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Scope"
      }
     },
     {
      "description": "Only profiles of this provider, for example `aws_s3` or `azure_blob`.",
      "in": "query",
      "name": "provider",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Provider"
      }
     },
     {
      "description": "Only profiles that serve this purpose, for example `audit_worm` or `documents`.",
      "in": "query",
      "name": "purpose",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Purpose"
      }
     },
     {
      "description": "Maximum number of profiles, 1 to 500, default 50.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Profiles V1 Storage Profiles Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the storage profiles",
    "tags": [
     "storage"
    ]
   },
   "post": {
    "description": "Creates a profile with status `unverified` and answers 201. Requires `tenant_admin` for scope `tenant` (inside a tenant) or `platform_admin` for scope `platform` (403 `storage_scope_forbidden`), and the policy decision `storage.profile.create`. Audited (`storage.profile.create`).\n\nValidation (422 unless stated): no secret field in `auth`, `options` or `encryption` (`storage_secret_in_profile`); supported provider (`storage_provider_unsupported`) and authentication method (`storage_auth_method_unsupported`); a `credential_ref` of the form `openbao://...` for a tenant profile or `env://EAI_CRED_...` for a platform profile (`storage_credential_ref_invalid`); `auth.account` for Azure; a valid bucket name; an HTTPS endpoint, required for `ibm_cos`, `seaweedfs` and `s3_compatible` (`storage_endpoint_required`); a known encryption mode, purpose and capability (`storage_profile_invalid`). A profile with the same name in the same scope answers 409 `storage_profile_exists`.",
    "operationId": "create_profile_v1_storage_profiles_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ProfileIn"
       }
      }
     },
     "description": "The new storage profile. Unknown fields are refused.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Profile V1 Storage Profiles Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a storage profile",
    "tags": [
     "storage"
    ]
   }
  },
  "/v1/storage/profiles/{profile_id}": {
   "delete": {
    "description": "Deletes the profile (the bucket and its objects are not touched) and answers 204. Requires `tenant_admin` for a tenant profile, `platform_admin` for a platform profile (403 `storage_scope_forbidden`), and the policy decision `storage.profile.delete`. The audit event `storage.profile.delete` records the provider, bucket and the number of audit exports that used it. Unknown id: 404 `storage_profile_not_found`.",
    "operationId": "delete_profile_v1_storage_profiles__profile_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the storage profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a storage profile",
    "tags": [
     "storage"
    ]
   },
   "get": {
    "description": "One storage profile with its status, discovered capabilities, verification time, missing and needed capabilities and last error. Never a secret value. Same readers as the list. Unknown id: 404 `storage_profile_not_found`.",
    "operationId": "get_profile_v1_storage_profiles__profile_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the storage profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Profile V1 Storage Profiles  Profile Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a storage profile",
    "tags": [
     "storage"
    ]
   },
   "patch": {
    "description": "Changes the given fields; the merged profile is validated like a new one. A change of provider, endpoint, region, bucket, `auth`, `credential_ref`, `encryption` or `options` clears the capabilities and sets the status back to `unverified`; `status: disabled` disables the profile, `status: active` on a disabled profile makes it `unverified`. Adding the purpose `audit_worm` without such a change requires a verified object lock capability (409 `storage_capability_missing`). Requires `tenant_admin` (platform profile: `platform_admin`) and the policy decision `storage.profile.update`; audited with the changed fields.",
    "operationId": "patch_profile_v1_storage_profiles__profile_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the storage profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ProfilePatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Profile V1 Storage Profiles  Profile Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a storage profile",
    "tags": [
     "storage"
    ]
   }
  },
  "/v1/storage/profiles/{profile_id}/checks": {
   "get": {
    "description": "History of the capability verifications of the profile, newest first: status, capabilities found, missing capabilities, whether a write probe ran, error, duration in milliseconds and who ran it. One page only (`next_cursor` is always null). Same readers as the list.",
    "operationId": "list_checks_v1_storage_profiles__profile_id__checks_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the storage profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     },
     {
      "description": "Maximum number of verifications, 1 to 500, default 50.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Checks V1 Storage Profiles  Profile Id  Checks Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the verifications of a profile",
    "tags": [
     "storage"
    ]
   }
  },
  "/v1/storage/profiles/{profile_id}/objects": {
   "get": {
    "description": "Objects stored under a prefix inside the presign prefixes of the profile: key relative to the profile key prefix (usable with presign and delete), stored key, size, ETag, content type, SHA-256, version, last modification and storage class. Requires `tenant_admin`, `developer`, `agent` or `auditor` (platform profile: `platform_admin`) and the policy decision `storage.object.list`; the listing is audited. Errors: 422 `storage_prefix_required` when `prefix` is omitted and the profile has not exactly one presign prefix, 403 `storage_key_out_of_scope` outside the presign prefixes, 409 `storage_profile_disabled`.",
    "operationId": "list_objects_v1_storage_profiles__profile_id__objects_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the storage profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     },
     {
      "description": "Key prefix to list, relative to the profile key prefix and inside one of its presign prefixes; 1024 characters at most. Defaults to the only presign prefix of the profile.",
      "in": "query",
      "name": "prefix",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 1024,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Prefix"
      }
     },
     {
      "description": "Maximum number of objects in one page, 1 to 500, default 50.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque continuation token of the backend, returned as `next_cursor` by the previous page; 4096 characters at most.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 4096,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Objects V1 Storage Profiles  Profile Id  Objects Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the objects of a profile",
    "tags": [
     "storage"
    ]
   }
  },
  "/v1/storage/profiles/{profile_id}/objects/delete": {
   "post": {
    "description": "Deletes one object (or one version of it) inside the presign prefixes of the profile. A profile serving `audit_worm` or `evidence` never deletes through the API (409 `storage_object_protected`); a retention refusal of the backend is returned as is. Requires `tenant_admin`, `developer` or `agent` (platform profile: `platform_admin`) and the policy decision `storage.object.delete`; audited with the full key and version. Other errors: 403 `storage_key_out_of_scope`, 422 `storage_key_invalid`, 409 `storage_profile_disabled`.",
    "operationId": "delete_object_v1_storage_profiles__profile_id__objects_delete_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the storage profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeleteObjectIn"
       }
      }
     },
     "description": "Key, and optionally version, of the object to delete.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Object V1 Storage Profiles  Profile Id  Objects Delete Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an object of a profile",
    "tags": [
     "storage"
    ]
   }
  },
  "/v1/storage/profiles/{profile_id}/presign": {
   "post": {
    "description": "Issues a presigned URL to read (`GET`) or write (`PUT`) one object directly in the bucket, and answers 201 with the grant id, URL, method, full key, lifetime and expiry. The key must be inside the presign prefixes (403 `storage_key_out_of_scope`) and the profile must have a verified, recent `presign` capability (409 `storage_capability_missing`). The lifetime may not exceed `EAI_STORAGE_PRESIGN_MAX_SECONDS` (3600 by default, never more than 604800; 422 `storage_presign_expiry_invalid`). Requires `tenant_admin`, `developer` or `agent` (platform profile: `platform_admin`) and the policy decision `storage.presign.read` or `storage.presign.write`. The grant is recorded with a SHA-256 of the URL (never the URL itself) and audited.",
    "operationId": "presign_v1_storage_profiles__profile_id__presign_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the storage profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PresignIn"
       }
      }
     },
     "description": "Object, direction and lifetime of the presigned URL.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Presign V1 Storage Profiles  Profile Id  Presign Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Issue a presigned URL",
    "tags": [
     "storage"
    ]
   }
  },
  "/v1/storage/profiles/{profile_id}/verify": {
   "post": {
    "description": "Discovers the capabilities of the bucket by real calls and stores them. Requires `tenant_admin` or `security_officer` (platform profile: `platform_admin`) and the policy decision `storage.profile.verify`. A disabled profile answers 409 `storage_profile_disabled`.\n\nSteps:\n\n1. The credential is resolved from its reference (422 `storage_credential_invalid` when it cannot be read).\n2. The adapter queries the bucket: versioning, object lock, encryption, lifecycle, replication, a multipart upload started then aborted, a presigned request and, with `probe_write`, a probe object written, read back and removed.\n3. The status becomes `verified`, `degraded` (a needed capability is missing) or `failed` (the bucket could not be reached), the check is added to the history and an audit event `storage.profile.verify` is written.\n\nThe answer gives the profile, the status, the missing capabilities, every capability found, the error and the duration in milliseconds.",
    "operationId": "verify_profile_v1_storage_profiles__profile_id__verify_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the storage profile.",
      "in": "path",
      "name": "profile_id",
      "required": true,
      "schema": {
       "title": "Profile Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/eai__domains__storage__routes__VerifyIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Verification options; the body may be omitted."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Verify Profile V1 Storage Profiles  Profile Id  Verify Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Verify the capabilities of a profile",
    "tags": [
     "storage"
    ]
   }
  },
  "/v1/telemetry/logs": {
   "get": {
    "description": "Request journal of the tenant from the span summaries, newest first: one line per span with its time, level (`error` when the span failed, else `info`), service, name, message (error type, or method, route and status code), duration, trace, span, run and kept attributes. Never a prompt or a model output. Requires a tenant principal with `platform_admin`, `tenant_admin`, `auditor`, `viewer` or `support_engineer` (403 `forbidden`). An unknown level or a `from` after `to` answers 400 `invalid_request`.",
    "operationId": "list_logs_v1_telemetry_logs_get",
    "parameters": [
     {
      "description": "Only lines of this level: `error` or `info`.",
      "in": "query",
      "name": "level",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Level"
      }
     },
     {
      "description": "Only spans of this service name (the OpenTelemetry `service.name`), exact match.",
      "in": "query",
      "name": "service",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Service"
      }
     },
     {
      "description": "Only spans of this trace: 32 hexadecimal characters, case insensitive.",
      "in": "query",
      "name": "trace_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Trace Id"
      }
     },
     {
      "description": "Text searched, case insensitive, in the span name and its kept attributes; 128 characters at most.",
      "in": "query",
      "name": "q",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 128,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Q"
      }
     },
     {
      "description": "Start of the window, ISO 8601. Default: one day before `to`.",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "description": "End of the window, ISO 8601. Default: now.",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     },
     {
      "description": "Maximum number of lines, 1 to 1000, default 100.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "maximum": 1000,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Logs V1 Telemetry Logs Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the request journal",
    "tags": [
     "telemetry"
    ]
   }
  },
  "/v1/telemetry/overview": {
   "get": {
    "description": "Dashboard of the tenant over the last `days` days: number of requests (root spans), errors, error rate, p50 and p95 latency in milliseconds, total cost, and per day requests, errors and cost (span costs plus the measured or estimated cost of the LLM usage events). Also says which exporters (Opik, OpenTelemetry, ClickHouse) are configured. The total cost is labelled USD. Requires a tenant principal (403 `tenant_required`).",
    "operationId": "overview_v1_telemetry_overview_get",
    "parameters": [
     {
      "description": "Length of the window in days, default 7; values are brought back between 1 and 366.",
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 7,
       "title": "Days",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Overview V1 Telemetry Overview Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the telemetry overview",
    "tags": [
     "telemetry"
    ]
   }
  },
  "/v1/telemetry/slo": {
   "get": {
    "description": "For each service, over the last `window_minutes` minutes: requests, errors (5xx), requests over the latency target, the latency target and where it comes from (`database` or `settings`), and for availability and latency the target, bad ratio, remaining budget and burn rate. Counts are those of the replica that answers. Requires `platform_admin`, `tenant_admin`, `auditor`, `viewer` or `support_engineer` (403 `forbidden`). A platform administrator reads the whole platform or one tenant; anyone else reads only its own tenant (403 `slo_scope_forbidden` for another one). A window outside 1 to `EAI_SLO_RETENTION_MINUTES` answers 422 `slo_window_invalid`. Each read is audited (`telemetry.slo.read`).",
    "operationId": "slo_v1_telemetry_slo_get",
    "parameters": [
     {
      "description": "Length of the window in minutes, default 60, from 1 to the retention `EAI_SLO_RETENTION_MINUTES`.",
      "in": "query",
      "name": "window_minutes",
      "required": false,
      "schema": {
       "default": 60,
       "title": "Window Minutes",
       "type": "integer"
      }
     },
     {
      "description": "Tenant to read. A platform administrator may omit it for the whole platform; any other caller may only give its own tenant.",
      "in": "query",
      "name": "tenant_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Tenant Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Slo V1 Telemetry Slo Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the SLO error budgets",
    "tags": [
     "telemetry"
    ]
   }
  },
  "/v1/telemetry/slo/targets/{service}": {
   "put": {
    "description": "Objectives of one platform service, written in the database where they override the `EAI_SLO_*` defaults for every replica within 30 seconds. Platform administrator only (403 `forbidden`). An unknown service answers 404 `slo_service_unknown`. The change, with the values before and after and the reason, is audited (`telemetry.slo.target.update`); the answer gives the stored objectives with their version.",
    "operationId": "put_target_v1_telemetry_slo_targets__service__put",
    "parameters": [
     {
      "description": "Service whose objectives are set: `control_plane_api`, `model_gateway`, `tool_gateway` or `realtime`.",
      "in": "path",
      "name": "service",
      "required": true,
      "schema": {
       "title": "Service",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/eai__domains__observability__slo__TargetIn"
       }
      }
     },
     "description": "New availability and latency objectives of the service.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Target V1 Telemetry Slo Targets  Service  Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the objectives of a service",
    "tags": [
     "telemetry"
    ]
   }
  },
  "/v1/telemetry/spans": {
   "post": {
    "description": "Accepts up to 5000 spans and answers 202 with the number accepted, the number stored (a span already known for the same trace and span id is skipped) and the result of each exporter (`ok` or `error`). Requires a tenant principal with `tenant_admin`, `developer` or `agent` (403 `forbidden`).\n\nSteps:\n\n1. The body is flattened: OTLP `resourceSpans` (the service comes from `service.name`) and a plain `spans` list are both read.\n2. Each span is checked: 32 hex trace id, 16 hex span id (and parent), start and end times; otherwise 400 `invalid_request`.\n3. A bounded summary is stored: allow listed attributes only, strings cut to 128 characters, 2 KB of attributes at most, name cut to 256 characters.\n4. An audit event `telemetry.ingest` is written, then the full spans are forwarded, best effort, to Opik, the OpenTelemetry collector and ClickHouse when configured.",
    "operationId": "ingest_v1_telemetry_spans_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Body",
        "type": "object"
       }
      }
     },
     "description": "OTLP JSON export request (`resourceSpans`) or `{spans: [...]}` where each span has `trace_id`, `span_id`, optional `parent_span_id`, `name`, `service`, `start_time`, `end_time` (ISO 8601 or `startTimeUnixNano` / `endTimeUnixNano`), `status`, `attributes`, optional `cost {amount, currency}`, `run_id` and `session_id`.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Ingest V1 Telemetry Spans Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ingest telemetry spans",
    "tags": [
     "telemetry"
    ]
   }
  },
  "/v1/telemetry/stream": {
   "get": {
    "description": "Server-Sent Events (`text/event-stream`) of the tenant: a `metrics` event at every tick (requests, errors, error rate and p95 latency over the last minute), a `trace` event for every new root span and an `incident` event for every incident created or changed. Each event carries an `id:` (a timestamp) the client sends back as `Last-Event-ID` or `since` to resume. The stream closes after `timeout` seconds (the EventSource reconnects after 3 seconds) or after `max_events` events. Requires a tenant principal with `platform_admin`, `tenant_admin`, `auditor`, `viewer` or `support_engineer`.",
    "operationId": "stream_v1_telemetry_stream_get",
    "parameters": [
     {
      "description": "Resume point, ISO 8601: only traces and incidents recorded after it are sent. Default: now. `Last-Event-ID` wins when both are given.",
      "in": "query",
      "name": "since",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Since"
      }
     },
     {
      "description": "Seconds between two polls, 0.05 to 60, default 2.",
      "in": "query",
      "name": "interval",
      "required": false,
      "schema": {
       "default": 2.0,
       "maximum": 60,
       "minimum": 0.05,
       "title": "Interval",
       "type": "number"
      }
     },
     {
      "description": "Seconds after which the server closes the stream, 1 to 3600, default 300.",
      "in": "query",
      "name": "timeout",
      "required": false,
      "schema": {
       "default": 300,
       "maximum": 3600,
       "minimum": 1,
       "title": "Timeout",
       "type": "integer"
      }
     },
     {
      "description": "Close the stream after this many events, 0 to 10000; 0 (default) means no limit.",
      "in": "query",
      "name": "max_events",
      "required": false,
      "schema": {
       "default": 0,
       "maximum": 10000,
       "minimum": 0,
       "title": "Max Events",
       "type": "integer"
      }
     },
     {
      "description": "Standard Server-Sent Events header: the `id` of the last event received, sent back by the browser to resume after a reconnection.",
      "in": "header",
      "name": "Last-Event-ID",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Last-Event-Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Stream live telemetry events",
    "tags": [
     "telemetry"
    ]
   }
  },
  "/v1/telemetry/traces": {
   "get": {
    "description": "Recent traces of the tenant, newest first: one row per root span with its name, service, start, duration, status, run, session and its span and error counts. Requires a tenant principal with `platform_admin`, `tenant_admin`, `auditor`, `viewer` or `support_engineer` (403 `forbidden`). An unknown status or a `from` after `to` answers 400 `invalid_request`.",
    "operationId": "list_traces_v1_telemetry_traces_get",
    "parameters": [
     {
      "description": "Only root spans with this status: `ok`, `error` or `unset`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only traces whose root span belongs to this service name, exact match.",
      "in": "query",
      "name": "service",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Service"
      }
     },
     {
      "description": "Only traces of this agent run.",
      "in": "query",
      "name": "run_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Run Id"
      }
     },
     {
      "description": "Start of the window, ISO 8601. Default: one day before `to`.",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "description": "End of the window, ISO 8601. Default: now.",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     },
     {
      "description": "Maximum number of traces, 1 to 500, default 50.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "maximum": 500,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Traces V1 Telemetry Traces Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the recent traces",
    "tags": [
     "telemetry"
    ]
   }
  },
  "/v1/telemetry/traces/{trace_id}": {
   "get": {
    "description": "Every span of the trace in start order (with cost when known), the span count, total duration in milliseconds, error count, the audit events that carry this trace id, and a link to the trace in Opik when Opik is configured. Requires a tenant principal (403 `tenant_required`). A malformed id answers 400 `invalid_request`; a trace without span nor audit event answers 404 `not_found`.",
    "operationId": "trace_v1_telemetry_traces__trace_id__get",
    "parameters": [
     {
      "description": "Trace identifier: 32 hexadecimal characters (W3C trace context), case insensitive.",
      "in": "path",
      "name": "trace_id",
      "required": true,
      "schema": {
       "title": "Trace Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Trace V1 Telemetry Traces  Trace Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get one trace",
    "tags": [
     "telemetry"
    ]
   }
  },
  "/v1/telephony/active-calls": {
   "get": {
    "description": "Calls in progress of the tenant: `{items, count}`, each item `linkedid`, `call_id`, `navin_call_id`, `branch`, `state` (ringing, queued, answered), `direction`, `from`, `to`, `extension`, `queue`, `started_at`, `answered_at`, `duration_seconds`, `node` and `channels` (`uniqueid`, `channel`, `state`, `node`). Kept up to date by the CEL events (CHAN_START, ANSWER, CHAN_END, LINKEDID_END) and the LiveKit webhooks. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_active_calls_v1_telephony_active_calls_get",
    "parameters": [
     {
      "description": "Only this queue (name without the tid).",
      "in": "query",
      "name": "queue",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Queue"
      }
     },
     {
      "description": "Only this extension number (2 to 8 digits).",
      "in": "query",
      "name": "extension",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "pattern": "^[0-9]{2,8}$",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Extension"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Active Calls V1 Telephony Active Calls Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the active calls",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/active-calls/{linkedid}/hangup": {
   "post": {
    "description": "Hangs up every channel of the call through ARI (`DELETE /ari/channels/{uniqueid}` on the node of each channel), or removes the SIP participant through the LiveKit RoomService for the AI branch. Answers `{linkedid, results}` with one `status` (ok, gone, failed) per channel; 502 `telephony_control_failed` when every channel failed. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.call.hangup`.",
    "operationId": "hangup_call_v1_telephony_active_calls__linkedid__hangup_post",
    "parameters": [
     {
      "description": "Asterisk linkedid of the active call (`linkedid` of `GET /v1/telephony/active-calls`).",
      "in": "path",
      "name": "linkedid",
      "required": true,
      "schema": {
       "title": "Linkedid",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Hangup Call V1 Telephony Active Calls  Linkedid  Hangup Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Hang up an active call",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/active-calls/{linkedid}/transfer": {
   "post": {
    "description": "Transfers a channel of the call: AMI `Redirect` to `{tid}-internal` (extension of the tenant, 422 `telephony_reference_invalid` when it does not exist) or `{tid}-outbound` (E.164 number, the permissions and destination rules of the dialplan apply); for the AI branch, LiveKit `TransferSIPParticipant` (SIP REFER). ARI `continue` and `redirect` are not used: they only act on channels inside a Stasis application. Answers `{linkedid, target, status, via, uniqueid}`; 502 `telephony_control_failed` on a refusal. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.call.transfer`.",
    "operationId": "transfer_call_v1_telephony_active_calls__linkedid__transfer_post",
    "parameters": [
     {
      "description": "Asterisk linkedid of the active call (`linkedid` of `GET /v1/telephony/active-calls`).",
      "in": "path",
      "name": "linkedid",
      "required": true,
      "schema": {
       "title": "Linkedid",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyTransferIn"
       }
      }
     },
     "description": "The target and, optionally, the channel to move.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Transfer Call V1 Telephony Active Calls  Linkedid  Transfer Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Transfer an active call",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/agents": {
   "get": {
    "description": "The human agents of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_agent_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only the enabled (true) or disabled (false) objects. Default: both.",
      "in": "query",
      "name": "enabled",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Enabled"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Agent List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the human agents",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the human agent in the caller's tenant and returns it (201). The extension must belong to the tenant. With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.agent.create`.",
    "operationId": "telephony_agent_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyAgentIn"
       }
      }
     },
     "description": "The human agent.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Agent Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a human agent",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/agents/{item_id}": {
   "delete": {
    "description": "Deletes the human agent (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.agent.delete`.",
    "operationId": "telephony_agent_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a human agent",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One human agent of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_agent_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Agent Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a human agent",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the human agent; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.agent.update`.",
    "operationId": "telephony_agent_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyAgentPatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Agent Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change a human agent",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/blocks": {
   "get": {
    "description": "Blocks of the tenant and of its extensions, newest first: `id`, `scope`, `extension`, `reason`, `origin` (manual, automatic), `alert_id`, `active`, `kamailio_key` (key of the Kamailio hash table `tenant_blocks`), `kamailio` (push report per JSONRPC endpoint), `created_by`, `created_at`, `lifted_by`, `lifted_at`, `lift_reason`. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_blocks_v1_telephony_blocks_get",
    "parameters": [
     {
      "description": "Only the active (true) or lifted (false) blocks.",
      "in": "query",
      "name": "active",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Active"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Blocks V1 Telephony Blocks Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the blocks",
    "tags": [
     "telephony",
     "telephony"
    ]
   },
   "post": {
    "description": "Writes the key `{tid}` or `{tid}-{extension}` into the Kamailio hash table `tenant_blocks` of every JSONRPC endpoint of the pool (`htable.sets`) and answers the block (201); an existing active block of the same scope is answered as is. 422 `telephony_block_scope` when the scope and the extension do not match. The worker job `telephony_blocks` pushes the active blocks again after a Kamailio restart. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.block.create`, published as `telephony.block.created`.",
    "operationId": "create_block_v1_telephony_blocks_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyBlockIn"
       }
      }
     },
     "description": "The scope, the extension and the reason.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Block V1 Telephony Blocks Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Block the tenant or an extension",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/blocks/{block_id}/lift": {
   "post": {
    "description": "Deletes the Kamailio key on every JSONRPC endpoint (`htable.delete`) and marks the block lifted. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.block.lift`, published as `telephony.block.lifted`.",
    "operationId": "lift_block_v1_telephony_blocks__block_id__lift_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the block.",
      "in": "path",
      "name": "block_id",
      "required": true,
      "schema": {
       "title": "Block Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyLiftIn"
       }
      }
     },
     "description": "Why the block is lifted.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Lift Block V1 Telephony Blocks  Block Id  Lift Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Lift a block",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/calls": {
   "get": {
    "description": "Call history of the tenant, newest first. Each item: `id`, `navin_call_id`, `linkedid`, `branch` (pbx or ai), `direction` (inbound, outbound, internal, unknown), `from`, `from_name`, `to`, `did`, `extension`, `queue`, `voice_agent_id`, `started_at`, `answered_at`, `ended_at`, `duration_seconds`, `billsec`, `wait_seconds`, `disposition`, `hangup_cause`, `hangup_cause_text`, `recording_id`, `legs`, `sip_call_id`, `livekit_room`, `pbx_instance_id`, `node`. Built from the Cdr and CEL events of AMI and the LiveKit webhooks. Keyset pagination: `limit` (1 to 500, default 50) and the opaque `cursor` of `next_cursor`. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_calls_v1_telephony_calls_get",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only this direction.",
      "in": "query",
      "name": "direction",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "inbound",
          "outbound",
          "internal",
          "unknown"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Direction"
      }
     },
     {
      "description": "Only this branch: `pbx` (Asterisk) or `ai` (LiveKit SIP).",
      "in": "query",
      "name": "branch",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "pbx",
          "ai"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Branch"
      }
     },
     {
      "description": "Only this extension number (2 to 8 digits).",
      "in": "query",
      "name": "extension",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "pattern": "^[0-9]{2,8}$",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Extension"
      }
     },
     {
      "description": "Only this queue (name without the tid).",
      "in": "query",
      "name": "queue",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Queue"
      }
     },
     {
      "description": "Only the calls whose caller, callee or DID is this number.",
      "in": "query",
      "name": "number",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 32,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Number"
      }
     },
     {
      "description": "Only this disposition of the Asterisk CDR.",
      "in": "query",
      "name": "disposition",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "ANSWERED",
          "NO ANSWER",
          "BUSY",
          "FAILED",
          "CONGESTION"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Disposition"
      }
     },
     {
      "description": "Calls started at or after this time (ISO 8601).",
      "in": "query",
      "name": "since",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Since"
      }
     },
     {
      "description": "Calls started before this time (ISO 8601).",
      "in": "query",
      "name": "until",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Until"
      }
     },
     {
      "description": "true: answered calls only; false: unanswered calls only.",
      "in": "query",
      "name": "answered",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Answered"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Calls V1 Telephony Calls Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the calls",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/calls/{call_id}": {
   "get": {
    "description": "One call with `legs` (one per Asterisk channel, from the Cdr events), `events` (CEL, AMI, LiveKit and voice worker events in time order: `source`, `type`, `occurred_at`, `uniqueid`, `channel`, `node`, `data`) and `recordings` (same fields as `GET /v1/telephony/recordings`). Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_call_v1_telephony_calls__call_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the call record, in the caller's tenant (another tenant's call answers 404).",
      "in": "path",
      "name": "call_id",
      "required": true,
      "schema": {
       "title": "Call Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Call V1 Telephony Calls  Call Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a call",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/calls/{call_id}/events": {
   "post": {
    "description": "Event of a call reported by its voice worker, written into the call events (`voice_agent.<type>`). `started` creates the AI branch call record when no other source announced it; `answered` and `ended` update it and publish `telephony.call.answered` and `telephony.call.ended`; `error` keeps `data.reason`. Answers `{status: recorded or duplicate, call_id}`. Only for a voice worker token: an API key of the tenant with the explicit scope `telephony:voice-worker` (403 `insufficient_scope` otherwise, a wildcard scope does not count); the voice agent and the call must belong to the tenant of the key (404 otherwise). Audited under `telephony.voice_agent.event.<type>`.",
    "operationId": "worker_call_event_v1_telephony_calls__call_id__events_post",
    "parameters": [
     {
      "description": "Call id of the worker job metadata: the call record id, the X-Navin-Call-Id or the LiveKit room name (letters, digits, `-`, `_`, 128 at most).",
      "in": "path",
      "name": "call_id",
      "required": true,
      "schema": {
       "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
       "title": "Call Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyWorkerEventIn"
       }
      }
     },
     "description": "The event.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Worker Call Event V1 Telephony Calls  Call Id  Events Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Report a call event",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/calls/{call_id}/tools/{name}": {
   "post": {
    "description": "Runs a lookup tool of the voice agent through the tool gateway of the platform (scopes, policy, DLP, approvals and invocation log): the name must start with `lookup_` and be in `allowed_tools` of the agent, and a tool of the registry must carry this name (or the name with `-` instead of `_`), else 403 `telephony_tool_not_allowed`. The key also needs the scope `tools:invoke`. Answers `{result}` (text, 8000 characters at most); 502 `telephony_tool_failed`. Only for a voice worker token: an API key of the tenant with the explicit scope `telephony:voice-worker` (403 `insufficient_scope` otherwise, a wildcard scope does not count); the voice agent and the call must belong to the tenant of the key (404 otherwise). Audited under `telephony.voice_agent.tool`.",
    "operationId": "worker_call_tool_v1_telephony_calls__call_id__tools__name__post",
    "parameters": [
     {
      "description": "Call id of the worker job metadata: the call record id, the X-Navin-Call-Id or the LiveKit room name (letters, digits, `-`, `_`, 128 at most).",
      "in": "path",
      "name": "call_id",
      "required": true,
      "schema": {
       "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
       "title": "Call Id",
       "type": "string"
      }
     },
     {
      "description": "Name of the lookup tool (`lookup_...`).",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "pattern": "^[a-z][a-z0-9_]{0,63}$",
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyWorkerToolIn"
       }
      }
     },
     "description": "The voice agent and the arguments of the tool.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Worker Call Tool V1 Telephony Calls  Call Id  Tools  Name  Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Run a lookup tool",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/calls/{call_id}/transfer": {
   "post": {
    "description": "Transfers the SIP participant of the call with LiveKit `TransferSIPParticipant` (SIP REFER). `target_uri` must be the transfer target of the voice agent (422 `telephony_worker_transfer_target`). Answers `{call_id, status, via, transfer_to}`; 502 `telephony_control_failed` when LiveKit refuses or the call has no SIP participant. Only for a voice worker token: an API key of the tenant with the explicit scope `telephony:voice-worker` (403 `insufficient_scope` otherwise, a wildcard scope does not count); the voice agent and the call must belong to the tenant of the key (404 otherwise). Audited under `telephony.voice_agent.transfer`.",
    "operationId": "worker_call_transfer_v1_telephony_calls__call_id__transfer_post",
    "parameters": [
     {
      "description": "Call id of the worker job metadata: the call record id, the X-Navin-Call-Id or the LiveKit room name (letters, digits, `-`, `_`, 128 at most).",
      "in": "path",
      "name": "call_id",
      "required": true,
      "schema": {
       "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
       "title": "Call Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyWorkerTransferIn"
       }
      }
     },
     "description": "The voice agent, the reason and the target URI.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Worker Call Transfer V1 Telephony Calls  Call Id  Transfer Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Transfer a call to a human",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/conference-sessions": {
   "get": {
    "description": "Sessions of the conference rooms of the tenant, from the Confbridge events of AMI, newest first: `id`, `conference_id`, `number`, `started_at`, `ended_at`, `active`, `participant_count`, `max_participants`, `total_joins`, `participants` (`uniqueid`, `channel`, `caller`, `name`, `joined_at`), `recorded`, `recording_id`. Keyset pagination: `limit` (1 to 500, default 50) and the opaque `cursor` of `next_cursor`. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_conference_sessions_v1_telephony_conference_sessions_get",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only the sessions of this conference room.",
      "in": "query",
      "name": "conference_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "uuid",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Conference Id"
      }
     },
     {
      "description": "true: sessions in progress; false: ended sessions.",
      "in": "query",
      "name": "active",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Active"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Conference Sessions V1 Telephony Conference Sessions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the conference sessions",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/conference-sessions/{session_id}": {
   "get": {
    "description": "One conference session with its participants (same fields as the list). Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_conference_session_v1_telephony_conference_sessions__session_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the conference session.",
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Conference Session V1 Telephony Conference Sessions  Session Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a conference session",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/conferences": {
   "get": {
    "description": "The conference rooms of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_conference_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Conference List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the conference rooms",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the conference room in the caller's tenant and returns it (201). The PIN is write only: the answer carries `has_pin`. With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.conference.create`.",
    "operationId": "telephony_conference_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyConferenceIn"
       }
      }
     },
     "description": "The conference room.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Conference Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a conference room",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/conferences/{item_id}": {
   "delete": {
    "description": "Deletes the conference room (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.conference.delete`.",
    "operationId": "telephony_conference_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a conference room",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One conference room of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_conference_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Conference Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a conference room",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the conference room; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.conference.update`.",
    "operationId": "telephony_conference_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyConferencePatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Conference Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change a conference room",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/config-versions/{version_id}": {
   "get": {
    "description": "One version with its files (secrets masked), Kamailio tables, LiveKit objects, delivery report per node (files read back and compared, reload outputs, restore), status and `diff` to the previous version. 404 when the caller may not read its pool.",
    "operationId": "get_version_v1_telephony_config_versions__version_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the configuration version.",
      "in": "path",
      "name": "version_id",
      "required": true,
      "schema": {
       "title": "Version Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Version V1 Telephony Config Versions  Version Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a configuration version",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/event-streams": {
   "get": {
    "description": "State of the AMI event connection of every node (worker job `telephony_events`): `pool_id`, `node`, `connected`, `connected_at`, `events`, `reconnects`, `last_error`, `updated_at`. Needs `platform_admin`.",
    "operationId": "list_event_streams_v1_telephony_event_streams_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Event Streams V1 Telephony Event Streams Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the AMI event connections",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/extensions": {
   "get": {
    "description": "The extensions of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_extension_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only the enabled (true) or disabled (false) objects. Default: both.",
      "in": "query",
      "name": "enabled",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Enabled"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Extension List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the extensions",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the extension in the caller's tenant and returns it (201). The SIP password and the voicemail PIN are write only: the answer carries `has_password` and `has_voicemail_pin`. The number is unique in the tenant across extensions, queues and conferences (409 `telephony_number_in_use`) and may not start with a national or international prefix nor be an emergency number (422 `telephony_number_reserved`). With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.extension.create`.",
    "operationId": "telephony_extension_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyExtensionIn"
       }
      }
     },
     "description": "The extension.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Extension Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an extension",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/extensions/{item_id}": {
   "delete": {
    "description": "Deletes the extension (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.extension.delete`.",
    "operationId": "telephony_extension_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an extension",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One extension of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_extension_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Extension Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read an extension",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the extension; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.extension.update`.",
    "operationId": "telephony_extension_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyExtensionPatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Extension Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change an extension",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/fraud-alerts": {
   "get": {
    "description": "Fraud signals of the tenant, newest first: `id`, `kind` (`cps`, `concurrency`, `destination_refused`, `extension_volume`), `severity`, `extension`, `destination`, `linkedid`, `details`, `status`, `block_id`, `created_at`, `acknowledged_at`, `acknowledged_by`. Each alert is also published as `telephony.fraud.alert`. Keyset pagination: `limit` (1 to 500, default 50) and the opaque `cursor` of `next_cursor`. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_fraud_alerts_v1_telephony_fraud_alerts_get",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only the open or the acknowledged alerts.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "open",
          "acknowledged"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only this kind of signal.",
      "in": "query",
      "name": "kind",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "cps",
          "concurrency",
          "destination_refused",
          "extension_volume"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Kind"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Fraud Alerts V1 Telephony Fraud Alerts Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the fraud alerts",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/fraud-alerts/{alert_id}/acknowledge": {
   "post": {
    "description": "Marks the alert acknowledged and answers it. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.fraud.acknowledge`.",
    "operationId": "acknowledge_alert_v1_telephony_fraud_alerts__alert_id__acknowledge_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the fraud alert.",
      "in": "path",
      "name": "alert_id",
      "required": true,
      "schema": {
       "title": "Alert Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Acknowledge Alert V1 Telephony Fraud Alerts  Alert Id  Acknowledge Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Acknowledge a fraud alert",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/infrastructure": {
   "get": {
    "description": "Reads, through the Platform Manager bridge (Manager API token, `X-NM-On-Behalf-Of`, the permissions of the Manager apply), the clusters and their `asterisk`, `kamailio`, `livekit` and `livekit-sip` instances. Answers `{clusters, binding, problems}`: each cluster `{id, name, mode, services}`, each service `{name, catalog_service, display_name, mode, method, version, managed, state, health, admin_state, tls_enabled, config_source (manager or defaults), config_version, bound, endpoints [{name, scheme, port, path}], nodes [{name, instance_id, host_id, hostname, fqdn, ip, component, state, desired_state, health, maintenance, host_state, addresses}], bindings {binding: {ref, kind}}, pool ({id, name, mode} of the PBX pool linked to an Asterisk instance, else null)}`. Asterisk addresses `ami`, `ari`, `sip`; Kamailio `jsonrpc` (`/RPC`, admin address of the host group), `sip`, `wss` with TLS; LiveKit `api`, `signal`; LiveKit SIP `sip`. `bound` is true for the instance bound to navin-enterprise. `binding` gives flags only (`cluster_id`, `asterisk.bound`, `asterisk.ami_secret`, `asterisk.ari_secret`, `kamailio.bound`, `kamailio.ephemeral_secret`, `livekit.bound`, `livekit.api_secret`, `livekit_sip.bound`), never a value. `problems` lists the instances whose configuration the Manager refused (`telephony_inventory_config_unreadable`, catalog defaults used). Needs `platform_admin`; 503 `platform_manager_not_configured`, 502 `platform_manager_unreachable`, a refusal of the Manager is relayed.",
    "operationId": "infrastructure_v1_telephony_infrastructure_get",
    "parameters": [
     {
      "description": "Only this cluster of the Manager (its identifier).",
      "in": "query",
      "name": "cluster_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 64,
         "pattern": "^[A-Za-z0-9_-]{1,64}$",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cluster Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Infrastructure V1 Telephony Infrastructure Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the telephony infrastructure of the Navin Manager",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/infrastructure/pools": {
   "post": {
    "description": "Creates (201) or refreshes (200) the PBX pool linked to an Asterisk instance of the Manager (`manager_cluster`, `manager_service`): nodes (host, AMI port, SIP address, Manager instance, ARI URL), `ami_tls`, Kamailio JSONRPC endpoints and addresses (the Kamailio instances bound to this Asterisk, or `kamailio_service`), `livekit_binding` (`url`, `sip_host`), AMI and ARI user names and the references of the secrets. A secret of the instance bound to navin-enterprise becomes `env://EAI_CRED_TELEPHONY_AMI_SECRET`, `env://EAI_CRED_TELEPHONY_ARI_PASSWORD` or `env://EAI_CRED_TELEPHONY_EPHEMERAL_SECRET` (variables rendered by the Manager in the sensitive environment file), a reference already on the pool is kept, never a value. Idempotent: the same inventory changes nothing (`changed: []`). Answers `{created, changed, pool, secrets {ami, ari, ephemeral: bound, kept or missing}, sources {cluster_id, asterisk, kamailio, livekit, livekit_sip}, problems}`. Errors: 404 `telephony_inventory_not_found`, 409 `telephony_inventory_no_nodes`, 422 `telephony_inventory_too_large`, the pool rules (422 `telephony_pool_mode`, 409 `telephony_name_taken`). Needs `platform_admin`; audited under `telephony.pbx_pool.sync` (plus `telephony.pbx_pool.create` or `telephony.pbx_pool.update`).",
    "operationId": "sync_from_inventory_v1_telephony_infrastructure_pools_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyInventorySyncIn"
       }
      }
     },
     "description": "The Asterisk instance of the Manager and the options of a new pool.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Sync From Inventory V1 Telephony Infrastructure Pools Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create or refresh a PBX pool from the Manager inventory",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/ivr-flows": {
   "get": {
    "description": "The IVR flows of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_ivr_flow_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Ivr Flow List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the IVR flows",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the IVR flow in the caller's tenant and returns it (201). The graph lives in the versions of the flow. With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.ivr_flow.create`.",
    "operationId": "telephony_ivr_flow_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyIvrFlowIn"
       }
      }
     },
     "description": "The IVR flow.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Ivr Flow Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an IVR flow",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/ivr-flows/{flow_id}/versions": {
   "get": {
    "description": "Versions of the flow with their status (`draft`, `published`, `archived`) and graph, by identifier. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_ivr_versions_v1_telephony_ivr_flows__flow_id__versions_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the IVR flow.",
      "in": "path",
      "name": "flow_id",
      "required": true,
      "schema": {
       "title": "Flow Id",
       "type": "string"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Ivr Versions V1 Telephony Ivr Flows  Flow Id  Versions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the versions of an IVR flow",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Adds a draft version (number + 1). The graph is validated: one `start` node, every edge names an existing node, every node reachable, unique DTMF digits, every menu with prompt, `timeout` and `invalid` exits, a wait of 1 to 30 seconds and 1 to 5 retries; the extensions, queues and voice agents it names exist in the tenant. The `prompt` of a play or menu node is a sound name of Asterisk or `navin:<name>`, an uploaded prompt of the tenant (POST /v1/telephony/ivr-prompts) the dialplan plays from its signed URL. Problems answer 422 with every one in `details.errors`. Needs `tenant_admin` or `platform_admin`; audited under `telephony.ivr_flow.version.create`.",
    "operationId": "create_ivr_version_v1_telephony_ivr_flows__flow_id__versions_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the IVR flow.",
      "in": "path",
      "name": "flow_id",
      "required": true,
      "schema": {
       "title": "Flow Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyIvrVersionIn"
       }
      }
     },
     "description": "The graph: `start` (node id) and `nodes` (id to node with `type` start, play, menu, time_condition, transfer, voicemail, queue, voice_agent or hangup).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Ivr Version V1 Telephony Ivr Flows  Flow Id  Versions Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a version of an IVR flow",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/ivr-flows/{flow_id}/versions/{version}": {
   "get": {
    "description": "One version of the flow with its graph; 404 `telephony_not_found` otherwise. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_ivr_version_v1_telephony_ivr_flows__flow_id__versions__version__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the IVR flow.",
      "in": "path",
      "name": "flow_id",
      "required": true,
      "schema": {
       "title": "Flow Id",
       "type": "string"
      }
     },
     {
      "description": "Version number (1, 2, ...).",
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "title": "Version",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Ivr Version V1 Telephony Ivr Flows  Flow Id  Versions  Version  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a version of an IVR flow",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/ivr-flows/{flow_id}/versions/{version}/publish": {
   "post": {
    "description": "Validates the version again and makes it the one the compiler uses; the previously published version is archived. The engines get it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.ivr_flow.version.publish`.",
    "operationId": "publish_ivr_version_v1_telephony_ivr_flows__flow_id__versions__version__publish_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the IVR flow.",
      "in": "path",
      "name": "flow_id",
      "required": true,
      "schema": {
       "title": "Flow Id",
       "type": "string"
      }
     },
     {
      "description": "Version number (1, 2, ...).",
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "title": "Version",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Publish Ivr Version V1 Telephony Ivr Flows  Flow Id  Versions  Version  Publish Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Publish a version of an IVR flow",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/ivr-flows/{item_id}": {
   "delete": {
    "description": "Deletes the IVR flow (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.ivr_flow.delete`.",
    "operationId": "telephony_ivr_flow_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an IVR flow",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One IVR flow of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_ivr_flow_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Ivr Flow Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read an IVR flow",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the IVR flow; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.ivr_flow.update`.",
    "operationId": "telephony_ivr_flow_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyIvrFlowPatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Ivr Flow Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change an IVR flow",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/ivr-prompts": {
   "get": {
    "description": "IVR prompts of the tenant, newest first (fields of the upload answer, `playback_url` empty). Keyset pagination: `limit` (1 to 500, default 50) and the opaque `cursor` of `next_cursor`. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_prompts_v1_telephony_ivr_prompts_get",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Prompts V1 Telephony Ivr Prompts Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the IVR prompts",
    "tags": [
     "telephony",
     "telephony"
    ]
   },
   "post": {
    "description": "Raw body: a PCM WAV file (`Content-Type: audio/wav`, 415 `telephony_prompt_type` otherwise, 413 `telephony_prompt_size` above 10 MB, 422 `telephony_prompt_invalid` when it is not readable, 422 `telephony_prompt_format` when it is not 8000 Hz, 16 bit, mono, the only WAV the `wav` format of Asterisk reads). The file goes through the file security pipeline (422 `file_blocked`, 503 `file_scan_unavailable`), is stored in the category `ivr-prompts` (no expiry) and answers 201 with `id`, `name`, `recording_id`, `content_type`, `size_bytes`, `sha256`, `duration_seconds`, `scan_id`, `created_at` and `playback_url`, the signed URL an IVR plays. 409 `telephony_name_taken` when the name is used. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.ivr_prompt.create`.",
    "operationId": "upload_prompt_v1_telephony_ivr_prompts_post",
    "parameters": [
     {
      "description": "Name of the prompt, unique in the tenant (lowercase letters, digits, `-`).",
      "in": "query",
      "name": "name",
      "required": true,
      "schema": {
       "pattern": "^[a-z0-9][a-z0-9-]{0,40}$",
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "audio/wav": {
       "schema": {
        "format": "binary",
        "type": "string"
       }
      }
     },
     "description": "The audio of the prompt (PCM WAV).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Upload Prompt V1 Telephony Ivr Prompts Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Upload an IVR prompt",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/ivr-prompts/{prompt_id}": {
   "delete": {
    "description": "Deletes the prompt and its audio (204); its playback URL answers 404 from then on. 409 `telephony_prompt_in_use` (with `details.ivr_flows`) while a draft or published IVR version plays it. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.ivr_prompt.delete`.",
    "operationId": "delete_prompt_v1_telephony_ivr_prompts__prompt_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the IVR prompt.",
      "in": "path",
      "name": "prompt_id",
      "required": true,
      "schema": {
       "title": "Prompt Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an IVR prompt",
    "tags": [
     "telephony",
     "telephony"
    ]
   },
   "get": {
    "description": "One IVR prompt; `playback_url` is filled for `tenant_admin` and `platform_admin` only. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_prompt_v1_telephony_ivr_prompts__prompt_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the IVR prompt.",
      "in": "path",
      "name": "prompt_id",
      "required": true,
      "schema": {
       "title": "Prompt Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Prompt V1 Telephony Ivr Prompts  Prompt Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read an IVR prompt",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/ivr-prompts/{prompt_id}/download": {
   "post": {
    "description": "Answers `{url, method: GET, expires_seconds: 300, expires_at, content_type, size_bytes, sha256}`: a SeaweedFS presigned URL valid 300 seconds; no storage credential is returned. 409 `telephony_recording_unavailable` when the object is not stored, 503 `telephony_storage_missing` when the platform profile is missing, 409 `storage_capability_missing` when presign was not verified. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`. Audited under `telephony.ivr_prompt.download`.",
    "operationId": "download_prompt_v1_telephony_ivr_prompts__prompt_id__download_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the IVR prompt.",
      "in": "path",
      "name": "prompt_id",
      "required": true,
      "schema": {
       "title": "Prompt Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Download Prompt V1 Telephony Ivr Prompts  Prompt Id  Download Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a download link of an IVR prompt",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/livekit/webhook": {
   "post": {
    "description": "Entry point of the LiveKit server, without platform authentication: the `Authorization` header carries the JWT LiveKit signs with its API key and secret, whose `sha256` claim must be the base64 SHA-256 of the raw body (401 `invalid_signature` otherwise). Handled events: `participant_joined` and `participant_left` of SIP participants (AI branch call record, active call, `telephony.call.*` events; linked to the PBX call by the attribute `navin.call_id` when the call came through Asterisk) and `egress_ended` (the files of LiveKit Egress are indexed and copied into the tenant layout). The tenant is the one whose tid prefixes the room; an attribute `navin.tenant_id` naming another tenant answers 422 `telephony_tenant_mismatch`. A delivery seen before answers `duplicate`.",
    "operationId": "livekit_webhook_v1_telephony_livekit_webhook_post",
    "requestBody": {
     "content": {
      "application/webhook+json": {
       "schema": {
        "type": "object"
       }
      }
     },
     "description": "The LiveKit WebhookEvent (JSON).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Receive a LiveKit webhook",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/media/prompts/{tenant_id}/{prompt_file}": {
   "get": {
    "description": "Audio (`audio/wav`) of an IVR prompt for Asterisk: the dialplan plays the `playback_url` with `Playback(https://...)` (res_http_media_cache with res_curl). No session: the URL carries an HMAC-SHA256 of the tenant, the prompt and its SHA-256 made with a key of the tenant kept in the vault; a wrong signature, another tenant or a deleted prompt answer 404.",
    "operationId": "play_prompt_v1_telephony_media_prompts__tenant_id___prompt_file__get",
    "parameters": [
     {
      "description": "Tenant of the prompt (UUID).",
      "in": "path",
      "name": "tenant_id",
      "required": true,
      "schema": {
       "title": "Tenant Id",
       "type": "string"
      }
     },
     {
      "description": "`<prompt id>.wav`.",
      "in": "path",
      "name": "prompt_file",
      "required": true,
      "schema": {
       "title": "Prompt File",
       "type": "string"
      }
     },
     {
      "description": "HMAC-SHA256 signature of the URL (64 hexadecimal characters).",
      "in": "query",
      "name": "sig",
      "required": true,
      "schema": {
       "pattern": "^[0-9a-f]{64}$",
       "title": "Sig",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "audio/wav": {
        "schema": {
         "format": "binary",
         "type": "string"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Play an IVR prompt",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/numbers": {
   "get": {
    "description": "The phone numbers of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_number_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only the enabled (true) or disabled (false) objects. Default: both.",
      "in": "query",
      "name": "enabled",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Enabled"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Number List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the phone numbers",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the phone number in the caller's tenant and returns it (201). The E.164 number is unique on the platform (409 `telephony_number_taken`); the destination must be an object of the tenant (422 `telephony_reference_invalid`); branch `ai` needs a voice agent. With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.number.create`.",
    "operationId": "telephony_number_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyNumberIn"
       }
      }
     },
     "description": "The phone number.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Number Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a phone number",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/numbers/{item_id}": {
   "delete": {
    "description": "Deletes the phone number (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.number.delete`.",
    "operationId": "telephony_number_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a phone number",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One phone number of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_number_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Number Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a phone number",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the phone number; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.number.update`.",
    "operationId": "telephony_number_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyNumberPatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Number Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change a phone number",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/pbx-pools": {
   "get": {
    "description": "Every pool for `platform_admin`; for the other readers the shared pools and the pools dedicated to their tenant, with `id`, `name`, `mode`, `tenant_id`, `enabled` and `dispatcher_set` only. Secret references are never returned to them; `has_*` flags tell whether a secret is set. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_pools_v1_telephony_pbx_pools_get",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Pools V1 Telephony Pbx Pools Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the PBX pools",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Declares an Asterisk pool installed by the Navin Manager: nodes and their AMI port, references of the AMI, ARI, JSONRPC and auth_ephemeral secrets (`openbao://` or `env://EAI_CRED_*`, never a value), Kamailio endpoints and addresses, dispatcher sets and LiveKit binding. A shared pool has no tenant, a dedicated pool one (422 `telephony_pool_mode`). Needs `platform_admin`; audited under `telephony.pbx_pool.create`.",
    "operationId": "create_pool_v1_telephony_pbx_pools_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyPoolIn"
       }
      }
     },
     "description": "The pool.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Pool V1 Telephony Pbx Pools Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Declare a PBX pool",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/pbx-pools/{pool_id}": {
   "delete": {
    "description": "Deletes a pool no tenant uses (409 `telephony_pool_in_use` otherwise) with its versions. Needs `platform_admin`; audited under `telephony.pbx_pool.delete`.",
    "operationId": "delete_pool_v1_telephony_pbx_pools__pool_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a PBX pool",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One pool visible to the caller (404 otherwise), limited fields except for `platform_admin`. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_pool_v1_telephony_pbx_pools__pool_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Pool V1 Telephony Pbx Pools  Pool Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a PBX pool",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields of the pool. Needs `platform_admin`; audited under `telephony.pbx_pool.update`.",
    "operationId": "update_pool_v1_telephony_pbx_pools__pool_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyPoolPatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Update Pool V1 Telephony Pbx Pools  Pool Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change a PBX pool",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/pbx-pools/{pool_id}/drain": {
   "post": {
    "description": "Sets the state of a destination on every Kamailio of the pool (`dispatcher.set_state`: `drain` inactive, `active` back in service) and returns the `dispatcher.list` of each. Needs `platform_admin`; audited under `telephony.pbx_pool.drain` or `telephony.pbx_pool.active`.",
    "operationId": "drain_destination_v1_telephony_pbx_pools__pool_id__drain_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyDrainIn"
       }
      }
     },
     "description": "The destination and its new state.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Drain Destination V1 Telephony Pbx Pools  Pool Id  Drain Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Drain or restore a dispatcher destination",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/pbx-pools/{pool_id}/preview": {
   "post": {
    "description": "Compiles every tenant of the pool and validates the result (graphs, references, no context of a tenant naming another tenant, a SIP domain for every tenant with extensions: `telephony_sip_domain_missing` otherwise), without delivery. Returns `valid`, `errors`, `files` (secrets masked), `kamailio`, `livekit`, `sha256`, `tenants`, `current_version`, `unchanged` and `diff` (unified diff per file to the published version). Shared pool: `platform_admin`; dedicated pool: its `tenant_admin`.",
    "operationId": "preview_pool_v1_telephony_pbx_pools__pool_id__preview_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Preview Pool V1 Telephony Pbx Pools  Pool Id  Preview Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Preview the configuration of a pool",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/pbx-pools/{pool_id}/publish": {
   "post": {
    "description": "Compiles and validates the pool (422 with every problem, `telephony_sip_domain_missing` for a tenant with extensions but no SIP domain), records a new version (`publishing`) and answers 202 with `version_id`, `version`, `sha256` and `operation_id` (headers `Operation-Id`, `Operation-Location`). In the background every node of the pool gets the files through AMI (CreateConfig, UpdateConfig, reloads, GetConfig read back), then the Kamailio tables and the LiveKit SIP objects are reconciled. The version ends `published` or `failed` (the failed nodes get the previous version back); follow it with `GET /v1/telephony/config-versions/{version_id}` or the operation. One publication at a time per pool (409 `telephony_publication_running`). `Idempotency-Key` honoured. Shared pool: `platform_admin`; dedicated pool: its `tenant_admin`. Audited under `telephony.config.publish` then `telephony.config.published` or `telephony.config.failed`.",
    "operationId": "publish_pool_v1_telephony_pbx_pools__pool_id__publish_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     },
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyPublishIn"
       }
      }
     },
     "description": "Why the configuration is published.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Publish Pool V1 Telephony Pbx Pools  Pool Id  Publish Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Publish the configuration of a pool",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/pbx-pools/{pool_id}/reconcile": {
   "post": {
    "description": "Compares the Kamailio hash tables and the LiveKit SIP trunks and dispatch rules with the published version and fixes the differences (idempotent: nothing changes when they match). A Kamailio whose `core.uptime` went down restarted and gets every entry again (`full_resync`). 409 `telephony_nothing_published` before the first publication. Same roles as the publication; audited under `telephony.config.reconcile`.",
    "operationId": "reconcile_pool_v1_telephony_pbx_pools__pool_id__reconcile_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Reconcile Pool V1 Telephony Pbx Pools  Pool Id  Reconcile Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Reconcile the routing of a pool",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/pbx-pools/{pool_id}/rollback": {
   "post": {
    "description": "Publishes the files, tables and LiveKit objects of an earlier `published` or `rolled_back` version again as a new version (`rollback_of`), as a long operation like the publication (202). Once published, the later versions become `rolled_back`. 409 `telephony_rollback_target` for another status. Same roles as the publication; audited under `telephony.config.rollback`.",
    "operationId": "rollback_pool_v1_telephony_pbx_pools__pool_id__rollback_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     },
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyRollbackIn"
       }
      }
     },
     "description": "The version to publish again and why.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Rollback Pool V1 Telephony Pbx Pools  Pool Id  Rollback Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Roll a pool back to a version",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/pbx-pools/{pool_id}/versions": {
   "get": {
    "description": "Versions of the pool, newest first, with status, author, reason, `sha256`, the SHA-256 of every file, `current` (the version the engines run) and the delivery report; `next_cursor` pages by version number. Shared pool: `platform_admin`; dedicated pool: the readers of its tenant.",
    "operationId": "list_versions_v1_telephony_pbx_pools__pool_id__versions_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the PBX pool.",
      "in": "path",
      "name": "pool_id",
      "required": true,
      "schema": {
       "title": "Pool Id",
       "type": "string"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Versions V1 Telephony Pbx Pools  Pool Id  Versions Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the configuration versions of a pool",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/preview": {
   "post": {
    "description": "Compiles the configuration of the caller's tenant alone and validates it, without any delivery: `valid`, `errors` (code, path, messages), the five Asterisk files with secrets masked, the Kamailio entries, the desired LiveKit objects and `sha256`. 409 `telephony_not_configured` without settings. Needs `tenant_admin` or `platform_admin`.",
    "operationId": "preview_tenant_v1_telephony_preview_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Preview Tenant V1 Telephony Preview Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Preview the configuration of the tenant",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/queues": {
   "get": {
    "description": "The call queues of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_queue_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Queue List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the call queues",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the call queue in the caller's tenant and returns it (201). Its optional number follows the extension number rules. With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.queue.create`.",
    "operationId": "telephony_queue_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyQueueIn"
       }
      }
     },
     "description": "The call queue.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Queue Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a call queue",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/queues/{item_id}": {
   "delete": {
    "description": "Deletes the call queue (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.queue.delete`.",
    "operationId": "telephony_queue_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a call queue",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One call queue of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_queue_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Queue Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a call queue",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the call queue; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.queue.update`.",
    "operationId": "telephony_queue_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyQueuePatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Queue Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change a call queue",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/queues/{queue_id}/members": {
   "get": {
    "description": "Extensions and human agents of the queue with their penalty. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_members_v1_telephony_queues__queue_id__members_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the queue.",
      "in": "path",
      "name": "queue_id",
      "required": true,
      "schema": {
       "title": "Queue Id",
       "type": "string"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Members V1 Telephony Queues  Queue Id  Members Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the members of a queue",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Adds exactly one extension or human agent of the tenant (422 `telephony_member_target` or `telephony_reference_invalid`). `Idempotency-Key` honoured. Needs `tenant_admin` or `platform_admin`; audited under `telephony.queue_member.create`.",
    "operationId": "add_member_v1_telephony_queues__queue_id__members_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the queue.",
      "in": "path",
      "name": "queue_id",
      "required": true,
      "schema": {
       "title": "Queue Id",
       "type": "string"
      }
     },
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyMemberIn"
       }
      }
     },
     "description": "The member and its penalty.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Add Member V1 Telephony Queues  Queue Id  Members Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Add a member to a queue",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/queues/{queue_id}/members/{member_id}": {
   "delete": {
    "description": "Removes the member (204). Needs `tenant_admin` or `platform_admin`; audited under `telephony.queue_member.delete`.",
    "operationId": "remove_member_v1_telephony_queues__queue_id__members__member_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the queue.",
      "in": "path",
      "name": "queue_id",
      "required": true,
      "schema": {
       "title": "Queue Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the queue member.",
      "in": "path",
      "name": "member_id",
      "required": true,
      "schema": {
       "title": "Member Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Remove a member from a queue",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Sets the penalty of the member (0 rings first). Needs `tenant_admin` or `platform_admin`; audited under `telephony.queue_member.update`.",
    "operationId": "update_member_v1_telephony_queues__queue_id__members__member_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the queue.",
      "in": "path",
      "name": "queue_id",
      "required": true,
      "schema": {
       "title": "Queue Id",
       "type": "string"
      }
     },
     {
      "description": "Identifier (UUID) of the queue member.",
      "in": "path",
      "name": "member_id",
      "required": true,
      "schema": {
       "title": "Member Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyMemberPatch"
       }
      }
     },
     "description": "The new penalty.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Update Member V1 Telephony Queues  Queue Id  Members  Member Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change the penalty of a queue member",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/quotas": {
   "get": {
    "description": "Quotas and fraud limits of the tenant (defaults with `configured: false` when never set): concurrent calls and calls per second (pushed to Kamailio `tenant_limits`), monthly minutes, allowed countries, premium prefixes, maximum call duration (dialplan) and recording retention. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_quotas_v1_telephony_quotas_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Quotas V1 Telephony Quotas Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the telephony quotas",
    "tags": [
     "telephony"
    ]
   },
   "put": {
    "description": "Replaces the quotas of the tenant. Prefixes are `+` then 1 to 8 digits (422 `telephony_prefix_invalid`). Needs `platform_admin`: a tenant never raises its own limits. Audited under `telephony.quotas.update`.",
    "operationId": "put_quotas_v1_telephony_quotas_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyQuotasIn"
       }
      }
     },
     "description": "The complete quotas; omitted fields take their default.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Quotas V1 Telephony Quotas Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the telephony quotas",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/recordings": {
   "get": {
    "description": "Index of the telephony objects of the tenant in SeaweedFS, newest first. Each item: `id`, `category`, `status` (pending, stored, failed, deleted), `source` (asterisk, livekit, upload, export), `content_type`, `size_bytes`, `sha256`, `duration_seconds`, `encryption` (what the backend reported, and `profile_mode`), `call_record_id`, `navin_call_id`, `retention_until`, `legal_hold`, `created_at`, `stored_at`, `deleted_at`, `last_error`. The object key is never returned. Keyset pagination: `limit` (1 to 500, default 50) and the opaque `cursor` of `next_cursor`. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "list_recordings_v1_telephony_recordings_get",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only this category of the layout.",
      "in": "query",
      "name": "category",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "call-recordings",
          "voicemail",
          "ivr-prompts",
          "conference-recordings",
          "ai-voice-recordings",
          "audio-exports"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Category"
      }
     },
     {
      "description": "Only this status.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "pending",
          "stored",
          "failed",
          "deleted"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only the recordings of this call record.",
      "in": "query",
      "name": "call_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "uuid",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Call Id"
      }
     },
     {
      "description": "Only the recordings with (true) or without (false) legal hold.",
      "in": "query",
      "name": "legal_hold",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Legal Hold"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Recordings V1 Telephony Recordings Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the recordings",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/recordings/{recording_id}": {
   "delete": {
    "description": "Deletes the object in SeaweedFS and marks the index row `deleted` (a voicemail message on it is deleted too). 409 `telephony_legal_hold` under legal hold. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.recording.delete` with the reason.",
    "operationId": "delete_recording_v1_telephony_recordings__recording_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the recording, in the caller's tenant (another tenant's recording answers 404).",
      "in": "path",
      "name": "recording_id",
      "required": true,
      "schema": {
       "title": "Recording Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/TelephonyDeleteIn"
         },
         {
          "type": "null"
         }
        ],
        "title": "Body"
       }
      }
     },
     "description": "Optional reason kept in the audit trail."
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Recording V1 Telephony Recordings  Recording Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a recording",
    "tags": [
     "telephony",
     "telephony"
    ]
   },
   "get": {
    "description": "One recording of the index (same fields as the list). Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_recording_v1_telephony_recordings__recording_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the recording, in the caller's tenant (another tenant's recording answers 404).",
      "in": "path",
      "name": "recording_id",
      "required": true,
      "schema": {
       "title": "Recording Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Recording V1 Telephony Recordings  Recording Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a recording",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/recordings/{recording_id}/download": {
   "post": {
    "description": "Answers `{url, method: GET, expires_seconds: 300, expires_at, content_type, size_bytes, sha256}`: a SeaweedFS presigned URL valid 300 seconds; no storage credential is returned. 409 `telephony_recording_unavailable` when the object is not stored, 503 `telephony_storage_missing` when the platform profile is missing, 409 `storage_capability_missing` when presign was not verified. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`. Audited under `telephony.recording.download` with the SHA-256 of the URL.",
    "operationId": "download_recording_v1_telephony_recordings__recording_id__download_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the recording, in the caller's tenant (another tenant's recording answers 404).",
      "in": "path",
      "name": "recording_id",
      "required": true,
      "schema": {
       "title": "Recording Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Download Recording V1 Telephony Recordings  Recording Id  Download Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a download link",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/recordings/{recording_id}/legal-hold": {
   "put": {
    "description": "Places or releases the legal hold: a held recording is never deleted, neither by the API nor by the retention job. Needs `tenant_admin` or `platform_admin`. Audited under `telephony.recording.legal_hold` with the reason.",
    "operationId": "set_legal_hold_v1_telephony_recordings__recording_id__legal_hold_put",
    "parameters": [
     {
      "description": "Identifier (UUID) of the recording, in the caller's tenant (another tenant's recording answers 404).",
      "in": "path",
      "name": "recording_id",
      "required": true,
      "schema": {
       "title": "Recording Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyLegalHoldIn"
       }
      }
     },
     "description": "The hold and its reason.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Set Legal Hold V1 Telephony Recordings  Recording Id  Legal Hold Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the legal hold of a recording",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/routing-rules": {
   "get": {
    "description": "The routing rules of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_routing_rule_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only the enabled (true) or disabled (false) objects. Default: both.",
      "in": "query",
      "name": "enabled",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Enabled"
      }
     },
     {
      "description": "Only the inbound or outbound rules. Default: both.",
      "in": "query",
      "name": "direction",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "inbound",
          "outbound"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Direction"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Routing Rule List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the routing rules",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the routing rule in the caller's tenant and returns it (201). Outbound rules list the trunks of the tenant in failover order; inbound rules need a destination of the tenant. With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.routing_rule.create`.",
    "operationId": "telephony_routing_rule_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyRuleIn"
       }
      }
     },
     "description": "The routing rule.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Routing Rule Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a routing rule",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/routing-rules/{item_id}": {
   "delete": {
    "description": "Deletes the routing rule (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.routing_rule.delete`.",
    "operationId": "telephony_routing_rule_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a routing rule",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One routing rule of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_routing_rule_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Routing Rule Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a routing rule",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the routing rule; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.routing_rule.update`.",
    "operationId": "telephony_routing_rule_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyRulePatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Routing Rule Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change a routing rule",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/runtime-settings": {
   "get": {
    "description": "Voicemail storage and fraud thresholds of the tenant (`configured` false and the defaults when never set). Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_runtime_settings_v1_telephony_runtime_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Runtime Settings V1 Telephony Runtime Settings Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the runtime settings",
    "tags": [
     "telephony",
     "telephony"
    ]
   },
   "put": {
    "description": "Replaces the runtime settings. `voicemail_storage` reaches Asterisk at the next publication of the pool (platform voicemail: Record then the UserEvent NavinVoicemail). Needs `tenant_admin` or `platform_admin`. Audited under `telephony.runtime_settings.update`.",
    "operationId": "put_runtime_settings_v1_telephony_runtime_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyRuntimeSettingsIn"
       }
      }
     },
     "description": "The complete runtime settings; omitted fields take their default.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Runtime Settings V1 Telephony Runtime Settings Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the runtime settings",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/settings": {
   "get": {
    "description": "Telephony settings of the caller's tenant: model, SIP domain, PBX pool, CDR retention, numbering plan, and `tid`, the short identifier the engines know the tenant by. `configured: false` when they were never set. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "get_settings_v1_telephony_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Settings V1 Telephony Settings Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Read the telephony settings",
    "tags": [
     "telephony"
    ]
   },
   "put": {
    "description": "Creates or replaces the settings of the tenant. The SIP domain is unique on the platform (409 `telephony_domain_taken`). Changing `model` or `pbx_instance_id` needs `platform_admin` (403 otherwise); the pool must be shared or dedicated to this tenant and match the model (422 `telephony_pool_mode`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.settings.update`.",
    "operationId": "put_settings_v1_telephony_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonySettingsIn"
       }
      }
     },
     "description": "The complete settings; omitted fields take their default.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Put Settings V1 Telephony Settings Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set the telephony settings",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/stats": {
   "get": {
    "description": "Dashboard figures of the tenant computed from the call tables: `active_calls`, `active_by_state`, `active_by_branch`, `calls`, `answered`, `answer_rate`, `average_billsec`, `average_wait_seconds`, `calls_per_hour` (`hour`, `calls`, `answered`, `inbound`, `outbound`), `queues` (`queue`, `sla_seconds`, `offered`, `answered`, `abandoned`, `waiting`, `average_wait_seconds`, `max_wait_seconds`, `sla` = share answered within the SLA of the queue, `abandon_rate`), `agents` (queue member states: `queue`, `interface`, `extension`, `member_name`, `device_status`, `paused`, `paused_reason`, `in_call`, `calls_taken`, `updated_at`), `registrations` (`extension`, `status`, `contacts`, `updated_at`), `open_fraud_alerts`, `active_blocks`, `generated_at`, `window_hours`. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "live_stats_v1_telephony_stats_get",
    "parameters": [
     {
      "description": "Window of the figures in hours, 1 to 168 (default 24).",
      "in": "query",
      "name": "window_hours",
      "required": false,
      "schema": {
       "default": 24,
       "maximum": 168,
       "minimum": 1,
       "title": "Window Hours",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Live Stats V1 Telephony Stats Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the live statistics",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/trunks": {
   "get": {
    "description": "The SIP trunks of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_trunk_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only the enabled (true) or disabled (false) objects. Default: both.",
      "in": "query",
      "name": "enabled",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Enabled"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Trunk List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the SIP trunks",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the SIP trunk in the caller's tenant and returns it (201). The password is write only: the answer carries `has_password`. With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.trunk.create`.",
    "operationId": "telephony_trunk_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyTrunkIn"
       }
      }
     },
     "description": "The SIP trunk.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Trunk Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a SIP trunk",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/trunks/{item_id}": {
   "delete": {
    "description": "Deletes the SIP trunk (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.trunk.delete`.",
    "operationId": "telephony_trunk_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a SIP trunk",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One SIP trunk of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_trunk_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Trunk Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read a SIP trunk",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the SIP trunk; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.trunk.update`.",
    "operationId": "telephony_trunk_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyTrunkPatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Trunk Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change a SIP trunk",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/voice-agents": {
   "get": {
    "description": "The AI voice agents of the caller's tenant, by identifier, `limit` per page (default 50, at most 500) with `next_cursor` for the next page. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_voice_agent_list",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only the enabled (true) or disabled (false) objects. Default: both.",
      "in": "query",
      "name": "enabled",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "title": "Enabled"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Voice Agent List",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the AI voice agents",
    "tags": [
     "telephony"
    ]
   },
   "post": {
    "description": "Creates the AI voice agent in the caller's tenant and returns it (201). The fallback queue must belong to the tenant. With an `Idempotency-Key`, a retry with the same body returns the first answer (`Idempotency-Replayed: true`), another body answers 409 `idempotency_conflict`. Validation problems answer 422 with every problem in `details.errors` (code, path, `message_en`, `message_fr`). Needs `tenant_admin` or `platform_admin`; audited under `telephony.voice_agent.create`.",
    "operationId": "telephony_voice_agent_create",
    "parameters": [
     {
      "description": "Client key that makes a retry safe: the same key with the same body returns the first result instead of creating a second object.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Key that makes a retried creation return the first answer.",
       "title": "Idempotency-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyVoiceAgentIn"
       }
      }
     },
     "description": "The AI voice agent.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Voice Agent Create",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create an AI voice agent",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/voice-agents/{item_id}": {
   "delete": {
    "description": "Deletes the AI voice agent (204); the engines lose it at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.voice_agent.delete`.",
    "operationId": "telephony_voice_agent_delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete an AI voice agent",
    "tags": [
     "telephony"
    ]
   },
   "get": {
    "description": "One AI voice agent of the caller's tenant; 404 `telephony_not_found` otherwise. Secrets are never returned, only `has_*` flags. Needs `tenant_admin`, `support_engineer`, `auditor` or `platform_admin`.",
    "operationId": "telephony_voice_agent_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Voice Agent Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read an AI voice agent",
    "tags": [
     "telephony"
    ]
   },
   "patch": {
    "description": "Changes the sent fields only and returns the AI voice agent; the same checks as the creation apply. A sent secret replaces the stored one (new vault version). The engines get the change at the next publication of the pool. Needs `tenant_admin` or `platform_admin`; audited under `telephony.voice_agent.update`.",
    "operationId": "telephony_voice_agent_update",
    "parameters": [
     {
      "description": "Identifier (UUID) of the object, in the caller's tenant (another tenant's object answers 404).",
      "in": "path",
      "name": "item_id",
      "required": true,
      "schema": {
       "title": "Item Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyVoiceAgentPatch"
       }
      }
     },
     "description": "The fields to change.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Telephony Voice Agent Update",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Change an AI voice agent",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/telephony/voice-agents/{voice_agent_id}/runtime": {
   "get": {
    "description": "Configuration a voice worker needs: `id`, `tenant_id`, `name`, `instructions`, `language`, `greeting`, `llm` (`model`, `base_url`), `stt` (`model`, `base_url`), `tts` (`model`, `voice`, `base_url`), `tools` (the `lookup_*` and `end_call` tools of the agent, plus `transfer_to_human` when a transfer target exists), `transfer` (`target_uri`, sip: or tel:), `max_duration_s`, `fallback_queue`. Base URLs: EAI_TELEPHONY_LLM_BASE_URL, EAI_TELEPHONY_STT_BASE_URL, EAI_TELEPHONY_TTS_BASE_URL, else the model gateway of the Control Plane. 409 `telephony_voice_agent_disabled`. Only for a voice worker token: an API key of the tenant with the explicit scope `telephony:voice-worker` (403 `insufficient_scope` otherwise, a wildcard scope does not count); the voice agent and the call must belong to the tenant of the key (404 otherwise).",
    "operationId": "voice_agent_runtime_v1_telephony_voice_agents__voice_agent_id__runtime_get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the voice agent, in the tenant of the worker token.",
      "in": "path",
      "name": "voice_agent_id",
      "required": true,
      "schema": {
       "title": "Voice Agent Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Voice Agent Runtime V1 Telephony Voice Agents  Voice Agent Id  Runtime Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Read the runtime of a voice agent",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/voicemail": {
   "get": {
    "description": "Voicemail messages (status new or read) of the tenant, newest first: `id`, `mailbox`, `extension_id`, `caller_number`, `caller_name`, `navin_call_id`, `recording_id`, `duration_seconds`, `status`, `read_at`, `received_at`. A message appears once its audio is stored. Readers see every mailbox; a human agent (any role) sees the mailboxes of the extensions it is bound to, 403 for anyone else. Keyset pagination: `limit` (1 to 500, default 50) and the opaque `cursor` of `next_cursor`.",
    "operationId": "list_voicemail_v1_telephony_voicemail_get",
    "parameters": [
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 500,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Only this mailbox (extension number).",
      "in": "query",
      "name": "mailbox",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "pattern": "^[0-9]{2,8}$",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Mailbox"
      }
     },
     {
      "description": "Only the new or the read messages.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "enum": [
          "new",
          "read"
         ],
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Voicemail V1 Telephony Voicemail Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the voicemail messages",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/voicemail/{message_id}": {
   "delete": {
    "description": "Deletes the message and its audio (409 `telephony_legal_hold` when the audio is held) and answers it with status `deleted`. Allowed to the readers and to the agent of the mailbox. Audited under `telephony.voicemail.delete`.",
    "operationId": "delete_voicemail_v1_telephony_voicemail__message_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the voicemail message.",
      "in": "path",
      "name": "message_id",
      "required": true,
      "schema": {
       "title": "Message Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Delete Voicemail V1 Telephony Voicemail  Message Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a voicemail message",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/voicemail/{message_id}/listen": {
   "post": {
    "description": "Answers the message (`message`) and its presigned link. Answers `{url, method: GET, expires_seconds: 300, expires_at, content_type, size_bytes, sha256}`: a SeaweedFS presigned URL valid 300 seconds; no storage credential is returned. 409 `telephony_recording_unavailable` when the object is not stored, 503 `telephony_storage_missing` when the platform profile is missing, 409 `storage_capability_missing` when presign was not verified. Allowed to the readers and to the agent of the mailbox. Audited under `telephony.voicemail.download`.",
    "operationId": "listen_voicemail_v1_telephony_voicemail__message_id__listen_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the voicemail message.",
      "in": "path",
      "name": "message_id",
      "required": true,
      "schema": {
       "title": "Message Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Listen Voicemail V1 Telephony Voicemail  Message Id  Listen Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Listen to a voicemail message",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/voicemail/{message_id}/read": {
   "post": {
    "description": "Marks the message read (or new again with `read=false`) and answers it. Allowed to the readers and to the agent of the mailbox. Audited under `telephony.voicemail.read` or `telephony.voicemail.unread`.",
    "operationId": "mark_voicemail_v1_telephony_voicemail__message_id__read_post",
    "parameters": [
     {
      "description": "Identifier (UUID) of the voicemail message.",
      "in": "path",
      "name": "message_id",
      "required": true,
      "schema": {
       "title": "Message Id",
       "type": "string"
      }
     },
     {
      "description": "true (default): read; false: new again.",
      "in": "query",
      "name": "read",
      "required": false,
      "schema": {
       "default": true,
       "title": "Read",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Mark Voicemail V1 Telephony Voicemail  Message Id  Read Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Mark a voicemail message read",
    "tags": [
     "telephony",
     "telephony"
    ]
   }
  },
  "/v1/telephony/webrtc/credentials": {
   "post": {
    "description": "Ephemeral SIP credentials of a WebRTC extension for the Kamailio `auth_ephemeral` module: `username` `<expiry>:<endpoint>`, `password` base64(HMAC-SHA1(shared secret, username)), `expires_at` (one hour at most), `sip_uri` `sip:<endpoint>@<SIP domain>` (the softphone registers and calls with its endpoint name as From and To user, the user Kamailio checks against the credentials), `ws_url`, `realm`, `endpoint` (`<tid>-<extension>`) and `number` (the extension number, for display). The SIP password of the extension never reaches the browser. Allowed for `tenant_admin`, `platform_admin` and the human agent bound to the extension (404 for anyone else). 409 `telephony_not_webrtc` or `telephony_not_configured`. Audited under `telephony.webrtc.credentials`.",
    "operationId": "webrtc_credentials_v1_telephony_webrtc_credentials_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TelephonyWebrtcIn"
       }
      }
     },
     "description": "The extension and the lifetime.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Webrtc Credentials V1 Telephony Webrtc Credentials Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get WebRTC credentials",
    "tags": [
     "telephony"
    ]
   }
  },
  "/v1/tenants": {
   "get": {
    "description": "Lists the tenants the caller may see, ordered by slug, paginated: their own tenant for a tenant credential, every tenant for a platform administrator.",
    "operationId": "list_tenants_v1_tenants_get",
    "parameters": [
     {
      "description": "Maximum number of tenants in one page (default 50, maximum 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Tenants V1 Tenants Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the tenants",
    "tags": [
     "tenancy"
    ]
   },
   "post": {
    "description": "Creates a tenant and makes each subject of `admins` its `tenant_admin`. Needs `platform_admin`. A slug already used answers 409 `conflict`. Writes the audit event `tenant.create` in the chain of the new tenant.",
    "operationId": "create_tenant_v1_tenants_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TenantIn"
       }
      }
     },
     "description": "Slug, name, residency, settings and first administrators of the tenant.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Tenant V1 Tenants Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a tenant",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/tenants/{tenant_id}": {
   "get": {
    "description": "Returns one tenant: slug, name, status, data residency and settings. A tenant the caller may not see answers 404 `not_found`.",
    "operationId": "get_tenant_v1_tenants__tenant_id__get",
    "parameters": [
     {
      "description": "Identifier (UUID) of the tenant.",
      "in": "path",
      "name": "tenant_id",
      "required": true,
      "schema": {
       "title": "Tenant Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Tenant V1 Tenants  Tenant Id  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a tenant",
    "tags": [
     "tenancy"
    ]
   },
   "patch": {
    "description": "Changes the name, data residency, settings or status of a tenant. Needs `tenant_admin`; changing `status` (`active` or `suspended`) needs a platform administrator (403 `forbidden`). A suspended tenant answers 403 `tenant_suspended` to every credential. Writes the audit event `tenant.update`.",
    "operationId": "patch_tenant_v1_tenants__tenant_id__patch",
    "parameters": [
     {
      "description": "Identifier (UUID) of the tenant.",
      "in": "path",
      "name": "tenant_id",
      "required": true,
      "schema": {
       "title": "Tenant Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TenantPatch"
       }
      }
     },
     "description": "Fields to change; omitted fields keep their value.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Patch Tenant V1 Tenants  Tenant Id  Patch",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a tenant",
    "tags": [
     "tenancy"
    ]
   }
  },
  "/v1/tokenization/detokenize": {
   "post": {
    "description": "Returns the original values of tokens given in `tokens` or found in `text`.\n\n1. The caller must be `tenant_admin` or `security_officer` (403 `forbidden`, the refusal being audited).\n2. The policy decides on `tokenization.detokenize` with the highest classification of the values and the `purpose` (403 `policy_denied`).\n\nThe answer gives `values` (token, type, value), `unknown` tokens, `decision_id` and, with `text`, the text with the tokens replaced. No token at all answers 400 `invalid_request`. Writes the audit event `tokenization.detokenize` with the decision.",
    "operationId": "detokenize_v1_tokenization_detokenize_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DetokenizeIn"
       }
      }
     },
     "description": "Tokens or text holding tokens, and purpose.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Detokenize V1 Tokenization Detokenize Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Detokenize values",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/tokenization/tokenize": {
   "post": {
    "description": "Replaces sensitive values by deterministic tokens `tok_<type>_<hex>` of the tenant (the same value always gives the same token), the values being stored encrypted in the vault. With `values`, returns `tokens`; with `text`, detects the entities and returns the tokenized `text`, `findings` and `classification`. One of the two is required (400 `invalid_request`). Open to any member of the tenant. Writes the audit event `tokenization.tokenize` (count only).",
    "operationId": "tokenize_v1_tokenization_tokenize_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TokenizeIn"
       }
      }
     },
     "description": "Values or text to tokenize.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Tokenize V1 Tokenization Tokenize Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Tokenize values",
    "tags": [
     "privacy"
    ]
   }
  },
  "/v1/tools": {
   "get": {
    "description": "Tools of the tenant in name order, optionally with one status. One page only.",
    "operationId": "list_tools_v1_tools_get",
    "parameters": [
     {
      "description": "Only this status: `draft`, `approved`, `restricted`, `deprecated` or `blocked`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Tools V1 Tools Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the tools",
    "tags": [
     "tools"
    ]
   },
   "post": {
    "description": "Applies a Tool manifest: creates or updates the tool (`apply_status`: `created`, `updated` or `unchanged`). Checked: valid JSON Schemas for input and output, an `http` endpoint needs an http(s) URL allowed by the egress policy, an `mcp` endpoint needs `mcp_server`, a `builtin` handler must be `echo` or `time.now`, risk level `unacceptable` is refused (422 `invalid_manifest`). Needs `tenant_admin`, `developer` or `application_owner`; the caller becomes ReBAC owner. Audited as `tool.apply`.",
    "operationId": "create_tool_v1_tools_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Manifest",
        "type": "object"
       }
      }
     },
     "description": "Tool manifest (`kind: Tool`, `metadata`, `spec` with description, action, input schema, endpoint, data classification and options).",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Tool V1 Tools Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register a tool",
    "tags": [
     "tools"
    ]
   }
  },
  "/v1/tools/invocations": {
   "get": {
    "description": "Invocations recorded by the Tool Gateway, newest first, paginated with `cursor`: tool and version, actor, run, agent, status, decision, approval, redacted arguments and result, DLP findings, HTTP status, error and duration. Arguments and results are stored redacted only.",
    "operationId": "list_invocations_v1_tools_invocations_get",
    "parameters": [
     {
      "description": "Only the invocations of this tool name.",
      "in": "query",
      "name": "tool",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Tool"
      }
     },
     {
      "description": "Only this status: `succeeded`, `failed`, `denied`, `blocked`, `pending_approval` or `rate_limited`.",
      "in": "query",
      "name": "status",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Status"
      }
     },
     {
      "description": "Only the invocations made by this run.",
      "in": "query",
      "name": "run_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Run Id"
      }
     },
     {
      "description": "Maximum number of items in one page. The server caps the value; read the next page with `cursor`.",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     },
     {
      "description": "Opaque cursor returned as `next_cursor` by the previous page. Omit it to read the first page.",
      "in": "query",
      "name": "cursor",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Cursor"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Invocations V1 Tools Invocations Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the tool invocations",
    "tags": [
     "tools"
    ]
   }
  },
  "/v1/tools/{name}": {
   "delete": {
    "description": "Removes the tool from the registry. Needs `tenant_admin` and the ReBAC relation `owner`. 404 `tool_not_found`. Audited as `tool.delete`.",
    "operationId": "delete_tool_v1_tools__name__delete",
    "parameters": [
     {
      "description": "Name of the tool.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a tool",
    "tags": [
     "tools"
    ]
   },
   "get": {
    "description": "Returns the tool with its manifest, risk level, owner and status. Needs the ReBAC relation `viewer`. 404 `tool_not_found`.",
    "operationId": "get_tool_v1_tools__name__get",
    "parameters": [
     {
      "description": "Name of the tool.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Tool V1 Tools  Name  Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get a tool",
    "tags": [
     "tools"
    ]
   },
   "patch": {
    "description": "Changes the owner, the description or the status. A status change needs `tenant_admin` or `security_officer`, other fields `tenant_admin`, `developer` or `application_owner`; the ReBAC relation `editor` is checked. `approved` goes through a promotion (202 with `approval_id`); other statuses apply at once (200). Audited as `tool.update`.",
    "operationId": "patch_tool_v1_tools__name__patch",
    "parameters": [
     {
      "description": "Name of the tool.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ToolPatch"
       }
      }
     },
     "description": "Fields to change; the omitted ones are kept.",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "title": "Response Patch Tool V1 Tools  Name  Patch"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Update a tool",
    "tags": [
     "tools"
    ]
   }
  },
  "/v1/tools/{name}/invoke": {
   "post": {
    "description": "Runs the gateway pipeline described in the tag introduction and returns the invocation: `status`, masked `result`, `error`, `duration_ms`, `decision_id`, DLP findings, usage event and cost. Needs `tenant_admin`, `developer` or `agent` and the ReBAC relation `can_invoke`.\nAnswers: 200 when executed (also when the upstream failed, see `status` and `error`); 202 `pending_approval` with `approval_id` when a human approval is needed (call again with the approved `approval_id` and the same arguments); 202 for a sandbox tool, with the sandbox execution id.\nErrors: 403 `tool_blocked`, `insufficient_scope`, `tool_not_granted`, `classification_exceeded`, `policy_denied`, `dlp_blocked`; 422 `invalid_arguments`; 409 `approval_consumed` (an approval serves one successful call); 429 `rate_limited` with `Retry-After: 60` or `quota_exceeded`.",
    "operationId": "invoke_tool_v1_tools__name__invoke_post",
    "parameters": [
     {
      "description": "Name of the tool.",
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/InvokeIn"
       }
      }
     },
     "description": "Arguments of the call and its context (run, agent, approval, purpose, classification).",
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Invoke a tool through the gateway",
    "tags": [
     "tools"
    ]
   }
  },
  "/v1/triggers": {
   "get": {
    "description": "Event triggers of the tenant, oldest first: agent, subject and filter. One page only.",
    "operationId": "list_triggers_v1_triggers_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Triggers V1 Triggers Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "List the triggers",
    "tags": [
     "agents"
    ]
   },
   "post": {
    "description": "Starts a run of the agent for every published event whose subject matches (NATS wildcards `*` and `>` allowed) and whose payload passes the filter. Needs `tenant_admin`, `developer` or `application_owner`. 422 `invalid_subject` or `invalid_filter`; 404 `agent_not_found`. Audited as `trigger.create`.",
    "operationId": "create_trigger_v1_triggers_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TriggerIn"
       }
      }
     },
     "description": "Agent, subject and optional payload filter.",
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Create Trigger V1 Triggers Post",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create a trigger",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/triggers/{trigger_id}": {
   "delete": {
    "description": "Deletes the event trigger; matching events no longer start runs. Needs `tenant_admin`, `developer` or `application_owner`. 404 `trigger_not_found`. Audited as `trigger.delete`.",
    "operationId": "delete_trigger_v1_triggers__trigger_id__delete",
    "parameters": [
     {
      "description": "Identifier (UUID) of the trigger.",
      "in": "path",
      "name": "trigger_id",
      "required": true,
      "schema": {
       "title": "Trigger Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete a trigger",
    "tags": [
     "agents"
    ]
   }
  },
  "/v1/webhooks/deliveries": {
   "get": {
    "description": "Webhook deliveries received, newest first: connector, delivery id, signature validity, status (`accepted`, `rejected`, `duplicate`), reason, SHA-256 of the payload and published event. The payload itself is not stored here.",
    "operationId": "deliveries_v1_webhooks_deliveries_get",
    "parameters": [
     {
      "description": "Only the deliveries of this connector name.",
      "in": "query",
      "name": "connector",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Connector"
      }
     },
     {
      "description": "Maximum number of deliveries returned (default 50, capped at 500).",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Limit"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Deliveries V1 Webhooks Deliveries Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List the webhook deliveries",
    "tags": [
     "connectors"
    ]
   }
  },
  "/v1/webhooks/{connector}": {
   "post": {
    "description": "Entry point for the provider, without platform authentication. Headers: `X-EAI-Tenant` (tenant slug, else 400 `tenant_required`), `X-EAI-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.\" + raw body>`; `X-EAI-Timestamp` may carry the time), optional `X-EAI-Delivery` (dedupe id).\nSteps:\n1. The connector must exist, be active and have webhooks enabled (404 `connector_not_found`).\n2. Signature checked with the stored `webhook_secret` or the manifest secret reference (401 `invalid_signature`); timestamp within 5 minutes (401 `webhook_replay`); a delivery already accepted answers 409 `webhook_duplicate`.\n3. The JSON body is screened as untrusted content (prompt injection blocked), then published as `connectors.<name>.webhook`, which may start triggered runs.\nAnswers 202 with `delivery_id`, `event_id` and `triggered`. Every delivery is recorded and audited as `webhook.receive`.",
    "operationId": "webhook_v1_webhooks__connector__post",
    "parameters": [
     {
      "description": "Name of the connector the provider sends to.",
      "in": "path",
      "name": "connector",
      "required": true,
      "schema": {
       "title": "Connector",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/octet-stream": {
       "schema": {
        "format": "binary",
        "type": "string"
       }
      }
     },
     "description": "Raw provider payload; the signature is verified on these exact bytes, whatever the content type.",
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Receive a provider webhook",
    "tags": [
     "connectors"
    ]
   }
  }
 },
 "tags": [
  {
   "name": "agents",
   "x-displayName": "Agents",
   "description": "Registry of the tenant's agents and the server side execution of their **runs**: steps, budgets, checkpoints, heartbeats, sub-agents, agent to agent (A2A) messages, conversation sessions, cron schedules, event triggers and sandbox executions.\n\n**Main concepts**\n- **Agent**: a named, versioned manifest (`kind: Agent`). Each version is immutable; the agent status is `active`, `suspended` or `killed` (kill switch).\n- **Run**: one execution of an agent, described by the Execution Contract v1 (state, steps, budget limits and consumption, errors, retry policy, trace). States: `pending`, `running`, `waiting_approval`, `waiting_input`, `suspended`, `succeeded`, `failed`, `cancelled`, `timed_out`.\n- **Step**: one unit of work reported by the runtime (`plan`, `act`, `verify`, `recover`, `model_call`, `tool_call`, `subagent`, `approval`, `checkpoint`). The Loop Controller decides the next run state after every step.\n- **Checkpoint**: a saved state of a run from which it can be resumed.\n- **Session**: a conversation with ordered messages, owned by a user.\n\n**Typical flow**\n1. Register the agent: `POST /v1/agents` with its manifest.\n2. Open a session if the run is conversational: `POST /v1/sessions`.\n3. Create the run: `POST /v1/agents/{agent_id}/runs` (policy check, budget, delegation).\n4. The runtime reports each step (`POST /v1/runs/{run_id}/steps`), sends heartbeats and saves checkpoints.\n5. Follow the run with `GET /v1/runs/{run_id}/events` (Server-Sent Events) and audit it with `GET /v1/runs/{run_id}/replay`.\n\n**Roles**: writing the registry, schedules and triggers needs `tenant_admin`, `developer` or `application_owner`; running and reporting needs `tenant_admin`, `developer` or `agent` (plus the scope `agents:run` to start a run); the kill switch needs `tenant_admin` or `security_officer`. Reads need a tenant principal; agent routes also check the ReBAC relation (`viewer`, `editor`, `owner`, `can_invoke`). A missing role answers 403 `forbidden`."
  },
  {
   "name": "applications",
   "x-displayName": "Applications",
   "description": "**Applications registry**: the business applications built on the platform (agent apps, assistants, workflows) and the **third party agents** that call it from outside. An application lists the agents, tools, MCP servers, models and plugins it may use; its deployments per environment go through an approval.\n\n**Main concepts**\n- **Application**: `kind` (`agent_app`, `assistant`, `workflow`, `external_agent`), `origin` (`internal` or `third_party`), environments, risk level and the resources granted to it. Statuses: `draft`, `approved`, `active`, `suspended`, `retired`.\n- **Deployment**: a version in an environment, active only once its approval is approved; activating it retires the previous active deployment of that environment.\n- **External agent identity**: an API key bound to the application, with the role `agent`. Every gateway call made with it is refused when the application is not active, or when the tool, MCP server or model is not granted (patterns allowed, for example `crm.*`).\n\n**Typical flow**\n1. Register the application: `POST /v1/applications`.\n2. Request a deployment: `POST /v1/applications/{app_id}/deployments` (opens an approval).\n3. Once approved, activate it: `POST .../deployments/{deployment_id}/activate`.\n4. For a third party agent, issue its key: `POST .../external-agents`.\n5. Suspend or retire the application with `POST .../status` (also used by the SOC kill switch).\n\n**Roles**: registration and deployments need `tenant_admin`, `developer` or `application_owner`; status changes need `tenant_admin` or `security_officer`; external agent identities need `tenant_admin`."
  },
  {
   "name": "approvals",
   "x-displayName": "Approvals",
   "description": "Human in the loop: approval requests for sensitive actions, with separation of duties, quorum and expiry. Agent runs that reach a tool needing approval, promotions of models, agents, tools, skills, MCP servers or plugins, break glass grants and mandates all create approval requests here.\n\nLife cycle of a request: `pending`, then `approved`, `rejected`, `expired` or `cancelled`.\n\nTypical flow:\n\n1. A requester (person, agent or service) calls `POST /v1/approvals` with the action, the resource, the quorum and the roles allowed to approve.\n2. Approvers list pending requests with `GET /v1/approvals?status=pending`.\n3. Each approver calls `POST /v1/approvals/{approval_id}/decide`. One `reject` ends the request; it is `approved` once the number of `approve` decisions reaches the quorum.\n4. The subject reacts: a waiting run resumes or fails, a promotion is applied, a break glass grant or a mandate is activated or refused.\n\nSeparation of duties: the requester, and the person an agent acts on behalf of, can never approve their own request (403 `separation_of_duties`). Each approver decides once (409 `already_decided`). A pending request past `expires_at` becomes `expired` on the next read. Every step writes an audit event (`approval.request`, `approval.decide`, `approval.cancel`, `approval.expire`)."
  },
  {
   "name": "audit",
   "x-displayName": "Audit",
   "description": "The tamper evident audit trail of the tenant.\n\nEvery change, refused authorization and sensitive read of the platform writes an Audit Event in the same transaction as the change. Events of a tenant form a hash chain: `hash = sha256(prev_hash + canonical event)`, the first event chaining on 64 zeros, with gapless `sequence` numbers. Each event records the actor, the action, the resource, the policy decision, the outcome, the trace id and, under a delegated execution context, who the call acts on behalf of.\n\nTypical flow for an auditor:\n\n1. `GET /v1/audit/events` searches the trail (actor, action, resource, outcome, trace, period).\n2. `GET /v1/audit/correlations` gathers everything that shares a trace, a run or a session.\n3. `GET /v1/audit/verify` recomputes the chain and reports the first break, if any.\n4. `POST /v1/audit/export` writes a signed export with its manifest to write once storage (object lock).\n\nApplications may add their own events with `POST /v1/audit/events`, under the `app.` namespace.\n\nRoles: `auditor`, `security_officer` and `tenant_admin` read, verify and export; reads, searches and verifications are themselves recorded in the evidence access log."
  },
  {
   "name": "auth",
   "x-displayName": "Portal sign in",
   "description": "Sign in with a local account (login and password) for the portal, when single sign on is not used or not yet configured, typically for the installer administrator.\n\nConcepts:\n\n- **Local account**: a login and a password stored hashed with scrypt, bound to one tenant with roles and a clearance. The first one comes from the installation (bootstrap administrator) and must change its password at the first sign in.\n- **Portal session**: a bearer token `eais_<prefix>_<secret>` returned once by the sign in; only its hash is stored. It expires after the configured lifetime (8 hours by default).\n\nTypical flow:\n\n1. `POST /v1/auth/login` with the login and the password returns `token` and `must_change_password`.\n2. Send `Authorization: Bearer <token>` on the next calls.\n3. While `must_change_password` is true, the session only reaches `POST /v1/auth/password`, `POST /v1/auth/logout`, `GET /v1/me` and `GET /v1/identity/whoami`; any other route answers 403 `password_change_required`.\n4. `POST /v1/auth/password` sets a new password; `POST /v1/auth/logout` ends the session.\n\nProtections: wrong passwords lock the account after the configured number of failures in a row (5 by default, for 15 minutes) and count in the authentication failure budget of the client IP. Every outcome, success or failure, writes an audit event (`auth.login`, `auth.password.change`, `auth.logout`). The whole tag answers 403 `local_auth_disabled` when local accounts are turned off."
  },
  {
   "name": "authz",
   "x-displayName": "Relationship authorization",
   "description": "Relationship based access control (ReBAC): check and manage the authorization tuples of the tenant. The engine is OpenFGA when configured, otherwise the builtin tuple table, with the same rules.\n\nA tuple says that a **subject** has a **relation** on an **object**:\n\n- subject: `user:alice`, `group:fin#member` (the members of a group) or `user:*` (everyone);\n- relation: a lowercase name such as `viewer`, `editor`, `owner` or `can_assume`;\n- object: `<type>:<id>`, for example `project:42` or `service_identity:7`.\n\nRelations are inherited from tenant to project to resource. Some relations, such as `can_assume`, are granted to named subjects only: a wildcard subject is refused (422 `authz_wildcard_not_allowed`).\n\nTypical flow:\n\n1. `POST /v1/authz/tuples` grants a relation (tenant administrator or security officer).\n2. `POST /v1/authz/check` tells whether a subject holds a relation, optionally with contextual tuples that are never stored.\n3. `DELETE /v1/authz/tuples` withdraws it.\n\nThe engine fails closed: when it cannot answer, the check is a refusal and the API answers 502 `authz_backend_error`. Checks, writes and deletions write the audit events `authz.check`, `authz.write` and `authz.delete`."
  },
  {
   "name": "channels",
   "x-displayName": "Channels",
   "description": "**Channel Gateway**: the entry points where end users talk to agents (web, mobile, email, Slack, Teams, WhatsApp, SMS, voice, API, and the Navin channels Discord, Telegram, Matrix, Mattermost and Signal). An inbound message becomes a session message and starts a run of the channel agent, within size, rate and session limits and with DLP.\n\n**Main concepts**\n- **Channel manifest** (`kind: Channel`): `type`, `agent_ref`, `auth` (`oidc`, `api_key`, `signed_webhook` with a secret reference, `anonymous`), `limits` (`max_message_bytes`, `rate_per_minute`, `max_concurrent_sessions`, `max_session_minutes`), `dlp` (`inbound` mode), `sessions` (`ttl_minutes`), optional `connection` to a Navin adapter.\n- **Session**: one per channel, external user and conversation; reused while open.\n\n**Typical flow**\n1. Create the channel: `POST /v1/channels` (or install one from the Navin library).\n2. The channel bridge or the provider posts each message: `POST /v1/channels/{name}/inbound`.\n3. The agent run answers in the session; follow it with the runs and sessions routes.\n4. Disable the channel with `PATCH /v1/channels/{name}` when needed.\n\n**Roles**: create and update need `tenant_admin`, `developer` or `application_owner`; deletion needs `tenant_admin`; inbound messages need `tenant_admin`, `developer` or `agent`. Reads need a tenant principal."
  },
  {
   "name": "compliance",
   "x-displayName": "Compliance & Audit Agent instances",
   "description": "**Activation and lifecycle of the Navin Enterprise Compliance & Audit Agent instances** (ADR-0177, section 8), a copy adapted from the RAG Agent model. The Control Plane owns the activation record of every instance (its status, its sector and pack, its deployment model, its versions and the resources it owns), because in the dedicated model the compliance runtime does not exist yet when an instance is activated. The compliance runtime reads its activation from `GET /v1/compliance/instances/{instance_id}`.\n\n**Sector and pack**: `sector` is `generic`, `banking`, `insurance` or `industry`; `pack` is the sector pack loaded on top of the generic core (`banking`, `insurance` or `industry`) or null for the core alone. Both are settings of the instance, sent to the Navin Manager with the install request of a dedicated runtime.\n\n**Statuses**: `draft`, `validating`, `provisioning`, `starting`, `ready`, `degraded`, `failed`, `stopping`, `stopped`, `updating`, `deleting`, `deleted`. The status says `ready` only after the `health` and `smoke` steps passed; the worker then follows the real health (`ready` and `degraded`).\n\n**Steps** (states `pending`, `running`, `done`, `failed`, `skipped`): `validation`, `resources` (governed application and agent of the instance), `database`, `object_storage` (key prefix in the documents storage profile), `qdrant` (knowledge base with `vector_store` qdrant), `memory` (memory policy of the agent), `security` (OpenFGA owner tuples, runtime API key kept as a secret reference), `deployment` (shared runtime declared by `EAI_COMPLIANCE_AGENT_SHARED_RUNTIME_URL`, or the Navin Manager through the platform_manager bridge for a dedicated instance), `health`, `smoke` (readiness and OpenAPI document of the runtime, knowledge base query), `activation`. Every step keeps its attempts and its logs; a failed step names itself and its reason in `last_error`.\n\n**Transitions**: each action is accepted only from the statuses of its row in the transition table, else 409 `compliance_transition_invalid` (audited as a denial). Repeating an action that is done or in progress answers the current record with `changed: false`. Retrying the failed operation resumes the same run from its failed step; the steps already done are never run again. Provisioning, start, stop, restart, upgrade and deletion are long operations (`Operation-Id`, `Idempotency-Key`) run by the worker job `compliance_lifecycle`.\n\n**Deployment models**: `shared` points the instance to the existing shared runtime; start and stop change the status (and the governed application) only. `dedicated` asks the Navin Manager to install a named instance of the catalog service `navin-compliance-agent`; while that service is not published in the catalog, the deployment step fails with the reason `service_not_published`.\n\n**Roles**: the writes need a tenant administrator or an owner of the project of the instance (403 `forbidden`); the reads need a principal of the tenant. Another tenant's instance answers 404 `compliance_instance_not_found`."
  },
  {
   "name": "connectors",
   "x-displayName": "Connectors",
   "description": "**Connector Hub**: registry of the connections to external systems (SaaS applications, APIs, data sources), their credentials kept server side, synchronisation runs, the **Credential Broker** that hands short lived leases instead of secrets, and the **Webhook Gateway** that receives signed provider events.\n\n**Main concepts**\n- **Connector manifest** (`kind: Connector`): base URL, `auth` (type, token URL for OAuth2, delegation mode), `resources` with their operations, `scopes`, optional `sync` (mode, incremental) and `webhooks` (signature required).\n- **Credentials**: stored in the secret store by kind (`oauth2_client`, `oauth2_code`, `api_key`, `service_account`, `basic`, `webhook_secret`); only their kind and field names are ever returned.\n- **Lease**: an opaque token (`token_type: eai_lease`) valid for some scopes and 600 seconds by default (30 to 3600), redeemed by the platform to call the connector. Disabling a connector revokes its leases.\n- **Webhook**: `POST /v1/webhooks/{connector}` checks an HMAC-SHA256 signature over the timestamp and the raw body, refuses replays and duplicates, then publishes the event `connectors.<name>.webhook`.\n\n**Typical flow**\n1. Register the connector: `POST /v1/connectors`.\n2. Store its credentials: `POST /v1/connectors/{name}/credentials`.\n3. Test it: `POST /v1/connectors/{name}/test`.\n4. Start a synchronisation or let agents obtain leases: `POST .../sync`, `POST /v1/credentials/broker/lease`.\n\n**Roles**: registration, update and test need `tenant_admin`, `developer` or `application_owner`; credentials need `tenant_admin` or `security_officer`; deletion needs `tenant_admin`; sync and leases need `tenant_admin`, `developer` or `agent`. The webhook receiver is called by the provider, authenticated by its signature only."
  },
  {
   "name": "context",
   "x-displayName": "Execution context",
   "description": "**Context Authority**: issues, verifies and revokes signed **ExecutionContext** documents, the proof that a call is made by a given principal, agent run and delegation chain, for a given audience and a short time.\n\n**Main concepts**\n- **Token**: JWS compact serialization (`typ: eai-ctx+jws`), header and payload in RFC 8785 canonical JSON, signed with ES256 or EdDSA. `kid` is the RFC 7638 thumbprint of the public key. Claims: `iss`, `aud` (list), `iat`, `exp`, `jti` (the context id), `sub`, `tid` and `ctx`, the Execution Context v1 document.\n- **Lifetime**: 900 seconds by default, 3600 at most unless the platform is configured otherwise.\n- **Keys**: rotated by the platform; a retired key keeps verifying the contexts it signed until they expire. Public keys are published as a JWKS.\n- **Fail closed**: a missing key or an unreachable key registry answers 503 `context_authority_unavailable`; the authority never signs or accepts a context it cannot check.\n\n**Typical flow**\n1. A runtime or a service requests a context: `POST /v1/context/issue` (optionally for a run or a delegation).\n2. It sends the token to the receiving service, which calls `POST /v1/context/verify` (or checks the signature offline with `GET /v1/context/jwks`).\n3. The context can be revoked before it expires: `POST /v1/context/{context_id}/revoke`; revoking a delegation revokes its contexts.\n\n**Roles**: issue, verify and revoke need a tenant principal (revoking another principal's context needs `tenant_admin` or `security_officer`); the key registry is readable by `security_officer` or `auditor`; revoking a signing key needs `platform_admin`."
  },
  {
   "name": "contracts",
   "x-displayName": "Contracts and manifests",
   "description": "Published JSON Schemas (contracts) of the platform documents, and declarative manifests that create or update objects from a document, in the spirit of infrastructure as code.\n\n- **Contract**: a JSON Schema (draft 2020-12) such as `agent-manifest` or `model-manifest`. Use them to validate documents before sending them.\n- **Manifest**: a document with `kind` (`Agent`, `Model`, `Tool`, `Skill`, `Plugin`, `Connector` or `Channel`), `metadata` (`name`, `version`, optional `tenant`, `environment`, `labels`) and the specification of the object.\n\nTypical flow:\n\n1. `GET /v1/contracts` lists the contracts; `GET /v1/contracts/{name}` returns one schema.\n2. `POST /v1/contracts/{name}/validate` checks a document without storing it.\n3. `POST /v1/manifests/apply` validates, checks the policy and creates or updates the object.\n4. `GET /v1/manifests/{kind}/{name}` exports the current manifest, for example to keep it in Git.\n\nAny authenticated caller reads and validates contracts; applying needs `tenant_admin` or `developer` and writes the audit event `manifest.apply`."
  },
  {
   "name": "delegation",
   "x-displayName": "Delegation, mandates and break glass",
   "description": "How an agent, an application or a sub-agent acts for someone, and how exceptional rights are granted.\n\n- **Delegation**: a principal (user or application) delegates part of its rights to a delegate (`agent:<name>`, `app:<id>`, `service:<name>` or `subagent:<name>`): scopes, audiences, resource restrictions, a classification ceiling, an expiry and a maximum depth. A delegation never grants more than its delegator holds. A child delegation (restriction) is always covered by its parent. Revoking a delegation revokes every descendant and their execution contexts.\n- **Mandate**: scheduled and autonomous runs act under an explicit, approved mandate bound to a service identity, never under an invented human identity. A mandate is pending until a tenant administrator or security officer other than the requester approves it.\n- **Break glass**: an exceptional, time bound elevation of a person (roles and scopes), active only after two distinct approvers, both different from the requester and the beneficiary, approve it. It expires on its own and can be revoked at any time.\n- **Authorize**: the effective permission of an action is user AND agent AND delegation AND resource AND relationship AND policy; every layer must allow.\n\nTypical flow for an agent acting for a user:\n\n1. The user creates a delegation to `agent:<name>` with the scopes the task needs (`POST /v1/delegations`), or the platform creates an implicit one when a run starts.\n2. The agent restricts it for a sub-agent (`POST /v1/delegations/{delegation_id}/restrict`).\n3. Before each sensitive action, the runtime calls `POST /v1/delegations/authorize`.\n4. The user or an administrator revokes it (`POST /v1/delegations/{delegation_id}/revoke`), effective at the next action.\n\nEvery step writes an audit event (`delegation.*`, `mandate.*`, `break_glass.*`)."
  },
  {
   "name": "developer",
   "x-displayName": "Developer",
   "description": "Developer kit: everything a developer gets from the platform to build one application, agent or project, in one answer and without any secret.\n\nThe kit has one row per platform resource: LLM gateway (LiteLLM), identity (Keycloak OIDC), permissions (OpenFGA and OPA), data protection (DLP and Presidio), AI traceability (Opik and OTLP), business tools (Secure MCP Gateway), document access (Qdrant and secure RAG), SDK and user context, quality and security tests (Ragas, Promptfoo, garak). Each row carries its values (addresses, identifiers, allowed models, tools, collections), its state (`ready`, `not_configured`, `service_not_installed`) and the action that fixes it (English and French message, portal page).\n\n**Typical flow**\n\n1. Read the kit with `GET /v1/developer/kit?application_id=...` (or `agent_id`, or `project`).\n2. Fix every row that is not `ready` with its action.\n3. Create the project key on the LLM management page (shown once) and put it in `EAI_API_KEY`.\n4. Copy the `env` entries into the environment file of the application.\n\n**Roles**: `developer`, `application_owner` or `tenant_admin`, inside a tenant. Reading only; the tenant row level security applies."
  },
  {
   "name": "evaluation",
   "x-displayName": "Evaluation and red team",
   "description": "Quality of the AI systems of the tenant: evaluation suites, evaluation runs, quality gates before promotion, A/B comparisons against a baseline and red team runs.\n\n- **Suite**: a dataset of cases, a target (model, agent, prompt, RAG pipeline, skill or tool), an engine (`ragas`, `promptfoo`, `garak` or `custom`), a kind (`quality`, `regression`, `red_team`, `safety`, `cost`, `latency`) and metrics with thresholds. A blocking suite takes part in quality gates; a suite with `run_on_promotion` runs automatically when its target is promoted.\n- **Run**: one execution of a suite; each case is sent to the target (or uses given outputs), scored, and the run ends `passed`, `failed` or `error`, with its cost.\n- **Gate**: the latest runs of the blocking suites of a target must all have passed.\n- **Comparison**: the same suite on a baseline and a candidate, with per metric deltas and a verdict.\n- **Red team run**: adversarial probes (prompt injection, jailbreak, leaks) against a target, with the attack success rate.\n\nTypical flow:\n\n1. `POST /v1/evaluations/suites` with cases and metrics.\n2. `POST /v1/evaluations/runs` to run it; follow it with the `Operation-Id` header if needed.\n3. `POST /v1/evaluations/gates/check` before a promotion: 409 `gate_failed` blocks it.\n4. `POST /v1/evaluations/comparisons` to compare a new model version with the current one; `POST /v1/redteam/runs` to test its resistance.\n\nRoles: any member of the tenant reads suites, runs and red team runs; `tenant_admin`, `developer`, `security_officer` or `ai_governance_officer` create suites, runs and red team runs (`agent` may also start runs); comparisons need `tenant_admin`, `developer` or `security_officer` to create and those roles, `auditor`, `viewer` or `finops` to read. Runs, gates, comparisons and red team runs write audit events."
  },
  {
   "name": "evidence",
   "x-displayName": "Evidence",
   "description": "Evidence layer of the audit trail: signed seals, offline verifiable bundles, the integrity monitor, the Audit Gateway, encrypted payloads, audited access, legal holds and purge evidence, and the execution configuration of agent runs.\n\n- **Seal**: an Ed25519 signature over a range of the tenant audit chain (Merkle root of the events, first and last hashes, previous seal). Seals are written by a job and on demand; without a signing key, nothing is sealed (fail closed).\n- **Bundle**: events, seals and public keys with a signed manifest, verifiable offline with `python -m eai.domains.evidence.verify`.\n- **Integrity alerts**: broken chain, sequence gap, invalid seal, event missing from the outbox, clock skew. The monitor never repairs anything.\n- **Audit Gateway**: delivery of every event, in order and without sampling, to the SIEM targets (HTTP, NATS).\n- **Payload**: sensitive fields of an event, encrypted with an envelope key; the chain keeps only their digest. Only `auditor` and `security_officer` decrypt them, never `platform_admin` by inheritance.\n- **Access log**: every read, search, verification, decryption and export of the trail is itself recorded.\n- **Legal hold**: freezes the payloads of a case and a period; releasing it needs two distinct approvers.\n- **Execution configuration**: versions of the model, prompt, tools, skills and plugins used by a run.\n\nTypical flow for an audit:\n\n1. `GET /v1/evidence/verify` checks chains and seals; `GET /v1/evidence/alerts` lists open problems.\n2. `GET /v1/evidence/bundle` exports what an external auditor verifies offline.\n3. `POST /v1/evidence/holds` freezes a case before an investigation.\n\nReaders are `auditor`, `security_officer` or `tenant_admin` unless stated otherwise."
  },
  {
   "name": "file-security",
   "x-displayName": "File security",
   "description": "Antivirus and content checks of every file that enters the platform, before any parser, model or store sees it.\n\n**Pipeline**: upload, quarantine, ClamAV, YARA-X, validation, Docling, then RAG or AI. Knowledge documents, media uploads, multimodal inputs, audio transcriptions, marketplace packages and media produced by the platform all go through it; `POST /v1/file-security/scans` runs it on demand without ingesting the file.\n\n**Concepts**\n\n- A **scan record** is written as `quarantined` first, then `released` (verdict `clean`) or `blocked` (verdict `malware`, `suspicious`, `unscannable`, `policy_violation` or `scan_error`), with the reasons, the detected type, the SHA-256 and the answer of each engine.\n- Built in checks apply the tenant **policy**: maximum size, allowed types, archives, type mismatch, Office macros. The **locked rules** never change: every file is scanned before ingestion, both engines are required in enforce mode, the pipeline fails closed, malware and uninspectable files are always blocked.\n- A blocked file may keep an encrypted **sample** for `quarantine_retention_days`, to rescan it later; the original upload is never released.\n- The mode is `enforce` unless the platform is configured in `dev` mode, where an engine that is not configured is skipped.\n\n**Typical flow**\n\n1. Check the engines with `GET /v1/file-security/status`.\n2. Tighten the tenant rules with `PUT /v1/file-security/policy`.\n3. Follow blocked files with `GET /v1/file-security/scans?status=blocked` and `GET /v1/file-security/stats`.\n4. After a signature update, rescan a sample with `POST /v1/file-security/scans/{scan_id}/rescan`, or purge it with `DELETE /v1/file-security/scans/{scan_id}/sample`.\n\n**Roles**: readers are `tenant_admin`, `security_officer` and `auditor` (they see every scan of the tenant; any other principal only sees its own scans); policy changes, rescans and purges need `security_officer` or `tenant_admin`. Every scan, policy change and purge is audited."
  },
  {
   "name": "finops",
   "x-displayName": "FinOps",
   "description": "Cost management of AI usage: price cards, usage events, estimates, quotas and reservations, GPU cost allocation, billing reconciliation and alerts.\n\n**Concepts**\n\n- **Price cards** are dated price revisions per provider, model pattern, region and usage type; a new card closes the previous one, so a past usage is always costed with the price of its time. **Media prices** do the same for audio seconds, images, video seconds, GPU seconds and storage; without a price the cost is `null` with `price_unknown`, never zero.\n- **Usage events** (Usage Event v1) record what was consumed; the platform prices them (measured cost) in the tenant currency, with FX rate snapshots. Ingestion is idempotent on `event_id`.\n- **Quotas** limit cost or tokens per tenant, project, agent, user, model or provider, per request, run, hour, day or month, `hard` (refused with 429 `quota_exceeded`) or `soft` (alert only). Callers **reserve** the worst case before a call, then **commit** the measured amount or **release** the reservation; an open reservation expires after its lifetime.\n- **Reconciliation** imports provider billing exports (OpenAI, Anthropic, AWS CUR, Azure, GCP, generic CSV), allocates the billed amounts to the usage events and reports the variance. **Alerts** fire at the budget and quota thresholds (50, 80 and 100 percent by default) and on billing variance.\n\n**Typical flow**\n\n1. Set the tenant currency and monthly budget with `PUT /v1/finops/settings`, the FX rates and the price cards.\n2. Create quotas with `POST /v1/quotas`.\n3. Before each call, reserve with `POST /v1/quotas/reserve`; after it, commit the measured cost and send the usage event (the Model Gateway does all of this by itself).\n4. Follow the spend with `GET /v1/finops/summary` and `GET /v1/finops/alerts`, and reconcile the invoices each month.\n\n**Roles**: readers are `finops`, `tenant_admin`, `auditor`, `developer`, `viewer` and `security_officer`; changes need `finops` or `tenant_admin`; usage ingestion and reservations need `finops`, `tenant_admin`, `agent` or `developer`; GPU samples and allocation policies need `platform_admin`. `platform_admin` passes every role check. Most routes need a tenant principal (403 `tenant_required`). Every change is audited."
  },
  {
   "name": "governance",
   "x-displayName": "Governance",
   "description": "Governance registry: one aggregated view of the AI assets of the tenant, to know what exists, who owns it and how risky it is.\n\nThe registry gathers agents, models, LLM providers, tools, skills, plugins and connectors. Each item gives its kind, id, name, version, owner, status, risk level, scope (`platform` for shared items, `tenant` for the items of the tenant) and last update. The risk level is the EU AI Act category of the latest risk assessment of the item, else the risk level declared on the item or in its spec.\n\n**Typical flow**\n\n1. Read `GET /v1/governance/registry` for the whole inventory, or filter with `kind`.\n2. Use the `summary` to find items without owner or without risk assessment (`unassessed`).\n3. Assess or assign them in the Risk and registry areas.\n\n**Access**: any authenticated principal of a tenant; the rows are filtered by the tenant row level security."
  },
  {
   "name": "identity",
   "x-displayName": "Identity",
   "description": "Who calls the API and with which rights. This tag covers the caller identity (`whoami`), API keys for scripts and services, service identities (SPIFFE workloads) that a user may temporarily act as, and the directory group mappings that turn Keycloak groups into project memberships and quotas.\n\nConcepts:\n\n- **API key**: `eai_<prefix>_<secret>` credential bound to the tenant, with its own roles, scopes, clearance and optionally a project and an environment. The secret is returned once at creation or rotation; only its hash is stored.\n- **Service identity**: a named workload identity (`spiffe://...`) with roles and scopes. Assuming it gives a signed, short lived execution context, never more rights than the caller holds.\n- **Group mapping**: a directory group (`groups` or `entra_groups` claim) mapped to a project, a role and optionally a quota profile. Mappings are applied at each OIDC sign in and revoked when the group leaves the token; memberships granted by hand are never touched.\n- **Quota profile**: a reusable cost and token limit attached to group mappings.\n\nTypical flow for a CI pipeline:\n\n1. A developer calls `POST /v1/api-keys` with the scopes the pipeline needs and an expiry.\n2. The pipeline stores the returned `key` in its secret store and sends it as `X-API-Key`.\n3. Before expiry, `POST /v1/api-keys/{key_id}/rotate` with a grace period issues a new key while the old one keeps working.\n4. `DELETE /v1/api-keys/{key_id}` revokes a key immediately.\n\nRoles: `tenant_admin`, `security_officer` and `developer` manage API keys (developers only their own); `tenant_admin` and `security_officer` manage service identities; `tenant_admin` manages group mappings and quota profiles, which `security_officer` and `auditor` may read. Every change writes an audit event (`api_key.*`, `service_identity.*`, `identity.group_mapping.*`, `identity.quota_profile.*`)."
  },
  {
   "name": "incidents",
   "x-displayName": "Incidents",
   "description": "Security and operations incidents of the tenant: severity, status, timeline, containment actions, Alertmanager alerts and forwarding to the SIEM.\n\nLife cycle: `open`, `investigating`, `contained`, `resolved`, `closed`. Severity: `sev1` (most severe) to `sev4`.\n\nTypical flow:\n\n1. An incident is opened by hand (`POST /v1/incidents`) or by an Alertmanager alert (`POST /v1/incidents/alerts`).\n2. A responder changes its status, severity or assignee and adds notes (`PATCH /v1/incidents/{incident_id}`).\n3. The responder contains it with an action (`POST /v1/incidents/{incident_id}/actions`): suspend, resume or kill an agent, suspend or disable a model, disable a provider, rotate or revoke a key. The first executed action moves an `open` or `investigating` incident to `contained`.\n4. The incident is resolved, then closed.\n\nEvery change is added to the timeline, forwarded to the configured SIEM and written as an audit event (`incident.create`, `incident.update`, `incident.action.<action>`, `incident.alert.*`).\n\nRoles: any member of the tenant reads incidents; `tenant_admin`, `security_officer`, `developer` and `agent` open them; `tenant_admin` and `security_officer` respond."
  },
  {
   "name": "knowledge",
   "x-displayName": "Knowledge bases",
   "description": "Knowledge bases for retrieval augmented generation (RAG): documents are scanned, extracted, screened for personal data and poisoning, chunked, embedded through the Model Gateway and searched with ACL and clearance filters.\n\n**Main concepts**\n- **Knowledge base**: a named collection with one embedding model of the Model Registry and its dimension, a chunking setting, a classification and an ACL (`readers`, `writers`). Two embedding spaces are never mixed: changing the model is a **reindex** job.\n- **Document**: a versioned text (same `uri` replaces the previous version) with its classification, readers, DLP result and provenance. A document flagged by the poisoning screening is **quarantined** until a data steward releases or rejects it.\n- **Query**: vector or hybrid search, filtered by the caller identities and clearance, optionally reranked, returned with citations and a lineage run.\n\n**Typical flow**\n1. Create the knowledge base: `POST /v1/knowledge-bases`.\n2. Add documents: `POST /v1/knowledge-bases/{kb_id}/documents`.\n3. Review the quarantine queue if needed: `GET .../quarantine`, then `POST .../documents/{doc_id}/review`.\n4. Query: `POST /v1/knowledge-bases/{kb_id}/query`.\n5. Move to another embedding model: `POST .../reindex`, follow it with `GET .../reindex-jobs`.\n\n**Access**: creation and reindex need `tenant_admin` or `developer`; routes on one knowledge base also check the ReBAC relation (`viewer`, `editor`, `can_invoke`, `owner`) and the knowledge base ACL. Readers are matched against the caller identities (`*`, `user:<id>`, `agent:<id>`, `role:<role>`, `group:<group>`); administrators get no implicit read access. The quarantine review needs `tenant_admin`, `security_officer` or `data_steward`."
  },
  {
   "name": "licensing",
   "x-displayName": "Licensing",
   "description": "Licence of the installation: activation of a signed licence, current state and history.\n\nA licence is a JWS compact token (algorithm EdDSA, `kid` header) signed by the publisher. It is verified locally against the trusted publisher keys of the settings (`EAI_LICENSE_PUBLIC_KEYS`): no network call is made, so the same check serves an air-gapped installation. A licence never carries a price, a seat, a quota or a limit, and its term is 12 or 36 months.\n\n**States** of the installation, computed from the stored licences and the clock:\n\n- `unlicensed`: no licence has started yet;\n- `valid`: the licence runs and its end is more than `EAI_LICENSE_EXPIRING_SOON_DAYS` (default 30) days away;\n- `expiring_soon`: the end is closer than that;\n- `grace`: the end has passed but the grace period of the licence is still running;\n- `expired`: the grace period is over.\n\nOnly `expired` restricts anything, and only new distribution upgrades and new marketplace installs (403 `license_expired`). Security, audit, recovery, the kill switch, running agents, new runs and the model gateway are never stopped by a licence state.\n\n**Typical flow**\n\n1. Read the state with `GET /v1/license` (any authenticated user; the portal shows its `banner`).\n2. A platform administrator activates the licence received from the publisher with `POST /v1/license/activations`. The first licence binds the installation to its installation group.\n3. Before the end, activate the renewal the same way: it becomes effective by itself on its `valid_from`, and no expiry banner shows while it follows without a gap.\n4. Review activations and refusals with `GET /v1/license/history`.\n\n**Roles**: reading the state needs an authenticated principal; activation and history need `platform_admin`. Every call also takes a policy decision (`license.read`, `license.activate`, `license.history.read`) recorded in the audit chain; a denial answers 403 `policy_denied`."
  },
  {
   "name": "lineage",
   "x-displayName": "Lineage",
   "description": "Data lineage of the tenant, fed with OpenLineage events: which jobs read which datasets and produce which others.\n\nThe graph has three kinds of nodes: **jobs** (`job:<namespace>:<name>`), **runs** of a job (`run:<runId>`) and **datasets** (`dataset:<namespace>:<name>`). Edges are `instance_of` (run to job), `input_to` (dataset to job) and `produces` (job to dataset).\n\nTypical flow:\n\n1. Pipelines, connectors and agents send OpenLineage RunEvents to `POST /v1/lineage/events`.\n2. `GET /v1/lineage/graph` returns the graph around a node, upstream, downstream or both.\n3. `GET /v1/lineage/datasets/{dataset_id}` answers impact questions on one dataset: who produces it, who consumes it.\n\nOpen to any member of the tenant. Ingestion writes the audit event `lineage.ingest`."
  },
  {
   "name": "llm",
   "x-displayName": "LLM and Model Gateway",
   "description": "Model providers, the model registry, routing rules and the Model Gateway: the only path agents and applications use to call models.\n\n**Concepts**\n\n- A **provider** is a configured model service (OpenAI, Anthropic, Azure OpenAI, AWS Bedrock, Mistral, vLLM, Ollama, LM Studio...). Its credentials go to the secret store and are never returned. A provider is shared (`platform`, platform administrator only) or belongs to the tenant.\n- A **model** is a registry entry (Model Manifest v1 plus the sheet: category, display name, knowledge cutoff, prices). Its status is `approved`, `restricted`, `deprecated` or `blocked`: a blocked model is always refused, a restricted one only serves `tenant_admin`, `security_officer` or a credential with the scope `models:restricted`, a deprecated one answers with a warning. A tenant change of a shared model creates a tenant override (copy on write).\n- **Versions** carry a licence and the weights provenance; a version needs an approval by someone else before it can be published fully or as a canary, and it can be rolled back.\n- **Routes** select a model among candidates (`priority`, `cost`, `latency` or `quality` strategy) with fallbacks. **Isolation** (`local_only`, `air_gapped`) restricts a tenant or project to local providers and declared internal hosts.\n- The **gateway** runs every control before any outbound call: kill switches, capability, provider, model and region allow lists, data classification and caller clearance, DLP (mask or block), secret isolation, TLS, provider retention, prompt injection screening, fallback policy, cost guardrails and the policy decision `model.invoke`; then it calls LiteLLM (or the provider directly), records the usage and audits hashes only. Answers carry `X-EAI-Decision-Id`, `X-EAI-Model`, `X-EAI-Cost-Estimated` and, when known, `X-EAI-Cost-Measured`.\n\n**Typical flow**\n\n1. Read the provider catalog with `GET /v1/providers/catalog`, then create a provider with `POST /v1/providers` and test it.\n2. Discover the models it serves with `POST /v1/providers/{pid}/models/discover` and import the chosen ones with `POST /v1/models/import`.\n3. Approve the models (`POST /v1/models/{model_id}/status`), define routes, then push the configuration to LiteLLM with `POST /v1/litellm/sync`.\n4. Call `POST /v1/gateway/chat/completions` (or embeddings, rerank, images, audio, video) with a credential that carries the scope `models:invoke`.\n\n**Roles**: reading needs one of `tenant_admin`, `platform_admin`, `security_officer`, `finops`, `developer`, `auditor`, `viewer`, `agent`, `ai_platform_engineer`, `ai_governance_officer`, `support_engineer`; changes need `tenant_admin`, `platform_admin` or `ai_platform_engineer` (versions, rollouts and isolation: `tenant_admin` or `platform_admin`); kill switches (disable) also accept `security_officer`. Every change is audited."
  },
  {
   "name": "llm-management",
   "x-displayName": "LLM management",
   "description": "LLM projects of a tenant, their quota and the LiteLLM virtual keys that applications use to call the models.\n\n**Concepts**\n\n- An **LLM project** groups the allowed models (model ids and model categories of the registry), an owner, a status (`active`, `suspended`, `archived`) and a quota: budget per period, token limit per period, requests and tokens per minute, parallel requests, alert threshold and hard stop.\n- Each project is mirrored in LiteLLM as a **team** (models, budget, budget period, rate limits). `sync_status` says whether the mirror is `synced`, `pending` (LiteLLM not configured) or `failed`.\n- When the project is linked to a tenant project (`project_id`) and active, its daily or monthly budget and token limit also become FinOps quotas of that project, enforced by the Control Plane gateway (weekly and total periods are enforced by LiteLLM only).\n- A **key** is a LiteLLM virtual key of the project. Its limits can never be wider than the project ones and its models must be allowed by the project. The clear key is shown once, in the creation answer; the platform only keeps its hash, alias, a display prefix, the limits, the status and the expiry.\n\n**Typical flow**\n\n1. Check the LiteLLM admin connection with `GET /v1/llm/management/status`.\n2. Create the project with `POST /v1/llm/projects`, then set its quota with `PUT /v1/llm/projects/{project_id}/quota`.\n3. Generate a key with `POST /v1/llm/projects/{project_id}/keys` and store it at once in the application secret (for example `EAI_API_KEY`).\n4. Follow the spend with `GET /v1/llm/projects/{project_id}/keys`; block, unblock or revoke a key when needed.\n\n**Roles**: `tenant_admin` or `platform_admin`, always inside the caller's tenant (400 `tenant_required` without a tenant). Without LiteLLM: 503 `litellm_not_configured`; LiteLLM down: 502 `litellm_unreachable`; LiteLLM refusing a call: 502 `litellm_rejected`. Every change is audited; audit events never carry a key."
  },
  {
   "name": "marketplace",
   "x-displayName": "Marketplace",
   "description": "Catalogue of signed **packs** (bundles of agents, sub-agents, skills, tools, connectors, MCP servers and assets), their publication gates, the production gate, the trusted **publishers**, the **installations** per environment and the change management pipeline.\n\n**Main concepts**\n- **Package** and **version**: a pack archive (`.tar.gz`) published with its signature, SBOM, vulnerability scan, test and evaluation reports and SLSA provenance. A version is `published`, then `production` after the production gate.\n- **Installation**: one per package and environment (`dev`, `test`, `staging`, `prod`). States: `pending_approval`, `installed`, `suspended`, `failed`, `uninstalled`. Only the permissions granted at install time are allowed at run time.\n- **Kill switch**: a package or an installation can be suspended at once; lifting it needs a four eyes approval.\n- **Change**: a change request of a prompt, skill, connector, rule, model, policy, tool, agent or pack that goes through `draft`, `test`, `security_review`, `business_approval`, `staging`, `production`, `monitoring`.\n\n**Typical flow**\n1. Register the publisher key: `POST /v1/marketplace/publishers`.\n2. Publish a version: `POST /v1/marketplace/packages` (every gate must pass).\n3. Promote it to production when it will be installed in `prod`: `POST .../versions/{version}/production`.\n4. Check the installation: `POST /v1/marketplace/preflight`.\n5. Request the installation (`POST /v1/marketplace/installations`, 202 with an approval), have it approved, then apply it (`POST .../installations/{id}/apply`).\n6. Supervise, upgrade, roll back, suspend or uninstall it.\n\n**Roles**: publishing and changes need `tenant_admin` or `developer`; installation lifecycle needs `tenant_admin` (preflight also `security_officer`); trust actions (publishers, production, kill switches, rejection) need `tenant_admin` or `security_officer`; the runtime check `authorize` accepts `tenant_admin`, `developer`, `agent` or `service`. Every write is first evaluated by the policy engine (403 `policy_denied`) and refusals are audited."
  },
  {
   "name": "mcp",
   "x-displayName": "MCP gateway",
   "description": "Registry of the upstream **MCP servers** (Model Context Protocol) and the **MCP Gateway**, a JSON-RPC 2.0 proxy that applies the platform controls to every call: project isolation, allowed callers, allow lists of tools and resources, scopes, DLP, policy, quota, prompt injection screening, metering and audit.\n\n**Main concepts**\n- **Server**: a name, an internal URL (public destinations are refused by the egress policy), a transport (`streamable_http` or `sse`), an upstream authentication (`none`, `bearer`, `api_key`, `query_param` or `connector`, secrets as `openbao://` or `env://` references), `allowed_tools` and `allowed_resources` (patterns, default `*`), an optional project and a status (`active`, `disabled`).\n- **Project isolation**: a server without a project is shared by the tenant; a server of a project is reached only from that project (`X-Project` header or an API key bound to the project), or by `tenant_admin` and `security_officer`.\n- **Catalogue**: discovery (`initialize`, `tools/list`) records each new or changed tool schema as a version waiting for approval.\n- **Methods** allowed through the gateway: `initialize`, `tools/list`, `tools/call`, `resources/list`, `resources/read`, `prompts/list`, `ping`.\n\n**Typical flow**\n1. Register the server: `POST /v1/mcp/servers` (or install it from a Navin preset).\n2. Discover its tools: `POST /v1/mcp/servers/{server_id}/discover`, then approve the catalogue versions.\n3. Restrict callers if needed: `PUT /v1/mcp/servers/{server_id}/access`.\n4. Agents call it through `POST /v1/mcp/gateway/{server_id}`.\n\n**Roles**: registration, discovery and access need `tenant_admin`, `developer` or `application_owner`; status changes need `tenant_admin` or `security_officer`; deletion and hosted sync need `tenant_admin`; gateway calls need `tenant_admin`, `developer` or `agent`. Routes on one server also check the ReBAC relation (`owner`, `editor`, `can_invoke`)."
  },
  {
   "name": "mcp-runtime",
   "x-displayName": "MCP runtime",
   "description": "**MCP Runtime**: isolated MCP server **instances** started on demand for one user of a project, from the templates of the platform catalogue, run by ToolHive in the namespace of the project and reached through the MCP Gateway.\n\n**Main concepts**\n- **Template**: an MCP server image with its parameters (hosts, database roles...) and its credential kind (a dynamic OpenBao database lease, or a personal secret reference of the user).\n- **Project policy**: templates allowed (empty: all), hosts allowed (patterns such as `*.example.org`), database roles allowed, idle time, maximum lifetime and quotas per user and per project.\n- **Instance lifecycle**: `provisioning`, `ready` (its gateway entry is callable by its owner and its agents only), `sleeping` (idle, lifetime reached, stopped, or destroyed after a failure; the next call recreates it with a new generation and new credentials), `failed` (repeated or permanent failure: calls are refused until its owner starts it again), `terminating`, `terminated`. Every step is written to an append only lifecycle journal.\n- **Secrets** never reach a table, an answer, an event or a log: a lease is sealed and cleared once revoked, a personal secret is kept as its reference only.\n\n**Typical flow**\n1. A tenant administrator sets the project policy: `PUT /v1/projects/{project_id}/mcp/policy`.\n2. A user lists the templates and starts an instance: `GET` then `POST /v1/projects/{project_id}/mcp/instances`.\n3. The user follows it until `ready`: `GET .../instances/{instance_id}`.\n4. Agents call it through `POST /v1/mcp/gateway/{server_id}`; it sleeps when idle and wakes at the next call.\n5. The user stops or deletes it at the end of the task.\n\n**Access**: project routes check the ReBAC relation `viewer` or `editor` on the project. A user sees and manages its own instances; `tenant_admin` and `security_officer` see every instance of the project. Creating an instance needs `tenant_admin`, `developer` or `application_owner`; the policy needs `tenant_admin`. When the platform runs without the MCP Runtime, creation answers 409 `mcp_runtime_disabled`."
  },
  {
   "name": "memory",
   "x-displayName": "Memory",
   "description": "**Memory Manager**: long lived memory items of agents and users, following the Memory Contract v1, with ACL, lifetime, legal hold, versioning and hybrid search.\n\n**Main concepts**\n- **Item**: content (or a reference to it) with a `scope` (`session`, `agent`, `user`, `project`, `tenant` and an id), a `kind` (`episodic`, `semantic`, `procedural`, `preference`, `fact`), a classification and an ACL (`readers`, `writers`, `owners`).\n- **Versions**: writing an existing `memory_id` keeps the former content as a version and increments `version`.\n- **Lifetime**: `ttl_seconds` sets `expires_at`; an expired item is no longer returned. A `legal_hold` item cannot be deleted; a non `deletable` item can only be deleted by `tenant_admin`.\n- **Embedding**: content is embedded through the Model Gateway with the platform memory embedding model; search compares only vectors of the current model.\n\n**Typical flow**\n1. Write an item: `POST /v1/memory` (personal data detection may raise the classification).\n2. Recall: `POST /v1/memory/search` (results are screened for prompt injection before they reach a prompt).\n3. Read or list: `GET /v1/memory/{memory_id}`, `GET /v1/memory`.\n4. Forget: `DELETE /v1/memory/{memory_id}`.\n\n**Access**: any tenant principal may call these routes; visibility is decided per item by its ACL (one of the caller identities must be listed, administrators get no implicit read access) and by the caller clearance. Writes and searches go through the policy engine (`memory.write`, `memory.search`)."
  },
  {
   "name": "multimodal",
   "x-displayName": "Multimodal",
   "description": "**Media and multimodal processing**: encrypted media storage and jobs for vision, image generation and edition, video processing and generation, speech to text, diarization, text to speech and multimodal DLP.\n\n**Main concepts**\n- **Media**: a stored file (image, audio, video, document) scanned by ClamAV and YARA-X, its text extracted and inspected by the DLP, encrypted with a tenant key and returned as a Multimodal Contract document. Its classification is raised when personal data is found.\n- **Job**: one operation (`vision_understanding`, `image_generation`, `image_edit`, `video_processing`, `video_generation`, `stt`, `diarization`, `tts`...). It runs inline when an adapter is available, otherwise it stays `queued` for the GPU workers, which report the result with `POST /v1/multimodal/jobs/{job_id}/complete`. Statuses: `queued`, `running`, `succeeded`, `failed`, `cancelled`.\n- Every operation is evaluated by the policy `multimodal.submit`, takes a quota reservation and records a usage event.\n\n**Typical flow**\n1. Upload the input: `POST /v1/media` (or pass `content_base64` inline to the operation).\n2. Start the operation, for example `POST /v1/multimodal/stt` with `media_id`.\n3. Read the job until it is finished: `GET /v1/multimodal/jobs/{job_id}`.\n4. Delete the media when it is no longer needed: `DELETE /v1/media/{media_id}`.\n\n**Roles**: processing and generation need `tenant_admin`, `developer` or `agent`; job completion needs `agent` or `tenant_admin`; upload, reads and the DLP check need a tenant principal; deleting a media needs its creator, `tenant_admin` or `security_officer`."
  },
  {
   "name": "navin-library",
   "x-displayName": "Navin library",
   "description": "The **Navin library** is the vendored catalogue of ready to use skills, plugins, commands, agents, MCP presets and channels. A project activates what it needs, installs MCP servers and channels from presets, and keeps its own **rules**, the durable instructions every run of the project receives.\n\n**Main concepts**\n- **Item**: one entry of the library, by kind (`skills`, `plugins`, `commands`, `agents`, `mcp-presets`, `channels`) and name, with a digest.\n- **Activation**: an item enabled for a project. A skill is registered in the Skill Registry of the tenant, verified by its library digest; a plugin brings its skills, commands and agents.\n- **Rule**: a Markdown instruction of a project, `always` (inlined in the prompt) or `conditional` (listed with its globs and description). Rules can be imported from the files of other coding agents (`.navin/rules`, `.cursor/rules`, `.cursorrules`, `.clinerules`, `.windsurfrules`, `.github/copilot-instructions.md`).\n\n**Typical flow**\n1. Browse the catalogue: `GET /v1/navin-library` and `GET /v1/navin-library/{kind}`.\n2. Activate items for a project: `POST /v1/projects/{project_id}/navin-library/activations`.\n3. Install an MCP server or a channel from a preset, with secret references only.\n4. Import or write the project rules, then read the prompt section with `GET .../rules/prompt`.\n\n**Access**: reading the catalogue needs a tenant principal. Project routes check the ReBAC relation `viewer` (reads) or `editor` (writes) on the project; writes also need `tenant_admin`, `developer` or `application_owner`. A project is named by its id or its slug (404 `project_not_found`)."
  },
  {
   "name": "operations",
   "x-displayName": "Operations",
   "description": "Long operations: one durable `operation_id` for every long creation, to follow it and to retry it safely.\n\nThe long requests are: agent runs, evaluation runs, red team runs, marketplace installs and upgrades, knowledge base reindexing, connector synchronization and video generation. Their answer carries the headers `Operation-Id` and `Operation-Location` (`/v1/operations/{operation_id}`).\n\n**Idempotency**: with an `Idempotency-Key` header (1 to 200 characters) the first answer is stored; a retry by the same principal with the same body replays it with `Idempotency-Replayed: true` without running the operation again. Another body under the same key answers 409 `idempotency_conflict`; a retry while the first request still runs answers 409 `operation_in_progress`. Agent runs deduplicate by themselves and share one operation row between their replays. A request that fails is not kept: it can be retried with the same key.\n\n**Typical flow**\n\n1. Send the long request, ideally with an `Idempotency-Key`.\n2. Read `Operation-Location` from the answer.\n3. Poll `GET /v1/operations/{operation_id}` until `status` shows the end state of the resource.\n\n**Access**: an authenticated principal of a tenant. The creator reads its own operations; `tenant_admin`, `platform_admin`, `auditor` and `security_officer` read every operation of the tenant."
  },
  {
   "name": "platform-manager",
   "x-displayName": "Platform Manager",
   "description": "Platform Manager space of the console: the Control Plane bridge to the Navin Manager, which installs, connects and operates the platform services on the customer's machines, plus the IT vault of the platform administrators.\n\n**How the bridge works**: every call is forwarded to the Navin Manager API with the Manager API token of the Control Plane and the identity of the portal user in `X-NM-On-Behalf-Of` (the local account name or the Keycloak username). The Manager stays the authority: its permissions (for example `services:install`, `hosts:manage`, `configs:read`, `backup:read`, `restore:execute`, `dr:manage`, `connections:manage`), approvals and stop rules apply. Secret values (passwords, private keys, enrollment tokens) are relayed to the Manager, never stored nor audited by the Control Plane. Every write is audited in the Control Plane chain, allowed or refused.\n\n**Concepts**: a **cluster** is an environment of the Manager (`production` or `sandbox`); **hosts** are its machines, enrolled with the node agent (over SSH or with an enrollment token); **services** come from the Manager **catalog** and are either installed on hosts or connected (an existing service of the customer); **connections** are existing PostgreSQL, Redis or OIDC issuers bound to services; **backup and DR** cover backup plans, restores (two approvers other than the requester) and DR exercises.\n\n**Typical flow**\n\n1. Check `GET /v1/platform-manager/setup`: platform core and Manager connection.\n2. Create a cluster, then enroll machines with `POST .../hosts/ssh-bootstrap` or an enrollment token, and run the preflight checks.\n3. Read the catalog, validate then install services (`POST .../services/validate`, `POST .../services`), or connect existing ones.\n4. Operate them (operations, modes), follow the summary, dashboards, configuration and operations, and plan backups and restores.\n\n**Roles**: every route needs `platform_admin` (403 `forbidden`). Bridge errors: 503 `platform_manager_not_configured` (no `EAI_PLATFORM_MANAGER_URL`), 503 `platform_manager_credential_missing` (token reference missing or unreadable), 502 `platform_manager_unreachable`; a refusal of the Manager is relayed with its HTTP status and the code `platform_manager_<manager code>`, with its English and French messages."
  },
  {
   "name": "plugins",
   "x-displayName": "Plugins",
   "description": "Registry and runtime lifecycle of **plugins**: signed OCI images run by the platform in a sandbox (gVisor, Kata or Wasm runtime class), with a Kubernetes Deployment and a NetworkPolicy rendered from the manifest.\n\n**Main concepts**\n- **Plugin manifest** (`kind: Plugin`): `artifact` (`oci_ref`, `digest`), `signature`, `sandbox` (runtime, network mode `none` or `egress_allowlist` with its allow list, read-only root file system, resource limits).\n- **Statuses**: `registered`, `installed`, `installing`, `failed`, `uninstalled`, `blocked`.\n- A pack (`format: pack`) is not a plugin: it is published and installed through the Marketplace.\n\n**Typical flow**\n1. Register the plugin: `POST /v1/plugins` (the signature is checked and the result stored).\n2. Install it: `POST /v1/plugins/{name}/install` (signature checked again, objects rendered and applied when Kubernetes is configured).\n3. Follow it: `GET /v1/plugins/{name}/status`.\n4. Uninstall it: `POST /v1/plugins/{name}/uninstall`.\n\n**Roles**: registration needs `tenant_admin`, `developer` or `application_owner`; install and uninstall need `tenant_admin` and the ReBAC relation `owner`; reads need the relation `viewer`."
  },
  {
   "name": "policies",
   "x-displayName": "Policies",
   "description": "Attribute based policies (ABAC) that decide every sensitive action of the platform, with the Policy Contract v1, the decision log, simulation, revisions and signed OPA bundles.\n\nA policy is either `builtin` (a list of rules evaluated by the platform) or `opa` (a Rego module run by Open Policy Agent). A rule targets actions and resource types (glob patterns), holds when all its conditions hold, and has an effect, `allow` or `deny`, with optional obligations (for example `dlp` masking or `approval`).\n\nOrder of evaluation, active policies sorted by priority then name:\n\n1. a matching `deny` rule wins;\n2. otherwise matching `allow` rules allow, their obligations merged;\n3. if allow rules target the action but none holds, the request is denied;\n4. with no applicable rule, the platform guards run (clearance against data classification, resource classification ceiling, resource regions), then the default of the tenant or the platform.\n\nEvery decision is stored in the decision log and written to the audit chain.\n\nTypical flow:\n\n1. `POST /v1/policies/simulate` to see which decisions a candidate policy would change.\n2. `POST /v1/policies` (or `PUT`) to activate it; every change appends a revision.\n3. `POST /v1/policies/evaluate` from an application to ask for a decision; `GET /v1/policies/decisions` to review them.\n4. For OPA, `POST /v1/policies/bundles` publishes a signed bundle that OPA polls.\n\nRoles: any member of the tenant reads policies and evaluates for themself; `tenant_admin` and `security_officer` manage policies and bundles and may evaluate on behalf of another subject; `developer` may simulate and read revisions; `auditor` reads decisions, bundles, engines and revisions."
  },
  {
   "name": "privacy",
   "x-displayName": "Privacy and data protection",
   "description": "Data protection services of the tenant: classification, DLP (data loss prevention), tokenization and envelope encryption.\n\n- **Classification**: detects personal and sensitive entities (email, phone, person, IBAN, credit card, French NIR, SIRET and SIREN, API keys, private keys, passwords, JWT...) with builtin recognizers or Presidio when configured, and gives the highest data classification found (`public` to `secret`).\n- **DLP**: applies a mode to the findings: `detect` (report only), `mask` (replace by `[TYPE]`), `tokenize` (replace by a reversible token) or `block` (empty the text). Tenant rules add patterns or entity types and may override the mode per entity, for example always block credit cards.\n- **Tokenization**: deterministic tokens `tok_<type>_<hex>` per tenant, the value kept encrypted in a vault; detokenizing needs an administrator role and an allow decision of the policy.\n- **Encryption keys**: named keys whose data keys are wrapped by OpenBao Transit (or locally), versioned and rotated; encrypt and decrypt return and accept `eaienc1:<key id>:<version>:...` ciphertexts.\n\nTypical flow:\n\n1. `POST /v1/dlp/rules` to add the patterns of the company.\n2. `POST /v1/dlp/redact` before sending a text to a model or a third party.\n3. `POST /v1/tokenization/tokenize` to store a pseudonymized value; `POST /v1/tokenization/detokenize` with a purpose to get it back.\n4. `POST /v1/encryption/keys`, then `POST /v1/encryption/encrypt` for application data; rotate keys regularly.\n\nRoles: any member of the tenant classifies, inspects, redacts, tokenizes, encrypts and decrypts, and reads rules and keys; `tenant_admin` or `security_officer` manage rules and keys and detokenize. DLP, tokenization and encryption calls write audit events, never with the values."
  },
  {
   "name": "prompts",
   "x-displayName": "Prompts",
   "description": "**Prompt registry**: versioned prompt templates with typed variables and validated rendering.\n\n**Main concepts**\n- **Prompt**: a named template. Placeholders are written `{{ variable }}`; each publication with a different template or variables creates a new immutable version, identified by a SHA-256 digest.\n- **Variable**: name, type (`string`, `integer`, `number`, `boolean`, `array`, `object`), required flag, default, `enum` and `max_length`. Without declared variables, every placeholder becomes a required string variable.\n- **Rendering**: values are checked against the declared variables before the text is produced; non string values are written as JSON.\n\n**Typical flow**\n1. Publish: `POST /v1/prompts` (first version, or a new version of an existing name).\n2. Review the history: `GET /v1/prompts/{name}/versions`.\n3. Render a version with values: `POST /v1/prompts/{name}/render`.\n\n**Roles**: publishing needs `tenant_admin` or `developer`; reading and rendering need a tenant principal."
  },
  {
   "name": "rag-agent",
   "x-displayName": "RAG Agent instances",
   "description": "**Activation and lifecycle of the Navin Enterprise RAG Agent instances.** The Control Plane owns the activation record of every instance (its status, its deployment model, its versions and the resources it owns), because in the dedicated model the RAG runtime does not exist yet when an instance is activated. The RAG runtime reads its activation from `GET /v1/rag-agent/instances/{instance_id}` and refuses to serve conversations unless the status is `ready` or `degraded` (`instance_not_ready`).\n\n**Statuses**: `draft`, `validating`, `provisioning`, `starting`, `ready`, `degraded`, `failed`, `stopping`, `stopped`, `updating`, `deleting`, `deleted`. The status says `ready` only after the `health` and `smoke` steps passed; the worker then follows the real health (`ready` and `degraded`).\n\n**Steps** (states `pending`, `running`, `done`, `failed`, `skipped`): `validation`, `resources` (governed application and agent of the instance), `database`, `object_storage` (key prefix in the documents storage profile), `qdrant` (knowledge base with `vector_store` qdrant), `memory` (memory policy of the agent), `security` (OpenFGA owner tuples, runtime API key kept as a secret reference), `deployment` (shared runtime declared by `EAI_RAG_AGENT_SHARED_RUNTIME_URL`, or the Navin Manager through the platform_manager bridge for a dedicated instance), `health`, `smoke`, `activation`. Every step keeps its attempts and its logs; a failed step names itself and its reason in `last_error`.\n\n**Transitions**: each action is accepted only from the statuses of its row in the transition table, else 409 `rag_agent_transition_invalid` (audited as a denial). Repeating an action that is done or in progress answers the current record with `changed: false`. Retrying the failed operation resumes the same run from its failed step; the steps already done are never run again. Provisioning, start, stop, restart, upgrade and deletion are long operations (`Operation-Id`, `Idempotency-Key`) run by the worker job `rag_agent_lifecycle`.\n\n**Deployment models**: `shared` points the instance to the existing shared runtime; start and stop change the status (and the governed application) only. `dedicated` asks the Navin Manager to install a named instance of the catalog service `navin-rag-agent`; while that service is not published in the catalog, the deployment step fails with the reason `service_not_published`.\n\n**Roles**: the writes need a tenant administrator or an owner of the project of the instance (403 `forbidden`); the reads need a principal of the tenant. Another tenant's instance answers 404 `rag_agent_instance_not_found`."
  },
  {
   "name": "realtime",
   "x-displayName": "Realtime voice",
   "description": "**Realtime voice** sessions: a LiveKit room token and a WebSocket event protocol to stream audio to an agent, with participant consent, turns, DLP filtered transcripts, optional recordings and metering.\n\n**Main concepts**\n- **Session**: a room, a pipeline (`echo`: transcript from the STT adapter or the client hint, audio echoed back; `stt`: STT adapter required), a configuration (`dlp_mode`, `vad`, `record`...), the caller identity, the agent and the user it acts for. Status `open` then `ended`.\n- **WebSocket**: `GET /v1/realtime/ws/{session_id}?token=...` (not listed in this reference, as a WebSocket route). Client events: `session.update`, `input_audio.append` (base64 PCM16), `input_audio.commit`, `input_audio.speech_started` (barge-in), `response.create`, `response.cancel`, `session.end`. Server events include `session.created`, `transcript.delta`, `response.audio.delta`, `response.done`, `response.cancelled`, `recording.saved`, `usage.update`, `error`, `session.ended`. The token is short lived and single use.\n- **Consent**: per participant, purpose, recording and transcription allowed, retention in days and capture method. Recording needs a consent that allows it; when the platform requires consent, transcription too (error `consent_required`). Transcripts and recordings expire with the consent retention.\n- **Transcripts** are stored after DLP only; the raw transcript is never stored.\n\n**Typical flow**\n1. Open a session: `POST /v1/realtime/sessions` (LiveKit token and WebSocket token).\n2. Record the consent of each participant: `POST .../consents`.\n3. Stream over the WebSocket; reconnect with a new token from `POST .../token`.\n4. End the session: `POST .../end` (usage recorded).\n5. Review `turns` and `transcripts`.\n\n**Roles**: writes need `tenant_admin`, `developer` or `agent`; transcripts need `tenant_admin`, `developer`, `auditor` or `security_officer`; other reads need a tenant principal (rows are read under the tenant row level security)."
  },
  {
   "name": "retention",
   "x-displayName": "Retention",
   "description": "How long the data of the tenant is kept, how it is purged, the erasure of a data subject (GDPR article 17) and legal holds.\n\n- **Retention policy**: per resource type (`memory`, `sessions`, `media`, `usage_raw`, `telemetry`, `documents`, `realtime`), a lifetime in days and an action, `erase` or `archive` (encrypted copy kept before deletion, memory only).\n- **Retention run**: applies the enabled policies now, or simulates them with `dry_run`.\n- **Erasure**: deletes everything the platform holds on one subject (memory, media, sessions, ended realtime sessions, optionally documents, Opik traces and ClickHouse analytics). The audit trail and the usage records are kept, as the law requires; the answer says so in `retained`.\n- **Legal hold**: freezes a resource or every resource of a subject; held items are skipped by runs and erasures.\n\nTypical flow:\n\n1. `POST /v1/retention/policies` sets the lifetime of each resource type.\n2. `POST /v1/retention/run` with `dry_run: true` shows what would be purged, then without it purges.\n3. On a data subject request, `POST /v1/retention/erase`; on litigation, `POST /v1/retention/legal-hold`.\n\nRoles: any member of the tenant reads the policies; `tenant_admin`, `security_officer` and `data_steward` change them, run, erase and hold. Every change writes an audit event (`retention.policy.upsert`, `retention.run`, `retention.erase`, `retention.legal_hold`)."
  },
  {
   "name": "risk",
   "x-displayName": "Risk and compliance",
   "description": "Risk management of the AI systems of the tenant: EU AI Act assessments, controls mapped to ISO/IEC 42001, NIST AI RMF, GDPR and the EU AI Act, evidence and time limited exceptions.\n\n- **Assessment**: classifies a target (agent, model, application...) from its declared use cases and answers into an EU AI Act category: `unacceptable` (Article 5 prohibited practice), `high` (Annex III area or safety component), `limited` (Article 50 transparency) or `minimal`, with the rationale and the obligations of that category. An assessment of an agent also updates the risk level of the agent in the registry.\n- **Control**: a control adopted by the tenant, from the builtin catalogue (`EAI-GOV-01`, `EAI-RISK-01`, `EAI-DATA-01`, `EAI-DATA-02`, `EAI-SEC-01`, `EAI-LOG-01`, `EAI-QA-01`, `EAI-QA-02`, `EAI-OPS-01`, `EAI-HUM-01`) or custom, with its status and owner.\n- **Evidence**: documents recorded on a control or an assessment, plus evidence collected automatically from the platform (inventory, DLP rules, retention, keys, audit chain, evaluations, red team runs, incidents, approvals).\n- **Exception**: a time limited waiver of a control or a target, at most 365 days, approved by someone other than the requester.\n\nTypical flow:\n\n1. `POST /v1/risk/assessments` before deploying an AI system.\n2. `POST /v1/risk/controls` to adopt the catalogue controls, with evidence.\n3. `GET /v1/risk/evidence` to prepare an audit.\n4. `POST /v1/risk/exceptions` when a control cannot be met yet, with compensating controls.\n\nRoles: any member of the tenant reads; `tenant_admin`, `security_officer`, `developer` and `ai_governance_officer` assess (only administrators and governance officers approve an assessment); `tenant_admin` and `security_officer` manage controls; they and `developer` request exceptions. Changes write audit events (`risk.assessment.create`, `risk.control.upsert`, `risk.exception.create`)."
  },
  {
   "name": "secrets",
   "x-displayName": "Secrets",
   "description": "Write only store of the tenant secrets: provider keys, connector passwords, tokens of MCP servers. Values are encrypted (in OpenBao when configured, otherwise with AES-GCM in the database) and are never returned by the API. Other objects refer to a secret by its path; the platform reads the value server side only when it needs it.\n\nTypical flow:\n\n1. `POST /v1/secrets` with a `path` such as `connectors/crm/password` and the `value`.\n2. Reference the path in a connector, a model provider or an MCP server.\n3. Write the same path again to rotate the value (the `version` grows); `DELETE /v1/secrets/{path}` removes it.\n\nRoles: `tenant_admin`, `security_officer` and `developer` write and delete secrets; a developer only overwrites or deletes the secrets they wrote. Any member of the tenant lists the metadata. Writes and deletions write the audit events `secret.write` and `secret.delete`, never with the value."
  },
  {
   "name": "security",
   "x-displayName": "Security",
   "description": "Security posture of the deployment and security settings of the tenant.\n\n- **Posture**: the protections in force (authentication methods, limits, headers) and a list of checks, each `pass`, `warn` or `fail` with a severity, for example whether development header authentication is off.\n- **Settings** of the tenant, stored with the tenant and merged with the defaults:\n  - `prompt_injection_mode`: `off`, `detect` or `block`;\n  - `untrusted_content_wrapping`: wrap tool and RAG content as data before it reaches a model (true or false);\n  - `output_links`: `allow` or `strip_untrusted` (links and images to unknown hosts removed from model output);\n  - `output_link_allowlist`: host names kept in model output;\n  - `egress_allowed_hosts`: when not empty, tools, connectors, MCP servers and providers of the tenant may only call these hosts. Only public host names are accepted (no IP address, no internal suffix such as `.internal` or `.local`); private access is a platform decision.\n\nRoles: `tenant_admin` and `security_officer`. Changes write the audit event `security.settings.update`."
  },
  {
   "name": "skills",
   "x-displayName": "Skills",
   "description": "**Skill Registry** and **Skill Loader**. A skill is a signed, versioned set of instructions (inline, or an artifact in Git or OCI) with the permissions it needs; agents load the skills granted in their manifest.\n\n**Main concepts**\n- **Skill**: a manifest of kind `Skill` with `instructions`, an optional `artifact` (`git_ref` or `oci_ref` and `digest`), a `signature` and `permissions` (`scopes`, `data_classification_max`).\n- **Verification**: the content digest and the signature are checked against the trusted publisher keys. A verified skill becomes `approved`, an unverified one stays `draft`.\n- **Statuses**: `draft`, `approved`, `restricted`, `deprecated`, `blocked`. A `blocked` or `deprecated` skill cannot be loaded.\n\n**Typical flow**\n1. Register the skill: `POST /v1/skills` with its manifest (verification runs at once).\n2. Verify it again when the keys change: `POST /v1/skills/{name}/verify`.\n3. An agent loads it at run time: `GET /v1/skills/{name}/load?agent=<agent>`.\n4. Restrict, deprecate or block it with `POST /v1/skills/{name}/status`; approval goes through a promotion.\n\n**Roles**: registration needs `tenant_admin`, `developer` or `application_owner`; verification also accepts `security_officer`; status changes need `tenant_admin` or `security_officer`. Routes on one skill check the ReBAC relation (`viewer`, `editor`, `can_invoke`)."
  },
  {
   "name": "soc",
   "x-displayName": "SOC and AI response",
   "description": "Security operations for AI (AI-SDR): detections, typed containment orders, the Kill Switch Registry, receipts, four eyes recovery, sealed incident evidence and reconciliation of side effecting transactions.\n\nConcepts:\n\n- **Detection**: a normalized finding (internal guard, DLP, egress, quotas, plugins, runtime, authz, policy, audit, knowledge, MCP, or external Falco, Tetragon and OpenSearch findings), scored, correlated into an incident and sealed as evidence. Its playbook of typed reactions is submitted to the Response Policy Engine.\n- **Containment order**: one typed reaction (never a command) on one typed target, for example `SUSPEND_AGENT` on an agent. The Response Policy Engine decides whether it is allowed, automatic or waiting for a second person (proportionality guard: confidence, blast radius, reactions that always need approval).\n- **Kill switch**: the record of a containment (desired state `SUSPENDED`), read by authentication, policy and the agents runtime; its observed state becomes `SUSPENDED_VERIFIED` only on a verified receipt.\n- **Recovery**: lifting a kill switch needs a request, two distinct SOC leads and a re-authorization by the policy.\n- **Evidence and custody**: append only, hash chained records per incident, and a second chain recording every seal, read and export.\n- **Transactions**: side effecting calls (payments, ERP writes) interrupted by an incident are reconciled by a person.\n\nTypical flow:\n\n1. A detection arrives (`POST /v1/soc/detections` or a signed webhook) and opens or joins an incident.\n2. Its playbook, or an analyst (`POST /v1/soc/orders`), orders a containment; a lead approves it when needed.\n3. The kill switch is verified (`POST /v1/soc/kill-switches/{switch_id}/verify`, or a signed in-cluster receipt).\n4. Once the threat is gone, `POST /v1/soc/recoveries`, two approvals, then `reauthorize`.\n\nRoles: analysts are `security_officer`, `soc_analyst` or `tenant_admin` for orders; leads are `security_officer` or `tenant_admin` (SOC lead); readers are `security_officer`, `tenant_admin`, `auditor` or `soc_analyst`. A refused access is audited (`soc.access.deny`) and every read is audited (`soc.access`)."
  },
  {
   "name": "storage",
   "x-displayName": "Storage",
   "description": "Storage profiles: the client buckets and containers the platform writes to (audit exports, evidence, documents, media, exports, backups), with their credential reference and their capabilities discovered by real calls.\n\n**Concepts**\n\n- A **profile** says where the data goes (provider `aws_s3`, `ibm_cos`, `seaweedfs`, `s3_compatible`, `azure_blob` or `gcs`; endpoint, region, bucket, key prefix, encryption, options) and how to authenticate (`auth` with non secret identifiers, `credential_ref` to the secret). Secret values are refused in the payload (422 `storage_secret_in_profile`) and never returned.\n- A **tenant** profile (scope `tenant`) uses an `openbao://` reference to a tenant secret; a **platform** profile (scope `platform`) uses an operator variable `env://EAI_CRED_<NAME>` or workload identity.\n- **Capabilities** (versioning, object lock, legal hold, retention, multipart, presign, encryption, KMS, storage classes, lifecycle, replication, integrity) are discovered by verification and stored with their time. A use that needs a missing, unknown or stale capability (older than `EAI_STORAGE_CAPABILITY_MAX_AGE_SECONDS`, one day by default) is refused with 409 `storage_capability_missing`. The purposes `audit_worm` and `evidence` need object lock and integrity (`audit_worm` also retention).\n- **Presign prefixes** bound the keys reachable through the API: presigned URLs, object listing and deletion only work inside them.\n\n**Typical flow**\n\n1. Store the credential in the secret store, then create the profile with `POST /v1/storage/profiles` (status `unverified`).\n2. Verify it with `POST /v1/storage/profiles/{profile_id}/verify`: status `verified`, `degraded` (a needed capability is missing) or `failed`.\n3. Issue presigned URLs with `POST /v1/storage/profiles/{profile_id}/presign`, list objects and delete them inside the presign prefixes.\n4. A change of provider, endpoint, region, bucket, authentication, encryption or options clears the capabilities: verify again.\n\n**Roles**: tenant profiles are managed by `tenant_admin` (verification also by `security_officer`) and read by `tenant_admin`, `security_officer`, `developer` and `auditor`; presigned URLs and object deletion by `tenant_admin`, `developer` and `agent`; object listing by `tenant_admin`, `developer`, `agent` and `auditor`. Platform profiles are managed by `platform_admin` only. Every action takes a policy decision first (403 `policy_denied`) and is audited."
  },
  {
   "name": "system",
   "x-displayName": "System",
   "description": "Technical endpoints of the Control Plane: liveness and readiness probes, description of the instance, identity of the caller, the catalog of platform bricks and the product roadmap.\n\n**Typical flow**\n\n1. Orchestrators probe `GET /healthz` (process alive) and `GET /readyz` (database reachable and migrated).\n2. A client reads `GET /v1/meta` to learn the API version, the locales, the loaded domains and which integrations are configured.\n3. After signing in, the client reads `GET /v1/me` to learn its principal, tenant, roles and scopes.\n\n**Access**: `/healthz`, `/readyz`, `/v1/meta`, the brick catalog and the roadmap need no authentication and are exempt from rate limiting for the probes; `/v1/me` needs an authenticated principal."
  },
  {
   "name": "telemetry",
   "x-displayName": "Telemetry",
   "description": "Traces, request journal, live stream and service level objectives (SLO) of the platform.\n\n**Spans**: applications and agents send OpenTelemetry spans (OTLP JSON `resourceSpans` or a simple `{spans: [...]}` list). PostgreSQL keeps a bounded summary of each span: trace and span ids, run, session, duration, status, cost, tokens and only a short allow list of attributes (no prompt, model output or business content). The full span is forwarded, best effort, to the configured exporters (Opik, OpenTelemetry collector, ClickHouse); the audit trail, not those stores, is the evidence.\n\n**SLO**: every request served by the API is counted per minute and per service (`control_plane_api`, `model_gateway`, `tool_gateway`, `realtime`): requests, errors (5xx) and requests slower than the latency target. The objectives of a service come from the database once a platform administrator wrote them, else from the `EAI_SLO_*` settings. The counters belong to the replica that served the request; the fleet view over 30 days comes from the Prometheus recording rules.\n\n**Typical flow**\n\n1. Send spans with `POST /v1/telemetry/spans`.\n2. Read the dashboard with `GET /v1/telemetry/overview`, the list with `GET /v1/telemetry/traces` and one trace with `GET /v1/telemetry/traces/{trace_id}`.\n3. Follow live activity with the Server-Sent Events of `GET /v1/telemetry/stream`.\n4. Check the error budgets with `GET /v1/telemetry/slo` and tune them with `PUT /v1/telemetry/slo/targets/{service}`.\n\n**Roles**: ingestion needs `tenant_admin`, `developer` or `agent`; traces list, logs, stream and SLO need `platform_admin`, `tenant_admin`, `auditor`, `viewer` or `support_engineer`; overview and one trace need any tenant principal; changing an objective needs `platform_admin`. Rows are always those of the caller's tenant."
  },
  {
   "name": "telephony",
   "x-displayName": "Telephony",
   "description": "**Telephony** (ADR-0173): enterprise PBX, SIP edge and AI voice agents of the tenant. Navin Enterprise keeps the data (trunks, extensions, numbers, routing rules, IVR flows, queues, human and AI agents, conferences, quotas), compiles the Asterisk managed files, the Kamailio routing tables and the LiveKit SIP objects per PBX pool, and publishes them to the engines through AMI, JSONRPC and Twirp with versions and rollback; it never runs a system command. The Navin Manager installs and operates the engines.\n\n**Typical flow**\n1. `platform_admin` declares the pool (`POST /v1/telephony/pbx-pools`) and assigns it (`PUT /v1/telephony/settings`), then sets the quotas (`PUT /v1/telephony/quotas`).\n2. The tenant administrator creates trunks, extensions, queues, IVR flows (and publishes a version), voice agents and numbers.\n3. `POST /v1/telephony/preview` or `POST .../pbx-pools/{pool_id}/preview` shows the compiled result and its problems.\n4. `POST .../pbx-pools/{pool_id}/publish` delivers it (202, long operation); `GET /v1/telephony/config-versions/{version_id}` follows it; `POST .../rollback` goes back.\n\n**Isolation**: every object belongs to the caller's tenant; an object of another tenant answers 404 and a reference to it 422. On the engines every name starts with the `tid` of the tenant and the compiler refuses a context naming another tenant. **Secrets** (SIP passwords, PINs, engine credentials) are write only and live in the vault; answers carry `has_*` flags. **Roles**: readers `tenant_admin`, `support_engineer`, `auditor`; writers `tenant_admin`; `platform_admin` for pools, quotas, shared pool publication and drain. Every change is audited."
  },
  {
   "name": "tenancy",
   "x-displayName": "Tenancy",
   "description": "Tenants, their hierarchy, projects, environments and members.\n\nConcepts:\n\n- **Tenant**: an isolated customer space. Every object of the platform belongs to one tenant; a credential only sees its own. Tenants are created by a platform administrator.\n- **Organization** and **business unit**: the hierarchy inside a tenant. An organization holds business units, which may be nested (`parent_id`, fixed at creation so that no cycle can appear).\n- **Project**: the workspace that owns agents, knowledge bases, quotas and secrets. It may be attached to an organization and one of its units. Callers select it with the `X-Project` header.\n- **Environment**: `dev`, `test`, `staging` or `prod`, at most one of each per project.\n- **Member**: a user (OIDC subject) with a role and a clearance in the tenant, optionally limited to a project.\n\nTypical flow:\n\n1. A platform administrator creates the tenant with `POST /v1/tenants` and names its first administrators in `admins`.\n2. The tenant administrator creates organizations and business units, then projects with their environments.\n3. The tenant administrator adds members with `POST /v1/members`, or lets directory group mappings (Identity tag) do it at sign in.\n\nRoles: `platform_admin` creates tenants and changes their status; `tenant_admin` manages the rest. Reading projects also needs the ReBAC relation `viewer` on the project; changing it `editor`; deleting it `owner` (the creator gets `owner`). Hierarchy objects carry `version`: send `expected_version` on PATCH to avoid overwriting a concurrent change. Every change writes an audit event (`tenant.*`, `organization.*`, `business_unit.*`, `project.*`, `environment.create`, `member.*`)."
  },
  {
   "name": "tools",
   "x-displayName": "Tools",
   "description": "**Tool Registry** and **Tool Gateway**. A tool is a declared action with an input schema, an endpoint (`http`, `mcp`, `builtin`, `sandbox`), a data classification, a risk level and optional approval, rate limit and cost. Every call goes through the gateway, which applies the controls and records an invocation.\n\n**Gateway pipeline** (`POST /v1/tools/{name}/invoke`)\n1. Status: a `blocked` or `deprecated` tool is refused; a third party application must be active and granted the tool.\n2. Scopes: `tools:invoke` plus the scopes the tool requires.\n3. Arguments: validated against the tool `input_schema`.\n4. Agent grant and classification: with `agent_id`, the tool must be listed in the agent manifest and the classification within the agent ceiling.\n5. Policy `tool.invoke`, then DLP on the arguments.\n6. Human approval when the tool, the agent grant, a policy obligation or `autonomy.human_approval_for` requires it.\n7. Rate limit, quota reservation, execution with server side credentials, DLP and prompt injection screening of the result, usage event.\n\n**Roles**: registration needs `tenant_admin`, `developer` or `application_owner`; status changes need `tenant_admin` or `security_officer`; deletion needs `tenant_admin`; invocation needs `tenant_admin`, `developer` or `agent`. Routes on one tool check the ReBAC relation (`viewer`, `editor`, `owner`, `can_invoke`)."
  }
 ],
 "x-tagGroups": [
  {
   "name": "Identity and access",
   "tags": [
    "identity",
    "auth",
    "authz",
    "delegation",
    "context",
    "secrets"
   ]
  },
  {
   "name": "Tenancy",
   "tags": [
    "tenancy"
   ]
  },
  {
   "name": "Agents and AI",
   "tags": [
    "agents",
    "llm",
    "llm-management",
    "prompts",
    "skills",
    "memory",
    "multimodal",
    "realtime",
    "evaluation"
   ]
  },
  {
   "name": "Knowledge and data",
   "tags": [
    "knowledge",
    "storage",
    "lineage",
    "navin-library"
   ]
  },
  {
   "name": "Tools and integrations",
   "tags": [
    "tools",
    "mcp",
    "mcp-runtime",
    "connectors",
    "channels",
    "plugins",
    "marketplace",
    "applications",
    "developer"
   ]
  },
  {
   "name": "Governance and compliance",
   "tags": [
    "governance",
    "policies",
    "approvals",
    "contracts",
    "risk",
    "privacy",
    "retention",
    "evidence",
    "audit"
   ]
  },
  {
   "name": "Security",
   "tags": [
    "security",
    "file-security",
    "soc",
    "incidents"
   ]
  },
  {
   "name": "FinOps",
   "tags": [
    "finops"
   ]
  },
  {
   "name": "Platform operations",
   "tags": [
    "operations",
    "platform-manager",
    "licensing",
    "telemetry",
    "system"
   ]
  },
  {
   "name": "Other",
   "tags": [
    "compliance",
    "rag-agent",
    "telephony"
   ]
  }
 ]
}
