{
  "openapi": "3.1.0",
  "info": {
    "title": "PromptGuard Developer API",
    "description": "Public API for developers to integrate PromptGuard security into their applications",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.promptguard.co",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/v1/chat/completions": {
      "post": {
        "summary": "Proxy Chat Completions",
        "description": "Proxy OpenAI-style chat completions through policy engine",
        "operationId": "proxy_chat_completions_api_v1_chat_completions_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/messages": {
      "post": {
        "summary": "Proxy Messages",
        "description": "Proxy Anthropic-style messages endpoint through policy engine.\n\nThis endpoint accepts requests from native Anthropic SDK (messages.create()).\nIt routes through the same handler as /chat/completions, and providers\nhandle endpoint mapping internally.",
        "operationId": "proxy_messages_api_v1_messages_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/responses": {
      "post": {
        "summary": "Proxy Responses",
        "description": "Proxy OpenAI's Responses API through the policy engine.\n\nSame handler as the other two routes, because the scanning path is shaped\nby the *body*, not the URL: `normalize_request` reads `instructions` and\n`input` alongside `system` and `messages`, `_text_segments` reads `output`\nalongside `choices`, and the SSE accumulator already recognises the\n`response.*` frame family.\n\nThat ordering is the point. This route did not exist for as long as those\nthree did not \u2014 a passthrough that forwarded a Responses body would have\nfound no `messages`, no `choices` and no known frames, and returned `allow`\non every request without scanning a single byte. Adding the route before\nteaching the parsers its shape would have shipped a hole, not a feature.",
        "operationId": "proxy_responses_api_v1_responses_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/messages/count_tokens": {
      "post": {
        "summary": "Proxy Count Tokens",
        "description": "Proxy Anthropic's token-counting endpoint.\n\nA compatibility gap rather than a security surface: an Anthropic SDK pointed\nat PromptGuard breaks on `client.messages.count_tokens()` because we did not\nserve the route. It counts tokens and returns a number -- nothing reaches a\nmodel and nothing is generated, so there is no completion to scan.\n\nThe request still goes through the same handler as the rest, which means the\nprompt IS scanned on the way in. That is deliberate: the body is a full\n`messages` array, so it is a place a caller could otherwise probe or stage\ncontent with no policy applied.\n\nNote this is NOT what enforces `max_tokens_per_request`. That runs inline on\nevery request and must not make a network call to do it -- see\nshared/security/token_limiter.py.",
        "operationId": "proxy_count_tokens_api_v1_messages_count_tokens_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/models": {
      "get": {
        "summary": "Proxy Models",
        "description": "Proxy models endpoint.\n\nNote: Returns OpenAI models by default. To get provider-specific models,\nclient should query the provider directly or we could add provider\nparameter.",
        "operationId": "proxy_models_api_v1_models_get",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/api-keys": {
      "get": {
        "tags": [
          "api-keys"
        ],
        "summary": "List Api Keys",
        "description": "List all API keys for the current user",
        "operationId": "list_api_keys_api_v1_api_keys_get",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ApiKeyResponse"
                  },
                  "title": "Response List Api Keys Api V1 Api Keys Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "api-keys"
        ],
        "summary": "Create Api Key",
        "description": "Create a new API key",
        "operationId": "create_api_key_api_v1_api_keys_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateApiKeyResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/api-keys/{key_id}": {
      "delete": {
        "tags": [
          "api-keys"
        ],
        "summary": "Delete Api Key",
        "description": "Delete an API key",
        "operationId": "delete_api_key_api_v1_api_keys__key_id__delete",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key Id"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/api-keys/{key_id}/toggle": {
      "put": {
        "tags": [
          "api-keys"
        ],
        "summary": "Toggle Api Key",
        "description": "Toggle API key active status",
        "operationId": "toggle_api_key_api_v1_api_keys__key_id__toggle_put",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key Id"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/api-keys/{key_id}/reveal": {
      "get": {
        "tags": [
          "api-keys"
        ],
        "summary": "Reveal Api Key",
        "description": "Reveal the full API key for copying.",
        "operationId": "reveal_api_key_api_v1_api_keys__key_id__reveal_get",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key Id"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyFullResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/usage/stats": {
      "get": {
        "tags": [
          "usage"
        ],
        "summary": "Get Usage Stats",
        "description": "Get current user's usage statistics",
        "operationId": "get_usage_stats_api_v1_usage_stats_get",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects": {
      "get": {
        "tags": [
          "projects"
        ],
        "summary": "List Projects",
        "description": "List all projects for the current user",
        "operationId": "list_projects_api_v1_projects_get",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/developer__projects__schemas__ProjectResponse"
                  },
                  "title": "Response List Projects Api V1 Projects Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "projects"
        ],
        "summary": "Create Project",
        "description": "Create a new project",
        "operationId": "create_project_api_v1_projects_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/developer__projects__schemas__CreateProjectRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/developer__projects__schemas__ProjectResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{project_id}": {
      "get": {
        "tags": [
          "projects"
        ],
        "summary": "Get Project",
        "description": "Get a specific project",
        "operationId": "get_project_api_v1_projects__project_id__get",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Project Id"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/developer__projects__schemas__ProjectResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "projects"
        ],
        "summary": "Delete Project",
        "description": "Delete a project",
        "operationId": "delete_project_api_v1_projects__project_id__delete",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Project Id"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/validate-tool": {
      "post": {
        "tags": [
          "agent"
        ],
        "summary": "Validate Tool Call",
        "description": "Validate a tool call before execution.\n\nThis endpoint should be called before allowing an AI agent\nto execute any tool/function call. It validates:\n- Tool is in allowed list\n- Arguments are safe (no injection, no sensitive paths)\n- Agent hasn't exceeded rate limits\n- Behavior is consistent with previous patterns",
        "operationId": "validate_tool_call_api_v1_agent_validate_tool_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/developer__agent__router__ToolCallRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/developer__agent__router__ToolCallResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Monthly quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/trace": {
      "post": {
        "tags": [
          "agent"
        ],
        "summary": "Ingest Agent Trace",
        "description": "Ingest a full agent execution trace and run the trace-level detectors.\n\nRuns the value-level dataflow-taint analyzer (``FLOW001``, fail-open) and\nthe goal-alignment auditor (fail-closed by its own design, opt-in) over the\ntrace, aggregates their outputs into an allow / warn / block decision, and\npersists a ``security_event``. Fails open: a detector or DB hiccup never\n500s the caller.",
        "operationId": "ingest_agent_trace_api_v1_agent_trace_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentTraceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentTraceResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Monthly quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/memory": {
      "post": {
        "tags": [
          "agent"
        ],
        "summary": "Scan Agent Memory",
        "description": "Scan a chunk of agent memory for poisoning (OWASP Agentic ASI06).\n\nA poisoned memory chunk is persisted, so it can be written once and fire in\na later session against a different user. Payloads are often latent \u2014 they\narm rather than act (\"when asked about X, do Y\") \u2014 so this detects\nconditional triggers as well as direct injection vocabulary.\n\nScan on `write` to stop the plant, and on `read` to catch chunks poisoned\nthrough another path. Fails open: a detector or database error returns a\ndecision rather than an error response.",
        "operationId": "scan_agent_memory_api_v1_agent_memory_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentMemoryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentMemoryResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Monthly quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/{agent_id}/stats": {
      "get": {
        "tags": [
          "agent"
        ],
        "summary": "Get Agent Stats",
        "description": "Get statistics for an agent.",
        "operationId": "get_agent_stats_api_v1_agent__agent_id__stats_get",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Agent Id"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentStats"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/{agent_id}/session/{session_id}": {
      "delete": {
        "tags": [
          "agent"
        ],
        "summary": "End Agent Session",
        "description": "Deprecated no-op. Agent session state is not retained server-side across\nrequests, so there is nothing to end. Returns 200 for compatibility;\nscheduled for removal \u2014 see the Sunset header.",
        "operationId": "end_agent_session_api_v1_agent__agent_id__session__session_id__delete",
        "deprecated": true,
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Agent Id"
            }
          },
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/register": {
      "post": {
        "tags": [
          "agent"
        ],
        "summary": "Register Agent",
        "description": "Register a new agent and return a one-time-visible credential.",
        "operationId": "register_agent_api_v1_agent_register_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentRegisterRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRegisterResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Monthly quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/{agent_id}/rotate-credential": {
      "post": {
        "tags": [
          "agent"
        ],
        "summary": "Rotate Agent Credential",
        "description": "Revoke the current credential and issue a new one.",
        "operationId": "rotate_agent_credential_api_v1_agent__agent_id__rotate_credential_post",
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Agent Id"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentRotateResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Monthly quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "A concurrent rotation won, or the agent has no active credential",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/health": {
      "get": {
        "tags": [
          "agent"
        ],
        "summary": "Agent Security Health",
        "description": "Health check for agent security service.",
        "operationId": "agent_security_health_api_v1_agent_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/managed-policy": {
      "get": {
        "tags": [
          "agent"
        ],
        "summary": "Managed Policy",
        "description": "The org-managed update policy for this enrolled device (resolved from the\nAPI key's org + its ``shadow_ai_fleet`` entitlement). The desktop agent polls\nthis and lets it override the local user preference (managed wins).",
        "operationId": "managed_policy_api_v1_agent_managed_policy_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManagedPolicyResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/security/scan": {
      "post": {
        "tags": [
          "security"
        ],
        "summary": "Scan Content",
        "description": "Scan content for security threats without proxying to an LLM.\n\nUses the same policy engine, ML ensemble, and preset configuration\nas the proxy pipeline. Each call is persisted to ``security_events``\nso the dashboard, audit log, and billing usage all match what the\nSDK / Playground actually sent.",
        "operationId": "scan_content_api_v1_security_scan_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScanRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Monthly quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/security/redact": {
      "post": {
        "tags": [
          "security"
        ],
        "summary": "Redact Content",
        "description": "Redact PII from content without proxying to an LLM.\n\nReturns the original text, the redacted version, and a list of\nPII types that were found and replaced.\n\nPass ``pii_types`` to redact only the entity types you name; omit it and\nthe policy's configured entities apply. ``piiFound`` reports the concrete\ndetector entities that matched, so a request for the ``phone`` family can\ncome back as ``[\"phone_us\"]``.",
        "operationId": "redact_content_api_v1_security_redact_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RedactRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RedactResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Monthly quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaErrorEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "Unrecognized entity name in pii_types",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/guard": {
      "post": {
        "tags": [
          "guard"
        ],
        "summary": "Guard Content",
        "description": "Scan messages for security threats without proxying to an LLM.\n\nThis is the primary endpoint for auto-instrumentation and framework\ncallback integrations. It runs the same policy engine, ML ensemble,\npreset configuration, custom rules, and entitlements checks as the\nproxy pipeline.\n\nUse ``direction=\"input\"`` before sending messages to the LLM and\n``direction=\"output\"`` after receiving a response.\n\nReturns a decision of ``allow``, ``block``, or ``redact`` along with\ndetailed threat information and optional redacted messages.",
        "operationId": "guard_content_api_v1_guard_post",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GuardRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GuardResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Monthly quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/enroll": {
      "post": {
        "tags": [
          "enroll"
        ],
        "summary": "Enroll Device",
        "operationId": "enroll_device_api_v1_enroll_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnrollRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnrollResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/exceptions": {
      "post": {
        "tags": [
          "shadow-exceptions"
        ],
        "summary": "Create Exception",
        "operationId": "create_exception_api_v1_exceptions_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExceptionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "shadow-exceptions"
        ],
        "summary": "List Exceptions",
        "operationId": "list_exceptions_api_v1_exceptions_get",
        "parameters": [
          {
            "name": "status_filter",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Status Filter"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/exceptions/active": {
      "get": {
        "tags": [
          "shadow-exceptions"
        ],
        "summary": "List Active Grants",
        "description": "The destinations this agent may currently send to via an approved grant.\nThe interceptor caches these and lets matching sends through.",
        "operationId": "list_active_grants_api_v1_exceptions_active_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/exceptions/{exception_id}": {
      "get": {
        "tags": [
          "shadow-exceptions"
        ],
        "summary": "Get Exception",
        "operationId": "get_exception_api_v1_exceptions__exception_id__get",
        "parameters": [
          {
            "name": "exception_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Exception Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/exceptions/{exception_id}/cancel": {
      "post": {
        "tags": [
          "shadow-exceptions"
        ],
        "summary": "Cancel Exception",
        "operationId": "cancel_exception_api_v1_exceptions__exception_id__cancel_post",
        "parameters": [
          {
            "name": "exception_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Exception Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/policies": {
      "get": {
        "tags": [
          "policies"
        ],
        "summary": "List Policies",
        "description": "Active policies enforced on this device: the project's own + the\naccount's global (project-less) policies, highest-priority first.",
        "operationId": "list_policies_api_v1_policies_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentPoliciesResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/overlays/preview": {
      "post": {
        "tags": [
          "overlays"
        ],
        "summary": "Preview Overlay",
        "description": "Evaluate a candidate overlay in shadow against a traffic sample.",
        "operationId": "preview_overlay_api_v1_overlays_preview_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OverlayPreviewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShadowReportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/overlays/apply": {
      "post": {
        "tags": [
          "overlays"
        ],
        "summary": "Apply Overlay Endpoint",
        "description": "Promote the overlay to active as a new version for the key's scope.",
        "operationId": "apply_overlay_endpoint_api_v1_overlays_apply_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OverlayApplyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OverlayOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/overlays/active": {
      "get": {
        "tags": [
          "overlays"
        ],
        "summary": "Get Active Overlay",
        "description": "Return the current active overlay for the key's scope, if any.",
        "operationId": "get_active_overlay_api_v1_overlays_active_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/OverlayOut"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Response Get Active Overlay Api V1 Overlays Active Get"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool-requests": {
      "get": {
        "tags": [
          "tool-requests"
        ],
        "summary": "List Tool Requests",
        "operationId": "list_tool_requests_api_v1_tool_requests_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "tool-requests"
        ],
        "summary": "Create Tool Request",
        "operationId": "create_tool_request_api_v1_tool_requests_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateToolRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool-requests/{request_id}/cancel": {
      "post": {
        "tags": [
          "tool-requests"
        ],
        "summary": "Cancel Tool Request",
        "operationId": "cancel_tool_request_api_v1_tool_requests__request_id__cancel_post",
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Request Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/github/webhook": {
      "post": {
        "tags": [
          "GitHub Webhooks"
        ],
        "summary": "Handle Webhook",
        "description": "Receive and process GitHub App webhook events.",
        "operationId": "handle_webhook_api_v1_github_webhook_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "summary": "Root",
        "description": "API root endpoint.\n\nSECURITY: Intentionally does NOT return ``version`` or\n``environment`` to unauthenticated callers. These are useful only\nto attackers correlating CVEs against deployed builds. Build info\nlives behind ``/dashboard/version``.",
        "operationId": "root__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Health",
        "description": "Health check endpoint.\n\nIntentionally does NOT return ``version`` or ``environment`` to\nunauthenticated callers. These are useful only to attackers\ncorrelating CVEs against deployed builds; uptime monitors only need\nthe ``status`` field. Authenticated build-info lives behind\n``/dashboard/version``.",
        "operationId": "health_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/version": {
      "get": {
        "summary": "Version",
        "description": "Public version probe.\n\nSECURITY: Intentionally returns ONLY a constant string, never the\nactual version, build SHA, or environment label. Build/version\nmetadata is privileged information used for CVE-correlation by\nattackers and is therefore moved behind authenticated\n``/dashboard/version``. The endpoint stays here so old deploy\nsmoke tests still get a 200, but the body is meaningless.",
        "operationId": "version_version_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "type": "object",
                  "title": "Response Version Version Get"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AgentMemoryRequest": {
        "properties": {
          "content": {
            "type": "string",
            "title": "Content",
            "description": "The memory chunk to scan"
          },
          "direction": {
            "type": "string",
            "title": "Direction",
            "description": "'write' before persisting a chunk, 'read' when a stored chunk is retrieved. Scan both: a chunk poisoned before this endpoint existed, or written through another path, is only catchable on read.",
            "default": "write"
          },
          "memory_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Memory Id",
            "description": "Your identifier for the chunk"
          }
        },
        "type": "object",
        "required": [
          "content"
        ],
        "title": "AgentMemoryRequest",
        "description": "Content being written to, or read back from, an agent's memory."
      },
      "AgentMemoryResponse": {
        "properties": {
          "decision": {
            "type": "string",
            "title": "Decision"
          },
          "detected": {
            "type": "boolean",
            "title": "Detected"
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "default": ""
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "default": 0.0
          },
          "match_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Match Type"
          },
          "content_hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Hash"
          },
          "event_id": {
            "type": "string",
            "title": "Event Id"
          }
        },
        "type": "object",
        "required": [
          "decision",
          "detected",
          "event_id"
        ],
        "title": "AgentMemoryResponse",
        "description": "Verdict on one memory chunk."
      },
      "AgentPoliciesResponse": {
        "properties": {
          "policies": {
            "items": {
              "$ref": "#/components/schemas/developer__policies__router__AgentPolicy"
            },
            "type": "array",
            "title": "Policies"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          }
        },
        "type": "object",
        "required": [
          "policies",
          "total"
        ],
        "title": "AgentPoliciesResponse"
      },
      "AgentRegisterRequest": {
        "properties": {
          "agent_name": {
            "type": "string",
            "title": "Agent Name"
          },
          "allowed_tools": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allowed Tools"
          }
        },
        "type": "object",
        "required": [
          "agent_name"
        ],
        "title": "AgentRegisterRequest",
        "description": "Request to register a new agent identity."
      },
      "AgentRegisterResponse": {
        "properties": {
          "agent_id": {
            "type": "string",
            "title": "Agent Id"
          },
          "agent_name": {
            "type": "string",
            "title": "Agent Name"
          },
          "agent_secret": {
            "type": "string",
            "title": "Agent Secret"
          },
          "credential_prefix": {
            "type": "string",
            "title": "Credential Prefix"
          }
        },
        "type": "object",
        "required": [
          "agent_id",
          "agent_name",
          "agent_secret",
          "credential_prefix"
        ],
        "title": "AgentRegisterResponse",
        "description": "Response from agent registration \u2014 secret is shown only once."
      },
      "AgentRotateResponse": {
        "properties": {
          "agent_id": {
            "type": "string",
            "title": "Agent Id"
          },
          "new_secret": {
            "type": "string",
            "title": "New Secret"
          },
          "credential_prefix": {
            "type": "string",
            "title": "Credential Prefix"
          },
          "old_credential_revoked": {
            "type": "boolean",
            "title": "Old Credential Revoked"
          }
        },
        "type": "object",
        "required": [
          "agent_id",
          "new_secret",
          "credential_prefix",
          "old_credential_revoked"
        ],
        "title": "AgentRotateResponse",
        "description": "Response from credential rotation."
      },
      "AgentStats": {
        "properties": {
          "agent_id": {
            "type": "string",
            "title": "Agent Id"
          },
          "total_tool_calls": {
            "type": "integer",
            "title": "Total Tool Calls"
          },
          "blocked_calls": {
            "type": "integer",
            "title": "Blocked Calls"
          },
          "avg_risk_score": {
            "type": "number",
            "title": "Avg Risk Score"
          },
          "active_sessions": {
            "type": "integer",
            "title": "Active Sessions",
            "description": "Always 0. Agent session state is not retained across requests; this field is deprecated and will be removed in the next API version.",
            "default": 0,
            "deprecated": true
          },
          "anomalies_detected": {
            "type": "integer",
            "title": "Anomalies Detected"
          }
        },
        "type": "object",
        "required": [
          "agent_id",
          "total_tool_calls",
          "blocked_calls",
          "avg_risk_score",
          "anomalies_detected"
        ],
        "title": "AgentStats",
        "description": "Statistics for an agent"
      },
      "AgentToolLabels": {
        "properties": {
          "untrusted_content": {
            "type": "boolean",
            "title": "Untrusted Content",
            "default": false
          },
          "private_data": {
            "type": "boolean",
            "title": "Private Data",
            "default": false
          },
          "public_sink": {
            "type": "boolean",
            "title": "Public Sink",
            "default": false
          },
          "destructive": {
            "type": "boolean",
            "title": "Destructive",
            "default": false
          }
        },
        "type": "object",
        "title": "AgentToolLabels",
        "description": "Capability profile for one tool along the four lethal-trifecta axes."
      },
      "AgentTraceEvent": {
        "properties": {
          "role": {
            "type": "string",
            "title": "Role",
            "default": ""
          },
          "tool_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tool Name"
          },
          "arguments": {
            "additionalProperties": true,
            "type": "object",
            "title": "Arguments"
          },
          "output": {
            "title": "Output"
          },
          "content": {
            "type": "string",
            "title": "Content",
            "default": ""
          },
          "thought": {
            "type": "string",
            "title": "Thought",
            "default": ""
          }
        },
        "type": "object",
        "title": "AgentTraceEvent",
        "description": "One event of a full agent execution trace.\n\nAn event with a ``tool_name`` is a tool call: its ``arguments`` (a sink's\ninputs) and ``output`` (a source of taint) drive the trace-level detectors.\nEvents without one are plain assistant / user turns, kept as context."
      },
      "AgentTraceFinding": {
        "properties": {
          "detector": {
            "type": "string",
            "title": "Detector"
          },
          "code": {
            "type": "string",
            "title": "Code"
          },
          "severity": {
            "type": "string",
            "title": "Severity"
          },
          "reason": {
            "type": "string",
            "title": "Reason"
          },
          "decision": {
            "type": "string",
            "title": "Decision"
          },
          "metadata": {
            "additionalProperties": true,
            "type": "object",
            "title": "Metadata"
          }
        },
        "type": "object",
        "required": [
          "detector",
          "code",
          "severity",
          "reason",
          "decision"
        ],
        "title": "AgentTraceFinding",
        "description": "A single detector hit, normalized across detectors."
      },
      "AgentTraceRequest": {
        "properties": {
          "user_objective": {
            "type": "string",
            "title": "User Objective",
            "default": ""
          },
          "events": {
            "items": {
              "$ref": "#/components/schemas/AgentTraceEvent"
            },
            "type": "array",
            "title": "Events"
          },
          "tool_labels": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/AgentToolLabels"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tool Labels"
          }
        },
        "type": "object",
        "title": "AgentTraceRequest",
        "description": "A full agent execution trace to audit post-hoc.\n\nUnlike ``/validate-tool`` (a pre-execution check of a single tool name +\nargs), this carries the whole chronological trace *with tool outputs* plus\nthe user's original objective, so the value-level dataflow-taint and\ngoal-alignment detectors can fire."
      },
      "AgentTraceResponse": {
        "properties": {
          "decision": {
            "type": "string",
            "title": "Decision"
          },
          "findings": {
            "items": {
              "$ref": "#/components/schemas/AgentTraceFinding"
            },
            "type": "array",
            "title": "Findings",
            "default": []
          },
          "event_id": {
            "type": "string",
            "title": "Event Id"
          }
        },
        "type": "object",
        "required": [
          "decision",
          "event_id"
        ],
        "title": "AgentTraceResponse",
        "description": "Aggregated verdict over the ingested trace."
      },
      "ApiKeyFullResponse": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "prefix": {
            "type": "string",
            "title": "Prefix"
          },
          "key": {
            "type": "string",
            "title": "Key"
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "prefix",
          "key"
        ],
        "title": "ApiKeyFullResponse",
        "description": "Response containing the full API key for copy functionality"
      },
      "ApiKeyResponse": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "prefix": {
            "type": "string",
            "title": "Prefix"
          },
          "key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Key"
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Id"
          },
          "project_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Name"
          },
          "permissions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Permissions"
          },
          "is_active": {
            "type": "boolean",
            "title": "Is Active"
          },
          "last_used_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Used At"
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "prefix",
          "project_id",
          "project_name",
          "permissions",
          "is_active",
          "last_used_at",
          "created_at"
        ],
        "title": "ApiKeyResponse"
      },
      "AuthErrorEnvelope": {
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail",
            "examples": [
              {
                "code": "missing_api_key",
                "message": "PromptGuard API key required. Please provide via X-API-Key header.",
                "type": "authentication_error"
              }
            ]
          }
        },
        "type": "object",
        "required": [
          "error"
        ],
        "title": "AuthErrorEnvelope"
      },
      "ContextDoc": {
        "properties": {
          "content": {
            "type": "string",
            "maxLength": 100000,
            "title": "Content",
            "description": "Document text content"
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Source identifier (URL, doc ID, etc.)"
          },
          "metadata": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Metadata",
            "description": "Extra metadata"
          }
        },
        "type": "object",
        "required": [
          "content"
        ],
        "title": "ContextDoc",
        "description": "A document retrieved by a RAG pipeline to be scanned for poisoning."
      },
      "CreateApiKeyRequest": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 50,
            "minLength": 1,
            "title": "Name",
            "description": "API key name"
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Id"
          },
          "permissions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Permissions",
            "default": []
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At"
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "CreateApiKeyRequest"
      },
      "CreateApiKeyResponse": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key"
          },
          "id": {
            "type": "string",
            "title": "Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "prefix": {
            "type": "string",
            "title": "Prefix"
          }
        },
        "type": "object",
        "required": [
          "key",
          "id",
          "name",
          "prefix"
        ],
        "title": "CreateApiKeyResponse"
      },
      "CreateExceptionRequest": {
        "properties": {
          "destination_host": {
            "type": "string",
            "maxLength": 255,
            "title": "Destination Host"
          },
          "policy_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "title": "Policy Id"
          },
          "threat": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "title": "Threat"
          },
          "reason_category": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason Category"
          },
          "justification": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Justification"
          },
          "requested_minutes": {
            "type": "integer",
            "maximum": 1440.0,
            "minimum": 1.0,
            "title": "Requested Minutes",
            "default": 60
          }
        },
        "type": "object",
        "required": [
          "destination_host"
        ],
        "title": "CreateExceptionRequest"
      },
      "CreateToolRequest": {
        "properties": {
          "requested_host": {
            "type": "string",
            "maxLength": 255,
            "title": "Requested Host"
          },
          "requested_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "title": "Requested Name"
          },
          "justification": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Justification"
          }
        },
        "type": "object",
        "required": [
          "requested_host"
        ],
        "title": "CreateToolRequest"
      },
      "DivergenceItemOut": {
        "properties": {
          "text_preview": {
            "type": "string",
            "title": "Text Preview"
          },
          "category": {
            "type": "string",
            "title": "Category"
          },
          "base_decision": {
            "type": "string",
            "title": "Base Decision"
          },
          "base_confidence": {
            "type": "number",
            "title": "Base Confidence"
          },
          "candidate_decision": {
            "type": "string",
            "title": "Candidate Decision"
          },
          "candidate_confidence": {
            "type": "number",
            "title": "Candidate Confidence"
          },
          "divergence": {
            "type": "string",
            "title": "Divergence"
          }
        },
        "type": "object",
        "required": [
          "text_preview",
          "category",
          "base_decision",
          "base_confidence",
          "candidate_decision",
          "candidate_confidence",
          "divergence"
        ],
        "title": "DivergenceItemOut"
      },
      "EnrollRequest": {
        "properties": {
          "token": {
            "type": "string",
            "title": "Token",
            "description": "Enrollment token from the admin"
          },
          "device_name": {
            "type": "string",
            "maxLength": 255,
            "title": "Device Name",
            "description": "Hostname / device label"
          },
          "platform": {
            "type": "string",
            "title": "Platform",
            "description": "macos | windows | browser | linux",
            "default": "macos"
          },
          "end_user_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "title": "End User Id",
            "description": "Employee attribution label"
          },
          "coverage": {
            "type": "string",
            "title": "Coverage",
            "description": "Capture tier the agent is running: 'extension' or 'proxy'",
            "default": "proxy"
          }
        },
        "type": "object",
        "required": [
          "token",
          "device_name"
        ],
        "title": "EnrollRequest"
      },
      "EnrollResponse": {
        "properties": {
          "api_key": {
            "type": "string",
            "title": "Api Key"
          },
          "project_id": {
            "type": "string",
            "title": "Project Id"
          },
          "device_id": {
            "type": "string",
            "title": "Device Id"
          },
          "organization_id": {
            "type": "string",
            "title": "Organization Id"
          },
          "enforced": {
            "type": "boolean",
            "title": "Enforced",
            "default": false
          },
          "mode": {
            "type": "string",
            "title": "Mode",
            "default": "enforce"
          },
          "fail_closed": {
            "type": "boolean",
            "title": "Fail Closed",
            "default": true
          },
          "end_user_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "End User Label"
          },
          "account_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Name"
          },
          "account_type": {
            "type": "string",
            "title": "Account Type",
            "default": "personal"
          }
        },
        "type": "object",
        "required": [
          "api_key",
          "project_id",
          "device_id",
          "organization_id"
        ],
        "title": "EnrollResponse"
      },
      "ErrorDetail": {
        "properties": {
          "message": {
            "type": "string",
            "title": "Message",
            "description": "Human-readable error description"
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "Error category, e.g. 'authentication_error'"
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Machine-readable error code"
          }
        },
        "type": "object",
        "required": [
          "message",
          "type",
          "code"
        ],
        "title": "ErrorDetail"
      },
      "ErrorEnvelope": {
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        },
        "type": "object",
        "required": [
          "error"
        ],
        "title": "ErrorEnvelope"
      },
      "GuardContext": {
        "properties": {
          "framework": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Framework",
            "description": "Framework name, e.g. 'langchain', 'crewai'"
          },
          "chain_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Chain Name",
            "description": "LangChain chain name or pipeline identifier"
          },
          "agent_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Id",
            "description": "Agent identifier for multi-agent systems"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Session identifier for multi-turn tracking"
          },
          "tool_calls": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array",
                "maxItems": 64
              },
              {
                "type": "null"
              }
            ],
            "title": "Tool Calls",
            "description": "Tool calls in this turn. The tool NAME and its ARGUMENTS are assembled into the scanned text and get the same detection stack as the messages \u2014 tool arguments are where an exfiltration payload actually travels, so they are scanned rather than logged. Both provider spellings are read: OpenAI's `{'type':'function','function':{'name','arguments'}}` and Anthropic's `{'type':'tool_use','name','input'}`, plus LangChain's `{'name','args'}`. A call in none of those shapes is reported in the response's `unscanned` array with its position; it is never quietly skipped."
          },
          "metadata": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Metadata",
            "description": "Arbitrary framework-specific metadata (not scanned)"
          }
        },
        "type": "object",
        "title": "GuardContext",
        "description": "Optional rich context from framework integrations.\n\nOnly ``tool_calls`` is scanned. The rest is descriptive \u2014 it labels the\nevent for the dashboard and the audit log, and does not reach a detector."
      },
      "GuardMessage": {
        "properties": {
          "role": {
            "type": "string",
            "title": "Role",
            "description": "Message role: system, user, assistant, tool"
          },
          "content": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              }
            ],
            "title": "Content",
            "description": "Message text, or an OpenAI/Anthropic content-block array. Attachments carried in blocks are extracted and scanned like any other text; blocks we cannot read are listed in `unscanned`.",
            "default": ""
          }
        },
        "type": "object",
        "required": [
          "role"
        ],
        "title": "GuardMessage",
        "description": "A single message in the conversation.\n\n``content`` takes either a plain string or a provider-shaped content-block\narray \u2014 OpenAI's ``text``/``image_url``/``input_audio``/``file`` and\nAnthropic's ``text``/``image``/``document`` are all understood, because\nthose are the two shapes our own proxy already receives.\n\nBlocks are accepted as loose dicts rather than a closed union on purpose.\nBoth providers add block types faster than we can model them, and a strict\nschema would 422 a request we could otherwise have scanned the text of.\nAnything unrecognised is *reported* in the response's ``unscanned`` rather\nthan dropped \u2014 see ``shared.security.content_parts``."
      },
      "GuardRequest": {
        "properties": {
          "messages": {
            "items": {
              "$ref": "#/components/schemas/GuardMessage"
            },
            "type": "array",
            "maxItems": 512,
            "minItems": 1,
            "title": "Messages",
            "description": "Messages to scan (OpenAI-style message array)"
          },
          "direction": {
            "type": "string",
            "pattern": "^(input|output)$",
            "title": "Direction",
            "description": "Scan direction: 'input' (pre-LLM) or 'output' (post-LLM)",
            "default": "input"
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model",
            "description": "Model being used (for logging)"
          },
          "context": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GuardContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional framework context"
          },
          "retrieved_context": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ContextDoc"
                },
                "type": "array",
                "maxItems": 32
              },
              {
                "type": "null"
              }
            ],
            "title": "Retrieved Context",
            "description": "RAG-retrieved documents to scan for knowledge poisoning. Each document is scanned individually; the first poisoned one blocks the request, and its position and source are returned in the event metadata so you know which document to drop. Scanning stops at that point, so a request with several poisoned documents reports the first. Optional; backwards-compatible."
          },
          "media": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/MediaPartSchema"
                },
                "type": "array",
                "maxItems": 8
              },
              {
                "type": "null"
              }
            ],
            "title": "Media",
            "description": "Media attachments to scan for steganographic payloads, adversarial patches, and font injection. Optional."
          }
        },
        "type": "object",
        "required": [
          "messages"
        ],
        "title": "GuardRequest",
        "description": "Request body for the guard endpoint."
      },
      "GuardResponse": {
        "properties": {
          "decision": {
            "type": "string",
            "title": "Decision",
            "description": "Policy decision: 'allow', 'block', or 'redact'"
          },
          "event_id": {
            "type": "string",
            "title": "Event Id",
            "description": "Unique event identifier for tracking"
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "description": "Confidence score of the decision"
          },
          "weighted_score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weighted Score",
            "description": "Aggregate decision-driving score (severity * confidence, clamped to [0, 1]) when a severity-carrying detector decided the verdict; null otherwise. Raw confidence stays in the `confidence` field."
          },
          "threat_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Threat Type",
            "description": "Primary threat type detected"
          },
          "redacted_messages": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/GuardMessage"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Redacted Messages",
            "description": "Redacted messages (only present when decision='redact'). Always the TEXT projection: a message sent as content blocks comes back as a string. Attachments are never rewritten \u2014 we do not re-encode a PDF with the secret removed, and returning one that looked redacted would be worse than returning none."
          },
          "threats": {
            "items": {
              "$ref": "#/components/schemas/ThreatDetail"
            },
            "type": "array",
            "title": "Threats",
            "description": "Detailed threat breakdown"
          },
          "latency_ms": {
            "type": "number",
            "title": "Latency Ms",
            "description": "Processing time in milliseconds"
          },
          "unscanned": {
            "items": {
              "$ref": "#/components/schemas/UnscannedAttachment"
            },
            "type": "array",
            "title": "Unscanned",
            "description": "Parts that reached us and produced nothing to scan. An `allow` with a non-empty `unscanned` is NOT 'this content is clean' \u2014 it is 'the text was clean and these parts were never read'. Reasons: url_only (we do not fetch caller-supplied URLs, that would be an SSRF primitive), file_id_unsupported, encrypted, no_text_extracted (a scanned/rasterised document), too_large, undecodable, unsupported_type, extractor_unavailable, unsupported_block, unsupported_tool_call (an entry in `context.tool_calls` in none of the shapes we can read \u2014 `index` is its position in that list)."
          }
        },
        "type": "object",
        "required": [
          "decision",
          "event_id",
          "confidence",
          "latency_ms"
        ],
        "title": "GuardResponse",
        "description": "Response from the guard endpoint."
      },
      "GuardrailDelta": {
        "properties": {
          "enabled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Enabled"
          },
          "level": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "strict",
                  "moderate",
                  "permissive"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Level"
          },
          "threshold": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Threshold"
          }
        },
        "type": "object",
        "title": "GuardrailDelta",
        "description": "Per-guardrail override the overlay wants to apply.\n\nMatches the ``guardrails`` override shape PolicyEngine already reads:\n``{enabled, level, threshold}``. ``enabled=False`` disables a detector and\nis only ever a *loosening* op (surfaced as a critical warning)."
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "ManagedPolicyResponse": {
        "properties": {
          "fleet": {
            "type": "boolean",
            "title": "Fleet",
            "default": false
          },
          "force_update_mode": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Force Update Mode"
          },
          "pinned_channel": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pinned Channel"
          },
          "min_version_override": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Min Version Override"
          }
        },
        "type": "object",
        "title": "ManagedPolicyResponse",
        "description": "The managed update policy an enrolled Shadow AI device should apply.\n``fleet`` reflects the org's ``shadow_ai_fleet`` entitlement; when false the\nother fields are null and the device keeps its local user preference."
      },
      "MediaPartSchema": {
        "properties": {
          "type": {
            "type": "string",
            "pattern": "^(image|audio|document)$",
            "title": "Type",
            "description": "Media type: 'image', 'audio' or 'document'"
          },
          "mime_type": {
            "type": "string",
            "title": "Mime Type",
            "description": "MIME type, e.g. 'image/png', 'audio/wav'"
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "URL to fetch the media from"
          },
          "base64": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base64",
            "description": "Base64-encoded media data"
          },
          "metadata": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Metadata",
            "description": "Extra metadata"
          }
        },
        "type": "object",
        "required": [
          "type",
          "mime_type"
        ],
        "title": "MediaPartSchema",
        "description": "A media attachment to be scanned for steganographic/adversarial payloads."
      },
      "OverlayApplyRequest": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Name"
          },
          "delta": {
            "$ref": "#/components/schemas/OverlayDelta"
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Id"
          },
          "acknowledge_loosening": {
            "type": "boolean",
            "title": "Acknowledge Loosening",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "name",
          "delta"
        ],
        "title": "OverlayApplyRequest"
      },
      "OverlayDelta": {
        "properties": {
          "detection_levels": {
            "additionalProperties": {
              "type": "string",
              "enum": [
                "strict",
                "moderate",
                "permissive"
              ]
            },
            "type": "object",
            "title": "Detection Levels"
          },
          "toxicity_threshold": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Toxicity Threshold"
          },
          "add_custom_patterns": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Add Custom Patterns"
          },
          "add_blocked_domains": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Add Blocked Domains"
          },
          "guardrails": {
            "additionalProperties": {
              "$ref": "#/components/schemas/GuardrailDelta"
            },
            "type": "object",
            "title": "Guardrails"
          }
        },
        "type": "object",
        "title": "OverlayDelta",
        "description": "Additive deltas over a base policy config.\n\nEverything here is meant to *tighten*. Loosening ops (raising a threshold,\ndropping a detection level toward permissive, disabling a guardrail) are\npermitted to be expressed but are flagged as warnings in the diff."
      },
      "OverlayOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "version": {
            "type": "integer",
            "title": "Version"
          },
          "status": {
            "type": "string",
            "title": "Status"
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Id"
          },
          "warnings": {
            "items": {
              "$ref": "#/components/schemas/OverlayWarningOut"
            },
            "type": "array",
            "title": "Warnings"
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "version",
          "status",
          "project_id",
          "warnings"
        ],
        "title": "OverlayOut"
      },
      "OverlayPreviewRequest": {
        "properties": {
          "delta": {
            "$ref": "#/components/schemas/OverlayDelta"
          },
          "sample": {
            "$ref": "#/components/schemas/SampleSource"
          },
          "max_examples": {
            "type": "integer",
            "maximum": 50.0,
            "minimum": 1.0,
            "title": "Max Examples",
            "default": 5
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Id"
          }
        },
        "type": "object",
        "required": [
          "delta"
        ],
        "title": "OverlayPreviewRequest"
      },
      "OverlayWarningOut": {
        "properties": {
          "kind": {
            "type": "string",
            "title": "Kind"
          },
          "field": {
            "type": "string",
            "title": "Field"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "severity": {
            "type": "string",
            "enum": [
              "warning",
              "critical"
            ],
            "title": "Severity"
          }
        },
        "type": "object",
        "required": [
          "kind",
          "field",
          "message",
          "severity"
        ],
        "title": "OverlayWarningOut"
      },
      "QuotaErrorDetail": {
        "properties": {
          "message": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "'quota_exceeded' or 'spending_limit_exceeded'"
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "'monthly_quota_exceeded' or 'spending_limit_exceeded'"
          },
          "current_plan": {
            "type": "string",
            "title": "Current Plan"
          },
          "requests_used": {
            "type": "integer",
            "title": "Requests Used"
          },
          "requests_limit": {
            "type": "integer",
            "title": "Requests Limit"
          },
          "upgrade_url": {
            "type": "string",
            "title": "Upgrade Url"
          },
          "retry_after": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Retry After"
          }
        },
        "type": "object",
        "required": [
          "message",
          "type",
          "code",
          "current_plan",
          "requests_used",
          "requests_limit",
          "upgrade_url"
        ],
        "title": "QuotaErrorDetail"
      },
      "QuotaErrorEnvelope": {
        "properties": {
          "error": {
            "$ref": "#/components/schemas/QuotaErrorDetail"
          }
        },
        "type": "object",
        "required": [
          "error"
        ],
        "title": "QuotaErrorEnvelope"
      },
      "RedactRequest": {
        "properties": {
          "content": {
            "type": "string",
            "maxLength": 100000,
            "title": "Content",
            "description": "Text to redact"
          },
          "pii_types": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pii Types",
            "description": "Entity types to redact. Omit to use the policy's configured entities. Accepts detector entity names ('email', 'ssn', 'credit_card', 'phone_us'), the family aliases 'phone', 'ip_address' and 'passport', and 'api_key'. An unrecognized name is rejected rather than ignored.",
            "examples": [
              [
                "email",
                "phone",
                "ssn"
              ]
            ]
          }
        },
        "type": "object",
        "required": [
          "content"
        ],
        "title": "RedactRequest"
      },
      "RedactResponse": {
        "properties": {
          "original": {
            "type": "string",
            "title": "Original"
          },
          "redacted": {
            "type": "string",
            "title": "Redacted"
          },
          "piiFound": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Piifound"
          }
        },
        "type": "object",
        "required": [
          "original",
          "redacted",
          "piiFound"
        ],
        "title": "RedactResponse"
      },
      "SampleSource": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "corpus",
              "inline"
            ],
            "title": "Kind",
            "default": "corpus"
          },
          "limit": {
            "type": "integer",
            "maximum": 2000.0,
            "minimum": 1.0,
            "title": "Limit",
            "default": 100
          },
          "texts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Texts"
          }
        },
        "type": "object",
        "title": "SampleSource",
        "description": "Where the shadow traffic sample comes from.\n\n``corpus`` reuses the curated Shadow eval corpus (offline, deterministic);\n``inline`` lets the caller pass their own recent-traffic prompts."
      },
      "ScanRequest": {
        "properties": {
          "content": {
            "type": "string",
            "maxLength": 100000,
            "title": "Content",
            "description": "Text to scan"
          },
          "type": {
            "type": "string",
            "pattern": "^(prompt|response)$",
            "title": "Type",
            "description": "Content type: 'prompt' or 'response'",
            "default": "prompt"
          }
        },
        "type": "object",
        "required": [
          "content"
        ],
        "title": "ScanRequest"
      },
      "ScanResponse": {
        "properties": {
          "blocked": {
            "type": "boolean",
            "title": "Blocked"
          },
          "decision": {
            "type": "string",
            "title": "Decision"
          },
          "reason": {
            "type": "string",
            "title": "Reason"
          },
          "threatType": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Threattype"
          },
          "confidence": {
            "type": "number",
            "title": "Confidence"
          },
          "eventId": {
            "type": "string",
            "title": "Eventid"
          },
          "processingTimeMs": {
            "type": "number",
            "title": "Processingtimems"
          }
        },
        "type": "object",
        "required": [
          "blocked",
          "decision",
          "reason",
          "confidence",
          "eventId",
          "processingTimeMs"
        ],
        "title": "ScanResponse"
      },
      "ShadowReportOut": {
        "properties": {
          "total": {
            "type": "integer",
            "title": "Total"
          },
          "counts": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Counts"
          },
          "blocked_base": {
            "type": "integer",
            "title": "Blocked Base"
          },
          "blocked_candidate": {
            "type": "integer",
            "title": "Blocked Candidate"
          },
          "warnings": {
            "items": {
              "$ref": "#/components/schemas/OverlayWarningOut"
            },
            "type": "array",
            "title": "Warnings"
          },
          "examples": {
            "additionalProperties": {
              "items": {
                "$ref": "#/components/schemas/DivergenceItemOut"
              },
              "type": "array"
            },
            "type": "object",
            "title": "Examples"
          }
        },
        "type": "object",
        "required": [
          "total",
          "counts",
          "blocked_base",
          "blocked_candidate",
          "warnings",
          "examples"
        ],
        "title": "ShadowReportOut"
      },
      "ThreatDetail": {
        "properties": {
          "type": {
            "type": "string",
            "title": "Type"
          },
          "confidence": {
            "type": "number",
            "title": "Confidence"
          },
          "details": {
            "type": "string",
            "title": "Details"
          },
          "weighted_score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weighted Score",
            "description": "severity_score * confidence, clamped to [0, 1]. The decision-driving number when a severity-carrying detector (e.g. structural heuristics) fired; null when confidence alone is the signal."
          }
        },
        "type": "object",
        "required": [
          "type",
          "confidence",
          "details"
        ],
        "title": "ThreatDetail",
        "description": "Individual threat found during scanning."
      },
      "UnscannedAttachment": {
        "properties": {
          "index": {
            "type": "integer",
            "title": "Index",
            "description": "Position within the list the reason names \u2014 the combined attachment list, or `context.tool_calls` for `unsupported_tool_call`. -1 when the part has no position, which is every `unsupported_block`."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Stable machine-readable code"
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "Reason with any extra qualifier, e.g. 'no_text_extracted:pages=3'"
          }
        },
        "type": "object",
        "required": [
          "index",
          "reason",
          "detail"
        ],
        "title": "UnscannedAttachment",
        "description": "One part of the request we could not read, and why."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "developer__agent__router__ToolCallRequest": {
        "properties": {
          "agent_id": {
            "type": "string",
            "title": "Agent Id"
          },
          "tool_name": {
            "type": "string",
            "title": "Tool Name"
          },
          "arguments": {
            "additionalProperties": true,
            "type": "object",
            "title": "Arguments"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          }
        },
        "type": "object",
        "required": [
          "agent_id",
          "tool_name",
          "arguments"
        ],
        "title": "ToolCallRequest",
        "description": "Request to validate a tool call"
      },
      "developer__agent__router__ToolCallResponse": {
        "properties": {
          "allowed": {
            "type": "boolean",
            "title": "Allowed"
          },
          "risk_score": {
            "type": "number",
            "title": "Risk Score"
          },
          "risk_level": {
            "type": "string",
            "title": "Risk Level"
          },
          "reason": {
            "type": "string",
            "title": "Reason"
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "default": []
          },
          "blocked_reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Blocked Reasons",
            "default": []
          }
        },
        "type": "object",
        "required": [
          "allowed",
          "risk_score",
          "risk_level",
          "reason"
        ],
        "title": "ToolCallResponse",
        "description": "Response from tool call validation"
      },
      "developer__policies__router__AgentPolicy": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "action": {
            "type": "string",
            "title": "Action"
          },
          "threat_types": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Threat Types",
            "default": []
          },
          "priority": {
            "type": "integer",
            "title": "Priority",
            "default": 100
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "action"
        ],
        "title": "AgentPolicy",
        "description": "A single enforced rule, flattened for the agent UI."
      },
      "developer__projects__schemas__CreateProjectRequest": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "fail_mode": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ],
            "title": "Fail Mode",
            "description": "Behaviour when the detection engine errors: 'open' forwards the request, 'closed' rejects it with 503.",
            "default": "open"
          },
          "use_case": {
            "type": "string",
            "title": "Use Case",
            "default": "default"
          },
          "strictness_level": {
            "type": "string",
            "enum": [
              "strict",
              "moderate",
              "permissive"
            ],
            "title": "Strictness Level",
            "default": "moderate"
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "CreateProjectRequest"
      },
      "developer__projects__schemas__ProjectResponse": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "fail_mode": {
            "type": "string",
            "title": "Fail Mode"
          },
          "use_case": {
            "type": "string",
            "title": "Use Case"
          },
          "strictness_level": {
            "type": "string",
            "title": "Strictness Level"
          },
          "zero_retention": {
            "type": "boolean",
            "title": "Zero Retention",
            "default": false
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "description",
          "fail_mode",
          "use_case",
          "strictness_level",
          "created_at"
        ],
        "title": "ProjectResponse"
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "PromptGuard API key for developer endpoints. Keys start with pg_live_ and are created in the dashboard."
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ]
}
