{
  "openapi": "3.1.0",
  "info": {
    "title": "AgentGround API",
    "version": "4.2.0",
    "summary": "Build, publish, and invoke versioned AI agents.",
    "description": "AgentGround separates editable drafts from immutable published versions. Use the\nmanagement API with an account token, then invoke a published agent with its\nagent-scoped API key. Production conversations remain pinned to the version on\nwhich they started. Every error includes a request ID for support and tracing.\nAPI calls are globally limited by client IP and authenticated calls have an\nadditional account or agent-key quota. Agent turns have an end-to-end deadline.\nRuntime calls can return JSON or an ordered Server-Sent Events lifecycle stream.\nBrowser widgets use short-lived, origin-bound client secrets issued by a trusted backend.\nTo embed an agent in another product, send messages to /v1/agents/{agentId}/responses\nand receive activity either in the response body, over the SSE stream, or through\nsigned webhook events. A machine-readable copy of this contract is served at\n/openapi.json and /openapi.yaml.\n",
    "license": {
      "name": "MIT"
    }
  },
  "servers": [
    {
      "url": "http://127.0.0.1:3000",
      "description": "Local development"
    }
  ],
  "tags": [
    {
      "name": "System",
      "description": "Health, platform capabilities, and public metadata."
    },
    {
      "name": "Authentication",
      "description": "Account registration and sessions."
    },
    {
      "name": "Projects",
      "description": "Tenant-isolated project workspaces with owner, editor, and viewer access."
    },
    {
      "name": "Governance",
      "description": "Project membership, roles, and controlled environment promotion."
    },
    {
      "name": "Connectors",
      "description": "Operator-approved external tool workflows."
    },
    {
      "name": "Agents",
      "description": "Mutable drafts, tests, and immutable publishing."
    },
    {
      "name": "Conversations",
      "description": "Conversation message inspection and correction."
    },
    {
      "name": "Leads",
      "description": "Schema-driven lead records and safe CSV export."
    },
    {
      "name": "API keys",
      "description": "Agent-scoped production credentials."
    },
    {
      "name": "Runtime",
      "description": "Production invocation for published agents."
    },
    {
      "name": "Presets",
      "description": "Operator-curated demo starting points for the agent builder."
    },
    {
      "name": "Webhooks",
      "description": "Signed outbound events delivered to an allow-listed destination."
    },
    {
      "name": "Handoffs",
      "description": "Human escalation requests raised by an agent."
    },
    {
      "name": "Administration",
      "description": "Global operations protected by the admin key."
    },
    {
      "name": "Compatibility",
      "description": "Session-based API for file-configured agents."
    }
  ],
  "security": [],
  "components": {
    "securitySchemes": {
      "accountBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "signed-account-token"
      },
      "agentApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "gqa_agent-key"
      },
      "widgetBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "signed-widget-client-secret"
      },
      "sessionBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "signed-session-token"
      },
      "adminKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Admin-API-Key"
      }
    },
    "parameters": {
      "ProjectId": {
        "name": "projectId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Project identifier."
      },
      "AgentId": {
        "name": "agentId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Agent identifier."
      },
      "ConversationId": {
        "name": "conversationId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Conversation identifier."
      },
      "MessageId": {
        "name": "messageId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Message identifier."
      },
      "KeyId": {
        "name": "keyId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "API key record identifier."
      },
      "UserId": {
        "name": "userId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Account identifier."
      },
      "ApprovalId": {
        "name": "approvalId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Approval identifier."
      },
      "EvaluationCaseId": {
        "name": "caseId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Evaluation case identifier."
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Unique key for one logical runtime request. Reuse it when retrying that same request.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        }
      },
      "RuntimeEnvironment": {
        "name": "AgentGround-Environment",
        "in": "header",
        "required": false,
        "description": "Selects staging or production for a new conversation. Production is the default; existing conversations stay pinned to their starting version.",
        "schema": {
          "type": "string",
          "enum": [
            "staging",
            "production"
          ],
          "default": "production"
        }
      }
    },
    "headers": {
      "RequestId": {
        "description": "Request correlation identifier.",
        "schema": {
          "type": "string"
        }
      },
      "RateLimitLimit": {
        "description": "Requests allowed in the active window.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "Requests remaining in the active window.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitReset": {
        "description": "Unix timestamp when the active window resets.",
        "schema": {
          "type": "integer"
        }
      },
      "AccountRateLimitLimit": {
        "description": "Requests allowed for the authenticated account in the active window.",
        "schema": {
          "type": "integer"
        }
      },
      "AccountRateLimitRemaining": {
        "description": "Requests remaining for the authenticated account in the active window.",
        "schema": {
          "type": "integer"
        }
      },
      "AccountRateLimitReset": {
        "description": "Unix timestamp when the account quota resets.",
        "schema": {
          "type": "integer"
        }
      },
      "AgentRateLimitLimit": {
        "description": "Requests allowed for the authenticated agent key in the active window.",
        "schema": {
          "type": "integer"
        }
      },
      "AgentRateLimitRemaining": {
        "description": "Requests remaining for the authenticated agent key in the active window.",
        "schema": {
          "type": "integer"
        }
      },
      "AgentRateLimitReset": {
        "description": "Unix timestamp when the agent-key quota resets.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "requestId"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "VALIDATION_ERROR"
              },
              "message": {
                "type": "string",
                "example": "The request could not be validated."
              },
              "details": {
                "description": "Optional structured diagnostic details."
              },
              "requestId": {
                "type": "string",
                "example": "b4b34d3e-3f1d-4e8f-8e1e-59159c8d89a8"
              }
            }
          }
        }
      },
      "User": {
        "type": "object",
        "required": [
          "id",
          "email",
          "displayName",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "usr_01JABC"
          },
          "email": {
            "type": "string",
            "format": "email",
            "example": "owner@example.com"
          },
          "displayName": {
            "type": "string",
            "example": "Ada Lovelace"
          },
          "status": {
            "type": "string",
            "example": "active"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastLoginAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Project": {
        "type": "object",
        "required": [
          "id",
          "name",
          "slug"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "prj_01JABC"
          },
          "name": {
            "type": "string",
            "example": "Product concierge"
          },
          "slug": {
            "type": "string",
            "example": "product-concierge"
          },
          "description": {
            "type": "string",
            "example": "Pre-sales product guidance."
          },
          "accessRole": {
            "type": "string",
            "enum": [
              "owner",
              "editor",
              "viewer"
            ],
            "description": "Effective role of the authenticated account for this project."
          },
          "agentCount": {
            "type": "integer",
            "minimum": 0
          },
          "publishedAgentCount": {
            "type": "integer",
            "minimum": 0
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "LeadField": {
        "type": "object",
        "required": [
          "key",
          "label",
          "type",
          "required"
        ],
        "properties": {
          "key": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]*$",
            "example": "work_email"
          },
          "label": {
            "type": "string",
            "maxLength": 80,
            "example": "Work email"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "email",
              "phone",
              "url",
              "date",
              "number",
              "boolean"
            ]
          },
          "required": {
            "type": "boolean"
          },
          "description": {
            "type": "string",
            "maxLength": 240
          }
        }
      },
      "Knowledge": {
        "type": "object",
        "required": [
          "title",
          "content"
        ],
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "example": "Returns policy"
          },
          "content": {
            "type": "string",
            "maxLength": 20000,
            "example": "Returns are accepted within 30 days."
          }
        }
      },
      "Citation": {
        "type": "object",
        "required": [
          "marker",
          "sourceId",
          "title",
          "excerpt"
        ],
        "description": "Snapshot of a retrieved knowledge excerpt actually referenced by its marker in this message. It records grounding context, not independent proof that the model's claim is true.",
        "properties": {
          "marker": {
            "type": "string",
            "pattern": "^S[1-8]$",
            "example": "S1"
          },
          "sourceId": {
            "type": "string",
            "example": "knw_01JABC"
          },
          "title": {
            "type": "string",
            "maxLength": 120,
            "example": "Returns policy"
          },
          "excerpt": {
            "type": "string",
            "maxLength": 6000,
            "example": "Returns are accepted within 30 days."
          }
        }
      },
      "Agent": {
        "type": "object",
        "required": [
          "id",
          "projectId",
          "name",
          "provider",
          "model",
          "status",
          "draftRevision"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "agt_01JABC"
          },
          "projectId": {
            "type": "string",
            "example": "prj_01JABC"
          },
          "name": {
            "type": "string",
            "example": "Product guide"
          },
          "slug": {
            "type": "string",
            "example": "product-guide"
          },
          "description": {
            "type": "string"
          },
          "provider": {
            "type": "string",
            "enum": [
              "openai",
              "gemini",
              "groq"
            ]
          },
          "model": {
            "type": "string",
            "example": "gpt-5-mini"
          },
          "testModel": {
            "type": "string",
            "example": "gpt-5-mini"
          },
          "serviceTier": {
            "type": "string",
            "enum": [
              "default",
              "flex",
              "fast"
            ]
          },
          "reasoningEffort": {
            "type": "string",
            "enum": [
              "none",
              "minimal",
              "low",
              "medium",
              "high",
              "xhigh",
              "max"
            ]
          },
          "tone": {
            "type": "string"
          },
          "openingMessage": {
            "type": "string"
          },
          "conversationStyle": {
            "$ref": "#/components/schemas/ConversationStyle"
          },
          "systemPrompt": {
            "type": "string"
          },
          "knowledge": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Knowledge"
            }
          },
          "leadCaptureEnabled": {
            "type": "boolean"
          },
          "leadFields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeadField"
            }
          },
          "handoffEnabled": {
            "type": "boolean",
            "description": "Exposes the internal human-handoff tool to this draft or published version."
          },
          "handoffInstructions": {
            "type": "string",
            "maxLength": 1000,
            "description": "Business-specific criteria for requesting human review."
          },
          "providerKeyConfigured": {
            "type": "boolean"
          },
          "draftRevision": {
            "type": "integer",
            "minimum": 1
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published",
              "draft_changes",
              "staged"
            ]
          },
          "enabledTools": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Names of operator-approved connectors enabled for this draft."
          },
          "published": {
            "type": "boolean"
          }
        }
      },
      "ConversationStyle": {
        "type": "string",
        "description": "Who leads. visitor_led: the person asks and the agent answers, and openingMessage is a display-only greeting. agent_led: the agent speaks first and keeps the initiative, and openingMessage is persisted as the first assistant turn of every conversation so the model can see what it already said.",
        "enum": [
          "visitor_led",
          "agent_led"
        ],
        "default": "visitor_led",
        "example": "agent_led"
      },
      "Message": {
        "type": "object",
        "required": [
          "id",
          "role",
          "content",
          "citations"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "msg_01JABC"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "assistant",
              "tool",
              "system"
            ]
          },
          "content": {
            "type": "string",
            "example": "Which plan is right for a small team?"
          },
          "citations": {
            "type": "array",
            "description": "Knowledge excerpts cited by this message. Empty for user messages and answers without supported retrieval markers.",
            "items": {
              "$ref": "#/components/schemas/Citation"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "editedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Lead": {
        "type": "object",
        "required": [
          "id",
          "agentId",
          "fields",
          "source",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "agentId": {
            "type": "string"
          },
          "conversationId": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": "string",
            "example": "agent_conversation"
          },
          "fields": {
            "type": "object",
            "additionalProperties": true,
            "example": {
              "work_email": "ada@example.com"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Handoff": {
        "type": "object",
        "required": [
          "id",
          "agentId",
          "conversationId",
          "reason",
          "summary",
          "priority",
          "status",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "handoff_01JABC"
          },
          "agentId": {
            "type": "string"
          },
          "agentVersionId": {
            "type": [
              "string",
              "null"
            ]
          },
          "conversationId": {
            "type": "string"
          },
          "externalUserId": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": "string",
            "maxLength": 240
          },
          "summary": {
            "type": "string",
            "maxLength": 1200
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "normal",
              "high",
              "urgent"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "in_progress",
              "resolved",
              "closed"
            ]
          },
          "resolvedBy": {
            "type": [
              "string",
              "null"
            ]
          },
          "resolvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEndpoint": {
        "type": "object",
        "required": [
          "id",
          "agentId",
          "url",
          "events",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "agentId": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            },
            "description": "Event types this endpoint is subscribed to."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEventType": {
        "type": "string",
        "description": "Outbound event an external application can subscribe to.",
        "enum": [
          "conversation.started",
          "message.created",
          "handoff.created",
          "handoff.updated"
        ],
        "example": "message.created"
      },
      "WebhookEvent": {
        "type": "object",
        "required": [
          "id",
          "type",
          "createdAt",
          "data"
        ],
        "description": "Signed JSON body POSTed to a subscribed endpoint. Verify AgentGround-Signature before trusting it and treat AgentGround-Delivery as the duplicate-detection key.",
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_01JABC"
          },
          "type": {
            "$ref": "#/components/schemas/WebhookEventType"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object",
            "description": "Event payload. message.created carries conversationId, agentId, channel, externalUserId, and message; conversation.started carries conversation; handoff events carry handoff.",
            "additionalProperties": true
          }
        }
      },
      "Conversation": {
        "type": "object",
        "required": [
          "id",
          "object",
          "agentId",
          "channel",
          "status",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "sess_01JABC"
          },
          "object": {
            "type": "string",
            "const": "agent.conversation"
          },
          "agentId": {
            "type": "string"
          },
          "agentVersionId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Immutable version this conversation stays pinned to."
          },
          "channel": {
            "type": "string",
            "enum": [
              "api",
              "widget",
              "test",
              "legacy"
            ]
          },
          "externalUserId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Your application's identifier for the end user."
          },
          "title": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          },
          "metadata": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Flat key/value pairs supplied by your application. Never place secrets here."
          },
          "status": {
            "type": "string",
            "example": "active"
          },
          "messageCount": {
            "type": "integer",
            "minimum": 0
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AgentPreset": {
        "type": "object",
        "required": [
          "id",
          "name",
          "category",
          "summary",
          "draft"
        ],
        "description": "Operator-curated starting point for the agent builder. Presets carry prompt, knowledge, lead, and evaluation defaults only, never credentials or endpoints.",
        "properties": {
          "id": {
            "type": "string",
            "example": "support-concierge"
          },
          "name": {
            "type": "string",
            "example": "Support concierge"
          },
          "category": {
            "type": "string",
            "example": "Customer support"
          },
          "icon": {
            "type": "string",
            "maxLength": 4
          },
          "summary": {
            "type": "string",
            "maxLength": 240
          },
          "bestFor": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sampleQuestions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Realistic questions to try after creating the agent."
          },
          "draft": {
            "type": "object",
            "description": "Draft defaults applied when the preset is used, including installed connectors only.",
            "additionalProperties": true
          },
          "knowledge": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Knowledge"
            }
          },
          "evaluationCases": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "AgentCreateRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "description": "Guided creation. Supply presetId to start from a curated preset, then override any field in the same call.",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 80,
            "example": "Support concierge"
          },
          "presetId": {
            "type": "string",
            "example": "support-concierge",
            "description": "Identifier from GET /api/presets. Preset defaults are applied first and every other field overrides them."
          },
          "description": {
            "type": "string",
            "maxLength": 1000
          },
          "provider": {
            "type": "string",
            "enum": [
              "openai",
              "gemini",
              "groq"
            ]
          },
          "model": {
            "type": "string",
            "maxLength": 120
          },
          "testModel": {
            "type": "string",
            "maxLength": 120
          },
          "serviceTier": {
            "type": "string",
            "enum": [
              "standard",
              "flex",
              "fast"
            ]
          },
          "reasoningEffort": {
            "type": "string",
            "enum": [
              "none",
              "minimal",
              "low",
              "medium",
              "high",
              "xhigh",
              "max"
            ]
          },
          "tone": {
            "type": "string",
            "maxLength": 120
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 2
          },
          "openingMessage": {
            "type": "string",
            "maxLength": 500,
            "description": "Required before publishing when conversationStyle is agent_led."
          },
          "conversationStyle": {
            "$ref": "#/components/schemas/ConversationStyle"
          },
          "systemPrompt": {
            "type": "string",
            "maxLength": 20000
          },
          "leadCaptureEnabled": {
            "type": "boolean"
          },
          "leadFields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeadField"
            }
          },
          "handoffEnabled": {
            "type": "boolean"
          },
          "handoffInstructions": {
            "type": "string",
            "maxLength": 1000
          },
          "enabledTools": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Operator-approved connector names. Scopes are derived on the server."
          },
          "knowledge": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Knowledge"
            }
          },
          "evaluationCases": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "providerApiKey": {
            "type": "string",
            "writeOnly": true,
            "description": "Project-owner only. Stored as authenticated ciphertext and never returned."
          }
        }
      },
      "ConversationCreateRequest": {
        "type": "object",
        "properties": {
          "externalUserId": {
            "type": "string",
            "maxLength": 128,
            "example": "customer-42"
          },
          "title": {
            "type": "string",
            "maxLength": 120,
            "example": "Refund for order 4182"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Up to 20 flat key/value pairs echoed back on every conversation read and event."
          },
          "environment": {
            "type": "string",
            "enum": [
              "staging",
              "production"
            ],
            "default": "production"
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "required": [
          "id",
          "agentId",
          "eventType",
          "status",
          "attemptCount",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable event and delivery ID for receiver-side duplicate detection."
          },
          "agentId": {
            "type": "string"
          },
          "eventType": {
            "$ref": "#/components/schemas/WebhookEventType"
          },
          "payload": {
            "type": "object",
            "additionalProperties": true
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "delivering",
              "delivered",
              "exhausted",
              "cancelled"
            ]
          },
          "attemptCount": {
            "type": "integer",
            "minimum": 0
          },
          "nextAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastStatusCode": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          },
          "deliveredAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApiKeyRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "example": "Production backend"
          },
          "prefix": {
            "type": "string",
            "example": "gqa_ab12"
          },
          "lastFour": {
            "type": "string",
            "example": "9xyz"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "revokedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "RuntimeRequest": {
        "type": "object",
        "required": [
          "input"
        ],
        "properties": {
          "input": {
            "type": "string",
            "minLength": 1,
            "maxLength": 12000,
            "example": "Which plan is right for a small team?"
          },
          "conversationId": {
            "type": "string",
            "description": "Return value from an earlier turn."
          },
          "externalUserId": {
            "type": "string",
            "maxLength": 200,
            "example": "visitor-42"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "Return an ordered Server-Sent Events lifecycle stream instead of one JSON document."
          },
          "environment": {
            "type": "string",
            "enum": [
              "staging",
              "production"
            ],
            "default": "production",
            "description": "Alternative to the AgentGround-Environment header for a new conversation."
          }
        }
      },
      "RuntimeResponse": {
        "type": "object",
        "required": [
          "id",
          "object",
          "agentId",
          "version",
          "conversationId",
          "output",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "agent.response"
          },
          "agentId": {
            "type": "string"
          },
          "version": {
            "type": "integer"
          },
          "conversationId": {
            "type": "string"
          },
          "inputMessage": {
            "$ref": "#/components/schemas/Message"
          },
          "output": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "description": "Assistant output messages for this turn."
          },
          "status": {
            "type": "string",
            "example": "completed"
          },
          "usage": {
            "type": "object",
            "additionalProperties": true
          },
          "approvals": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "WidgetSessionRequest": {
        "type": "object",
        "required": [
          "allowedOrigin"
        ],
        "properties": {
          "allowedOrigin": {
            "type": "string",
            "format": "uri",
            "example": "https://www.example.com",
            "description": "Exact HTTPS browser origin allowed to use the client secret. Localhost may use HTTP."
          },
          "externalUserId": {
            "type": "string",
            "maxLength": 128,
            "example": "customer-42",
            "description": "Optional application identity bound to conversations created by this client secret."
          },
          "environment": {
            "type": "string",
            "enum": [
              "staging",
              "production"
            ],
            "default": "production"
          }
        }
      },
      "WidgetSession": {
        "type": "object",
        "required": [
          "clientSecret",
          "expiresAt",
          "allowedOrigin",
          "resumable",
          "responseUrl",
          "scriptUrl"
        ],
        "properties": {
          "clientSecret": {
            "type": "string",
            "writeOnly": true,
            "description": "Short-lived signed browser credential. Never persist or log it."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "allowedOrigin": {
            "type": "string",
            "format": "uri"
          },
          "resumable": {
            "type": "boolean",
            "description": "True when the trusted backend supplied a stable externalUserId, allowing a refreshed widget session to continue that user's conversation."
          },
          "responseUrl": {
            "type": "string",
            "format": "uri"
          },
          "scriptUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "WidgetRuntimeRequest": {
        "type": "object",
        "required": [
          "input"
        ],
        "properties": {
          "input": {
            "type": "string",
            "minLength": 1,
            "maxLength": 12000,
            "example": "Can you help me choose a plan?"
          },
          "conversationId": {
            "type": "string",
            "description": "Widget conversation returned by an earlier turn using this agent."
          },
          "stream": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "RuntimeStreamEvent": {
        "type": "object",
        "required": [
          "type",
          "sequence"
        ],
        "description": "One SSE data object. Events are ordered by the monotonically increasing sequence field.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "response.created",
              "response.progress",
              "response.output_text.done",
              "response.completed",
              "error"
            ]
          },
          "sequence": {
            "type": "integer",
            "minimum": 1
          },
          "response": {
            "description": "Lifecycle metadata or the completed RuntimeResponse."
          },
          "event": {
            "type": "object",
            "additionalProperties": true,
            "description": "Internal progress event without prompt or credential data."
          },
          "text": {
            "type": "string",
            "description": "Complete assistant text, emitted by response.output_text.done."
          },
          "citations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Citation"
            },
            "description": "Citation snapshots emitted with the completed text."
          },
          "messageId": {
            "type": "string"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "type": "string"
              }
            }
          }
        }
      },
      "EvaluationCase": {
        "type": "object",
        "required": [
          "id",
          "agentId",
          "name",
          "input",
          "expectedKeywords"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "evalcase_01JABC"
          },
          "agentId": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 80,
            "example": "Explains refund window"
          },
          "input": {
            "type": "string",
            "minLength": 1,
            "maxLength": 12000,
            "example": "How long do I have to return an item?"
          },
          "expectedKeywords": {
            "type": "array",
            "minItems": 1,
            "maxItems": 8,
            "items": {
              "type": "string",
              "maxLength": 80
            },
            "example": [
              "return",
              "30 days"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "EvaluationSummary": {
        "type": "object",
        "required": [
          "draftRevision",
          "caseCount",
          "evaluatedCount",
          "passedCount",
          "failedCount",
          "ready"
        ],
        "properties": {
          "draftRevision": {
            "type": "integer"
          },
          "caseCount": {
            "type": "integer",
            "minimum": 0
          },
          "evaluatedCount": {
            "type": "integer",
            "minimum": 0
          },
          "passedCount": {
            "type": "integer",
            "minimum": 0
          },
          "failedCount": {
            "type": "integer",
            "minimum": 0
          },
          "ready": {
            "type": "boolean",
            "description": "True only when every saved case passed against this draft revision."
          },
          "evaluatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "EvaluationRun": {
        "type": "object",
        "required": [
          "id",
          "agentId",
          "draftRevision",
          "caseName",
          "input",
          "expectedKeywords",
          "status",
          "latencyMs",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "evalrun_01JABC"
          },
          "agentId": {
            "type": "string"
          },
          "caseId": {
            "type": [
              "string",
              "null"
            ]
          },
          "draftRevision": {
            "type": "integer",
            "minimum": 1
          },
          "sessionId": {
            "type": [
              "string",
              "null"
            ]
          },
          "caseName": {
            "type": "string"
          },
          "input": {
            "type": "string",
            "description": "Snapshot of the evaluated visitor input."
          },
          "expectedKeywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "passed",
              "failed",
              "error"
            ]
          },
          "output": {
            "type": [
              "string",
              "null"
            ],
            "description": "Snapshot of the assistant output when available."
          },
          "latencyMs": {
            "type": "integer",
            "minimum": 0
          },
          "errorCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ModelTrace": {
        "type": "object",
        "description": "Prompt-free operational metadata for one provider call.",
        "properties": {
          "id": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "phase": {
            "type": "string",
            "example": "chat"
          },
          "latencyMs": {
            "type": "integer",
            "minimum": 0
          },
          "status": {
            "type": "string"
          },
          "errorCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "providerRequestId": {
            "type": [
              "string",
              "null"
            ]
          },
          "promptTokens": {
            "type": [
              "integer",
              "null"
            ]
          },
          "completionTokens": {
            "type": [
              "integer",
              "null"
            ]
          },
          "totalTokens": {
            "type": [
              "integer",
              "null"
            ]
          },
          "cachedInputTokens": {
            "type": [
              "integer",
              "null"
            ]
          },
          "reasoningTokens": {
            "type": [
              "integer",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AgentObservability": {
        "type": "object",
        "required": [
          "runCount",
          "completedCount",
          "failedCount",
          "averageLatencyMs",
          "totalTokens",
          "cachedInputTokens",
          "recentRuns"
        ],
        "properties": {
          "runCount": {
            "type": "integer",
            "minimum": 0
          },
          "completedCount": {
            "type": "integer",
            "minimum": 0
          },
          "failedCount": {
            "type": "integer",
            "minimum": 0
          },
          "averageLatencyMs": {
            "type": "integer",
            "minimum": 0
          },
          "totalTokens": {
            "type": "integer",
            "minimum": 0
          },
          "cachedInputTokens": {
            "type": "integer",
            "minimum": 0
          },
          "recentRuns": {
            "type": "array",
            "maxItems": 30,
            "items": {
              "$ref": "#/components/schemas/ModelTrace"
            }
          }
        }
      },
      "EvaluationPayload": {
        "type": "object",
        "required": [
          "summary",
          "cases",
          "runs",
          "observability"
        ],
        "properties": {
          "summary": {
            "$ref": "#/components/schemas/EvaluationSummary"
          },
          "cases": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "$ref": "#/components/schemas/EvaluationCase"
            }
          },
          "runs": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/EvaluationRun"
            }
          },
          "observability": {
            "$ref": "#/components/schemas/AgentObservability"
          }
        }
      }
    },
    "requestBodies": {
      "RegisterCredentials": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "displayName",
                "email",
                "password"
              ],
              "properties": {
                "email": {
                  "type": "string",
                  "format": "email",
                  "example": "owner@example.com"
                },
                "password": {
                  "type": "string",
                  "minLength": 10,
                  "example": "correct-horse-battery-staple"
                },
                "displayName": {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 80,
                  "example": "Ada Lovelace"
                }
              }
            }
          }
        }
      },
      "LoginCredentials": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "email",
                "password"
              ],
              "properties": {
                "email": {
                  "type": "string",
                  "format": "email",
                  "example": "owner@example.com"
                },
                "password": {
                  "type": "string",
                  "minLength": 1,
                  "example": "correct-horse-battery-staple"
                }
              }
            }
          }
        }
      },
      "MessageUpdate": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "content"
              ],
              "properties": {
                "content": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 12000,
                  "example": "Corrected message text."
                }
              }
            }
          }
        }
      }
    },
    "responses": {
      "Error": {
        "description": "Request failed. The status and error code identify the failure class.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/RequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "VALIDATION_ERROR",
                "message": "The request could not be validated.",
                "requestId": "b4b34d3e-3f1d-4e8f-8e1e-59159c8d89a8"
              }
            }
          }
        }
      },
      "NoContent": {
        "description": "Operation completed successfully."
      }
    }
  },
  "paths": {
    "/api/health": {
      "get": {
        "tags": [
          "System"
        ],
        "operationId": "getHealth",
        "summary": "Check service readiness",
        "description": "Verifies database access and reports provider-vault and REST-tool readiness.",
        "responses": {
          "200": {
            "description": "Service health snapshot."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/platform": {
      "get": {
        "tags": [
          "System"
        ],
        "operationId": "getPlatformCapabilities",
        "summary": "List studio capabilities",
        "description": "Returns supported providers, models, and credential-vault readiness for the public studio.",
        "responses": {
          "200": {
            "description": "Platform capabilities."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents": {
      "get": {
        "tags": [
          "System",
          "Compatibility"
        ],
        "operationId": "listPublicAgents",
        "summary": "List file-configured agents",
        "description": "Returns public metadata for compatibility agents loaded from config/agents.",
        "responses": {
          "200": {
            "description": "Public agent list."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/auth/register": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "operationId": "registerAccount",
        "summary": "Create an account",
        "description": "Creates an isolated account and returns its signed account session token.",
        "requestBody": {
          "$ref": "#/components/requestBodies/RegisterCredentials"
        },
        "responses": {
          "201": {
            "description": "Account and bearer token created."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/auth/login": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "operationId": "loginAccount",
        "summary": "Sign in to an account",
        "description": "Verifies the password and returns a new signed account session token.",
        "requestBody": {
          "$ref": "#/components/requestBodies/LoginCredentials"
        },
        "responses": {
          "200": {
            "description": "Account and bearer token."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/auth/me": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "operationId": "getCurrentAccount",
        "summary": "Read the signed-in account",
        "description": "Returns the account represented by the current bearer token.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Current account.",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-AccountRateLimit-Limit": {
                "$ref": "#/components/headers/AccountRateLimitLimit"
              },
              "X-AccountRateLimit-Remaining": {
                "$ref": "#/components/headers/AccountRateLimitRemaining"
              },
              "X-AccountRateLimit-Reset": {
                "$ref": "#/components/headers/AccountRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/connectors": {
      "get": {
        "tags": [
          "Connectors"
        ],
        "operationId": "listApprovedConnectors",
        "summary": "List operator-approved connectors",
        "description": "Returns safe connector metadata available to authenticated studios; credentials, fixed values, and full endpoint URLs are omitted.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Approved connector catalog."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/projects": {
      "get": {
        "tags": [
          "Projects"
        ],
        "operationId": "listProjects",
        "summary": "List accessible projects",
        "description": "Lists projects owned by or explicitly shared with the authenticated account and includes its effective role.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Owned project summaries."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "operationId": "createProject",
        "summary": "Create a project",
        "description": "Creates a new tenant-isolated project workspace.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 80,
                    "example": "Product concierge"
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Project created."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/projects/{projectId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "get": {
        "tags": [
          "Projects"
        ],
        "operationId": "getProject",
        "summary": "Get a project workspace",
        "description": "Returns an accessible project with its agents, members, and role-appropriate API-key summaries.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Project workspace."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "tags": [
          "Projects"
        ],
        "operationId": "updateProject",
        "summary": "Update a project",
        "description": "Updates an accessible project's name or description. Editor or owner access is required.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated project."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/presets": {
      "get": {
        "tags": [
          "Presets"
        ],
        "operationId": "listAgentPresets",
        "summary": "List demo agent presets",
        "description": "Returns the operator-curated presets a builder can start from, with connectors that are not installed reported separately so the studio can explain the gap.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Preset catalogue.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "presets": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AgentPreset"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/projects/{projectId}/agents": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "post": {
        "tags": [
          "Agents"
        ],
        "operationId": "createAgent",
        "summary": "Create a configured agent draft",
        "description": "Creates a mutable draft inside an accessible project in one call. A presetId seeds instructions, knowledge, lead fields, connectors, and evaluation cases, and any supplied field overrides the preset. Nothing is written when validation fails. Editor access is required; supplying providerApiKey requires the project owner.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Agent draft created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agent": {
                      "$ref": "#/components/schemas/Agent"
                    },
                    "presetId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/projects/{projectId}/members": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "put": {
        "tags": [
          "Governance"
        ],
        "operationId": "setProjectMember",
        "summary": "Add or update a project member",
        "description": "Owner-only operation that grants editor or viewer access to an existing AgentGround account. The owner remains implicit and cannot be replaced here.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "role"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "editor",
                      "viewer"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Membership updated."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/projects/{projectId}/members/{userId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/UserId"
        }
      ],
      "delete": {
        "tags": [
          "Governance"
        ],
        "operationId": "removeProjectMember",
        "summary": "Remove a project member",
        "description": "Owner-only operation that immediately removes a collaborator's project access without affecting their account.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Member removed."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "get": {
        "tags": [
          "Agents"
        ],
        "operationId": "getAgentDraft",
        "summary": "Get an agent draft",
        "description": "Returns the owned mutable draft, version history, lead count, and key summaries.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Agent studio state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agent": {
                      "$ref": "#/components/schemas/Agent"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "tags": [
          "Agents"
        ],
        "operationId": "updateAgentDraft",
        "summary": "Update an agent draft",
        "description": "Updates draft configuration without changing any published version.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Agent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated draft."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/test": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "post": {
        "tags": [
          "Agents"
        ],
        "operationId": "testAgentDraft",
        "summary": "Test the current draft",
        "description": "Runs a private conversation against the latest editable draft and its test model.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "message"
                ],
                "properties": {
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 12000,
                    "example": "Help me choose a plan."
                  },
                  "conversationId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Draft response and conversation identifier."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/evaluations": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "get": {
        "tags": [
          "Agents"
        ],
        "operationId": "getAgentEvaluations",
        "summary": "Read an agent evaluation suite",
        "description": "Returns tenant-scoped cases, recent results for draft revisions, and prompt-free model telemetry.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Evaluation suite, quality summary, and recent model-run metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvaluationPayload"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "Agents"
        ],
        "operationId": "createAgentEvaluationCase",
        "summary": "Add an evaluation case",
        "description": "Adds one repeatable visitor prompt with 1-8 case-insensitive keywords required in the response.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "input",
                  "expectedKeywords"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 80
                  },
                  "input": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 12000
                  },
                  "expectedKeywords": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 8,
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 80
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Evaluation case created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "evaluationCase": {
                      "$ref": "#/components/schemas/EvaluationCase"
                    },
                    "summary": {
                      "$ref": "#/components/schemas/EvaluationSummary"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/evaluations/run": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "post": {
        "tags": [
          "Agents"
        ],
        "operationId": "runAgentEvaluationSuite",
        "summary": "Run the current draft evaluation suite",
        "description": "Executes every saved case sequentially within one shared agent deadline using the draft test model, then records pass, failure, latency, token, and error metadata.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Completed suite results and refreshed evaluation summary.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EvaluationPayload"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "results": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "caseId": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "passed",
                                  "failed",
                                  "error"
                                ]
                              },
                              "missingKeywords": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "errorCode": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/evaluations/{caseId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        },
        {
          "$ref": "#/components/parameters/EvaluationCaseId"
        }
      ],
      "delete": {
        "tags": [
          "Agents"
        ],
        "operationId": "deleteAgentEvaluationCase",
        "summary": "Delete an evaluation case",
        "description": "Removes the selected case while retaining historical run snapshots without the deleted case relationship.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Evaluation case removed and summary refreshed."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/handoffs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "get": {
        "tags": [
          "Handoffs"
        ],
        "operationId": "listAgentHandoffs",
        "summary": "List human handoffs and webhook activity",
        "description": "Returns the owned agent's persisted handoff queue, configured webhook endpoint metadata, and recent delivery attempts.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Handoff workflow state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "handoffs": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Handoff"
                      }
                    },
                    "webhookEndpoint": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/WebhookEndpoint"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "deliveries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/handoffs/{handoffId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        },
        {
          "name": "handoffId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "patch": {
        "tags": [
          "Handoffs"
        ],
        "operationId": "updateAgentHandoff",
        "summary": "Update a human handoff status",
        "description": "Moves an owned handoff through open, in-progress, resolved, or closed state and queues a signed handoff.updated event when configured.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "open",
                      "in_progress",
                      "resolved",
                      "closed"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated handoff.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "handoff": {
                      "$ref": "#/components/schemas/Handoff"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/webhook-endpoint": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "rotateAgentWebhookEndpoint",
        "summary": "Create or rotate an agent webhook endpoint",
        "description": "Validates an allow-listed HTTPS destination, replaces any prior endpoint, cancels its pending deliveries, and returns a new signing secret once. Subscribe to conversation and message events to receive agent activity without polling.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2000
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/WebhookEventType"
                    },
                    "default": [
                      "handoff.created",
                      "handoff.updated"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Endpoint metadata and one-time signing secret.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "endpoint": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    },
                    "secret": {
                      "type": "string",
                      "writeOnly": true
                    },
                    "warning": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "deleteAgentWebhookEndpoint",
        "summary": "Delete an agent webhook endpoint",
        "description": "Removes the endpoint and cancels deliveries that are still pending under its signing secret.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Endpoint removed."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/webhook-deliveries/{deliveryId}/retry": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        },
        {
          "name": "deliveryId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "retryAgentWebhookDelivery",
        "summary": "Retry a terminal webhook delivery",
        "description": "Requeues an exhausted or cancelled event against the currently configured endpoint and resets its attempt counter.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "202": {
            "description": "Delivery queued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "delivery": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/publish": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "post": {
        "tags": [
          "Agents"
        ],
        "operationId": "publishAgentDraft",
        "summary": "Publish an immutable agent version",
        "description": "Validates prerequisites, including an opening message for an agent-led agent and the current-draft evaluation gate when enabled, snapshots the draft, and promotes that immutable version to staging. The first release also initializes production.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "201": {
            "description": "Immutable version published."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/environments/{environment}/promotions": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        },
        {
          "name": "environment",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "enum": [
              "staging",
              "production"
            ]
          },
          "description": "Target release environment."
        }
      ],
      "post": {
        "tags": [
          "Governance",
          "Agents"
        ],
        "operationId": "promoteAgentVersion",
        "summary": "Promote an immutable agent version",
        "description": "Promotes any version belonging to this agent, enabling rollback without rebuilding. Editors may manage staging; only owners may change production.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "versionId"
                ],
                "properties": {
                  "versionId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Environment promotion recorded."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/conversations/{conversationId}/messages": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ConversationId"
        }
      ],
      "get": {
        "tags": [
          "Conversations"
        ],
        "operationId": "listStudioConversationMessages",
        "summary": "List studio conversation messages",
        "description": "Lists messages when the authenticated account owns the agent behind the conversation.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Conversation messages."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/conversations/{conversationId}/messages/{messageId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ConversationId"
        },
        {
          "$ref": "#/components/parameters/MessageId"
        }
      ],
      "patch": {
        "tags": [
          "Conversations"
        ],
        "operationId": "updateStudioConversationMessage",
        "summary": "Correct a studio message",
        "description": "Replaces one message's content while preserving its stable identifier and edit timestamp.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/MessageUpdate"
        },
        "responses": {
          "200": {
            "description": "Updated message."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "Conversations"
        ],
        "operationId": "deleteStudioConversationMessage",
        "summary": "Delete a studio message",
        "description": "Removes one owned conversation message.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/NoContent"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/leads": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "get": {
        "tags": [
          "Leads"
        ],
        "operationId": "listAgentLeads",
        "summary": "List captured leads",
        "description": "Returns structured lead values for an owned agent.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Lead records.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "leads": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Lead"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/leads/export.csv": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "get": {
        "tags": [
          "Leads"
        ],
        "operationId": "exportAgentLeads",
        "summary": "Export captured leads as CSV",
        "description": "Produces a formula-prefix-protected CSV using the configured lead schema.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "CSV export.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/api-keys": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        }
      ],
      "get": {
        "tags": [
          "API keys"
        ],
        "operationId": "listAgentApiKeys",
        "summary": "List agent API-key records",
        "description": "Returns prefixes and audit metadata, never complete key secrets.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "API-key records."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "API keys"
        ],
        "operationId": "createAgentApiKey",
        "summary": "Create an agent API key",
        "description": "Returns the complete secret once; only a hash is retained.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 80,
                    "example": "Production backend"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Key record and one-time API-key secret."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/agents/{agentId}/api-keys/{keyId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        },
        {
          "$ref": "#/components/parameters/KeyId"
        }
      ],
      "delete": {
        "tags": [
          "API keys"
        ],
        "operationId": "revokeAgentApiKey",
        "summary": "Revoke an agent API key",
        "description": "Immediately prevents the selected key from authenticating new requests.",
        "security": [
          {
            "accountBearer": []
          }
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/NoContent"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/agents/{agentId}/widget-sessions": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        },
        {
          "$ref": "#/components/parameters/RuntimeEnvironment"
        }
      ],
      "post": {
        "tags": [
          "Runtime"
        ],
        "operationId": "createWidgetSession",
        "summary": "Create a short-lived widget session",
        "description": "Called only by a trusted customer backend. Exchanges an agent API key for a version-pinned client secret restricted to one exact browser origin.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WidgetSessionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Short-lived browser session. Return this response to the widget without caching it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WidgetSession"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/agents/{agentId}/responses": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AgentId"
        },
        {
          "$ref": "#/components/parameters/IdempotencyKey"
        },
        {
          "$ref": "#/components/parameters/RuntimeEnvironment"
        }
      ],
      "post": {
        "tags": [
          "Runtime"
        ],
        "operationId": "createAgentResponse",
        "summary": "Invoke a published agent",
        "description": "Starts or continues a version-pinned production conversation using an agent-scoped key. Set stream=true for lifecycle SSE; response.output_text.done carries the complete assistant text after generation rather than token deltas.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RuntimeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed agent turn.",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-AgentRateLimit-Limit": {
                "$ref": "#/components/headers/AgentRateLimitLimit"
              },
              "X-AgentRateLimit-Remaining": {
                "$ref": "#/components/headers/AgentRateLimitRemaining"
              },
              "X-AgentRateLimit-Reset": {
                "$ref": "#/components/headers/AgentRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RuntimeResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "SSE frames whose data fields conform to RuntimeStreamEvent."
                },
                "example": "event: response.created\ndata: {\"type\":\"response.created\",\"sequence\":1,\"response\":{\"status\":\"in_progress\"}}\n\nevent: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"sequence\":2,\"text\":\"Hello!\"}\n\nevent: response.completed\ndata: {\"type\":\"response.completed\",\"sequence\":3,\"response\":{\"status\":\"completed\"}}\n"
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/widget/responses": {
      "parameters": [
        {
          "$ref": "#/components/parameters/IdempotencyKey"
        }
      ],
      "post": {
        "tags": [
          "Runtime"
        ],
        "operationId": "createWidgetResponse",
        "summary": "Invoke an agent from the browser widget",
        "description": "Uses a short-lived widget client secret and requires the request Origin to exactly match the origin bound during session creation. The external user identity and published version come from the client secret, not browser input.",
        "security": [
          {
            "widgetBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WidgetRuntimeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed widget turn as JSON or ordered lifecycle SSE when stream=true.",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-AgentRateLimit-Limit": {
                "$ref": "#/components/headers/AgentRateLimitLimit"
              },
              "X-AgentRateLimit-Remaining": {
                "$ref": "#/components/headers/AgentRateLimitRemaining"
              },
              "X-AgentRateLimit-Reset": {
                "$ref": "#/components/headers/AgentRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RuntimeResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "SSE frames whose data fields conform to RuntimeStreamEvent."
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/agent": {
      "get": {
        "tags": [
          "Runtime"
        ],
        "operationId": "getRuntimeAgent",
        "summary": "Describe the agent behind this API key",
        "description": "Returns the published agent identity, opening message, conversationStyle, lead schema, released environments, and the exact endpoint URLs an integrating application should call. Use it to self-configure instead of hard-coding identifiers, and to decide whether your UI should open with the agent's message or wait for the person to type.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Agent descriptor for integrators."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/conversations": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RuntimeEnvironment"
        }
      ],
      "get": {
        "tags": [
          "Runtime",
          "Conversations"
        ],
        "operationId": "listRuntimeConversations",
        "summary": "List conversations for this agent key",
        "description": "Returns API-channel conversations newest first, optionally filtered to one externalUserId. Page with the returned nextBefore cursor.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "externalUserId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Return only conversations belonging to this end user."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Cursor from a previous nextBefore value."
          }
        ],
        "responses": {
          "200": {
            "description": "Conversation list page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "conversations": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Conversation"
                      }
                    },
                    "nextBefore": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "Runtime",
          "Conversations"
        ],
        "operationId": "createRuntimeConversation",
        "summary": "Open a conversation before the first message",
        "description": "Creates a version-pinned conversation and returns the published opening message. For an agent_led agent the opener is persisted as the first assistant turn and returned in output, so the host application renders it and waits for the person to reply. For a visitor_led agent it is a display-only greeting and output is empty. Sending a message without a conversationId still creates the conversation, and seeds the same opener.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConversationCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Conversation created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "conversation": {
                      "$ref": "#/components/schemas/Conversation"
                    },
                    "conversationStyle": {
                      "$ref": "#/components/schemas/ConversationStyle"
                    },
                    "openingMessage": {
                      "type": "string"
                    },
                    "output": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Message"
                      },
                      "description": "The persisted opening turn for an agent-led agent; empty for a visitor-led agent."
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/conversations/{conversationId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ConversationId"
        }
      ],
      "get": {
        "tags": [
          "Runtime",
          "Conversations"
        ],
        "operationId": "getRuntimeConversation",
        "summary": "Read one conversation",
        "description": "Returns conversation state, metadata, message count, and the most recent visible message for the supplied agent key.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Conversation state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "conversation": {
                      "$ref": "#/components/schemas/Conversation"
                    },
                    "lastMessage": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/Message"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/conversations/{conversationId}/messages": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ConversationId"
        }
      ],
      "get": {
        "tags": [
          "Runtime",
          "Conversations"
        ],
        "operationId": "listRuntimeConversationMessages",
        "summary": "List production conversation messages",
        "description": "Lists messages oldest first, only when the supplied agent key owns the conversation. Poll for new activity by passing the last message ID as after, or subscribe to message.created webhooks instead.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Return only messages recorded after this message ID."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Production conversation messages.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "conversationId": {
                      "type": "string"
                    },
                    "messages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Message"
                      }
                    },
                    "nextAfter": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/conversations/{conversationId}/messages/{messageId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ConversationId"
        },
        {
          "$ref": "#/components/parameters/MessageId"
        }
      ],
      "patch": {
        "tags": [
          "Runtime",
          "Conversations"
        ],
        "operationId": "updateRuntimeConversationMessage",
        "summary": "Correct a production message",
        "description": "Replaces message content after enforcing agent-key conversation ownership.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/MessageUpdate"
        },
        "responses": {
          "200": {
            "description": "Updated message."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "Runtime",
          "Conversations"
        ],
        "operationId": "deleteRuntimeConversationMessage",
        "summary": "Delete a production message",
        "description": "Removes one message after enforcing agent-key conversation ownership.",
        "security": [
          {
            "agentApiKey": []
          }
        ],
        "responses": {
          "204": {
            "$ref": "#/components/responses/NoContent"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/admin/metrics": {
      "get": {
        "tags": [
          "Administration"
        ],
        "operationId": "getAdminMetrics",
        "summary": "Read operational metrics",
        "description": "Returns global request, conversation, token, tool, approval, and failure metrics.",
        "security": [
          {
            "adminKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Operational metrics snapshot."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/admin/audit": {
      "get": {
        "tags": [
          "Administration"
        ],
        "operationId": "listAuditEvents",
        "summary": "List audit events",
        "description": "Returns recent security and administration audit events with optional limit filtering.",
        "security": [
          {
            "adminKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audit events."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/admin/config/reload": {
      "post": {
        "tags": [
          "Administration"
        ],
        "operationId": "reloadConfiguration",
        "summary": "Reload agent and tool configuration",
        "description": "Revalidates on-disk configuration and swaps it into the running process only when valid.",
        "security": [
          {
            "adminKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Reload result."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/admin/users/{userId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/UserId"
        }
      ],
      "get": {
        "tags": [
          "Administration"
        ],
        "operationId": "getAdminUser",
        "summary": "Inspect an account",
        "description": "Returns account details for administration without exposing password material.",
        "security": [
          {
            "adminKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Account administration record."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/admin/users/{userId}/reset-access": {
      "parameters": [
        {
          "$ref": "#/components/parameters/UserId"
        }
      ],
      "post": {
        "tags": [
          "Administration"
        ],
        "operationId": "resetUserAccess",
        "summary": "Reset account access",
        "description": "Performs the configured administrative access-reset action and records an audit event.",
        "security": [
          {
            "adminKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Reset result."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/sessions": {
      "post": {
        "tags": [
          "Compatibility"
        ],
        "operationId": "createCompatibilitySession",
        "summary": "Create a compatibility session",
        "description": "Starts a signed session for a public file-configured agent.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agentId": {
                    "type": "string"
                  },
                  "userId": {
                    "type": "string"
                  },
                  "context": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Signed session token and session metadata."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/session": {
      "get": {
        "tags": [
          "Compatibility"
        ],
        "operationId": "getCompatibilitySession",
        "summary": "Read the current compatibility session",
        "description": "Returns session metadata represented by the session bearer token.",
        "security": [
          {
            "sessionBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Session state."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/chat": {
      "post": {
        "tags": [
          "Compatibility"
        ],
        "operationId": "createCompatibilityChatTurn",
        "summary": "Send a compatibility chat message",
        "description": "Runs one turn for the session's file-configured agent, including scoped tools and approvals.",
        "security": [
          {
            "sessionBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "message"
                ],
                "properties": {
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 12000
                  },
                  "idempotencyKey": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chat turn result."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/approvals": {
      "get": {
        "tags": [
          "Compatibility"
        ],
        "operationId": "listPendingApprovals",
        "summary": "List pending approvals",
        "description": "Lists consequential tool calls awaiting a decision in the signed session.",
        "security": [
          {
            "sessionBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Pending approvals."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/approvals/{approvalId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ApprovalId"
        }
      ],
      "post": {
        "tags": [
          "Compatibility"
        ],
        "operationId": "decideApproval",
        "summary": "Approve or reject a tool call",
        "description": "Records a decision and, when approved, resumes the gated operation.",
        "security": [
          {
            "sessionBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "decision"
                ],
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "approve",
                      "reject"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Approval decision result."
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  }
}
