{
  "openapi": "3.1.0",
  "info": {
    "title": "Spectorn AI Security Gateway",
    "version": "0.1.0-sprint14",
    "description": "Spectorn — AI security verdict service (Track 1) + hybrid LLM gateway (Tracks 2/3/4 launching Sprint 15-17). Constitution v0.2 (12 falsifiable principles, two non-amendable). Per Constitution Принцип 12, every response includes a `channel_disclosed` field; responses can be independently verified using the open-source `spct-verify-channel` CLI. See SPECTORN_CONSTITUTION_DRAFT.md and SPECTORN_TOS_DRAFT.md в the source repository.",
    "x-spec-source": "Generated fallback snapshot derived from spectorn-server/src/openapi.rs by dashboard/scripts/sync-openapi.mjs. The authoritative spec is served live at GET /openapi.json. Do not hand-edit; run `node dashboard/scripts/sync-openapi.mjs`."
  },
  "servers": [
    {
      "url": "https://api.global.spectorn.ai",
      "description": "Global contour; availability is subject to release gates"
    },
    {
      "url": "https://api.ru.spectorn.ai",
      "description": "RU contour; availability is subject to release gates"
    },
    {
      "url": "http://localhost:8080",
      "description": "Local development"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Spectorn API key"
      },
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "spectorn_session"
      }
    }
  },
  "paths": {
    "/v1/admin/account": {
      "delete": {
        "summary": "Self-terminate account; revoke all keys (TOS §7.1)",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/admin/detection-tuning": {
      "get": {
        "summary": "Read the live global detection tuning baseline",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      },
      "put": {
        "summary": "Set or clear the live global detection tuning baseline",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/admin/detection-tuning/reload": {
      "post": {
        "summary": "Reload the global detection tuning baseline from disk",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/admin/eligibility/reviews": {
      "get": {
        "summary": "List Global Free eligibility reviews for platform triage",
        "tags": [
          "eligibility"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/admin/eligibility/reviews/{review_id}/decision": {
      "post": {
        "summary": "Approve, deny, or revoke a Global Free eligibility review",
        "tags": [
          "eligibility"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "review_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/admin/keys": {
      "get": {
        "summary": "List API keys",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      },
      "post": {
        "summary": "Create an API key",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tenant_id",
                  "tier"
                ],
                "properties": {
                  "tenant_id": {
                    "type": "string",
                    "pattern": "^[a-z0-9_-]{1,64}$",
                    "description": "Canonical lowercase tenant id"
                  },
                  "tier": {
                    "type": "string"
                  },
                  "label": {
                    "type": "string"
                  },
                  "rate_limit_per_min": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/admin/keys/{tenant_id}": {
      "delete": {
        "summary": "Revoke all keys for a tenant",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/admin/tenants/{tenant_id}/model-routes": {
      "get": {
        "summary": "Read a tenant's gateway model aliases",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9_-]{1,64}$"
            },
            "description": "Target tenant id"
          }
        ]
      },
      "put": {
        "summary": "Replace a tenant's gateway model aliases",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9_-]{1,64}$"
            },
            "description": "Target tenant id"
          }
        ]
      }
    },
    "/v1/admin/tenants/{tenant_id}/policy": {
      "put": {
        "summary": "Set or clear a tenant's policy (null body clears to default)",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9_-]{1,64}$"
            },
            "description": "Target tenant id"
          }
        ]
      }
    },
    "/v1/admin/tenants/{tenant_id}/scan-config": {
      "get": {
        "summary": "Read a tenant's scan mode + policy",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9_-]{1,64}$"
            },
            "description": "Target tenant id"
          }
        ]
      }
    },
    "/v1/admin/tenants/{tenant_id}/scan-mode": {
      "put": {
        "summary": "Set a tenant's scan enforcement mode (enforce/shadow)",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9_-]{1,64}$"
            },
            "description": "Target tenant id"
          }
        ]
      }
    },
    "/v1/admin/usage": {
      "get": {
        "summary": "Return content-free daily usage across all active tenants",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/audit/verify": {
      "get": {
        "summary": "Verify the global audit log (platform admin only)",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/billing/checkout": {
      "post": {
        "summary": "Create a Stripe Checkout session",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/billing/status": {
      "get": {
        "summary": "Read the webhook-backed tenant billing entitlement",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/chat/completions": {
      "post": {
        "summary": "OpenAI-compatible stateless gateway proxy: scan, route, then forward to the model",
        "tags": [
          "gateway"
        ],
        "responses": {
          "200": {
            "description": "Gateway-processed upstream success. Non-streaming JSON may be sanitized, restored, or re-serialized; stream:true can return gateway-scanned SSE that may terminate with a gateway-generated error event; other provider media types can be returned on non-streaming paths.",
            "headers": {
              "X-Spectorn-Stream-Downgraded": {
                "description": "Present when stream:true was buffered so a whole-body gateway control could run",
                "schema": {
                  "type": "string",
                  "enum": [
                    "l2_egress_enforcer",
                    "action_guard",
                    "l2_egress_enforcer,action_guard"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "description": "Provider-defined JSON that may be sanitized, restored, or re-serialized by gateway controls"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Gateway-scanned SSE data that may be transformed or terminated with a gateway-generated error event"
                }
              },
              "*/*": {}
            }
          },
          "400": {
            "description": "The gateway rejected an invalid request, or the upstream provider returned 400. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "401": {
            "description": "The gateway rejected authentication, or an authenticated forwarded request received upstream 401. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "402": {
            "description": "Billing balance or output-token allowance requires payment, or the upstream provider returned 402. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "403": {
            "description": "Authentication scope, eligibility, prompt policy, output policy, or billing policy refused the request, or the upstream provider returned 403. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "408": {
            "description": "The gateway request timed out, or the upstream provider returned 408. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "409": {
            "description": "Any present X-Spectorn-Session or X-Spectorn-Turn-Id value is rejected with memory_scope_required, or an authenticated forwarded request received upstream 409. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "413": {
            "description": "HTTP body or prompt exceeded its bound, or the upstream provider returned 413. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "429": {
            "description": "The gateway or upstream provider rate-limited the request. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "500": {
            "description": "The gateway failed internally, or the upstream provider returned 500. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "502": {
            "description": "Upstream resolution, transport, or response-size failure, or the upstream provider returned 502. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "503": {
            "description": "Scan, billing, or eligibility dependency unavailable, or the upstream provider returned 503. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "504": {
            "description": "The upstream provider returned 504 Gateway Timeout. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "default": {
            "description": "A non-enumerated response status selected from the upstream provider. Its media type and JSON shape are provider-defined; gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "*/*": {}
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "model",
                  "messages"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "Model id, optionally prefixed with provider/ for routing"
                  },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  },
                  "stream": {
                    "type": "boolean",
                    "default": false
                  }
                },
                "additionalProperties": true
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "description": "Structured gateway failures use JSON. Provider-origin responses can use the provider's media type, but response bodies are not byte-for-byte passthrough: gateway scanning, masking, model-alias sanitation, billing, and hosted-provider controls may buffer, transform, terminate, withhold, or replace them. Legacy stream:true can return gateway-scanned text/event-stream data or be downgraded to buffered JSON; the default response documents non-enumerated provider statuses.",
        "parameters": [
          {
            "name": "X-Provider-Key",
            "in": "header",
            "required": false,
            "description": "BYOK upstream provider key when no provider is configured in the dashboard",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Provider",
            "in": "header",
            "required": false,
            "description": "Route to a configured provider without prefixing the model name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Spectorn-Session",
            "in": "header",
            "required": false,
            "description": "Reserved for the project-scoped chat route. Any present value on this legacy stateless route is rejected with 409 memory_scope_required.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,128}$"
            }
          },
          {
            "name": "X-Spectorn-Turn-Id",
            "in": "header",
            "required": false,
            "description": "Reserved for the project-scoped chat route. Any present value on this legacy stateless route is rejected with 409 memory_scope_required.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,128}$"
            }
          }
        ]
      }
    },
    "/v1/dashboard-template": {
      "get": {
        "summary": "Grafana dashboard template",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/dispute/file": {
      "post": {
        "summary": "File a dispute (TOS §7.3)",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject",
                  "body"
                ],
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 16384
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/dispute/list": {
      "get": {
        "summary": "List the authenticated tenant's own disputes",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/eligibility/reviews": {
      "post": {
        "summary": "Submit a structured Global Free eligibility review",
        "tags": [
          "eligibility"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/eligibility/reviews/current": {
      "get": {
        "summary": "Read the caller tenant's current Global Free eligibility review",
        "tags": [
          "eligibility"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/engines": {
      "get": {
        "summary": "Full canonical list of available engines",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/explain/{verdict_id}": {
      "get": {
        "summary": "Fetch a causal chain for a verdict",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "A vdt_ id: the stored verdict at the caller's disclosure level. Any other id: the memory subsystem's causal chain.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "required": [
                        "source",
                        "schema",
                        "disclosure",
                        "decision",
                        "risk_band",
                        "classes",
                        "channel_disclosed"
                      ],
                      "properties": {
                        "schema": {
                          "type": "string",
                          "const": "spectorn.verdict_projection.v1"
                        },
                        "disclosure": {
                          "type": "string",
                          "enum": [
                            "decision",
                            "remediation",
                            "diagnostics"
                          ],
                          "description": "decision (A) for a Global Free Guard key; remediation (B) for every other key; diagnostics (C) for a key with the diagnostics grant or a platform operator."
                        },
                        "verdict_id": {
                          "type": "string",
                          "pattern": "^vdt_[0-9a-f]{24}$",
                          "description": "Random; the key for GET /v1/explain/{verdict_id}. Absent when a verdict has none."
                        },
                        "evaluation_status": {
                          "type": "string",
                          "enum": [
                            "evaluated",
                            "protection_unavailable",
                            "refused_excess_evidence"
                          ],
                          "description": "refused_excess_evidence: the engines refused to analyse the text, so it was not checked. It appears in the spectorn object of a proxy or memory block; /v1/scan answers such a refusal with 403 analysis_refused instead of a verdict. Treat it as a block, never as an allow."
                        },
                        "decision": {
                          "type": "string",
                          "enum": [
                            "allow",
                            "block",
                            "redact"
                          ],
                          "description": "The tenant policy's decision; not a synonym of detected."
                        },
                        "mode": {
                          "type": "string",
                          "enum": [
                            "enforce",
                            "shadow"
                          ]
                        },
                        "enforced": {
                          "type": "boolean"
                        },
                        "risk_band": {
                          "type": "string",
                          "enum": [
                            "none",
                            "low",
                            "high"
                          ],
                          "description": "Derived from the decision, never from the engines' score: none (nothing matched), low (matched, not blocked), high (the policy blocks)."
                        },
                        "classes": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "prompt_attack",
                              "data_exposure",
                              "harmful_content",
                              "agent_abuse",
                              "obfuscation",
                              "other"
                            ]
                          }
                        },
                        "policy_version": {
                          "type": "string"
                        },
                        "findings": {
                          "type": "array",
                          "description": "Levels B and C.",
                          "items": {
                            "type": "object",
                            "required": [
                              "finding_id",
                              "category",
                              "reason_code",
                              "suggested_action"
                            ],
                            "properties": {
                              "finding_id": {
                                "type": "string",
                                "description": "Names the finding within this answer only; the same text scanned again gets new ids."
                              },
                              "category": {
                                "type": "string",
                                "enum": [
                                  "prompt_attack",
                                  "data_exposure",
                                  "harmful_content",
                                  "agent_abuse",
                                  "obfuscation",
                                  "other"
                                ]
                              },
                              "reason_code": {
                                "type": "string",
                                "enum": [
                                  "instruction_override",
                                  "manipulation",
                                  "personal_data",
                                  "sensitive_data_leak",
                                  "harmful_content",
                                  "tool_misuse",
                                  "agent_trust_violation",
                                  "unsafe_code",
                                  "hidden_payload",
                                  "quoted_mention",
                                  "unclassified_signal"
                                ]
                              },
                              "source_spans": {
                                "type": "array",
                                "description": "UTF-8 byte offsets into the prompt as sent, only where the gateway verified the mapping. Absent when none was verified.",
                                "items": {
                                  "type": "object",
                                  "required": [
                                    "start_byte",
                                    "end_byte"
                                  ],
                                  "properties": {
                                    "start_byte": {
                                      "type": "integer",
                                      "minimum": 0
                                    },
                                    "end_byte": {
                                      "type": "integer",
                                      "minimum": 0
                                    }
                                  }
                                }
                              },
                              "suggested_action": {
                                "type": "string",
                                "enum": [
                                  "remove_embedded_instructions",
                                  "rephrase_request",
                                  "mask_personal_data",
                                  "remove_sensitive_data",
                                  "review_tool_call",
                                  "review_agent_permissions",
                                  "review_generated_code",
                                  "remove_hidden_content",
                                  "request_review"
                                ]
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "diagnostics": {
                          "type": "object",
                          "description": "Level C only: engine, rule, confidence and engine-view offsets of every match, and the post-policy trace."
                        },
                        "source": {
                          "type": "string",
                          "const": "spectorn_verdict_store"
                        },
                        "detected": {
                          "type": "boolean"
                        },
                        "would_block": {
                          "type": "boolean"
                        },
                        "channel_disclosed": {
                          "type": "object"
                        },
                        "explanation": {
                          "type": "object",
                          "description": "Level C only: the stored engines, confidences, threshold and reasons."
                        }
                      },
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "description": "Causal chain for an id the verdict store does not own."
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "verdict_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/gateway/capabilities": {
      "get": {
        "summary": "Return tenant gateway capabilities and available model aliases",
        "tags": [
          "gateway"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/health": {
      "get": {
        "summary": "Liveness probe (process responding)",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/logout": {
      "post": {
        "summary": "Logout the current browser session",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memory/all": {
      "delete": {
        "summary": "Delete all tenant memory",
        "tags": [
          "memory"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/memory/export": {
      "post": {
        "summary": "Export tenant memory",
        "tags": [
          "memory"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/memory/projects/{project_id}/chat/completions": {
      "post": {
        "summary": "OpenAI-compatible gateway proxy with exact project/session recall and store",
        "tags": [
          "gateway"
        ],
        "responses": {
          "200": {
            "description": "Buffered upstream success accepted for exact recall/store semantics and committed as the durable completed turn. Matching retries are not replayed and do not launch a fresh provider chain. The JSON body may be sanitized, restored, or re-serialized, and the provider-declared media type can be retained.",
            "headers": {
              "X-Spectorn-Stream-Downgraded": {
                "description": "Present as session_memory when a requested stream was buffered for exact recall/store semantics",
                "schema": {
                  "type": "string",
                  "const": "session_memory"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "description": "Gateway-processed chat-completion JSON. The winning turn must be storable; later matching retries return a typed 409 because exact response replay is unavailable."
                }
              },
              "*/*": {}
            }
          },
          "400": {
            "description": "Invalid project id or unrepresentable chat request (memory_user_turn_required or memory_request_not_storable), or the upstream provider returned 400. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "401": {
            "description": "The gateway rejected authentication, or an authenticated forwarded request received upstream 401. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "402": {
            "description": "Billing balance or output-token allowance requires payment, or the upstream provider returned 402. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "403": {
            "description": "Authentication scope, eligibility, prompt policy, output policy, or billing policy refused the request, or the upstream provider returned 403. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "408": {
            "description": "The scoped operation timed out, or the upstream provider returned 408. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "409": {
            "description": "Missing or malformed exact session/turn scope (memory_scope_required or memory_turn_id_required); a conflicting request_ref (memory_turn_conflict); a live claim or execution (memory_turn_claimed or memory_turn_execution_in_progress); a stale execution with an unknowable provider outcome (memory_turn_outcome_uncertain); a completed turn whose exact response cannot be replayed (memory_turn_replay_unavailable); or the upstream provider returned 409. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "413": {
            "description": "HTTP body, prompt, or prompt plus recalled memory exceeded its bound, or the upstream provider returned 413. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "423": {
            "description": "Session memory operation blocked by runtime self-defense mode, or the upstream provider returned 423. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "429": {
            "description": "The gateway or upstream provider rate-limited the request. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "500": {
            "description": "The gateway failed internally, or the upstream provider returned 500. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "502": {
            "description": "Memory backend, upstream resolution, transport, or response-size failure, or the upstream provider returned 502. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "503": {
            "description": "Session memory, scan, billing, or eligibility dependency unavailable, or the upstream provider returned 503. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "504": {
            "description": "The upstream provider returned 504 Gateway Timeout. Structured gateway failures use application/json; provider-origin media and JSON shapes are provider-defined, and transport fallbacks can use any media type. Gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Structured gateway failures are JSON objects; upstream application/json payloads are provider-defined"
                }
              },
              "*/*": {}
            }
          },
          "default": {
            "description": "A non-enumerated response status selected from the upstream provider. Its media type and JSON shape are provider-defined; gateway controls may transform, terminate, withhold, or replace the payload",
            "content": {
              "*/*": {}
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "model",
                  "messages"
                ],
                "properties": {
                  "model": {
                    "type": "string"
                  },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  },
                  "stream": {
                    "type": "boolean",
                    "default": false,
                    "description": "Accepted for compatibility, but true is buffered and disclosed in X-Spectorn-Stream-Downgraded"
                  }
                },
                "additionalProperties": true
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "description": "Structured gateway failures use JSON. Scoped stream:true is always buffered and disclosed through X-Spectorn-Stream-Downgraded. The gateway reserves prepaid billing before walking the provider chain. A durable cross-process claim is acquired only after a sendable provider request has been built, then its owner begins execution immediately before the first provider dispatch. Thus a billing refusal or wholly unsendable provider chain creates no durable claim state. A configured fallback chain can contact multiple providers, so the guarantee is at-most-one dispatch chain, not provider exactly-once. CLAIMED leases may expire before dispatch; EXECUTING is never stolen, becomes durably UNCERTAIN after its deadline, and both UNCERTAIN and COMPLETED fail closed. Exact response bytes are not persisted for replay, so completed retries return memory_turn_replay_unavailable without a new provider call. Reusing the turn id with a different canonical request returns memory_turn_conflict. Provider-origin errors can use the provider's media type, while gateway controls may transform, withhold, or replace their payloads. Exact error responses allow gateway JSON and arbitrary upstream media; the default response documents non-enumerated provider statuses.",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
              "not": {
                "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
              }
            }
          },
          {
            "name": "X-Spectorn-Session",
            "in": "header",
            "required": true,
            "description": "Exact session boundary inside the path project",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,128}$"
            }
          },
          {
            "name": "X-Spectorn-Turn-Id",
            "in": "header",
            "required": true,
            "description": "Caller occurrence token for one logical turn. Reuse it only with the same canonical caller request; use a new value for every new turn. A durable cross-process claim permits at most one provider dispatch chain for the canonical project/session/turn/request identity. The winning fallback chain may contact multiple providers, so this is not provider exactly-once. Because exact response bytes are not durably replayed, a retry after dispatch began, became uncertain, or completed returns a typed 409 and never starts a fresh provider chain.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,128}$"
            }
          },
          {
            "name": "X-Provider-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Provider",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/memory/projects/{project_id}/export": {
      "post": {
        "summary": "Export one explicit memory project",
        "tags": [
          "memory"
        ],
        "responses": {
          "200": {
            "description": "Project-scoped memory export",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "result",
                    "memory_scope",
                    "channel_disclosed"
                  ],
                  "properties": {
                    "result": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "tenant_id",
                        "project_id",
                        "exported_at_utc",
                        "facts",
                        "count"
                      ],
                      "properties": {
                        "tenant_id": {
                          "type": "string"
                        },
                        "project_id": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
                        },
                        "exported_at_utc": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "facts": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "tenant_id",
                              "project_id",
                              "content"
                            ],
                            "properties": {
                              "tenant_id": {
                                "type": "string",
                                "const": "local"
                              },
                              "project_id": {
                                "type": "string",
                                "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                                "not": {
                                  "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                                }
                              },
                              "content": {
                                "type": "string"
                              },
                              "origin": {
                                "type": "string",
                                "enum": [
                                  "unspecified",
                                  "builtin",
                                  "user",
                                  "derived",
                                  "external"
                                ]
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "count": {
                          "type": "integer",
                          "minimum": 0
                        }
                      }
                    },
                    "memory_scope": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "version",
                        "kind",
                        "project_id"
                      ],
                      "properties": {
                        "version": {
                          "type": "integer",
                          "const": 1
                        },
                        "kind": {
                          "type": "string",
                          "const": "project"
                        },
                        "project_id": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                          "not": {
                            "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                          }
                        }
                      }
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid project identifier or scoped request arguments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated request refused by API-key scope, eligibility, or browser CSRF controls",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "408": {
            "description": "Request timed out before the scoped operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "413": {
            "description": "Configured memory export bound exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "423": {
            "description": "Runtime self-defense mode blocked the operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "Memory backend did not confirm the requested project scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "503": {
            "description": "Memory or scan backend unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "504": {
            "description": "Memory backend timed out",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Explicit project boundary. The legacy default project is available only through /v1/memory/store, /search, /stats, and /export.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
              "not": {
                "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
              }
            }
          }
        ]
      }
    },
    "/v1/memory/projects/{project_id}/search": {
      "get": {
        "summary": "Search one explicit memory project",
        "tags": [
          "memory"
        ],
        "responses": {
          "200": {
            "description": "Project-scoped facts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "result",
                    "memory_scope",
                    "channel_disclosed"
                  ],
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "tenant_id",
                          "project_id",
                          "content"
                        ],
                        "properties": {
                          "tenant_id": {
                            "type": "string",
                            "const": "local"
                          },
                          "project_id": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                            "not": {
                              "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                            }
                          },
                          "content": {
                            "type": "string"
                          },
                          "origin": {
                            "type": "string",
                            "enum": [
                              "unspecified",
                              "builtin",
                              "user",
                              "derived",
                              "external"
                            ]
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "memory_scope": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "version",
                        "kind",
                        "project_id"
                      ],
                      "properties": {
                        "version": {
                          "type": "integer",
                          "const": 1
                        },
                        "kind": {
                          "type": "string",
                          "const": "project"
                        },
                        "project_id": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                          "not": {
                            "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                          }
                        }
                      }
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid project identifier or scoped request arguments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated request refused by API-key scope or eligibility controls, or protection policy blocked the search query",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "408": {
            "description": "Request timed out before the scoped operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "413": {
            "description": "A stored fact identity, stored fact payload, or aggregate search scope exceeds the bounded search limit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "423": {
            "description": "Runtime self-defense mode blocked the operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "Memory backend did not confirm the requested project scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "503": {
            "description": "Memory or scan backend unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "504": {
            "description": "Memory backend timed out",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Explicit project boundary. The legacy default project is available only through /v1/memory/store, /search, /stats, and /export.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
              "not": {
                "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
              }
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "keyword",
                "semantic",
                "hybrid"
              ],
              "default": "keyword"
            }
          }
        ]
      }
    },
    "/v1/memory/projects/{project_id}/stats": {
      "get": {
        "summary": "Summarize one explicit memory project",
        "tags": [
          "memory"
        ],
        "responses": {
          "200": {
            "description": "Project-scoped memory statistics",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "result",
                    "memory_scope",
                    "channel_disclosed"
                  ],
                  "properties": {
                    "result": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "total_facts",
                        "live_facts",
                        "archived_count",
                        "by_level",
                        "by_domain",
                        "by_origin",
                        "stale_count",
                        "with_embeddings",
                        "gene_count",
                        "cold_count"
                      ],
                      "properties": {
                        "total_facts": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "live_facts": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "archived_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "by_level": {
                          "type": "object",
                          "propertyNames": {
                            "pattern": "^[0-3]$"
                          },
                          "additionalProperties": {
                            "type": "integer",
                            "minimum": 0
                          }
                        },
                        "by_domain": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "integer",
                            "minimum": 0
                          }
                        },
                        "by_origin": {
                          "type": "object",
                          "propertyNames": {
                            "enum": [
                              "unspecified",
                              "builtin",
                              "user",
                              "derived",
                              "external"
                            ]
                          },
                          "additionalProperties": {
                            "type": "integer",
                            "minimum": 0
                          }
                        },
                        "stale_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "with_embeddings": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "gene_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "cold_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "genome_hash": {
                          "type": "string"
                        }
                      }
                    },
                    "memory_scope": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "version",
                        "kind",
                        "project_id"
                      ],
                      "properties": {
                        "version": {
                          "type": "integer",
                          "const": 1
                        },
                        "kind": {
                          "type": "string",
                          "const": "project"
                        },
                        "project_id": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                          "not": {
                            "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                          }
                        }
                      }
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid project identifier or scoped request arguments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated request refused by API-key scope, eligibility, or browser CSRF controls",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "408": {
            "description": "Request timed out before the scoped operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "413": {
            "description": "A stored stats domain, aggregate domain scope, or domain count exceeds the bounded statistics limit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "423": {
            "description": "Runtime self-defense mode blocked the operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "Memory backend did not confirm the requested project scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "503": {
            "description": "Memory or scan backend unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "504": {
            "description": "Memory backend timed out",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Explicit project boundary. The legacy default project is available only through /v1/memory/store, /search, /stats, and /export.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
              "not": {
                "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
              }
            }
          }
        ]
      }
    },
    "/v1/memory/projects/{project_id}/store": {
      "post": {
        "summary": "Store a fact in one explicit memory project",
        "tags": [
          "memory"
        ],
        "responses": {
          "200": {
            "description": "Exact project-scoped fact replayed without mutation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "result",
                    "memory_scope",
                    "channel_disclosed"
                  ],
                  "properties": {
                    "result": {
                      "type": "object",
                      "required": [
                        "tenant_id",
                        "project_id",
                        "content"
                      ],
                      "properties": {
                        "tenant_id": {
                          "type": "string",
                          "const": "local"
                        },
                        "project_id": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                          "not": {
                            "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                          }
                        },
                        "content": {
                          "type": "string"
                        },
                        "origin": {
                          "type": "string",
                          "enum": [
                            "unspecified",
                            "builtin",
                            "user",
                            "derived",
                            "external"
                          ]
                        }
                      },
                      "additionalProperties": true
                    },
                    "memory_scope": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "version",
                        "kind",
                        "project_id"
                      ],
                      "properties": {
                        "version": {
                          "type": "integer",
                          "const": 1
                        },
                        "kind": {
                          "type": "string",
                          "const": "project"
                        },
                        "project_id": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                          "not": {
                            "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                          }
                        }
                      }
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Project-scoped fact stored",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "result",
                    "memory_scope",
                    "channel_disclosed"
                  ],
                  "properties": {
                    "result": {
                      "type": "object",
                      "required": [
                        "tenant_id",
                        "project_id",
                        "content"
                      ],
                      "properties": {
                        "tenant_id": {
                          "type": "string",
                          "const": "local"
                        },
                        "project_id": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                          "not": {
                            "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                          }
                        },
                        "content": {
                          "type": "string"
                        },
                        "origin": {
                          "type": "string",
                          "enum": [
                            "unspecified",
                            "builtin",
                            "user",
                            "derived",
                            "external"
                          ]
                        }
                      },
                      "additionalProperties": true
                    },
                    "memory_scope": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "version",
                        "kind",
                        "project_id"
                      ],
                      "properties": {
                        "version": {
                          "type": "integer",
                          "const": 1
                        },
                        "kind": {
                          "type": "string",
                          "const": "project"
                        },
                        "project_id": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
                          "not": {
                            "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
                          }
                        }
                      }
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid project identifier or scoped request arguments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated request refused by API-key scope, eligibility, or browser CSRF controls, or protection policy blocked caller content",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "408": {
            "description": "Request timed out before the scoped operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "409": {
            "description": "Exact fact identity conflicts with a different live fact, or the project is not writable",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "413": {
            "description": "Configured memory store size bound exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "423": {
            "description": "Runtime self-defense mode blocked the operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "502": {
            "description": "Memory backend did not confirm the requested project scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "503": {
            "description": "Memory or scan backend unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "504": {
            "description": "Memory backend timed out",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "content"
                ],
                "properties": {
                  "content": {
                    "type": "string"
                  },
                  "level": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 3,
                    "default": 1
                  },
                  "domain": {
                    "type": "string"
                  },
                  "module": {
                    "type": "string"
                  },
                  "origin": {
                    "type": "string",
                    "enum": [
                      "user",
                      "derived",
                      "external"
                    ]
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Explicit project boundary. The legacy default project is available only through /v1/memory/store, /search, /stats, and /export.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$",
              "not": {
                "pattern": "^[dD][eE][fF][aA][uU][lL][tT]$"
              }
            }
          }
        ]
      }
    },
    "/v1/memory/search": {
      "get": {
        "summary": "Search tenant memory",
        "tags": [
          "memory"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/memory/store": {
      "post": {
        "summary": "Store a tenant memory fact",
        "tags": [
          "memory"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/metrics": {
      "get": {
        "summary": "Prometheus metrics",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/metrics/aggregate": {
      "get": {
        "summary": "Privacy-safe aggregate Prometheus metrics",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/model-routes": {
      "get": {
        "summary": "Read the caller tenant's gateway model aliases",
        "tags": [
          "gateway"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      },
      "put": {
        "summary": "Replace the caller tenant's gateway model aliases",
        "tags": [
          "gateway"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/models": {
      "get": {
        "summary": "List customer-visible gateway model aliases",
        "tags": [
          "gateway"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/observe": {
      "post": {
        "summary": "Structured observation: stateless engines shared, stateful engines owned by the tenant",
        "description": "Runs one structured engine on one versioned typed observation. The engines GET /v1/engines lists as structured_observe_stateless_engines compute their answer from the observation alone. The engines it lists as structured_observe_tenant_engines keep history between calls in a registry owned by the authenticated tenant: tenant_id in the observation is replaced by the authenticated one, the history lives in the server process only (a restart, deployment or rollback starts it empty), and it is dropped when the tenant's data is erased. Engines listed in structured_observe_unavailable are not served. The result reports state_scope and carries no customer content.",
        "x-spectorn-handler-contract": {
          "stateless_engines": [
            "pipeline_bypass_routing",
            "agent_metadata_smuggling",
            "rag_index_collision_attack",
            "rag_retrieval_amplification",
            "rag_stale_knowledge_exploit",
            "rag_citation_fabrication",
            "rag_context_overflow_eviction",
            "staging_to_prod_promotion_attack",
            "backdoored_finetune",
            "synthetic_persona_detection",
            "temporal_safety",
            "cascading_hallucination",
            "crescendo_session",
            "conversation",
            "groundedness"
          ],
          "tenant_scoped_engines": [
            "swarm_guard",
            "rag_corpus_guard",
            "model_drift_unified",
            "model_drift",
            "telemetry_integrity",
            "severity_inflation_attack",
            "feedback_loop_poisoning",
            "inference_quota_exhaustion",
            "agentic_graph_traversal_attack",
            "emergent_consensus_manipulation",
            "agent_role_drift",
            "chain_of_engines_confusion",
            "temporal_replay_variants",
            "cost_anomaly",
            "mia_runtime",
            "extraction_defense",
            "streaming_inspector",
            "rogue_agent",
            "drift"
          ],
          "tenant_state": "process_memory",
          "privileged_engines": [
            "cross_agent_boundary",
            "cost_attribution_attack"
          ],
          "privileged_engine_code": "observe_privileged_engine_unavailable",
          "capacity_code": "observe_tenant_registry_capacity_exhausted",
          "initialization_code": "observe_tenant_registry_initialization_failed",
          "disabled_code": "observe_tenant_isolation_incomplete",
          "retry_after_seconds": 300
        },
        "tags": [
          "scan"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "engine_name",
                  "schema",
                  "observation"
                ],
                "properties": {
                  "engine_name": {
                    "type": "string",
                    "example": "temporal_safety"
                  },
                  "schema": {
                    "type": "string",
                    "example": "spectorn-typed-observation/v1"
                  },
                  "observation": {
                    "type": "object"
                  },
                  "report_max_findings": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 256
                  }
                }
              },
              "examples": {
                "read_then_send": {
                  "summary": "A tool sequence that reads a secret and then sends it out",
                  "value": {
                    "engine_name": "temporal_safety",
                    "schema": "spectorn-typed-observation/v1",
                    "observation": {
                      "events": [
                        {
                          "tool_name": "files.read",
                          "predicates": [
                            "read_secret"
                          ]
                        },
                        {
                          "tool_name": "net.post",
                          "predicates": [
                            "external_channel"
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The engine's typed result (spectorn-typed-observation/v1) with state_scope (none or tenant_process_memory) and channel_disclosed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed body, missing or unknown engine_name, or an observation the typed admission refused",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated request refused by scope, eligibility, or browser CSRF controls",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "408": {
            "description": "Request timed out",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Transport, middleware or engine failure",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "503": {
            "description": "The named engine is not served (privileged, or stateful observation is off on this server), every tenant registry slot is taken, the tenant's registry could not be built, the engine pool is saturated, or eligibility middleware failed closed.",
            "headers": {
              "Retry-After": {
                "description": "Seconds before the client may retry",
                "schema": {
                  "type": "string",
                  "example": "300"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "code",
                    "channel_disclosed"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "retry_after_seconds": {
                      "type": "integer"
                    },
                    "available_engines": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                },
                "examples": {
                  "privileged_engine": {
                    "summary": "An engine that reads claims about other tenants was named",
                    "value": {
                      "error": "this engine reads claims about other tenants and needs a server-owned broker; it is not served",
                      "code": "observe_privileged_engine_unavailable",
                      "retry_after_seconds": 300,
                      "channel_disclosed": {
                        "channel_class": "track1_security_only"
                      }
                    }
                  },
                  "capacity_exhausted": {
                    "summary": "Every tenant registry slot on this server is taken",
                    "value": {
                      "error": "structured observation for stateful engines is at capacity on this server",
                      "code": "observe_tenant_registry_capacity_exhausted",
                      "retry_after_seconds": 300,
                      "channel_disclosed": {
                        "channel_class": "track1_security_only"
                      }
                    }
                  },
                  "observe_disabled": {
                    "summary": "A stateful engine was named on a server running without tenant registries",
                    "value": {
                      "error": "structured observation is temporarily unavailable for this engine",
                      "code": "observe_tenant_isolation_incomplete",
                      "retry_after_seconds": 300,
                      "channel_disclosed": {
                        "channel_class": "track1_security_only"
                      }
                    }
                  },
                  "eligibility_unavailable": {
                    "summary": "Eligibility middleware failed closed before the handler",
                    "value": {
                      "error": "Global Free Guard eligibility could not be determined safely.",
                      "code": "global_free_eligibility_unavailable",
                      "channel_disclosed": {
                        "channel_class": "track1_security_only"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/public/channel-matrix": {
      "get": {
        "summary": "Signed channel-matrix envelope (Constitution §12)",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/firewall-attestation": {
      "get": {
        "summary": "Signed firewall-attestation envelope (Constitution §11)",
        "tags": [
          "verification"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/models": {
      "get": {
        "summary": "List the public gateway model catalog preview",
        "tags": [
          "gateway"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scan": {
      "post": {
        "summary": "Analyze a prompt with one engine or the full registry",
        "tags": [
          "scan"
        ],
        "responses": {
          "200": {
            "description": "Verdict at the caller's disclosure level",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "schema",
                    "disclosure",
                    "evaluation_status",
                    "decision",
                    "mode",
                    "enforced",
                    "risk_band",
                    "classes",
                    "policy_version",
                    "detected",
                    "would_block",
                    "allowed",
                    "policy_applied",
                    "latency_ms",
                    "self_scanned",
                    "self_scan_passed",
                    "channel_disclosed"
                  ],
                  "properties": {
                    "schema": {
                      "type": "string",
                      "const": "spectorn.verdict_projection.v1"
                    },
                    "disclosure": {
                      "type": "string",
                      "enum": [
                        "decision",
                        "remediation",
                        "diagnostics"
                      ],
                      "description": "decision (A) for a Global Free Guard key; remediation (B) for every other key; diagnostics (C) for a key with the diagnostics grant or a platform operator."
                    },
                    "verdict_id": {
                      "type": "string",
                      "pattern": "^vdt_[0-9a-f]{24}$",
                      "description": "Random; the key for GET /v1/explain/{verdict_id}. Absent when a verdict has none."
                    },
                    "evaluation_status": {
                      "type": "string",
                      "enum": [
                        "evaluated",
                        "protection_unavailable",
                        "refused_excess_evidence"
                      ],
                      "description": "refused_excess_evidence: the engines refused to analyse the text, so it was not checked. It appears in the spectorn object of a proxy or memory block; /v1/scan answers such a refusal with 403 analysis_refused instead of a verdict. Treat it as a block, never as an allow."
                    },
                    "decision": {
                      "type": "string",
                      "enum": [
                        "allow",
                        "block",
                        "redact"
                      ],
                      "description": "The tenant policy's decision; not a synonym of detected."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "enforce",
                        "shadow"
                      ]
                    },
                    "enforced": {
                      "type": "boolean"
                    },
                    "risk_band": {
                      "type": "string",
                      "enum": [
                        "none",
                        "low",
                        "high"
                      ],
                      "description": "Derived from the decision, never from the engines' score: none (nothing matched), low (matched, not blocked), high (the policy blocks)."
                    },
                    "classes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "prompt_attack",
                          "data_exposure",
                          "harmful_content",
                          "agent_abuse",
                          "obfuscation",
                          "other"
                        ]
                      }
                    },
                    "policy_version": {
                      "type": "string"
                    },
                    "findings": {
                      "type": "array",
                      "description": "Levels B and C.",
                      "items": {
                        "type": "object",
                        "required": [
                          "finding_id",
                          "category",
                          "reason_code",
                          "suggested_action"
                        ],
                        "properties": {
                          "finding_id": {
                            "type": "string",
                            "description": "Names the finding within this answer only; the same text scanned again gets new ids."
                          },
                          "category": {
                            "type": "string",
                            "enum": [
                              "prompt_attack",
                              "data_exposure",
                              "harmful_content",
                              "agent_abuse",
                              "obfuscation",
                              "other"
                            ]
                          },
                          "reason_code": {
                            "type": "string",
                            "enum": [
                              "instruction_override",
                              "manipulation",
                              "personal_data",
                              "sensitive_data_leak",
                              "harmful_content",
                              "tool_misuse",
                              "agent_trust_violation",
                              "unsafe_code",
                              "hidden_payload",
                              "quoted_mention",
                              "unclassified_signal"
                            ]
                          },
                          "source_spans": {
                            "type": "array",
                            "description": "UTF-8 byte offsets into the prompt as sent, only where the gateway verified the mapping. Absent when none was verified.",
                            "items": {
                              "type": "object",
                              "required": [
                                "start_byte",
                                "end_byte"
                              ],
                              "properties": {
                                "start_byte": {
                                  "type": "integer",
                                  "minimum": 0
                                },
                                "end_byte": {
                                  "type": "integer",
                                  "minimum": 0
                                }
                              }
                            }
                          },
                          "suggested_action": {
                            "type": "string",
                            "enum": [
                              "remove_embedded_instructions",
                              "rephrase_request",
                              "mask_personal_data",
                              "remove_sensitive_data",
                              "review_tool_call",
                              "review_agent_permissions",
                              "review_generated_code",
                              "remove_hidden_content",
                              "request_review"
                            ]
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "diagnostics": {
                      "type": "object",
                      "description": "Level C only: engine, rule, confidence and engine-view offsets of every match, and the post-policy trace."
                    },
                    "detected": {
                      "type": "boolean",
                      "description": "An engine matched. Not a block: see decision."
                    },
                    "would_block": {
                      "type": "boolean"
                    },
                    "allowed": {
                      "type": "boolean"
                    },
                    "policy_applied": {
                      "type": "boolean"
                    },
                    "latency_ms": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Gateway time rounded up to whole milliseconds."
                    },
                    "self_scanned": {
                      "type": "boolean"
                    },
                    "self_scan_passed": {
                      "type": "boolean"
                    },
                    "channel_disclosed": {
                      "type": "object"
                    },
                    "risk_score": {
                      "type": "number",
                      "description": "Level C only."
                    },
                    "matches": {
                      "type": "array",
                      "description": "Level C only."
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Analysis refused: the engines found more matches than they bound, so the text was not checked. Treat this answer as a block, never as an allow, and do not retry the same text.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "code",
                    "reason",
                    "evaluation_status"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "const": "analysis_refused"
                    },
                    "reason": {
                      "type": "string",
                      "const": "match_budget_exceeded"
                    },
                    "evaluation_status": {
                      "type": "string",
                      "const": "refused_excess_evidence"
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ],
        "description": "Answers at the caller's disclosure level (schema spectorn.verdict_projection.v1): a key reads the policy decision, a risk band derived from it, coarse classes and findings; the engines' score, rules and offsets reach only a key with the diagnostics grant."
      }
    },
    "/v1/scan/artifact": {
      "post": {
        "summary": "Scan a model artifact byte stream",
        "tags": [
          "scan"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Analysis refused: the engines found more matches than they bound, so the text was not checked. Treat this answer as a block, never as an allow, and do not retry the same text.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "code",
                    "reason",
                    "evaluation_status"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "const": "analysis_refused"
                    },
                    "reason": {
                      "type": "string",
                      "const": "match_budget_exceeded"
                    },
                    "evaluation_status": {
                      "type": "string",
                      "const": "refused_excess_evidence"
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/scan/target": {
      "post": {
        "summary": "Analyze exactly one declared user or assistant target",
        "tags": [
          "scan"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Analysis refused: the engines found more matches than they bound, so the text was not checked. Treat this answer as a block, never as an allow, and do not retry the same text.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "code",
                    "reason",
                    "evaluation_status"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "const": "analysis_refused"
                    },
                    "reason": {
                      "type": "string",
                      "const": "match_budget_exceeded"
                    },
                    "evaluation_status": {
                      "type": "string",
                      "const": "refused_excess_evidence"
                    },
                    "channel_disclosed": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/security/self-defense": {
      "get": {
        "summary": "Return runtime self-defense mode and recent security events",
        "tags": [
          "security"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/security/self-defense/recover": {
      "post": {
        "summary": "Recover runtime self-defense mode after operator review",
        "tags": [
          "security"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/signup": {
      "post": {
        "summary": "Request a signup magic link",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "API signup is closed on this server: registration, legal publication or SPECTORN_API_SIGNUP_ENABLED is off",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "426": {
            "description": "Hosted Spectorn edge refused the request before it reached the server"
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "description": "Closed on hosted Spectorn: the RU and Global edges answer 426 before the request reaches the server. A self-hosted server serves it only when SPECTORN_REGISTRATION_ENABLED is true, SPECTORN_LEGAL_PUBLICATION_STATUS is published and SPECTORN_API_SIGNUP_ENABLED is true; otherwise it answers 403.",
        "x-spectorn-availability": "hosted_edge_closed",
        "x-spectorn-hosted-edge-contract": {
          "status": 426,
          "request_forwarded": false
        }
      }
    },
    "/v1/signup/verify": {
      "get": {
        "summary": "Render signup magic-link confirmation",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "API signup is closed on this server: registration, legal publication or SPECTORN_API_SIGNUP_ENABLED is off",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "426": {
            "description": "Hosted Spectorn edge refused the request before it reached the server"
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "description": "Closed on hosted Spectorn: the RU and Global edges answer 426 before the request reaches the server. A self-hosted server serves it only when SPECTORN_REGISTRATION_ENABLED is true, SPECTORN_LEGAL_PUBLICATION_STATUS is published and SPECTORN_API_SIGNUP_ENABLED is true; otherwise it answers 403.",
        "x-spectorn-availability": "hosted_edge_closed",
        "x-spectorn-hosted-edge-contract": {
          "status": 426,
          "request_forwarded": false
        }
      },
      "post": {
        "summary": "Consume a signup magic-link token",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "API signup is closed on this server: registration, legal publication or SPECTORN_API_SIGNUP_ENABLED is off",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "426": {
            "description": "Hosted Spectorn edge refused the request before it reached the server"
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "description": "Closed on hosted Spectorn: the RU and Global edges answer 426 before the request reaches the server. A self-hosted server serves it only when SPECTORN_REGISTRATION_ENABLED is true, SPECTORN_LEGAL_PUBLICATION_STATUS is published and SPECTORN_API_SIGNUP_ENABLED is true; otherwise it answers 403.",
        "x-spectorn-availability": "hosted_edge_closed",
        "x-spectorn-hosted-edge-contract": {
          "status": 426,
          "request_forwarded": false
        }
      }
    },
    "/v1/usage": {
      "get": {
        "summary": "Return current tenant usage summary",
        "tags": [
          "account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "cookieAuth": []
          }
        ]
      }
    },
    "/v1/webhooks/stripe": {
      "post": {
        "summary": "Receive Stripe webhook events",
        "tags": [
          "billing"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  }
}
