{"openapi":"3.1.0","info":{"title":"Runbear API","description":"Runbear API Documentation","version":"1.0.0","contact":{"name":"Runbear Support","url":"https://runbear.io/support","email":"support@runbear.io"}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An organization API key, sent as `Authorization: Bearer <key>`. Obtain one from the Runbear Manage API Keys menu (refer to https://app.arcade.software/share/5DnGz7O9j4EB5brIRQBG). Each key carries a scope — a set of capabilities (`chat`, `manageAgents`, `manageApiKeys`) and an optional allowlist of agents it may touch. Every operation publishes the permission it requires as `x-runbear-scope`; the vocabulary is documented at the document root under `x-runbear-api-key-scopes`."},"sessionPass":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A browser session pass, minted by POST /v1/sessions from your server and sent by the widget as `Authorization: Bearer <pass>`. It is scoped to one agent and one thread, expires in minutes, and is accepted on only three routes. It can never be used to mint another pass, list threads, upload files, or reach any management endpoint."}},"schemas":{"AgentCreateRequest":{"type":"object","properties":{"name":{"description":"Name of the agent","type":"string","minLength":1,"maxLength":255},"systemPrompt":{"description":"The system prompt for this agent. Limited to 200000 characters; put reference material in a knowledge base rather than in the prompt.","type":"string","maxLength":200000},"provider":{"$ref":"#/components/schemas/ProviderCreate"},"tools":{"type":"object","properties":{"requireApprovalForResourceChanges":{"description":"Whether approval is required for resource changes","type":"boolean"},"requireApprovalBeforeToolCalls":{"description":"Whether approval is required before any tool call. When enabled, supersedes requireApprovalForResourceChanges.","type":"boolean"},"integrations":{"description":"List of managed integrations to enable (Anthropic only: webSearch)","type":"array","items":{"type":"string","enum":["webSearch"]}}}},"longTermMemory":{"description":"Long-term memory configuration. Defaults to enabled if not provided.","type":"object","properties":{"enabled":{"description":"Whether long-term memory is enabled","type":"boolean"}},"required":["enabled"]},"toolProgress":{"description":"Tool activity configuration. Defaults to enabled if not provided.","type":"object","properties":{"enabled":{"description":"Whether tool activity is surfaced to the caller","type":"boolean"}},"required":["enabled"]},"knowledgeSearch":{"$ref":"#/components/schemas/KnowledgeSearchInput"},"aiGateway":{"description":"Cloudflare AI Gateway configuration (Anthropic and OpenAI agents, enterprise plan required)","$ref":"#/components/schemas/AiGatewayInput"},"timeoutMinutes":{"description":"Maximum execution time in minutes for a single chat completion. Defaults to 6 minutes if omitted; capped at 20 minutes.","type":"integer","minimum":1,"maximum":20}},"required":["name","provider"]},"ProviderCreate":{"description":"Provider configuration for creating an agent","anyOf":[{"$ref":"#/components/schemas/AnthropicProviderCreate"},{"$ref":"#/components/schemas/OpenAIResponsesProviderCreate"},{"$ref":"#/components/schemas/GeminiProviderCreate"},{"$ref":"#/components/schemas/ClaudeAgentSdkProviderCreate"}]},"AnthropicProviderCreate":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"anthropic"},"thinking":{"description":"Extended thinking configuration. `disabled` is stored on any model but has no effect on the models that always think (claude-fable-5-1, claude-opus-5-5, claude-fable-5): they reject an explicit opt-out, so those agents run with adaptive thinking regardless. On claude-sonnet-5-5, `disabled` (or no thinking) runs with between-tools thinking only, at `high` effort or below.","oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"enabled"},"effort":{"$ref":"#/components/schemas/AnthropicThinkingEffort"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"disabled"}},"required":["type"]}],"type":"object"},"temperature":{"description":"Temperature value for response generation","anyOf":[{"type":"number"},{"type":"null"}]},"model":{"description":"Model ID (e.g., claude-sonnet-5-5). Defaults to claude-sonnet-5-5 if not provided. Opus-class models are available under the managed key but billed at ~5x the Sonnet rate — expect higher credit usage.","$ref":"#/components/schemas/AnthropicManagedModel"},"useOwnApiKey":{"description":"Use managed API key (default)","type":"boolean","const":false}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"anthropic"},"thinking":{"description":"Extended thinking configuration. `disabled` is stored on any model but has no effect on the models that always think (claude-fable-5-1, claude-opus-5-5, claude-fable-5): they reject an explicit opt-out, so those agents run with adaptive thinking regardless. On claude-sonnet-5-5, `disabled` (or no thinking) runs with between-tools thinking only, at `high` effort or below.","oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"enabled"},"effort":{"$ref":"#/components/schemas/AnthropicThinkingEffort"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"disabled"}},"required":["type"]}],"type":"object"},"temperature":{"description":"Temperature value for response generation","anyOf":[{"type":"number"},{"type":"null"}]},"model":{"description":"Model ID (any supported Anthropic model, including Opus). Defaults to claude-sonnet-5-5 if not provided.","$ref":"#/components/schemas/AnthropicModel"},"useOwnApiKey":{"description":"Use your own API key","type":"boolean","const":true},"apiKey":{"description":"Your Anthropic API key (required when useOwnApiKey is true)","type":"string","minLength":1,"maxLength":500}},"required":["type","useOwnApiKey","apiKey"]}]},"AnthropicThinkingEffort":{"description":"How much reasoning the model spends per turn when extended thinking is enabled. Defaults to `medium` when omitted, which is what every agent ran at before this field existed. `xhigh` and `max` consume substantially more thinking tokens — on Runbear's managed key that shows up directly as higher credit usage. Only the adaptive-thinking models (claude-sonnet-5-5, claude-fable-5-1, claude-opus-5-5, claude-opus-5, claude-fable-5, claude-sonnet-5, claude-opus-4-8, claude-opus-4-7) act on this; older models use a token budget instead and store the value without effect, so it applies if the agent is later moved to an adaptive model.","type":"string","enum":["low","medium","high","xhigh","max"]},"AnthropicManagedModel":{"description":"Anthropic models available with Runbear's managed API key","type":"string","enum":["claude-sonnet-5-5","claude-opus-5-5","claude-opus-5","claude-sonnet-5","claude-opus-4-8","claude-opus-4-7","claude-opus-4-6","claude-opus-4-5","claude-opus-4-5-20251101","claude-opus-4-1","claude-opus-4-1-20250805","claude-opus-4-0","claude-opus-4-20250514","claude-sonnet-4-6","claude-sonnet-4-5","claude-haiku-4-5","claude-sonnet-4-0"]},"AnthropicModel":{"description":"All supported Anthropic models. Opus-class models are billable at ~5x the per-token rate of Sonnet — credit usage will be correspondingly higher on the managed key.","type":"string","enum":["claude-sonnet-5-5","claude-fable-5-1","claude-fable-5","claude-opus-5-5","claude-opus-5","claude-sonnet-5","claude-opus-4-8","claude-opus-4-7","claude-opus-4-6","claude-opus-4-5","claude-opus-4-5-20251101","claude-sonnet-4-6","claude-sonnet-4-5","claude-haiku-4-5","claude-opus-4-1","claude-opus-4-1-20250805","claude-sonnet-4-0","claude-opus-4-0","claude-opus-4-20250514"]},"OpenAIResponsesProviderCreate":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"openai-responses"},"reasoning":{"type":"object","properties":{"effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}]}}},"text":{"type":"object","properties":{"verbosity":{"anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}]}}},"model":{"description":"Model ID (e.g., gpt-5.4). Defaults to gpt-5.4 if not provided. These models are not available with the managed API key — set useOwnApiKey: true to use them: `gpt-5.5-pro`, `gpt-5.4-pro`, `gpt-5`, `gpt-5.2`, `gpt-4o`.","$ref":"#/components/schemas/OpenAIManagedModel"},"useOwnApiKey":{"description":"Use managed API key (default)","type":"boolean","const":false}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"openai-responses"},"reasoning":{"type":"object","properties":{"effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}]}}},"text":{"type":"object","properties":{"verbosity":{"anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}]}}},"model":{"description":"Model ID (any supported OpenAI Responses model, including the BYOK-only ones: `gpt-5.5-pro`, `gpt-5.4-pro`, `gpt-5`, `gpt-5.2`, `gpt-4o`). Defaults to gpt-5.4 if not provided.","$ref":"#/components/schemas/OpenAIModel"},"useOwnApiKey":{"description":"Use your own API key","type":"boolean","const":true},"apiKey":{"description":"Your OpenAI API key (required when useOwnApiKey is true)","type":"string","minLength":1,"maxLength":500}},"required":["type","useOwnApiKey","apiKey"]}]},"OpenAIManagedModel":{"description":"OpenAI models available with Runbear's managed API key","type":"string","enum":["gpt-5.6-sol","gpt-5.6-terra","gpt-5.6-luna","gpt-5.5","gpt-5.4","gpt-5.4-mini","gpt-5.4-nano","gpt-5-mini","gpt-5-nano"]},"OpenAIModel":{"description":"Any supported OpenAI Responses model, including those available only with your own API key (`gpt-5.5-pro`, `gpt-5.4-pro`, `gpt-5`, `gpt-5.2`, `gpt-4o`)","type":"string","enum":["gpt-5.6-sol","gpt-5.6-terra","gpt-5.6-luna","gpt-5.5","gpt-5.4","gpt-5.4-mini","gpt-5.4-nano","gpt-5-mini","gpt-5-nano","gpt-5.5-pro","gpt-5.4-pro","gpt-5","gpt-5.2","gpt-4o"]},"GeminiProviderCreate":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"gemini"},"model":{"description":"Model ID (e.g., gemini-3.1-pro-preview). Defaults to gemini-3.1-pro-preview if not provided.","$ref":"#/components/schemas/GeminiManagedModel"},"useOwnApiKey":{"description":"Use managed API key (default)","type":"boolean","const":false}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"gemini"},"model":{"description":"Model ID (e.g., gemini-3.1-pro-preview). Defaults to gemini-3.1-pro-preview if not provided.","$ref":"#/components/schemas/GeminiManagedModel"},"useOwnApiKey":{"description":"Use your own API key","type":"boolean","const":true},"apiKey":{"description":"Your Gemini API key (required when useOwnApiKey is true)","type":"string","minLength":1,"maxLength":500}},"required":["type","useOwnApiKey","apiKey"]}]},"GeminiManagedModel":{"description":"Available Gemini models for managed API key","type":"string","enum":["gemini-3.1-pro-preview","gemini-3.7-flash","gemini-3.6-flash","gemini-3.5-flash","gemini-3.5-flash-lite"]},"ClaudeAgentSdkProviderCreate":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"claude-agent-sdk"},"model":{"description":"Claude, Gemini, or OpenAI model ID. Defaults to claude-sonnet-5-5. Runbear-provided access uses Runbear credits. Opus-class Claude models bill at ~5x the Sonnet rate, so expect higher credit usage.","$ref":"#/components/schemas/ClaudeAgentSdkManagedModel"},"useOwnApiKey":{"description":"Use Runbear-provided access and Runbear credits (default)","type":"boolean","const":false}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"claude-agent-sdk"},"model":{"description":"Claude, Gemini, or OpenAI model ID. Claude models require an Anthropic API key, Gemini models require a Google AI Studio API key, and OpenAI models require an OpenAI API key. Defaults to claude-sonnet-5-5.","$ref":"#/components/schemas/ClaudeAgentSdkModel"},"useOwnApiKey":{"description":"Use your own API key. Anthropic, Google, or OpenAI bills usage to that key.","type":"boolean","const":true},"apiKey":{"description":"Your Anthropic API key for a Claude model, Google AI Studio API key for a Gemini model, or OpenAI API key for an OpenAI model. Required when useOwnApiKey is true.","type":"string","minLength":1,"maxLength":500}},"required":["type","useOwnApiKey","apiKey"]}]},"ClaudeAgentSdkManagedModel":{"description":"Supported Claude models, these Gemini models: `gemini-3.1-pro-preview`, `gemini-3.8-flash`, `gemini-3.5-flash-lite`, and these OpenAI models: `gpt-6-astra`, `gpt-6-sol`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-6-luna`, `gpt-5.6-luna`. Runbear-provided access uses Runbear credits.","anyOf":[{"$ref":"#/components/schemas/AnthropicManagedModel"},{"type":"string","enum":["gemini-3.1-pro-preview","gemini-3.8-flash","gemini-3.5-flash-lite"]},{"type":"string","enum":["gpt-6-astra","gpt-6-sol","gpt-5.6-sol","gpt-5.6-terra","gpt-6-luna","gpt-5.6-luna"]}]},"ClaudeAgentSdkModel":{"description":"Supported Claude models, these Gemini models: `gemini-3.1-pro-preview`, `gemini-3.8-flash`, `gemini-3.5-flash-lite`, and these OpenAI models: `gpt-6-astra`, `gpt-6-sol`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-6-luna`, `gpt-5.6-luna`. On Runbear-provided access these run on Runbear credits. With your own key, Claude models require an Anthropic API key, Gemini models require a Google AI Studio API key, and OpenAI models require an OpenAI API key, and that provider bills the usage.","anyOf":[{"$ref":"#/components/schemas/AnthropicModel"},{"type":"string","enum":["gemini-3.1-pro-preview","gemini-3.8-flash","gemini-3.5-flash-lite"]},{"type":"string","enum":["gpt-6-astra","gpt-6-sol","gpt-5.6-sol","gpt-5.6-terra","gpt-6-luna","gpt-5.6-luna"]}]},"KnowledgeSearchInput":{"description":"Knowledge base search tuning parameters. Controls how knowledge base search results are ranked and filtered.","type":"object","properties":{"maxResults":{"description":"Maximum documents returned per knowledge base search (1–50). Default: 5.","type":"integer","minimum":1,"maximum":50},"scoreThreshold":{"description":"Minimum relevance score to include a result (0–1). Lower means higher recall. Default: 0.444.","type":"number","minimum":0,"maximum":1},"semanticWeight":{"description":"Weight for semantic/embedding matching vs keyword matching (0–1). 0 = all keyword, 1 = all semantic. Default: 0.4. Only effective for providers that support hybrid search (Anthropic, Gemini, Upstage). OpenAI Responses agents ignore this value.","type":"number","minimum":0,"maximum":1}}},"AiGatewayInput":{"description":"Cloudflare AI Gateway configuration for a single Anthropic or OpenAI agent, overriding the organization-level default. Set `enabled: true` with full config to override it, or `enabled: false` to opt this agent out of it.","anyOf":[{"type":"object","properties":{"cloudflareAccountId":{"description":"Cloudflare account ID","type":"string","minLength":1},"gatewayName":{"description":"Cloudflare AI Gateway name","type":"string","minLength":1},"cfApiToken":{"description":"Cloudflare API token with AI Gateway permissions","type":"string","minLength":1},"enabled":{"type":"boolean","const":true}},"required":["cloudflareAccountId","gatewayName","cfApiToken","enabled"]},{"type":"object","properties":{"enabled":{"description":"Explicitly opt out of org-level gateway default","type":"boolean","const":false}},"required":["enabled"]}]},"AgentUpdateRequest":{"type":"object","properties":{"name":{"description":"Name of the agent","type":"string","minLength":1,"maxLength":255},"systemPrompt":{"description":"The system prompt for this agent. Pass an empty string to clear the current prompt. Limited to 200000 characters, except on agents whose stored prompt is already longer — those accept any prompt no longer than the one they currently have.","type":"string"},"provider":{"$ref":"#/components/schemas/ProviderUpdate"},"tools":{"type":"object","properties":{"requireApprovalForResourceChanges":{"description":"Whether approval is required for resource changes","type":"boolean"},"requireApprovalBeforeToolCalls":{"description":"Whether approval is required before any tool call. When enabled, supersedes requireApprovalForResourceChanges.","type":"boolean"}}},"longTermMemory":{"description":"Long-term memory configuration.","type":"object","properties":{"enabled":{"description":"Whether long-term memory is enabled","type":"boolean"}},"required":["enabled"]},"toolProgress":{"description":"Tool activity configuration.","type":"object","properties":{"enabled":{"description":"Whether tool activity is surfaced to the caller","type":"boolean"}},"required":["enabled"]},"responseComponents":{"$ref":"#/components/schemas/ResponseComponentsInput"},"knowledgeSearch":{"$ref":"#/components/schemas/KnowledgeSearchInput"},"aiGateway":{"description":"Cloudflare AI Gateway configuration (Anthropic and OpenAI agents, enterprise plan required)","$ref":"#/components/schemas/AiGatewayInput"},"timeoutMinutes":{"description":"Maximum execution time in minutes for a single chat completion. Defaults to 6 minutes if omitted; capped at 20 minutes.","type":"integer","minimum":1,"maximum":20}}},"ProviderUpdate":{"description":"Provider configuration for updating an agent","oneOf":[{"$ref":"#/components/schemas/AnthropicProviderUpdate"},{"$ref":"#/components/schemas/OpenAIResponsesProviderUpdate"},{"$ref":"#/components/schemas/GeminiProviderUpdate"},{"$ref":"#/components/schemas/ClaudeAgentSdkProviderUpdate"}],"type":"object","discriminator":{"propertyName":"type","mapping":{"anthropic":"#/components/schemas/AnthropicProviderUpdate","openai-responses":"#/components/schemas/OpenAIResponsesProviderUpdate","gemini":"#/components/schemas/GeminiProviderUpdate","claude-agent-sdk":"#/components/schemas/ClaudeAgentSdkProviderUpdate"}}},"AnthropicProviderUpdate":{"type":"object","properties":{"type":{"type":"string","const":"anthropic"},"model":{"description":"Model ID (e.g., claude-sonnet-4-6). Opus-class models are available under both the managed key and BYOK; expect ~5x the Sonnet credit usage per token when picking Opus.","$ref":"#/components/schemas/AnthropicModel"},"thinking":{"description":"Extended thinking configuration. `disabled` is stored on any model but has no effect on the models that always think (claude-fable-5-1, claude-opus-5-5, claude-fable-5): they reject an explicit opt-out, so those agents run with adaptive thinking regardless. On claude-sonnet-5-5, `disabled` (or no thinking) runs with between-tools thinking only, at `high` effort or below.","oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"enabled"},"effort":{"$ref":"#/components/schemas/AnthropicThinkingEffort"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"disabled"}},"required":["type"]}],"type":"object"},"webSearch":{"description":"Enable web search capability","type":"boolean"},"temperature":{"description":"Temperature value for response generation","anyOf":[{"type":"number"},{"type":"null"}]}},"required":["type"]},"OpenAIResponsesProviderUpdate":{"type":"object","properties":{"type":{"type":"string","const":"openai-responses"},"model":{"description":"Model ID (e.g., gpt-5.4). These models require the agent to use its own API key, and switching a managed-key agent to one is rejected: `gpt-5.5-pro`, `gpt-5.4-pro`, `gpt-5`, `gpt-5.2`, `gpt-4o`. Re-sending the model a managed-key agent is already stored on is allowed.","$ref":"#/components/schemas/OpenAIModel"},"reasoning":{"type":"object","properties":{"effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}]}}},"text":{"type":"object","properties":{"verbosity":{"anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}]}}}},"required":["type"]},"GeminiProviderUpdate":{"type":"object","properties":{"type":{"type":"string","const":"gemini"},"model":{"description":"Model ID (e.g., gemini-3.1-pro-preview)","$ref":"#/components/schemas/GeminiManagedModel"}},"required":["type"]},"ClaudeAgentSdkProviderUpdate":{"type":"object","properties":{"type":{"type":"string","const":"claude-agent-sdk"},"model":{"description":"Claude, Gemini, or OpenAI model ID. An agent on Runbear-provided access cannot switch to a Claude model that requires its own API key. To switch between Claude, Gemini, and OpenAI while using your own key, also send useOwnApiKey: true and replace apiKey with the matching Anthropic, Google AI Studio, or OpenAI key.","$ref":"#/components/schemas/ClaudeAgentSdkModel"},"useOwnApiKey":{"description":"Send true with apiKey when replacing the saved API key.","type":"boolean","const":true},"apiKey":{"description":"Replacement Anthropic API key for Claude, Google AI Studio API key for Gemini, or OpenAI API key for OpenAI. Send useOwnApiKey: true in the same request.","type":"string","minLength":1,"maxLength":500}},"required":["type"]},"ResponseComponentsInput":{"description":"Interactive response component configuration.","type":"object","properties":{"frequency":{"description":"How often the agent is nudged to answer with an interactive response component. One of: off, low, medium, high; an unrecognized value is rejected rather than coerced. Writing a non-\"off\" level on an agent type that cannot emit components is refused with 422 unsupported_for_agent_type. This write is gated by the API key's manageAgents capability — the public-surface equivalent of the dashboard's feature:write permission, which has no representation on an API key and is only issuable by an org admin.","type":"string","enum":["off","low","medium","high"]}},"required":["frequency"]},"GoogleDriveKBSetupRequest":{"description":"Google Drive knowledge base setup request","type":"object","properties":{"integrationId":{"description":"Service account integration ID. Required when more than one service account is available to the user who owns the API key. Auto-detected if only one is.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"fileIds":{"description":"Google Drive file or folder IDs to use as knowledge base","minItems":1,"type":"array","items":{"type":"string","minLength":1}}},"required":["fileIds"]},"WebsiteKBUpdateRequest":{"description":"Website-crawl knowledge base update request","type":"object","properties":{"configs":{"description":"Full set of website crawl configurations. PUT semantics: existing rootUrls in this list have their excludedUrls overwritten and their dashboard-set per-page selections preserved; a rootUrl with no per-page selections is seeded with its root page, which the crawl starts from; existing rootUrls absent from this list are removed. Pass an empty array to stop crawling entirely. Each rootUrl must appear at most once.","type":"array","items":{"$ref":"#/components/schemas/WebsiteKBConfigInput"}}},"required":["configs"]},"WebsiteKBConfigInput":{"type":"object","properties":{"rootUrl":{"description":"Root URL to crawl. Must be a fully-qualified URL (e.g., https://example.com). It is canonicalized before storage (hash dropped, trailing slash added), so https://example.com and https://example.com/ refer to the same root.","type":"string","format":"uri"},"excludedUrls":{"description":"Fully-qualified URLs to exclude from the crawl under this root URL. Each must be an absolute URL (e.g., https://example.com/admin); everything at or below it is skipped. Relative paths or glob patterns are rejected.","type":"array","items":{"type":"string","format":"uri"}}},"required":["rootUrl"]},"CreateToolIntegrationRequest":{"description":"Create a tool integration on an agent. Discriminated on `type`. For `managed-mcp` the server derives the transport config from the catalog manifest. `pipedream` and `custom-mcp` integrations are created as app-scoped (organization-wide).","oneOf":[{"$ref":"#/components/schemas/ManagedMcpToolIntegrationInput"},{"$ref":"#/components/schemas/PipedreamToolIntegrationInput"},{"$ref":"#/components/schemas/CustomMcpToolIntegrationInput"}],"type":"object","discriminator":{"propertyName":"type","mapping":{"managed-mcp":"#/components/schemas/ManagedMcpToolIntegrationInput","pipedream":"#/components/schemas/PipedreamToolIntegrationInput","custom-mcp":"#/components/schemas/CustomMcpToolIntegrationInput"}}},"ManagedMcpToolIntegrationInput":{"type":"object","properties":{"type":{"type":"string","const":"managed-mcp"},"app":{"description":"Managed MCP catalog slug (e.g., \"notion\", \"hubspot\"). The transport config is derived server-side from the catalog manifest.","type":"string"},"secrets":{"type":"object","properties":{"envMap":{"description":"Environment variable name → value map for stdio Managed MCP servers. Stored in the vault. Rejected for remote (OAuth) apps.","readOnly":true,"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["envMap"]},"excludedTools":{"description":"Tool names to exclude from the agent's toolbox.","readOnly":true,"type":"array","items":{"type":"string"}}},"required":["type","app"]},"PipedreamToolIntegrationInput":{"type":"object","properties":{"type":{"type":"string","const":"pipedream"},"nameSlug":{"description":"Pipedream app slug (e.g., \"firecrawl\", \"aws\").","type":"string"},"authType":{"description":"Authentication style required by the Pipedream app.","anyOf":[{"type":"string","enum":["keys","oauth","none"]},{"type":"null"}]},"excludedTools":{"description":"Tool names to exclude from the agent's toolbox.","readOnly":true,"type":"array","items":{"type":"string"}}},"required":["type","nameSlug","authType"]},"CustomMcpToolIntegrationInput":{"type":"object","properties":{"type":{"type":"string","const":"custom-mcp"},"app":{"description":"Display label for the MCP server.","type":"string"},"url":{"description":"Remote MCP server URL.","type":"string","format":"uri"},"transportType":{"type":"string","enum":["sse","streamableHttp"]},"auth":{"$ref":"#/components/schemas/CustomMcpAuthInput"},"httpHeaders":{"description":"HTTP headers forwarded to the MCP server. Use `secret` for values that should be stored in the vault.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/HttpHeaderInput"}},"excludedTools":{"description":"Tool names to exclude from the agent's toolbox.","readOnly":true,"type":"array","items":{"type":"string"}}},"required":["type","app","url","transportType","auth"]},"CustomMcpAuthInput":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"oauth"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"none"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"static"},"headerKey":{"type":"string"}},"required":["type","headerKey"]}],"type":"object"},"HttpHeaderInput":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"plain_text"},"value":{"type":"string"}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"secret"},"value":{"description":"Secret header value. Stored in Runbear's vault on write and returned as `{ type: \"vault\", keyName }` on read — never echoed back.","type":"string"}},"required":["type","value"]}],"type":"object"},"UpdateToolIntegrationRequest":{"description":"Replace a tool integration's mutable config. The `type` and identity (`app` / `nameSlug`) must match the existing integration; changing them is rejected. Secret headers are rotated in the vault.","oneOf":[{"$ref":"#/components/schemas/ManagedMcpToolIntegrationInput"},{"$ref":"#/components/schemas/PipedreamToolIntegrationInput"},{"$ref":"#/components/schemas/CustomMcpToolIntegrationInput"}],"type":"object","discriminator":{"propertyName":"type","mapping":{"managed-mcp":"#/components/schemas/ManagedMcpToolIntegrationInput","pipedream":"#/components/schemas/PipedreamToolIntegrationInput","custom-mcp":"#/components/schemas/CustomMcpToolIntegrationInput"}}},"SessionStartHookSetRequest":{"$ref":"#/components/schemas/SessionStartHook"},"SessionStartHook":{"type":"object","properties":{"app":{"description":"Custom MCP integration namespace (`app`) that hosts the hook tool.","type":"string","minLength":1},"toolName":{"description":"Name of the MCP tool invoked server-side once at session start. Hidden from the model's tool list.","type":"string","minLength":1},"timeoutMs":{"description":"Per-call timeout in milliseconds. On timeout the engine degrades gracefully (responds without injected context). Omit for the engine default.","type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"staticArgs":{"description":"Constant arguments always passed to the hook tool, applied only when the tool's input schema declares a matching property (e.g. an authorization key: `{ \"invocation_key\": \"…\" }`). NON-SECRET values only — secrets belong in the integration's `httpHeaders`.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["app","toolName"]},"AgentHooksSetRequest":{"type":"object","properties":{"hooks":{"$ref":"#/components/schemas/AgentHooksMap"}},"required":["hooks"],"additionalProperties":false},"AgentHooksMap":{"description":"Claude Code hooks document restricted to the events and handler types Runbear runs: event name → matcher groups → handlers. At most 8 handlers per event across all groups. Handlers for one event run in parallel; every `additionalContext` is kept in handler order, a single `block` blocks (on `PreToolUse` the strictest `permissionDecision` wins), and any one string is capped at 10,000 characters.","type":"object","properties":{"SessionStart":{"description":"Runs once per thread, before the first reply. Returned context is added to the system prompt for the life of the thread. Always fails open.","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/AgentHookMatcherGroup"}},"UserPromptSubmit":{"description":"Runs for every user message, before the model. Returned context is placed next to that message and replayed on later turns; a `decision: \"block\"` stops the reply and shows `reason` to the user.","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/AgentHookMatcherGroup"}},"PreToolUse":{"description":"Runs before each tool call, with `tool_name` and `tool_input`. `hookSpecificOutput.permissionDecision` decides whether the call runs: `allow`, `deny` (the model receives `permissionDecisionReason` as the tool's error result), or `ask`, which is treated as `deny` because Runbear has no per-call approval prompt. `hookSpecificOutput.updatedInput` replaces the arguments. Across handlers the strictest decision wins. Server-side tools the model provider runs itself (Anthropic web search and code execution, Vertex `google_search` and `code_execution`) are not hookable. Honours `failClosed`.","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/AgentHookMatcherGroup"}},"PostToolUse":{"description":"Runs after each tool call that succeeded, with `tool_input` (the arguments the tool ran with) and `tool_response`; a call the runtime marked as an error is not hooked. Returned context is appended to the tool result the model reads; a `decision: \"block\"` cannot undo the call, so its `reason` is fed back to the model as guidance next to the result. Always fails open.","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/AgentHookMatcherGroup"}},"Stop":{"description":"Runs when the reply is ready, with `last_assistant_message`. A `decision: \"block\"` sends `reason` back to the agent and lets it continue once per turn; on that continuation `stop_hook_active` is `true` and a further block is ignored. Always fails open.","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/AgentHookMatcherGroup"}}},"additionalProperties":false},"AgentHookMatcherGroup":{"type":"object","properties":{"matcher":{"description":"Which invocations the group applies to, evaluated the way Claude Code does: omitted, empty or `*` matches everything; `A|B` is an exact-name list; anything else is an unanchored regular expression. `SessionStart` matches on how the session started (always `startup` on Runbear); `PreToolUse` and `PostToolUse` match on the tool name as the model sees it; `UserPromptSubmit` and `Stop` have no matcher and a value there is ignored.","type":"string"},"hooks":{"description":"Handlers to run when the matcher applies.","readOnly":true,"minItems":1,"type":"array","items":{"$ref":"#/components/schemas/AgentHookHandler"}}},"required":["hooks"],"additionalProperties":false},"AgentHookHandler":{"oneOf":[{"$ref":"#/components/schemas/AgentHookHttpHandler"},{"$ref":"#/components/schemas/AgentHookMcpToolHandler"}],"type":"object","discriminator":{"propertyName":"type","mapping":{"http":"#/components/schemas/AgentHookHttpHandler","mcp_tool":"#/components/schemas/AgentHookMcpToolHandler"}}},"AgentHookHttpHandler":{"description":"POSTs the hook input to your endpoint and reads a Claude Code JSON output from a 2xx response. An empty 2xx body is a no-op; any other status is a failure.","type":"object","properties":{"type":{"type":"string","const":"http"},"url":{"description":"Endpoint that receives the hook input as a JSON POST. Must be `https` and resolve to a public address; a private or loopback address is refused at call time.","type":"string","format":"uri"},"headers":{"description":"Request headers (at most 16), typically an authorization token. Values are stored in the organization vault and never returned: reads show every value as `<redacted>`, and sending `<redacted>` back on PUT keeps the stored value for that URL and header name. `content-type`, `content-length`, `host` and `x-runbear-hook-event` cannot be overridden.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string"}},"timeout":{"description":"Timeout in seconds. Defaults to 5 on `SessionStart`, 3 on `UserPromptSubmit`, 3 on `PreToolUse`, 3 on `PostToolUse`, 3 on `Stop`; at most 10. Every hook sits on the reply's critical path, so keep it short.","type":"integer","exclusiveMinimum":0,"maximum":10},"failClosed":{"description":"Block the operation when this handler fails (timeout, transport error, non-2xx response, malformed output) instead of ignoring the failure: the reply on `UserPromptSubmit`, the tool call on `PreToolUse`. Rejected on `SessionStart`, `PostToolUse` and `Stop`, which always fail open.","type":"boolean"}},"required":["type","url"],"additionalProperties":false},"AgentHookMcpToolHandler":{"description":"Calls a tool on one of the agent's Custom MCP servers. The tool's text result is read as Claude Code JSON output when it looks like JSON, otherwise as plain additional context.","type":"object","properties":{"type":{"type":"string","const":"mcp_tool"},"server":{"description":"Namespace (`app`) of one of the agent's Custom MCP integrations. Must exist on the agent when the document is written.","type":"string","minLength":1},"tool":{"description":"Name of the tool to call on that server.","type":"string","minLength":1},"input":{"description":"Arguments for the tool. String values may reference hook input fields as `${field}` (dot paths allowed, e.g. `${prompt}`, `${channel_user_id}`). A value that is exactly one placeholder keeps the referenced value's JSON type; a placeholder that resolves to nothing drops the key. Keys the tool does not declare are dropped.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"timeout":{"description":"Timeout in seconds. Defaults to 5 on `SessionStart`, 3 on `UserPromptSubmit`, 3 on `PreToolUse`, 3 on `PostToolUse`, 3 on `Stop`; at most 10. Every hook sits on the reply's critical path, so keep it short.","type":"integer","exclusiveMinimum":0,"maximum":10},"failClosed":{"description":"Block the operation when this handler fails (timeout, transport error, non-2xx response, malformed output) instead of ignoring the failure: the reply on `UserPromptSubmit`, the tool call on `PreToolUse`. Rejected on `SessionStart`, `PostToolUse` and `Stop`, which always fail open.","type":"boolean"}},"required":["type","server","tool"],"additionalProperties":false},"CreateChatCompletionsRequest":{"example":{"assistant_id":"0fade940-133f-49e6-bf4b-8f662186479b","message":[{"role":"assistant","content":"I'd be happy to help you write a business plan. A comprehensive business plan typically includes several key sections..."},{"role":"user","content":"Can you help me write a business plan?"}]},"type":"object","properties":{"assistant_id":{"description":"Unique identifier of the assistant","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"messages":{"description":"Array of conversation messages for context","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}},"thread_id":{"description":"Unique identifier of the thread","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"stream":{"description":"Whether to stream the completion results","type":"boolean"},"config":{"description":"Configuration options for the completion","type":"object","properties":{"userContext":{"description":"User context metadata for scoping tool calls and retrievals","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}}}}},"required":["assistant_id","messages"]},"ChatMessage":{"type":"object","properties":{"role":{"description":"Role of the message sender","type":"string","enum":["user","assistant"]},"content":{"description":"Content of the message","type":"string","minLength":1},"id":{"description":"Optional message identifier","type":"string","minLength":1},"attachments":{"description":"Files attached to this message","readOnly":true,"type":"array","items":{"type":"object","properties":{"name":{"description":"Name of the attached file","type":"string"},"url":{"description":"URL of the attached file","type":"string","format":"uri"},"contentType":{"description":"MIME type of the attached file","type":"string"}},"required":["name","url","contentType"]}}},"required":["role","content"]},"CreateChatSuggestionsRequest":{"example":{"assistant_id":"0fade940-133f-49e6-bf4b-8f662186479b","message":[{"role":"assistant","content":"I'd be happy to help you write a business plan. A comprehensive business plan typically includes several key sections..."},{"role":"user","content":"Can you help me write a business plan?"}]},"type":"object","properties":{"assistant_id":{"description":"Unique identifier of the assistant","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"messages":{"description":"Array of conversation messages for context","readOnly":true,"type":"array","items":{"type":"object","properties":{"role":{"description":"Role of the message sender","type":"string","enum":["user","assistant"]},"content":{"description":"Content of the message","type":"string","minLength":1},"id":{"description":"Optional message identifier","type":"string","minLength":1}},"required":["role","content"]}}},"required":["assistant_id","messages"]},"FileUploadRequest":{"type":"object","properties":{"file":{"description":"File to upload (max 50MB)","anyOf":[{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/pdf"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/vnd.ms-excel"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/vnd.openxmlformats-officedocument.presentationml.presentation"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/vnd.ms-powerpoint"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"text/csv"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"text/plain"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"text/markdown"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"text/x-python"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/json"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/xml"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"text/xml"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/vnd.openxmlformats-officedocument.wordprocessingml.document"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"application/msword"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"image/png"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"image/jpeg"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"image/gif"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"image/webp"},{"type":"string","format":"binary","contentEncoding":"binary","maxLength":52428800,"contentMediaType":"image/svg+xml"}]},"assistant_id":{"description":"Unique identifier of the agent","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"thread_id":{"description":"Unique identifier of the thread","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"}},"required":["file","assistant_id","thread_id"]},"CreateSessionRequest":{"type":"object","properties":{"assistant_id":{"description":"Unique identifier of the agent this session may talk to. The pass carries it; a request naming any other agent is rejected.","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"thread_id":{"description":"Resume an existing thread instead of creating one. The thread must belong to your organization AND to `assistant_id`. Omit to create a new thread — the usual case.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"endUser":{"description":"An opaque, stable identifier for the signed-in visitor (your user id — never an email). Runbear salts and hashes it server-side and binds the resume token to it; refresh must then present the same value. Omit only for genuinely anonymous widgets: without it the resume token is a pure bearer credential and is issued with a materially shorter lifetime (2 hours instead of 24).","example":"user_8fj2k","type":"string","minLength":1,"maxLength":256}},"required":["assistant_id"],"additionalProperties":false},"RefreshSessionRequest":{"type":"object","properties":{"resumeToken":{"description":"The `resumeToken.token` returned by POST /v1/sessions. Required — a missing or empty value is a 400 from the validator, never a silent new session.","type":"string","minLength":1},"endUser":{"description":"Required when the session was minted with `endUser`; must be byte-identical to that value. Omitted otherwise.","type":"string","minLength":1,"maxLength":256}},"required":["resumeToken"],"additionalProperties":false},"CreateThreadRunRequest":{"type":"object","properties":{"assistant_id":{"description":"Unique identifier of the assistant","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"messages":{"description":"Array of messages to process","readOnly":true,"minItems":1,"type":"array","items":{"type":"object","properties":{"role":{"description":"Role of the message sender","type":"string","enum":["user","assistant","system"]},"content":{"description":"Content of the message","type":"string"},"id":{"description":"Optional unique identifier for the message. Used as the deduplication key for the turn, so two distinct ids are two turns and a repeated id is one. Reserved prefix: an id beginning with `rbc:` must be `rbc:<uuid>:<uuid>`, the form the SDK mints for a component click.","type":"string","minLength":1,"maxLength":200},"attachments":{"readOnly":true,"type":"array","items":{"type":"object","properties":{"name":{"description":"Name of the attached file","type":"string"},"url":{"description":"URL of the attached file","type":"string","format":"uri"},"contentType":{"description":"MIME type of the attached file","type":"string"}},"required":["name","url","contentType"]}}},"required":["role","content"]}},"config":{"description":"Configuration options for the run","type":"object","properties":{"userContext":{"description":"User context metadata for scoping tool calls and retrievals","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}}}}},"required":["assistant_id","messages"]},"CreateThreadRequest":{"example":{"assistant_id":"0fade940-133f-49e6-bf4b-8f662186479b"},"type":"object","properties":{"assistant_id":{"description":"Unique identifier of the assistant","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"}},"required":["assistant_id"]},"AiGatewayConfig":{"type":"object","properties":{"cloudflareAccountId":{"description":"Cloudflare account ID","type":"string"},"gatewayName":{"description":"Cloudflare AI Gateway name","type":"string"},"enabled":{"description":"Whether routing through the gateway is active","type":"boolean"}},"required":["cloudflareAccountId","gatewayName","enabled"],"additionalProperties":false},"ApiKey":{"type":"object","properties":{"id":{"description":"Unique identifier of the API key","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"description":{"description":"Human-readable label for the key","anyOf":[{"type":"string"},{"type":"null"}]},"canChat":{"description":"Whether the key may run threads, chat, and upload files","type":"boolean"},"canManageAgents":{"description":"Whether the key may create/update/delete agents and org configuration","type":"boolean"},"canManageApiKeys":{"description":"Whether the key may create/list/revoke the organization's API keys","type":"boolean"},"allowedAgentIds":{"description":"Agent (App) ids the key is restricted to. Empty = all agents.","readOnly":true,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"}},"createdAt":{"description":"ISO 8601 creation timestamp","type":"string"},"lastUsedAt":{"description":"ISO 8601 timestamp the key was last used, if ever","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","description","canChat","canManageAgents","canManageApiKeys","allowedAgentIds","createdAt","lastUsedAt"],"additionalProperties":false},"ApiKeyCreated":{"type":"object","properties":{"id":{"description":"Unique identifier of the API key","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"token":{"description":"The raw secret token. Shown once at creation and never retrievable again.","type":"string"}},"required":["id","token"],"additionalProperties":false},"AgentInformationList":{"type":"object","properties":{"agents":{"description":"Array of agent information objects","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/AgentInformation"}}},"required":["agents"],"additionalProperties":false},"AgentInformation":{"description":"Detailed configuration information about an agent","type":"object","properties":{"id":{"description":"Unique identifier for the agent","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"name":{"description":"Name of the agent","type":"string"},"systemPrompt":{"description":"The system prompt stored for this agent on Runbear. This is the configured prompt, not the fully composed one: agents that support context blocks append them to it at invocation time.","anyOf":[{"type":"string"},{"type":"null"}]},"provider":{"$ref":"#/components/schemas/Provider"},"tools":{"$ref":"#/components/schemas/ToolsConfig"},"longTermMemory":{"description":"Long-term memory configuration. When enabled, the agent remembers user preferences and frequently referenced resources across conversations.","type":"object","properties":{"enabled":{"description":"Whether long-term memory is enabled","type":"boolean"}},"required":["enabled"],"additionalProperties":false},"toolProgress":{"description":"Tool activity configuration. When disabled, `thread.tool_call.progress` events are withheld from the streaming API and no tool cards are posted to the chat channels; the agent still runs the same tools and the run trace still records them. Enabled does not guarantee events — a runtime that reports no tool activity has none to send.","type":"object","properties":{"enabled":{"description":"Whether tool activity is surfaced to the caller","type":"boolean"}},"required":["enabled"],"additionalProperties":false},"responseComponents":{"$ref":"#/components/schemas/ResponseComponents"},"knowledgeSearch":{"$ref":"#/components/schemas/KnowledgeSearch"},"aiGateway":{"description":"Cloudflare AI Gateway configuration. Present when the agent routes LLM traffic through a gateway for observability.","$ref":"#/components/schemas/AiGatewayResponse"},"timeoutMinutes":{"description":"Maximum execution time in minutes for a single chat completion. Defaults to 6 minutes; capped at 20 minutes.","type":"integer","minimum":1,"maximum":20},"createdAt":{"description":"ISO 8601 timestamp when the agent was created","type":"string"},"lastModifiedAt":{"description":"ISO 8601 timestamp of the last update to the agent record. May reflect system-driven updates, not only user edits.","type":"string"},"channels":{"description":"Connected communication channels (slack, teams, discord, hubspot, zendesk)","readOnly":true,"type":"array","items":{"description":"Communication channel type","type":"string","enum":["slack","teams","discord","hubspot","zendesk"]}},"toolIntegrations":{"description":"User-attached MCP, Pipedream, and Custom MCP integrations. Distinct from `tools.integrations`, which lists provider-builtin tools (webSearch, codeInterpreter, ...). Empty for agent types that don't support tool integrations.","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ToolIntegration"}}},"required":["id","name","systemPrompt","provider","tools","longTermMemory","toolProgress","responseComponents","knowledgeSearch","timeoutMinutes","createdAt","lastModifiedAt","channels","toolIntegrations"],"additionalProperties":false},"Provider":{"description":"Provider-specific options","oneOf":[{"$ref":"#/components/schemas/AnthropicProvider"},{"$ref":"#/components/schemas/OpenAIResponsesProvider"},{"$ref":"#/components/schemas/GeminiProvider"},{"$ref":"#/components/schemas/ClaudeAgentSdkProvider"}],"type":"object","discriminator":{"propertyName":"type","mapping":{"anthropic":"#/components/schemas/AnthropicProvider","openai-responses":"#/components/schemas/OpenAIResponsesProvider","gemini":"#/components/schemas/GeminiProvider","claude-agent-sdk":"#/components/schemas/ClaudeAgentSdkProvider"}}},"AnthropicProvider":{"type":"object","properties":{"type":{"type":"string","const":"anthropic"},"model":{"type":"string"},"useOwnApiKey":{"description":"Whether the organization uses their own provider API key","type":"boolean"},"thinking":{"description":"Extended thinking configuration","oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"enabled"},"budgetTokens":{"type":"number"},"effort":{"$ref":"#/components/schemas/AnthropicThinkingEffort"}},"required":["type","budgetTokens"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"disabled"}},"required":["type"],"additionalProperties":false}],"type":"object"},"temperature":{"description":"Temperature value for response generation","anyOf":[{"type":"number"},{"type":"null"}]}},"required":["type","model","useOwnApiKey"],"additionalProperties":false},"OpenAIResponsesProvider":{"type":"object","properties":{"type":{"type":"string","const":"openai-responses"},"model":{"type":"string"},"useOwnApiKey":{"description":"Whether the organization uses their own provider API key","type":"boolean"},"reasoning":{"description":"Reasoning configuration for reasoning models","type":"object","properties":{"effort":{"description":"Constrains effort on reasoning for reasoning models. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.","anyOf":[{"type":"string","enum":["none","minimal","low","medium","high","xhigh"]},{"type":"null"}]},"summary":{"description":"A summary of the reasoning performed by the model. This can be useful for debugging and understanding the model's reasoning process.","anyOf":[{"type":"string","enum":["auto","concise","detailed"]},{"type":"null"}]}},"additionalProperties":false},"text":{"description":"Configuration for response text output","type":"object","properties":{"format":{"description":"An object specifying the format that the model must output.","$ref":"#/components/schemas/ResponseFormatText"},"verbosity":{"description":"The verbosity level of the response text. Can be low, medium, or high.","anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}]}},"additionalProperties":false}},"required":["type","model","useOwnApiKey"],"additionalProperties":false},"ResponseFormatText":{"description":"Response format configuration","oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"text"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"json_object"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"json_schema"},"jsonSchema":{"type":"object","properties":{"name":{"type":"string"},"schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"strict":{"type":"boolean"},"description":{"type":"string"}},"required":["name"],"additionalProperties":false}},"required":["type","jsonSchema"],"additionalProperties":false}],"type":"object"},"GeminiProvider":{"type":"object","properties":{"type":{"type":"string","const":"gemini"},"model":{"type":"string"},"useOwnApiKey":{"description":"Whether the organization uses their own provider API key","type":"boolean"}},"required":["type","model","useOwnApiKey"],"additionalProperties":false},"ClaudeAgentSdkProvider":{"type":"object","properties":{"type":{"type":"string","const":"claude-agent-sdk"},"model":{"type":"string"},"useOwnApiKey":{"description":"Whether the organization uses their own provider API key","type":"boolean"}},"required":["type","model","useOwnApiKey"],"additionalProperties":false},"ToolsConfig":{"type":"object","properties":{"requireApprovalForResourceChanges":{"description":"Whether approval is required for resource changes","type":"boolean"},"requireApprovalBeforeToolCalls":{"description":"Whether approval is required before any tool call. When enabled, supersedes requireApprovalForResourceChanges.","type":"boolean"},"integrations":{"description":"List of enabled managed tool integrations","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ManagedToolIntegration"}}},"additionalProperties":false},"ManagedToolIntegration":{"description":"Managed tool integration","type":"object","properties":{"type":{"type":"string","const":"managed"},"id":{"$ref":"#/components/schemas/ManagedIntegrationId"},"name":{"description":"Name of the integration","type":"string"}},"required":["type","id","name"],"additionalProperties":false},"ManagedIntegrationId":{"description":"Managed tool integration ID","type":"string","enum":["webSearch","codeInterpreter","imageInterpretation","dalleImageGeneration","urlFetch","currentDateFetching"]},"ResponseComponents":{"description":"Interactive response component configuration. Absent from storage means \"off\".","type":"object","properties":{"frequency":{"description":"How often the agent is nudged to answer with an interactive response component. Currently one of: off, low, medium, high. New levels may be appended, so treat this as an open string rather than a closed union. \"off\" withholds the tool entirely; an agent whose type cannot emit response components reports \"off\" unless the dial was set while its type still supported them.","type":"string"}},"required":["frequency"],"additionalProperties":false},"KnowledgeSearch":{"description":"Knowledge base search tuning parameters. Controls how knowledge base search results are ranked and filtered.","type":"object","properties":{"maxResults":{"description":"Maximum documents returned per knowledge base search (1–50).","type":"integer","minimum":1,"maximum":50},"scoreThreshold":{"description":"Minimum relevance score to include a result (0–1). Lower means higher recall.","type":"number","minimum":0,"maximum":1},"semanticWeight":{"description":"Weight for semantic/embedding matching vs keyword matching (0–1). 0 = all keyword, 1 = all semantic. Only effective for providers that support hybrid search (Anthropic, Gemini, Upstage). OpenAI Responses agents ignore this value.","type":"number","minimum":0,"maximum":1}},"required":["maxResults","scoreThreshold","semanticWeight"],"additionalProperties":false},"AiGatewayResponse":{"type":"object","properties":{"cloudflareAccountId":{"description":"Cloudflare account ID","type":"string"},"gatewayName":{"description":"Cloudflare AI Gateway name","type":"string"},"enabled":{"description":"Whether routing through the gateway is active","type":"boolean"},"source":{"description":"Where the active gateway config comes from — agent-level override or organization default","type":"string","enum":["agent","organization"]}},"required":["cloudflareAccountId","gatewayName","enabled","source"],"additionalProperties":false},"ToolIntegration":{"description":"A tool integration attached to an agent. Discriminated on `type`: `managed-mcp` (Runbear-managed MCP server), `pipedream` (Pipedream connector), or `custom-mcp` (caller-hosted MCP server).","oneOf":[{"$ref":"#/components/schemas/ManagedMcpIntegration"},{"$ref":"#/components/schemas/PipedreamIntegration"},{"$ref":"#/components/schemas/CustomMcpIntegration"}],"type":"object","discriminator":{"propertyName":"type","mapping":{"managed-mcp":"#/components/schemas/ManagedMcpIntegration","pipedream":"#/components/schemas/PipedreamIntegration","custom-mcp":"#/components/schemas/CustomMcpIntegration"}}},"ManagedMcpIntegration":{"type":"object","properties":{"id":{"description":"Tool integration ID.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"status":{"description":"Connection health. `ready` means the integration is fully authorized and callable. `pending_auth` means the user must complete OAuth (or otherwise complete setup) before tools are usable.","type":"string","enum":["ready","pending_auth"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"excludedTools":{"description":"Tools excluded from the agent's toolbox by name.","readOnly":true,"type":"array","items":{"type":"string"}},"type":{"type":"string","const":"managed-mcp"},"app":{"description":"Managed MCP catalog slug (e.g., \"notion\").","type":"string"}},"required":["id","status","createdAt","updatedAt","type","app"],"additionalProperties":false},"PipedreamIntegration":{"type":"object","properties":{"id":{"description":"Tool integration ID.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"status":{"description":"Connection health. `ready` means the integration is fully authorized and callable. `pending_auth` means the user must complete OAuth (or otherwise complete setup) before tools are usable.","type":"string","enum":["ready","pending_auth"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"excludedTools":{"description":"Tools excluded from the agent's toolbox by name.","readOnly":true,"type":"array","items":{"type":"string"}},"type":{"type":"string","const":"pipedream"},"nameSlug":{"description":"Pipedream app slug (e.g., \"firecrawl\", \"aws\").","type":"string"},"authType":{"description":"Authentication style required by the Pipedream app.","anyOf":[{"type":"string","enum":["keys","oauth","none"]},{"type":"null"}]}},"required":["id","status","createdAt","updatedAt","type","nameSlug","authType"],"additionalProperties":false},"CustomMcpIntegration":{"type":"object","properties":{"id":{"description":"Tool integration ID.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"status":{"description":"Connection health. `ready` means the integration is fully authorized and callable. `pending_auth` means the user must complete OAuth (or otherwise complete setup) before tools are usable.","type":"string","enum":["ready","pending_auth"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"excludedTools":{"description":"Tools excluded from the agent's toolbox by name.","readOnly":true,"type":"array","items":{"type":"string"}},"type":{"type":"string","const":"custom-mcp"},"app":{"description":"Display label for the MCP server.","type":"string"},"url":{"description":"Remote MCP server URL.","type":"string"},"transportType":{"type":"string","enum":["sse","streamableHttp"]},"auth":{"$ref":"#/components/schemas/CustomMcpAuth"},"httpHeaders":{"description":"HTTP headers forwarded to the MCP server. Vault-backed values expose only `keyName`, never the secret value.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/HttpHeader"}}},"required":["id","status","createdAt","updatedAt","type","app","url","transportType","auth"],"additionalProperties":false},"CustomMcpAuth":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"oauth"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"none"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"static"},"headerKey":{"type":"string"}},"required":["type","headerKey"],"additionalProperties":false}],"type":"object"},"HttpHeader":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"plain_text"},"value":{"type":"string"}},"required":["type","value"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"vault"},"keyName":{"description":"Opaque identifier for the secret stored in Runbear's vault. The plaintext value is never returned by the API.","type":"string"}},"required":["type","keyName"],"additionalProperties":false}],"type":"object"},"ForbiddenErrorResponse":{"type":"object","properties":{"statusCode":{"type":"number","const":403},"code":{"description":"Machine-readable cause, one of: forbidden_by_key_role, forbidden_by_agent_allowlist, forbidden_org_endpoint_for_scoped_key, forbidden_for_session_pass, forbidden_agent_not_in_pass, forbidden_trace_access_for_hipaa_agent, forbidden_ai_gateway_not_permitted, forbidden_google_drive_sa, forbidden_service_account_manage. Always terminal — never retry and never renew a credential in response to a 403.","type":"string"},"error":{"type":"string"},"message":{"type":"string"}},"required":["statusCode","error","message"],"additionalProperties":false},"UnsupportedForAgentTypeResponse":{"type":"object","properties":{"error":{"type":"string","const":"unsupported_for_agent_type"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false},"FeedbackAnalyticsResponse":{"type":"object","properties":{"analytics":{"description":"Feedback analytics data","type":"object","properties":{"feedbacks":{"description":"Feedback aggregations by emoji","readOnly":true,"type":"array","items":{"type":"object","properties":{"feedback":{"description":"Feedback emoji or 'No feedbacks' for messages without feedback","type":"string"},"messageCount":{"description":"Number of messages with this feedback","type":"number"},"ratio":{"description":"Ratio of messages with this feedback (0-1)","type":"number"}},"required":["feedback","messageCount","ratio"],"additionalProperties":false}},"usage":{"description":"Usage statistics","type":"object","properties":{"message":{"description":"Total number of messages","type":"number"},"user":{"description":"Number of unique users","type":"number"},"estimatedTimeSaved":{"description":"Estimated time saved in minutes","type":"number"}},"required":["message","user","estimatedTimeSaved"],"additionalProperties":false},"usageWithFeedback":{"description":"Number of messages that received feedback","type":"number"}},"required":["feedbacks","usage","usageWithFeedback"],"additionalProperties":false}},"required":["analytics"],"additionalProperties":false},"ListAgentTracesResponse":{"type":"object","properties":{"traces":{"description":"Array of trace summaries","readOnly":true,"type":"array","items":{"type":"object","properties":{"id":{"description":"Trace ID","type":"string"},"timestamp":{"description":"ISO 8601 timestamp","type":"string"},"sessionId":{"description":"Session ID","anyOf":[{"type":"string"},{"type":"null"}]},"latency":{"description":"Latency in seconds","anyOf":[{"type":"number"},{"type":"null"}]},"input":{"description":"Last user message text","anyOf":[{"type":"string"},{"type":"null"}]},"output":{"description":"Assistant output markdown","anyOf":[{"type":"string"},{"type":"null"}]},"reactions":{"description":"Emoji reactions on this trace's bot response","readOnly":true,"type":"array","items":{"type":"object","properties":{"emoji":{"description":"Emoji name (skin tone variants merged)","type":"string"},"count":{"description":"Number of unique users who reacted","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["emoji","count"],"additionalProperties":false}}},"required":["id","timestamp","sessionId","latency","input","output","reactions"],"additionalProperties":false}},"meta":{"description":"Pagination metadata","type":"object","properties":{"page":{"description":"Current page number","type":"number"},"limit":{"description":"Items per page","type":"number"},"totalItems":{"description":"Total number of items","type":"number"},"totalPages":{"description":"Total number of pages","type":"number"}},"required":["page","limit","totalItems","totalPages"],"additionalProperties":false}},"required":["traces","meta"],"additionalProperties":false},"RateLimitErrorResponse":{"type":"object","properties":{"statusCode":{"description":"HTTP status code (429)","type":"number"},"code":{"description":"Machine-readable error code, when present","type":"string"},"error":{"description":"Machine-readable error code","type":"string"},"message":{"description":"Human-readable detail, including any back-off hint","type":"string"}},"required":["statusCode","error","message"],"additionalProperties":false},"ExportAgentTracesResponse":{"type":"object","properties":{"traces":{"description":"Whole traces, newest first. Page size varies because traces are never split across pages.","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ExportedTrace"}},"meta":{"$ref":"#/components/schemas/ExportTracesMeta"}},"required":["traces","meta"],"additionalProperties":false},"ExportedTrace":{"description":"One complete agent interaction. Mirrors the retrieveAgentTrace payload minus the thread ID, reactions, and session-start hook.","type":"object","properties":{"traceId":{"description":"Trace ID","type":"string"},"timestamp":{"description":"ISO 8601 timestamp the interaction started","type":"string"},"sessionId":{"description":"Session ID (channel thread ID)","anyOf":[{"type":"string"},{"type":"null"}]},"latency":{"description":"Latency in seconds","anyOf":[{"type":"number"},{"type":"null"}]},"metadata":{"description":"Trace metadata (sensitive fields excluded)","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"model":{"description":"LLM model used in the last generation","anyOf":[{"type":"string"},{"type":"null"}]},"input":{"description":"First message content from this turn"},"output":{"description":"Last generation output"},"steps":{"description":"Interaction steps including tool calls from this turn","readOnly":true,"type":"array","items":{"type":"object","properties":{"role":{"description":"Message role","type":"string"},"content":{"description":"Message content"}},"required":["role","content"],"additionalProperties":false}}},"required":["traceId","timestamp","sessionId","latency","metadata","model","input","output","steps"],"additionalProperties":false},"ExportTracesMeta":{"type":"object","properties":{"cursor":{"description":"Pass back as `cursor` to fetch the next page. `null` means the requested window has been fully exported.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["cursor"],"additionalProperties":false},"RetrieveAgentTraceResponse":{"type":"object","properties":{"traceId":{"description":"Trace ID","type":"string"},"timestamp":{"description":"ISO 8601 timestamp","type":"string"},"threadId":{"description":"Thread ID (UUID)","anyOf":[{"type":"string"},{"type":"null"}]},"latency":{"description":"Latency in seconds","anyOf":[{"type":"number"},{"type":"null"}]},"metadata":{"description":"Trace metadata (sensitive fields excluded)","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"model":{"description":"LLM model used in the last generation","anyOf":[{"type":"string"},{"type":"null"}]},"input":{"description":"First message content from this turn"},"steps":{"description":"Interaction steps including tool calls from this turn","readOnly":true,"type":"array","items":{"type":"object","properties":{"role":{"description":"Message role","type":"string"},"content":{"description":"Message content"}},"required":["role","content"],"additionalProperties":false}},"output":{"description":"Last generation output"},"reactions":{"description":"Emoji reactions on this trace's bot response","readOnly":true,"type":"array","items":{"type":"object","properties":{"emoji":{"description":"Emoji name (skin tone variants merged)","type":"string"},"count":{"description":"Number of unique users who reacted","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["emoji","count"],"additionalProperties":false}},"userContext":{"description":"User context metadata passed via SDK","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"sessionStartHook":{"description":"Outcome of the agent's session-start hook for this trace's thread. The hook runs at most once per thread, so every trace in the same thread carries the same value. Absent entirely for organizations without the session-start hook feature. For organizations that have it, `null` means the agent has no session-start hook configured, or the hook never ran for this thread.","anyOf":[{"type":"object","properties":{"fetchedAt":{"description":"ISO 8601 timestamp of when the hook was attempted","example":"2026-07-22T19:03:58.412Z","type":"string"},"status":{"description":"`ok` — the hook completed successfully; its returned context entries (possibly none) were injected into the system prompt. `degraded` — the hook failed (timeout, error, or invalid response) and the session proceeded without injected context.","type":"string","enum":["ok","degraded"]},"contexts":{"description":"Context entries injected into the system prompt, one per result the hook returned. May be empty when `status` is `ok` (the hook returned no content) and is always empty when `status` is `degraded`.","readOnly":true,"type":"array","items":{"type":"object","properties":{"name":{"description":"Name of the context entry","type":"string"},"context":{"description":"Context text injected into the system prompt","type":"string"}},"required":["name","context"],"additionalProperties":false}}},"required":["fetchedAt","status","contexts"],"additionalProperties":false},{"type":"null"}]}},"required":["traceId","timestamp","threadId","latency","metadata","model","input","steps","output","reactions"],"additionalProperties":false},"WebsiteKnowledgeBase":{"description":"Runbear-managed website crawl knowledge base for the agent","type":"object","properties":{"configs":{"description":"Crawl configurations for the website knowledge base","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/WebsiteKnowledgeBaseConfig"}},"syncStatus":{"description":"Sync status, or null if a sync has not been recorded","anyOf":[{"$ref":"#/components/schemas/KnowledgeBaseSyncStatus"},{"type":"null"}]}},"required":["configs","syncStatus"],"additionalProperties":false},"WebsiteKnowledgeBaseConfig":{"type":"object","properties":{"rootUrl":{"description":"Root URL crawled for this knowledge base entry","type":"string"},"excludedUrls":{"description":"URLs excluded from the crawl","readOnly":true,"type":"array","items":{"type":"string"}},"nodeSelections":{"description":"Specific pages/subtrees selected under the root URL","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/KnowledgeBaseNodeSelection"}}},"required":["rootUrl","nodeSelections"],"additionalProperties":false},"KnowledgeBaseNodeSelection":{"description":"Selection within a hierarchical knowledge base source. Identical shape across sources; the string `id`/`ancestorIds` are interpreted per source.","type":"object","properties":{"id":{"description":"Selection node ID. For Google Drive: the Drive/folder/file ID. For Website: the URL.","type":"string"},"ancestorIds":{"description":"Ancestor node IDs, root first","readOnly":true,"type":"array","items":{"type":"string"}},"excludedChildIds":{"description":"Node IDs explicitly excluded from sync","readOnly":true,"type":"array","items":{"type":"string"}},"disableSyncNewChildren":{"description":"When true, newly discovered children of this node are not auto-synced","type":"boolean"}},"required":["id","ancestorIds","excludedChildIds"],"additionalProperties":false},"KnowledgeBaseSyncStatus":{"description":"Sync status snapshot for a knowledge base. lastHeartbeatAt and internal error metadata are omitted.","type":"object","properties":{"state":{"description":"Current sync state for this knowledge base","type":"string","enum":["IN_PROGRESS","SUCCESS","PARTIAL_SUCCESS","FAILED","SUSPENDED"]},"lastSuccessAt":{"description":"Timestamp of the last fully successful sync, or null if never completed","anyOf":[{"type":"string"},{"type":"null"}]},"lastDurationMs":{"description":"Duration of the last sync attempt in milliseconds","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"error":{"description":"Most recent sync error, if any","anyOf":[{"type":"object","properties":{"type":{"description":"Error category (server_error, authentication, authorization, disintegrated, …)","type":"string"},"message":{"description":"Human-readable error message","type":"string"}},"required":["type","message"],"additionalProperties":false},{"type":"null"}]}},"required":["state","lastSuccessAt","lastDurationMs","error"],"additionalProperties":false},"GoogleDriveOAuthKnowledgeBase":{"description":"Google Drive knowledge base backed by a per-user OAuth integration","type":"object","properties":{"integrationId":{"description":"Google Drive user OAuth integration ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"nodeSelections":{"description":"Selected Drive, folder, or file nodes","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/KnowledgeBaseNodeSelection"}},"syncStatus":{"anyOf":[{"$ref":"#/components/schemas/KnowledgeBaseSyncStatus"},{"type":"null"}]}},"required":["integrationId","nodeSelections","syncStatus"],"additionalProperties":false},"GoogleDriveServiceAccountKnowledgeBase":{"description":"Google Drive knowledge base backed by an organization service account","type":"object","properties":{"integrationId":{"description":"Google service account integration ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"nodeSelections":{"description":"Selected Drive, folder, or file nodes","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/KnowledgeBaseNodeSelection"}},"syncStatus":{"anyOf":[{"$ref":"#/components/schemas/KnowledgeBaseSyncStatus"},{"type":"null"}]}},"required":["integrationId","nodeSelections","syncStatus"],"additionalProperties":false},"UploadedFile":{"type":"object","properties":{"id":{"description":"File identifier","type":"string"},"name":{"description":"Original file name","type":"string"},"mimeType":{"description":"File MIME type","type":"string"},"size":{"description":"File size in bytes","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"uploadedAt":{"description":"ISO 8601 timestamp when the file was uploaded","type":"string"}},"required":["id","name","mimeType","size","uploadedAt"],"additionalProperties":false},"AgentToolIntegrationListResponse":{"type":"object","properties":{"toolIntegrations":{"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ToolIntegration"}}},"required":["toolIntegrations"],"additionalProperties":false},"AgentToolIntegrationAuthUrlResponse":{"type":"object","properties":{"authUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["authUrl"],"additionalProperties":false},"AgentHooksDocument":{"type":"object","properties":{"hooks":{"$ref":"#/components/schemas/AgentHooksMap"}},"required":["hooks"],"additionalProperties":false},"AgentHooksForbiddenResponse":{"type":"object","properties":{"statusCode":{"type":"number","const":403},"code":{"type":"string"},"error":{"description":"`hooks_not_enabled` when agent hooks are not enabled for the organization. A body carrying `code` instead is the API-key scope check's denial.","type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false},"AgentHooksValidationErrorResponse":{"type":"object","properties":{"error":{"description":"`invalid_hooks` — the document failed validation; `unknown_mcp_server` — an `mcp_tool` handler names a `server` that is not a Custom MCP integration on this agent. Append-only; treat an unrecognized value as `invalid_hooks`.","type":"string"},"message":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"description":"Dotted path into `hooks`, e.g. `UserPromptSubmit.0.hooks.1.url`.","type":"string"},"message":{"type":"string"}},"required":["path","message"],"additionalProperties":false}}},"required":["error","message"],"additionalProperties":false},"ManagedMcpCatalogResponse":{"type":"object","properties":{"managedMcps":{"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ManagedMcpCatalogEntry"}}},"required":["managedMcps"],"additionalProperties":false},"ManagedMcpCatalogEntry":{"type":"object","properties":{"slug":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string"},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"transportType":{"type":"string","enum":["stdio","sse","streamableHttp"]},"authType":{"type":"string","enum":["oauth","none"]},"requiredScopes":{"readOnly":true,"type":"array","items":{"type":"string"}},"tools":{"readOnly":true,"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string"}},"required":["name","displayName","description"],"additionalProperties":false}}},"required":["slug","displayName","description","iconUrl","transportType","authType","tools"],"additionalProperties":false},"AssistantsList":{"type":"object","properties":{"assistants":{"description":"Array of assistant objects matching the request criteria","readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/Assistant"}}},"required":["assistants"],"additionalProperties":false},"Assistant":{"description":"Metadata about the assistant","example":{"id":"0fade940-133f-49e6-bf4b-8f662186479b","name":"ChatBot","createdAt":"2023-01-01T00:00:00.000Z"},"type":"object","properties":{"id":{"description":"Unique identifier for the assistant","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"name":{"description":"Name of the assistant","type":"string"},"createdAt":{"description":"ISO 8601 timestamp when the assistant was created","type":"string"}},"required":["id","name","createdAt"],"additionalProperties":false},"AssistantDetails":{"type":"object","properties":{"assistant":{"$ref":"#/components/schemas/Assistant"}},"required":["assistant"],"additionalProperties":false},"NonStreamCreateChatCompletionsResponse":{"type":"object","properties":{"message":{"type":"object","properties":{"id":{"description":"Unique identifier of the message","type":"string"},"content":{"description":"Content of the message","type":"string"}},"required":["content"],"additionalProperties":false},"threadId":{"description":"Unique identifier of the thread","type":"string"}},"required":["message","threadId"],"additionalProperties":false},"MessageEvent":{"oneOf":[{"type":"object","properties":{"event":{"type":"string","const":"thread.message.created"},"data":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"],"additionalProperties":false}},"required":["event","data"],"additionalProperties":false},{"type":"object","properties":{"event":{"type":"string","const":"thread.message.delta"},"data":{"type":"object","properties":{"content":{"type":"string"}},"required":["content"],"additionalProperties":false}},"required":["event","data"],"additionalProperties":false},{"type":"object","properties":{"event":{"type":"string","const":"thread.message.thinking_delta"},"data":{"type":"object","properties":{"content":{"type":"string"}},"required":["content"],"additionalProperties":false}},"required":["event","data"],"additionalProperties":false},{"type":"object","properties":{"event":{"type":"string","const":"thread.message.completed"},"data":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string"}},"required":["content"],"additionalProperties":false}},"required":["event","data"],"additionalProperties":false},{"type":"object","properties":{"event":{"type":"string","const":"thread.message.component"},"data":{"$ref":"#/components/schemas/ResponseComponent"}},"required":["event","data"],"additionalProperties":false},{"type":"object","properties":{"event":{"type":"string","const":"thread.tool_call.progress"},"data":{"type":"object","properties":{"toolUseId":{"type":"string"},"toolName":{"type":"string"},"toolDisplayName":{"type":"string"},"status":{"type":"string","enum":["preparing","running","completed","failed"]},"message":{"type":"string"}},"required":["toolUseId","toolName","toolDisplayName","status","message"],"additionalProperties":false}},"required":["event","data"],"additionalProperties":false},{"type":"object","properties":{"event":{"type":"string","const":"done"}},"required":["event"],"additionalProperties":false},{"type":"object","properties":{"event":{"type":"string","const":"error"},"data":{"type":"object","properties":{"error":{"type":"string"},"code":{"description":"Machine-readable cause, one of: context_length_exceeded, provider_overloaded, provider_authentication_error, invalid_tool_schema, rate_limit, timeout, empty_response, authorization_required, monthly_credit_limit_exceeded, organization_suspended, assistant_not_found, provider_error, provider_credit_exhausted, empty_message, max_output_tokens_reached, unsupported_model_parameter, file_unavailable, conversation_unrecoverable, provider_request_rejected, internal_error. Treat an unrecognized value as internal_error — this list is append-only.","type":"string"},"fatal":{"type":"boolean"}},"required":["error","code"],"additionalProperties":false}},"required":["event","data"],"additionalProperties":false}],"type":"object"},"ResponseComponent":{"type":"object","properties":{"componentId":{"description":"Opaque key for this component instance. Echoed back by the SDK for analytics only: the server neither resolves it nor treats it as an authorization input.","type":"string","maxLength":64},"name":{"description":"Render key. Built-in names include confirm, select, card. Treat any other value as a component this client does not render and show fallbackText.","type":"string","maxLength":64,"pattern":"^[a-z][a-z0-9-]*$"},"props":{"description":"Component-specific payload, passed through verbatim. Its shape depends on `name`; a client that does not recognise `name` must not read it.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"fallbackText":{"description":"Prose to show instead whenever no renderer matches `name`. Never empty.","type":"string","maxLength":2000}},"required":["componentId","name","props","fallbackText"],"additionalProperties":false},"ThreadNotFoundResponse":{"type":"object","properties":{"statusCode":{"type":"number","const":404},"error":{"type":"string"},"message":{"type":"string"}},"required":["statusCode","error","message"],"additionalProperties":false},"UnprocessableEntityResponse":{"type":"object","properties":{"error":{"type":"string","const":"unprocessable_entity"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false},"CreateChatSuggestionsResponse":{"example":{"suggestions":["Create a financial projection for the next 3 years","Help me outline the marketing strategy section","What should I include in the executive summary?"]},"anyOf":[{"type":"object","properties":{"suggestions":{"description":"Array of suggested follow-up prompts","readOnly":true,"type":"array","items":{"type":"string"}}},"required":["suggestions"],"additionalProperties":false},{"type":"null"}]},"CreditUsage":{"type":"object","properties":{"planIncludedCredits":{"description":"Credits the plan includes each billing period, with an enterprise contract override taking precedence. `null` means unlimited.","anyOf":[{"type":"number"},{"type":"null"}]},"complimentaryCredits":{"description":"Unexpired one-off credit grants on top of the plan. `0` when there are none.","type":"number"},"includedCredits":{"description":"`planIncludedCredits + complimentaryCredits` — the base overage is measured from. `null` means unlimited.","anyOf":[{"type":"number"},{"type":"null"}]},"currentUsageCredits":{"description":"Chargeable credits consumed so far in the current billing period.","type":"number"},"overageCreditsUsed":{"description":"Chargeable credits consumed beyond `includedCredits` — usage past the included allowance, not the invoiced amount (the two can differ). Always `0` on an unlimited plan.","type":"number"},"overageLimitCredits":{"description":"The overage allowance enabled for the organization. `null` when overage is off, which caps usage at `includedCredits`.","anyOf":[{"type":"number"},{"type":"null"}]},"periodStart":{"description":"Start of the billing period the usage figures cover (ISO 8601).","type":"string"},"periodEnd":{"description":"End of that period (ISO 8601), exclusive.","type":"string"}},"required":["planIncludedCredits","complimentaryCredits","includedCredits","currentUsageCredits","overageCreditsUsed","overageLimitCredits","periodStart","periodEnd"],"additionalProperties":false},"CreditUsagePeriod":{"type":"object","properties":{"planIncludedCredits":{"description":"Credits the plan includes each billing period, with an enterprise contract override taking precedence. `null` means unlimited.","anyOf":[{"type":"number"},{"type":"null"}]},"complimentaryCredits":{"description":"Unexpired one-off credit grants on top of the plan. `0` when there are none.","type":"number"},"includedCredits":{"description":"`planIncludedCredits + complimentaryCredits` — the base overage is measured from. `null` means unlimited.","anyOf":[{"type":"number"},{"type":"null"}]},"currentUsageCredits":{"description":"Chargeable credits consumed so far in the current billing period.","type":"number"},"overageCreditsUsed":{"description":"Chargeable credits consumed beyond `includedCredits` — usage past the included allowance, not the invoiced amount (the two can differ). Always `0` on an unlimited plan.","type":"number"},"overageLimitCredits":{"description":"The overage allowance enabled for the organization. `null` when overage is off, which caps usage at `includedCredits`.","anyOf":[{"type":"number"},{"type":"null"}]},"periodStart":{"description":"Start of the billing period the usage figures cover (ISO 8601).","type":"string"},"periodEnd":{"description":"End of that period (ISO 8601), exclusive.","type":"string"},"isCurrent":{"description":"True when this entry's own `periodStart`/`periodEnd` window contains the current instant — the period still accumulating usage, whose figures `GET /v1/credits/usage` returns. The flag is read off that window, not off the entry's position in the page: starting a walk with no cursor it is the first entry of the first page, and a cursor that resolves back inside the open period returns it flagged here too. An entry whose window has already ended is closed, and its figures are final.","type":"boolean"}},"required":["planIncludedCredits","complimentaryCredits","includedCredits","currentUsageCredits","overageCreditsUsed","overageLimitCredits","periodStart","periodEnd","isCurrent"],"additionalProperties":false},"CreditUsageEntry":{"type":"object","properties":{"id":{"description":"Stable identifier for this ledger entry.","type":"string"},"occurredAt":{"description":"When the metered call was recorded (ISO 8601).","type":"string"},"traceId":{"description":"Identifies the conversation turn this spend belongs to. Group entries by this field to get the cost of one turn. Treat it as an opaque grouping key — an entry carries either a 32-character OTel id or, from before that move completed in May 2026, a 36-character Langfuse id. The two never collide, and both group a turn. Not resolvable through `GET /v1/agents/{agentId}/traces/{traceId}` — agents on the newest engine record their traces in a store that endpoint does not read, so the lookup answers 404. `null` on some entries recorded before 2026-09-18, whose path did not record the turn; every entry since carries one.","anyOf":[{"type":"string"},{"type":"null"}]},"agentId":{"description":"The agent the spend is attributed to. `null` for usage not tied to one.","anyOf":[{"type":"string"},{"type":"null"}]},"model":{"description":"Model that served the call.","type":"string"},"modelProvider":{"description":"Provider of that model, e.g. `anthropic`, `openai`.","type":"string"},"byok":{"description":"True when the call ran on your own provider key. Credits then cover Runbear's processing fee only, not the provider's inference charge — that one lands on your provider invoice instead.","type":"boolean"},"chargeable":{"description":"False for inference Runbear performs and does not bill — every `usageContext` except `message` and `personal_agent`. These entries are included so the ledger is complete; only entries with `chargeable: true` count toward billed usage.","type":"boolean"},"usageContext":{"description":"What produced the call. One of `message`, `personal_agent`, `memory_update`, `mcp_sub_agent`, `ambient`, `gating`, `compaction`.","type":"string"},"credits":{"description":"Credits this entry consumed.","type":"number"},"creditsByTokenType":{"description":"`credits` split by what consumed them, summing to `credits` exactly. `input` is the prompt the model was sent — including tool definitions and tool results, which are not metered separately. `cacheRead` and `cacheWrite` are prompt caching, and are where a growing conversation shows up. `output` is the reply. `null` for entries recorded before Runbear stored the split; it cannot be recovered from the total, because the price schedule and discount that produced it are not reconstructable after the fact.","anyOf":[{"type":"object","properties":{"input":{"type":"number"},"cacheRead":{"type":"number"},"cacheWrite":{"type":"number"},"output":{"type":"number"}},"required":["input","cacheRead","cacheWrite","output"],"additionalProperties":false},{"type":"null"}]}},"required":["id","occurredAt","traceId","agentId","model","modelProvider","byok","chargeable","usageContext","credits","creditsByTokenType"],"additionalProperties":false},"FileUploadResult":{"type":"object","properties":{"url":{"description":"Public URL of the uploaded file","type":"string","format":"uri"},"name":{"description":"Path name of the uploaded file","type":"string"},"contentType":{"description":"MIME type of the uploaded file","type":"string"}},"required":["url","name","contentType"],"additionalProperties":false},"IntegrationSuggestionsConfig":{"type":"object","properties":{"disabled":{"description":"When true, agents in this org will NOT suggest Runbear sign-in / integration-setup links for unconfigured apps. Default `false`.","type":"boolean"}},"required":["disabled"],"additionalProperties":false},"GoogleDriveServiceAccountInfo":{"type":"object","properties":{"id":{"description":"Unique identifier","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"email":{"description":"Service account email address","type":"string"},"projectId":{"description":"Google Cloud project ID","type":"string"},"agentCount":{"description":"Number of agents using this service account","type":"number"},"createdAt":{"description":"ISO 8601 creation timestamp","type":"string"}},"required":["id","email","projectId","agentCount","createdAt"],"additionalProperties":false},"SessionCredentials":{"type":"object","properties":{"session":{"$ref":"#/components/schemas/Session"},"pass":{"description":"The browser credential. Short-lived; can read and run only `session.thread_id`.","$ref":"#/components/schemas/SessionCredential"},"resumeToken":{"description":"Obtains a fresh pass and cannot chat. Returned by `POST /v1/sessions` only — `POST /v1/sessions/refresh` never rotates or re-returns it.","$ref":"#/components/schemas/SessionCredential"}},"required":["session","pass"],"additionalProperties":false},"Session":{"type":"object","properties":{"id":{"description":"Stable id for this visitor session. Log it — it is the join key across the session's requests.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"assistant_id":{"description":"The one agent this session may talk to.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"thread_id":{"description":"The one thread this session may read and run. Created by this call unless you passed `thread_id`. Always present — the browser must never create a thread itself.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"expiresAt":{"description":"The resume token's expiry: the last instant at which a fresh pass can be obtained. Refreshing issues a new pass but never moves it. A pass issued just before this instant keeps its own full lifetime, so chat can continue for up to 15 minutes past it — after that the session is over and you must create a new one.","type":"string"}},"required":["id","assistant_id","thread_id","expiresAt"],"additionalProperties":false},"SessionCredential":{"type":"object","properties":{"token":{"description":"Send as `Authorization: Bearer <token>`. Never place it in a URL or query parameter.","type":"string"},"expiresAt":{"description":"Instant after which this token is rejected.","type":"string"},"expiresInSeconds":{"description":"Seconds from issuance until `expiresAt`, measured by the server. Prefer this over comparing `expiresAt` to a browser clock.","example":900,"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["token","expiresAt","expiresInSeconds"],"additionalProperties":false},"BadRequestErrorResponse":{"type":"object","properties":{"statusCode":{"type":"number","const":400},"code":{"description":"Machine-readable cause. `resume_token_invalid` / `resume_token_expired` on POST /v1/sessions/refresh; `FST_ERR_VALIDATION` when the request body failed schema validation.","type":"string"},"error":{"type":"string"},"message":{"type":"string"}},"required":["statusCode","error","message"],"additionalProperties":false},"UnauthorizedErrorResponse":{"type":"object","properties":{"statusCode":{"type":"number","const":401},"code":{"description":"Machine-readable cause, one of: credential_missing, api_key_invalid, pass_invalid, pass_expired. Only `pass_expired` may be healed by obtaining a fresh credential and retrying once; every other value is terminal. Treat an unrecognized value as terminal — this list is append-only.","type":"string"},"error":{"type":"string"},"message":{"type":"string"}},"required":["statusCode","error","message"],"additionalProperties":false},"SessionNotFoundErrorResponse":{"type":"object","properties":{"error":{"description":"Which resource was not available: `agent_not_found` or `thread_not_found`.","type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false},"CreateThreadRunResponse":{"type":"object","properties":{"message":{"type":"object","properties":{"id":{"description":"ID of the response message","type":"string"},"content":{"description":"Content of the assistant's response","type":"string"}},"required":["content"],"additionalProperties":false}},"required":["message"],"additionalProperties":false},"ThreadMessage":{"type":"object","properties":{"role":{"description":"Role of the message sender","type":"string","enum":["user","assistant","system"]},"content":{"description":"Content of the message","type":"string"},"id":{"description":"Message identifier","type":"string","minLength":1},"traceId":{"description":"Langfuse trace id for the turn that produced this message. Null for user and system messages, and for messages produced before trace-id persistence shipped. Traces are retained for 90 days, after which this id no longer resolves.","anyOf":[{"type":"string"},{"type":"null"}]},"interrupted":{"description":"Present and true when the turn ended without delivering a reply, so `content` holds only the text the assistant had produced up to that point. Recorded for non-streaming runs too, where that text was never sent to you — the message reflects what the assistant produced, not what you received. Treat presence as the signal: the field is omitted for a completed message, and also wherever a partial cannot be captured, so its absence is not a guarantee that nothing was lost.","type":"boolean"},"components":{"description":"Components this message carried, in the order they were produced. Omitted when it carried none. `content` already contains a prose description of the same choices, so a client that renders a component should suppress that trailing block rather than show both.","readOnly":true,"maxItems":4,"type":"array","items":{"$ref":"#/components/schemas/ResponseComponent"}}},"required":["role","content","id","traceId"],"additionalProperties":false},"UnprocessableEntityWithStatusResponse":{"type":"object","properties":{"statusCode":{"type":"number","const":422},"error":{"type":"string","const":"unprocessable_entity"},"message":{"type":"string"}},"required":["statusCode","error","message"],"additionalProperties":false},"ThreadDetails":{"example":{"id":"0fade940-133f-49e6-bf4b-8f662186479b","createdAt":"2022-01-01T00:00:00.000Z","title":"My first thread"},"type":"object","properties":{"id":{"description":"Unique identifier of the thread","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"createdAt":{"description":"Timestamp when the thread was created","example":"2022-01-01T00:00:00.000Z","type":"string"},"title":{"description":"Optional title of the thread","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","createdAt","title"],"additionalProperties":false},"CreateThreadResponse":{"example":{"thread":{"id":"0fade940-133f-49e6-bf4b-8f662186479b"}},"type":"object","properties":{"thread":{"type":"object","properties":{"id":{"description":"Unique identifier of the thread","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"}},"required":["id"],"additionalProperties":false}},"required":["thread"],"additionalProperties":false},"SessionStartHookOutput":{"type":"object","properties":{"app":{"description":"Custom MCP integration namespace (`app`) that hosts the hook tool.","type":"string","minLength":1},"toolName":{"description":"Name of the MCP tool invoked server-side once at session start. Hidden from the model's tool list.","type":"string","minLength":1},"timeoutMs":{"description":"Per-call timeout in milliseconds. On timeout the engine degrades gracefully (responds without injected context). Omit for the engine default.","type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"staticArgs":{"description":"Constant arguments always passed to the hook tool, applied only when the tool's input schema declares a matching property (e.g. an authorization key: `{ \"invocation_key\": \"…\" }`). NON-SECRET values only — secrets belong in the integration's `httpHeaders`.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["app","toolName"],"additionalProperties":false}}},"paths":{"/v1/ai-gateway":{"get":{"operationId":"retrieveAiGatewayConfig","summary":"Retrieve AI Gateway configuration","description":"Retrieve the organization-level Cloudflare AI Gateway configuration. While its `enabled` flag is true it applies to every Anthropic and OpenAI agent that does not set its own `aiGateway` override on create or update agent; while false no agent routes through it. A disabled configuration is still returned here. The API token is never returned.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiGatewayConfig"}}}},"204":{"description":"No gateway configured"},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"forbidden"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config"}},"put":{"operationId":"upsertAiGatewayConfig","summary":"Set AI Gateway configuration","description":"Create or update the organization-level Cloudflare AI Gateway configuration. While `enabled` is true here, Anthropic and OpenAI agents route through this gateway unless an agent overrides the default with its own `aiGateway` field on create or update agent — pass `enabled: false` there to opt a single agent out.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cloudflareAccountId":{"description":"Cloudflare account ID","type":"string","minLength":1},"gatewayName":{"description":"Cloudflare AI Gateway name","type":"string","minLength":1},"cfApiToken":{"description":"Cloudflare API token with AI Gateway permissions","type":"string","minLength":1},"enabled":{"description":"Whether to actively route requests through the gateway","type":"boolean"}},"required":["cloudflareAccountId","gatewayName","cfApiToken","enabled"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiGatewayConfig"}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"forbidden"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageAgents"}},"delete":{"operationId":"deleteAiGatewayConfig","summary":"Remove AI Gateway configuration","description":"Remove the organization-level Cloudflare AI Gateway configuration. Agents fall back to calling the provider directly, except those whose own `aiGateway` override sets `enabled: true` — they keep routing through the gateway they configure. An agent whose override sets `enabled: false` was already calling the provider directly.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"}},"required":["success","message"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"forbidden"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageAgents"}}},"/v1/api-keys":{"get":{"operationId":"listApiKeys","summary":"List API keys","description":"List the organization's API keys. Never returns the secret token. Requires a key with the manage-API-keys capability.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"apiKeys":{"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["apiKeys"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageApiKeys"}},"post":{"operationId":"createApiKey","summary":"Create an API key","description":"Create a new API key for the organization. The raw token is returned once and never retrievable again. Requires a key with the manage-API-keys capability.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"description":"Human-readable label for the key","default":null,"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"canChat":{"description":"Allow the key to run threads, chat, and upload files","default":true,"type":"boolean"},"canManageAgents":{"description":"Allow the key to create/update/delete agents and org config","default":true,"type":"boolean"},"canManageApiKeys":{"description":"Allow the key to manage the organization's API keys. The highest-privilege capability — grant only to trusted internal keys.","default":false,"type":"boolean"},"allowedAgentIds":{"description":"Restrict the key to these agent (App) ids. Omit or leave empty for all agents.","default":[],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"}}}}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageApiKeys"}}},"/v1/api-keys/{id}":{"patch":{"operationId":"updateApiKey","summary":"Update an API key","description":"Update an API key's capabilities, agent allowlist, or description. Only the fields you send are changed; the secret token is never rotated and the key id is stable. Requires a key with the manage-API-keys capability.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"description":"Human-readable label for the key. Send null to clear it; omit to leave it unchanged.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"canChat":{"description":"Allow the key to run threads, chat, and upload files","type":"boolean"},"canManageAgents":{"description":"Allow the key to create/update/delete agents and org config","type":"boolean"},"canManageApiKeys":{"description":"Allow the key to manage the organization's API keys. The highest-privilege capability — grant only to trusted internal keys.","type":"boolean"},"allowedAgentIds":{"description":"Replaces the key's agent (App) allowlist. Send an empty array to allow all agents; omit to leave the allowlist unchanged.","type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"}}}}}}},"parameters":[{"schema":{"description":"The API key id to update","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"in":"path","name":"id","required":true,"description":"The API key id to update"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","const":404},"error":{"type":"string"},"message":{"type":"string"}},"required":["statusCode","error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageApiKeys"}},"delete":{"operationId":"revokeApiKey","summary":"Revoke an API key","description":"Revoke (permanently disable) an API key by id. Requires a key with the manage-API-keys capability.","parameters":[{"schema":{"description":"The API key id to revoke","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"in":"path","name":"id","required":true,"description":"The API key id to revoke"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"}},"required":["success","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageApiKeys"}}},"/v1/agents":{"get":{"operationId":"listAgents","summary":"List agents","description":"List detailed configuration information for multiple agents. Returns agent settings including LLM provider, system prompt, advanced options, and integration status.","parameters":[{"schema":{"description":"Comma-separated list of agent IDs to retrieve information for (max 100)","example":"0fade940-133f-49e6-bf4b-8f662186479b,1fade940-133f-49e6-bf4b-8f662186479c","type":"string"},"in":"query","name":"ids","required":true,"description":"Comma-separated list of agent IDs to retrieve information for (max 100)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentInformationList"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped"}},"post":{"operationId":"createAgent","summary":"Create agent","description":"Create a new agent with the specified configuration. Only Anthropic, OpenAI Responses, Gemini, and Claude Agent SDK providers are supported.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateRequest"}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentInformation"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["ai_gateway_unsupported_provider","knowledge_search_not_permitted","agent_limit_reached","claude_agent_sdk_not_permitted","reasoning_unsupported_for_model","bad_request"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"403":{"description":"The organization is not entitled to AI Gateway. Same plan/flag decision the org-level `/v1/ai-gateway` endpoints refuse with; `code` is `forbidden_ai_gateway_not_permitted`. Terminal until the plan changes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents"}}},"/v1/agents/{id}":{"get":{"operationId":"retrieveAgent","summary":"Retrieve agent","description":"Retrieve detailed configuration information for a single agent. Returns agent settings including LLM provider, system prompt, advanced options, and integration status.","parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentInformation"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}},"patch":{"operationId":"updateAgent","summary":"Update agent","description":"Update an existing agent's configuration. Only provided fields will be updated (partial update). Provider type cannot be changed.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentUpdateRequest"}}}},"parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentInformation"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["provider_type_mismatch","ai_gateway_unsupported_provider","managed_key_model_unsupported","model_unsupported_in_hipaa_mode","provider_key_model_mismatch","provider_key_update_requires_byok","knowledge_search_not_permitted","claude_agent_sdk_not_permitted","reasoning_unsupported_for_model","system_prompt_too_long","bad_request"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"403":{"description":"The organization is not entitled to AI Gateway. Same plan/flag decision the org-level `/v1/ai-gateway` endpoints refuse with; `code` is `forbidden_ai_gateway_not_permitted`. Terminal until the plan changes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"422":{"description":"The request sets a non-`off` `responseComponents.frequency` on an agent type that cannot emit response components. Terminal for this agent — the dial is only meaningful on a type that supports them.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsupportedForAgentTypeResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}},"delete":{"operationId":"deleteAgent","summary":"Delete agent","description":"Delete an existing agent. This action cannot be undone. Only Anthropic, OpenAI Responses, Gemini, and Claude Agent SDK agents can be deleted via this API.","parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"}},"required":["success","message"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/agents/{id}/analytics/feedback":{"get":{"operationId":"getAgentFeedbackAnalytics","summary":"Get feedback analytics for an agent","description":"Retrieve emoji-based feedback statistics for a specific agent within a date range.","parameters":[{"schema":{"description":"Start date (ISO 8601 format)","type":"string"},"in":"query","name":"from","description":"Start date (ISO 8601 format)"},{"schema":{"description":"End date (ISO 8601 format)","type":"string"},"in":"query","name":"to","description":"End date (ISO 8601 format)"},{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackAnalyticsResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}}},"/v1/agents/{id}/traces":{"get":{"operationId":"listAgentTraces","summary":"List agent traces","description":"List traces for a specific agent. Returns trace summaries including input/output content.\n\n**Rate limit:** 30 requests per minute per organization. Every response carries the standard `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` (seconds until the window resets) headers; a `429` response additionally carries `Retry-After`. The limit is enforced per API replica, so the effective budget scales with the number of replicas — treat the headers as a pacing signal rather than an exact global counter. For large exports, page with a small `limit`, back off on `429`, and stay within the 90-day retention window.","parameters":[{"schema":{"description":"Page number, starts at 1","example":"1","type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"in":"query","name":"page","description":"Page number, starts at 1"},{"schema":{"description":"Number of items per page (max 100)","example":"50","type":"integer","exclusiveMinimum":0,"maximum":100},"in":"query","name":"limit","description":"Number of items per page (max 100)"},{"schema":{"description":"Filter traces by session ID (channel thread ID)","type":"string"},"in":"query","name":"sessionId","description":"Filter traces by session ID (channel thread ID)"},{"schema":{"description":"Filter traces from this timestamp (ISO 8601). Defaults to 90 days ago.","example":"2026-03-01T00:00:00.000Z","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"in":"query","name":"fromTimestamp","description":"Filter traces from this timestamp (ISO 8601). Defaults to 90 days ago."},{"schema":{"description":"Filter traces up to this timestamp (ISO 8601). Defaults to now.","example":"2026-03-08T00:00:00.000Z","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"in":"query","name":"toTimestamp","description":"Filter traces up to this timestamp (ISO 8601). Defaults to now."},{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAgentTracesResponse"}}}},"403":{"description":"The agent runs in HIPAA data handling mode, which disables trace access. Terminal until the agent's data handling mode changes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"429":{"description":"Rate limit exceeded — either the per-org trace-list limiter or a sustained upstream throttle. Retry after the number of seconds in the `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}}},"/v1/agents/{id}/traces/export":{"get":{"operationId":"exportAgentTraces","summary":"Bulk-export agent traces","description":"Export an agent's full interaction history — input, output, and tool calls for every turn — over a large time window, in cursor-paginated pages.\n\nUse this instead of `listAgentTraces` for high-volume extraction: analytics pipelines, warehouse loads, and multi-month pulls. It reads a higher-throughput upstream API and carries a separate, larger rate-limit budget.\n\n**Paging:** follow `meta.cursor` until it is `null`, passing it back as the `cursor` query parameter. Do not pass `fromTimestamp`/`toTimestamp` changes mid-export. Every page contains whole traces — a trace is never split across pages nor returned twice — so pages vary in size.\n\n**Rate limit:** 20 requests per minute per organization, enforced per API replica. Responses carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset`; a `429` additionally carries `Retry-After`.\n\n**Retention:** traces older than 90 days are not retained and cannot be exported; `fromTimestamp` is silently clamped to that window.\n\n**Freshness:** a trace becomes exportable a few minutes after it completes (measured at ~2-3 minutes). An export whose `toTimestamp` reaches the present may therefore omit the most recent interactions; they appear on a later run. For a reproducible extract, set `toTimestamp` at least 15 minutes in the past.","parameters":[{"schema":{"description":"Export traces from this timestamp (ISO 8601). Defaults to, and is clamped at, 90 days ago.","example":"2026-05-01T00:00:00.000Z","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"in":"query","name":"fromTimestamp","description":"Export traces from this timestamp (ISO 8601). Defaults to, and is clamped at, 90 days ago."},{"schema":{"description":"Export traces up to this timestamp (ISO 8601, exclusive). Defaults to now. Ignored once `cursor` is supplied.","example":"2026-08-01T00:00:00.000Z","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"in":"query","name":"toTimestamp","description":"Export traces up to this timestamp (ISO 8601, exclusive). Defaults to now. Ignored once `cursor` is supplied."},{"schema":{"description":"Continuation token from the previous page's `meta.cursor`. Pass it back verbatim; treat it as opaque.","type":"string"},"in":"query","name":"cursor","description":"Continuation token from the previous page's `meta.cursor`. Pass it back verbatim; treat it as opaque."},{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportAgentTracesResponse"}}}},"403":{"description":"The agent runs in HIPAA data handling mode, which disables trace access. Terminal until the agent's data handling mode changes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"429":{"description":"Rate limit exceeded — either the per-org export limiter or a sustained upstream throttle. Retry after the number of seconds in the `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}}},"/v1/agents/{id}/traces/{traceId}":{"get":{"operationId":"retrieveAgentTrace","summary":"Retrieve agent trace","description":"Retrieve detailed trace data for a specific agent trace, including messages and generation output.","parameters":[{"schema":{"description":"The ID of the agent","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent"},{"schema":{"description":"The ID of the trace","example":"12b7beea-1234-5678-9abc-def012345678","type":"string"},"in":"path","name":"traceId","required":true,"description":"The ID of the trace"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetrieveAgentTraceResponse"}}}},"403":{"description":"The agent runs in HIPAA data handling mode, which disables trace access. Terminal until the agent's data handling mode changes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}}},"/v1/agents/{id}/messages/{messageId}/trace":{"get":{"operationId":"retrieveAgentTraceByMessage","summary":"Retrieve the trace for a message","description":"Resolve and retrieve the trace produced for a specific message, identified by the message ID returned from the thread messages endpoint. Returns the same shape as retrieveAgentTrace. Returns 404 when no trace can be resolved for the message — because it predates the trace-retention window, because the message belongs to a different agent than the one in the path, or because the message was not produced by an agent run at all. A non-UUID message ID is rejected at validation with a 400.\n\n**Rate limit:** shares the trace-list limiter — 30 requests per minute per organization. Responses carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers, plus `Retry-After` on a `429`.","parameters":[{"schema":{"description":"The ID of the agent","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent"},{"schema":{"description":"The ID of the message (as returned by the thread messages endpoint) to resolve a trace for","example":"019ecd2c-488f-7bc2-a51c-73bd28549b96","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"in":"path","name":"messageId","required":true,"description":"The ID of the message (as returned by the thread messages endpoint) to resolve a trace for"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetrieveAgentTraceResponse"}}}},"403":{"description":"The agent runs in HIPAA data handling mode, which disables trace access. Terminal until the agent's data handling mode changes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"429":{"description":"Rate limit exceeded — either the per-org trace-list limiter or a sustained upstream throttle. Retry after the number of seconds in the `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}}},"/v1/agents/{id}/knowledge-bases/google-drive":{"put":{"operationId":"setupAgentGoogleDriveKB","summary":"Set up Google Drive knowledge base","description":"Configure a Google Drive knowledge base for an agent using a service account integration. If exactly one service account is available to the user who owns the API key, it is auto-selected.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleDriveKBSetupRequest"}}},"description":"Google Drive knowledge base setup request"},"parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"}},"required":["success","message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["google_drive_sa_not_configured","google_drive_sa_ambiguous","claude_agent_sdk_not_permitted","bad_request"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"403":{"description":"The user who owns the API key may not attach this service account. `code` is `forbidden_google_drive_sa`. Terminal until an admin grants access.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"agent_not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/agents/{id}/knowledge-bases/website":{"get":{"operationId":"retrieveAgentWebsiteKnowledgeBase","summary":"Retrieve the agent's website knowledge base","description":"Returns the website-crawl knowledge base configuration and sync status for an agent. Returns 404 if the agent has no website knowledge base configured.","parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebsiteKnowledgeBase"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["agent_not_found","website_knowledge_base_not_configured"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}},"put":{"operationId":"updateAgentWebsiteKB","summary":"Set up website-crawl knowledge base","description":"Configure the website-crawl knowledge base for an agent. PUT semantics: the request fully replaces the set of crawl roots. For each rootUrl already present in the agent's configuration, the existing dashboard-set per-page selections (nodeSelections) are preserved and only excludedUrls are overwritten. A rootUrl with no per-page selections is seeded with its root page, which the crawl starts from and expands to discover linked pages beneath it. Existing rootUrls absent from the request are removed. Pass an empty configs array to stop crawling entirely. A website sync is enqueued on every successful PUT.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebsiteKBUpdateRequest"}}},"description":"Website-crawl knowledge base update request"},"parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebsiteKnowledgeBase"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["provider_does_not_support_website_sync","claude_agent_sdk_not_permitted","bad_request"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"agent_not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/agents/{id}/knowledge-bases/google-drive-oauth":{"get":{"operationId":"retrieveAgentGoogleDriveOAuthKnowledgeBase","summary":"Retrieve the agent's Google Drive (OAuth) knowledge base","description":"Returns the per-user-OAuth Google Drive knowledge base configuration and sync status for an agent. Returns 404 if the agent has no Google Drive OAuth knowledge base configured.","parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleDriveOAuthKnowledgeBase"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["agent_not_found","google_drive_oauth_knowledge_base_not_configured"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}}},"/v1/agents/{id}/knowledge-bases/google-drive-service-account":{"get":{"operationId":"retrieveAgentGoogleDriveServiceAccountKnowledgeBase","summary":"Retrieve the agent's Google Drive (service-account) knowledge base","description":"Returns the organization-service-account Google Drive knowledge base configuration and sync status for an agent. Returns 404 if the agent has no Google Drive service-account knowledge base configured.","parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleDriveServiceAccountKnowledgeBase"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["agent_not_found","google_drive_service_account_knowledge_base_not_configured"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}}},"/v1/agents/{id}/knowledge-bases/uploaded-files":{"get":{"operationId":"listAgentUploadedFiles","summary":"List files uploaded directly to the agent","description":"Returns the files attached directly to the agent as a knowledge-base source, including both pending uploads and files that have finished embedding. Returns an empty array when the agent has no uploaded files. 404 is reserved for agent-not-found.","parameters":[{"schema":{"description":"The ID of the agent to retrieve","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the agent to retrieve"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"uploadedFiles":{"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/UploadedFile"}}},"required":["uploadedFiles"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"agent_not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}}},"/v1/agents/{id}/tool-integrations":{"get":{"operationId":"listAgentToolIntegrations","summary":"List agent tool integrations","description":"List MCP, Pipedream, and Custom MCP integrations attached to an agent. `status` is computed: `ready` means the integration is fully authorized and callable; `pending_auth` means OAuth must be completed before tools are usable. Returns 404 when the agent is not found or its provider does not support tool integrations.","parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentToolIntegrationListResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}},"post":{"operationId":"createAgentToolIntegration","summary":"Create agent tool integration","description":"Attach an MCP, Pipedream, or Custom MCP integration to an agent. For `managed-mcp` the transport config is derived server-side from the catalog manifest. `pipedream` and `custom-mcp` integrations are created app-scoped (organization-wide). Returns 400 when the agent's provider does not support tool integrations, 404 when the agent is not found, and 409 when an integration for the same app already exists on the agent.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateToolIntegrationRequest"}}},"description":"Create a tool integration on an agent. Discriminated on `type`. For `managed-mcp` the server derives the transport config from the catalog manifest. `pipedream` and `custom-mcp` integrations are created as app-scoped (organization-wide)."},"parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolIntegration"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/agents/{id}/tool-integrations/{integrationId}":{"get":{"operationId":"retrieveAgentToolIntegration","summary":"Retrieve agent tool integration","description":"Retrieve a single tool integration attached to an agent. Returns 404 when the agent or the integration is not found.","parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"},{"schema":{"description":"Tool integration ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"in":"path","name":"integrationId","required":true,"description":"Tool integration ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolIntegration"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}},"patch":{"operationId":"updateAgentToolIntegration","summary":"Update agent tool integration","description":"Replace a tool integration's mutable config. The integration's `type` and identity (`app` / `nameSlug`) are immutable — changing them returns 400. Secret headers are rotated in the vault.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateToolIntegrationRequest"}}},"description":"Replace a tool integration's mutable config. The `type` and identity (`app` / `nameSlug`) must match the existing integration; changing them is rejected. Secret headers are rotated in the vault."},"parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"},{"schema":{"description":"Tool integration ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"in":"path","name":"integrationId","required":true,"description":"Tool integration ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolIntegration"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}},"delete":{"operationId":"deleteAgentToolIntegration","summary":"Delete agent tool integration","description":"Detach a tool integration from an agent and clean up any secrets it stored in the vault. Returns 404 when the agent or integration is not found.","parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"},{"schema":{"description":"Tool integration ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"in":"path","name":"integrationId","required":true,"description":"Tool integration ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"}},"required":["success","message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/agents/{id}/tool-integrations/{integrationId}/auth-url":{"post":{"operationId":"generateAgentToolIntegrationAuthUrl","summary":"Generate a tool integration OAuth URL","description":"Generate a Runbear-hosted OAuth URL for an integration that needs browser-based authorization (step two of the two-step OAuth flow). The caller opens `authUrl` in a browser; Runbear completes the handshake server-side. `authUrl` is `null` when the integration is already authorized. Returns 400 `auth_url_not_applicable` for rows that need no browser auth (Pipedream `none`/`null`, Managed MCP stdio, remote/custom MCP with `auth.type` `none`/`static`), 400 when the agent's provider does not support tool integrations, and 404 when the agent or integration is not found.","parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"},{"schema":{"description":"Tool integration ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},"in":"path","name":"integrationId","required":true,"description":"Tool integration ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentToolIntegrationAuthUrlResponse"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/agents/{id}/session-start-hook":{"get":{"operationId":"getAgentSessionStartHook","summary":"Get agent session-start hook","description":"Retrieve the agent's session-start hook — the Custom MCP tool the engine invokes server-side once at the start of a thread to inject deterministic per-user context. Returns 404 when the agent is not found, its provider does not support tool integrations, or no hook is configured.","parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStartHookOutput"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}},"put":{"operationId":"setAgentSessionStartHook","summary":"Set agent session-start hook","description":"Set or replace the agent's session-start hook on the Custom MCP integration named by `app`. The hook tool is invoked server-side at session start and hidden from the model. Returns 404 when the agent is not found / unsupported, or when the agent has no Custom MCP integration with the given `app`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStartHookSetRequest"}}}},"parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionStartHookOutput"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}},"delete":{"operationId":"deleteAgentSessionStartHook","summary":"Clear agent session-start hook","description":"Remove the agent's session-start hook. The Custom MCP integration itself is left intact. Idempotent — succeeds whether or not a hook was set. Returns 404 only when the agent is not found or its provider does not support tool integrations.","parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"}],"security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Hook cleared"},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/agents/{id}/hooks":{"get":{"operationId":"getAgentHooks","summary":"Get agent hooks","description":"Retrieve the agent's hooks document — the HTTP endpoints and Custom MCP tools Runbear calls when a thread starts (`SessionStart`), when a user message arrives (`UserPromptSubmit`), before and after each tool call (`PreToolUse`, `PostToolUse`) and when the reply is ready (`Stop`), in the Claude Code hooks schema. `http` header values are always returned as `<redacted>`. An agent without hooks returns `{ \"hooks\": {} }`. Returns 404 when the agent is not found or its provider does not run hooks.","parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentHooksDocument"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}},"put":{"operationId":"setAgentHooks","summary":"Set agent hooks","description":"Replace the agent's hooks document as one unit, the way a Claude Code settings file is saved. `http` header values are moved into the organization vault; send `<redacted>` for a header to keep the value already stored for that URL and header name. Every `mcp_tool` handler's `server` must be the `app` namespace of a Custom MCP integration on this agent. Returns the stored document with header values redacted. Returns 404 when the agent is not found or its provider does not run hooks, 403 when agent hooks are not enabled for the organization, and 422 with per-field `issues` when the document is invalid.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentHooksSetRequest"}}}},"parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentHooksDocument"}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentHooksForbiddenResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentHooksValidationErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}},"delete":{"operationId":"deleteAgentHooks","summary":"Clear agent hooks","description":"Remove the agent's hooks document and the vault secrets its headers referenced. The Custom MCP integrations hooks pointed at are left intact. Idempotent — succeeds whether or not hooks were set. Returns 404 only when the agent is not found or its provider does not run hooks.","parameters":[{"schema":{"description":"Agent ID","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Agent ID"}],"security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Hooks cleared"},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/tool-integrations/managed-mcps":{"get":{"operationId":"listManagedMcpCatalog","summary":"List managed MCP catalog","description":"Catalog of Managed MCP integrations Runbear can attach to agents. Use the returned `slug` as the identifier when creating a new integration.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagedMcpCatalogResponse"}}}}},"x-runbear-scope":{"endpointClass":"catalog"}}},"/v1/assistants":{"get":{"operationId":"listAssistants","summary":"List assistants","description":"Retrieve a list of agents (apps) accessible to the authenticated organization. Optionally filter by name with case-insensitive search.","parameters":[{"schema":{"description":"Filter assistants by name (case-insensitive partial match)","type":"string"},"in":"query","name":"name"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistantsList"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped"}}},"/v1/assistants/{id}":{"get":{"operationId":"getAssistant","summary":"Get assistant by ID","description":"Retrieve a specific assistant by its unique identifier. The assistant must be accessible to the authenticated organization.","parameters":[{"schema":{"description":"Unique identifier of the assistant","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Unique identifier of the assistant"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistantDetails"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","agentIdParam":"id"}},"patch":{"operationId":"updateAssistant","summary":"Update assistant","description":"Update core fields of an assistant. Only provided fields will be updated (partial update). Both name and description are optional.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string"}},"additionalProperties":false}}}},"parameters":[{"schema":{"description":"Unique identifier of the assistant","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"Unique identifier of the assistant"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"}},"required":["success","message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["system_prompt_too_long","bad_request"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"manageAgents","agentIdParam":"id"}}},"/v1/chat/completions":{"post":{"operationId":"createChatCompletions","summary":"Create chat completions","description":"Generate completions for a conversation based on the assistant's capabilities and conversation history.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChatCompletionsRequest"}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Either a single JSON object (`stream` absent or false) or a stream. A newline-delimited JSON (NDJSON) stream: one complete JSON object per line, each terminated by `\\n`. Despite the `text/event-stream` media type this is **not** Server-Sent Events — there is no `data:` prefix and no blank-line record separator, so an off-the-shelf SSE parser will not read it. Split the body on `\\n` and `JSON.parse` each non-empty line, buffering any trailing partial line across reads: a line can straddle a transport chunk boundary. A `*_delta` event carries the whole value so far rather than an increment, so replace what you are holding instead of appending to it; note that `thread.message.delta` snapshots can transiently include tool-status text and are not guaranteed to grow monotonically. The stream normally ends with `{\"event\":\"done\"}` — a connection aborted or stalled mid-turn ends without one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NonStreamCreateChatCompletionsResponse"}},"text/event-stream":{"schema":{"$ref":"#/components/schemas/MessageEvent"}}}},"404":{"description":"The thread does not exist, or it is not accessible with the presented credential. Absent and inaccessible threads are deliberately indistinguishable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadNotFoundResponse"}}}},"422":{"description":"The request cannot be processed by the addressed agent: either its type cannot be executed by this API, or a message carries more file attachments than the agent's runtime accepts. Raised before the response begins, so it applies to the streaming variant too. A failure discovered *during* a turn cannot use this status — the response has already begun — and is reported per the streaming error contract instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnprocessableEntityResponse"}}}},"429":{"description":"Rate limit exceeded for this organization and agent. Retry after the number of seconds in the `Retry-After` header. Every response — not only a 429 — carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"chat"}}},"/v1/chat/suggestions":{"post":{"operationId":"createChatSuggestions","summary":"Create chat suggestions","description":"Generate follow-up suggestions for a conversation based on the assistant's capabilities and conversation history.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChatSuggestionsRequest"}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChatSuggestionsResponse"}}}},"429":{"description":"Rate limit exceeded for this organization and agent. Retry after the number of seconds in the `Retry-After` header. Every response — not only a 429 — carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"chat"}}},"/v1/credits/usage":{"get":{"operationId":"retrieveCreditUsage","summary":"Retrieve credit usage for the current billing period","description":"Retrieve the organization's credit position for the current billing period: the credits included in the plan, the overage allowance and the overage consumed, and usage to date. The same numbers the Runbear billing page shows, for pulling into your own tracking.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditUsage"}}}}},"x-runbear-scope":{"endpointClass":"org-config"}}},"/v1/credits/usage/periods":{"get":{"operationId":"listCreditUsagePeriods","summary":"List credit usage by billing period","description":"Retrieve the organization's credit position for each of its billing periods, newest first — the same figures `GET /v1/credits/usage` returns, one entry per period, for building period-over-period tracking on your side.\n\nThe period still open carries `isCurrent: true` and matches `GET /v1/credits/usage` exactly; starting a walk with no cursor, that is the first entry of the first page. Every entry whose period has already ended is closed and its usage figures are final.\n\nHistory reaches back to the organization's first recorded day of credit usage — there is no fixed retention cutoff, so the number of periods available grows with the age of the account. Pass `cursor` to page further back; `nextCursor` is `null` once the oldest recorded period has been returned.\n\nOne caveat on the allowance fields (`planIncludedCredits`, `complimentaryCredits`, `includedCredits`, `overageLimitCredits`): they reflect the organization's plan configuration as it stands *today*, not as it stood during a past period. Runbear does not snapshot plan configuration per period. `currentUsageCredits` is the field that is genuinely historical, and `overageCreditsUsed` is derived from it against today's allowance.","parameters":[{"schema":{"description":"Maximum number of billing periods to return in this page (1–24). Defaults to 12.","example":12,"default":12,"type":"integer","minimum":1,"maximum":24},"in":"query","name":"limit","description":"Maximum number of billing periods to return in this page (1–24). Defaults to 12."},{"schema":{"description":"Opaque pagination cursor. Pass the `nextCursor` from a previous response to fetch the next page of periods (ordered newest first). Omit on the first request.","type":"string","minLength":1,"maxLength":1024},"in":"query","name":"cursor","description":"Opaque pagination cursor. Pass the `nextCursor` from a previous response to fetch the next page of periods (ordered newest first). Omit on the first request."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"periods":{"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/CreditUsagePeriod"}},"nextCursor":{"description":"Opaque cursor for the next page, or null once the oldest recorded period has been returned. Pass it back as the `cursor` query parameter.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["periods","nextCursor"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config"}}},"/v1/credits/usage/entries":{"get":{"operationId":"listCreditUsageEntries","summary":"Export the credit ledger entry by entry","description":"Export the organization's credit ledger for a time window, newest first — one entry per metered inference call, for loading into your own warehouse and modelling cost per message, per agent, or per model.\n\n**The unit is one metered call, not one message.** How many entries a single conversation turn produces depends on the engine that served it. Group by `traceId` to get the cost of a turn.\n\n**Nothing is filtered out.** Entries Runbear does not bill for — memory updates, ambient runs, gating, context compaction — are included with `chargeable: false`, and entries with a `null` `traceId` are included too. Summing `credits` over the entries with `chargeable: true` for a billing period gives exactly the `currentUsageCredits` that `GET /v1/credits/usage` reports for it. That is the property to check your load against.\n\nPass `from` and `to` to bound the window; it may not exceed 31 days per request. Follow `nextCursor` until it is `null` to walk a window in full. History reaches back to the organization's first recorded usage — the ledger has no retention cutoff, and `traceId` reaches back with it.","parameters":[{"schema":{"description":"Start of the window to export (ISO 8601), inclusive. Required.","type":"string"},"in":"query","name":"from","required":true,"description":"Start of the window to export (ISO 8601), inclusive. Required."},{"schema":{"description":"End of the window (ISO 8601), exclusive. Required.","type":"string"},"in":"query","name":"to","required":true,"description":"End of the window (ISO 8601), exclusive. Required."},{"schema":{"description":"Maximum number of entries per page (1–1000). Defaults to 500.","example":500,"default":500,"type":"integer","minimum":1,"maximum":1000},"in":"query","name":"limit","description":"Maximum number of entries per page (1–1000). Defaults to 500."},{"schema":{"description":"Opaque pagination cursor. Pass the `nextCursor` from the previous response. Omit on the first request.","type":"string","minLength":1,"maxLength":1024},"in":"query","name":"cursor","description":"Opaque pagination cursor. Pass the `nextCursor` from the previous response. Omit on the first request."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/CreditUsageEntry"}},"nextCursor":{"description":"Opaque cursor for the next page, or null once the window has been fully exported.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["entries","nextCursor"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config"}}},"/v1/files/upload":{"post":{"operationId":"uploadFiles","summary":"Upload file attachment","description":"Upload a file attachment for an agent thread. Supports various file types including documents, images, and text files up to 50MB.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/FileUploadRequest"}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadResult"}}}},"404":{"description":"The thread does not exist, or it is not accessible with the presented credential. Absent and inaccessible threads are deliberately indistinguishable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadNotFoundResponse"}}}},"429":{"description":"Rate limit exceeded for this organization and agent. Retry after the number of seconds in the `Retry-After` header. Every response — not only a 429 — carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"chat"}}},"/v1/integration-suggestions":{"get":{"operationId":"retrieveIntegrationSuggestionsConfig","summary":"Retrieve integration-suggestions configuration","description":"Retrieve the organization-level toggle that controls whether the agent suggests Runbear sign-in / integration-setup links for apps it does not currently have integrated.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationSuggestionsConfig"}}}}},"x-runbear-scope":{"endpointClass":"org-config"}},"put":{"operationId":"upsertIntegrationSuggestionsConfig","summary":"Set integration-suggestions configuration","description":"Enable or disable the organization-level integration-suggestions behavior. When `disabled: true`, agents stop responding with `🔔 Integration Required` blocks pointing chatters to Runbear's setup page for unconfigured apps. Useful for operator-built agents whose end-users are not Runbear-aware.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"disabled":{"description":"Whether to suppress integration suggestions for every agent in this org.","type":"boolean"}},"required":["disabled"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationSuggestionsConfig"}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageAgents"}}},"/v1/integrations/google-drive/service-accounts":{"get":{"operationId":"listGoogleServiceAccounts","summary":"List Google Drive service accounts","description":"List the Google service account integrations available to the user who owns the API key. Organization admins and owners see every account.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"serviceAccounts":{"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/GoogleDriveServiceAccountInfo"}}},"required":["serviceAccounts"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config"}},"post":{"operationId":"createGoogleServiceAccount","summary":"Create Google Drive service account","description":"Upload a Google service account key to create a new integration. The key is validated by testing Google Drive API access.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keyFileContent":{"description":"The JSON key file content as a string (not base64-encoded)","type":"string"}},"required":["keyFileContent"]}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleDriveServiceAccountInfo"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_credential","bad_request"]},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageAgents"}}},"/v1/integrations/google-drive/service-accounts/{id}":{"delete":{"operationId":"deleteGoogleServiceAccount","summary":"Delete Google Drive service account","description":"Delete a Google service account integration. Only organization admins and the user who added the account can delete it. Any knowledge base settings linked to this service account will also be removed.","parameters":[{"schema":{"description":"The ID of the service account to delete","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"id","required":true,"description":"The ID of the service account to delete"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"}},"required":["success","message"],"additionalProperties":false}}}},"403":{"description":"Only organization admins and the user who added the service account may delete it. `code` is `forbidden_service_account_manage`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"org-config","requiredCapability":"manageAgents"}}},"/v1/sessions":{"post":{"operationId":"createSession","summary":"Create a browser session","description":"Mint a short-lived session pass plus a resume token for one browser visitor, and create the single thread that pass is bound to. Call this from YOUR server after authenticating the visitor — the org API key must never reach the browser. The returned `pass` is the only credential the browser holds; it can read and run exactly one thread of one agent and nothing else.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionRequest"}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCredentials"}}}},"400":{"description":"The request body failed validation. `code` is `FST_ERR_VALIDATION`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BadRequestErrorResponse"}}}},"401":{"description":"The organization API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnauthorizedErrorResponse"}}}},"403":{"description":"The key lacks the chat capability, its agent allowlist excludes `assistant_id`, or a browser session pass was presented — a pass can never mint another pass (`forbidden_for_session_pass`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"The agent or the supplied thread is not available to this organization. Absent, foreign and wrongly-owned resources are deliberately indistinguishable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionNotFoundErrorResponse"}}}},"422":{"description":"The agent has a type the public API cannot run, so no session could be bound to it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnprocessableEntityResponse"}}}},"429":{"description":"Mint rate limit exceeded for this organization and agent. Retry after the number of seconds in the `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"chat"}}},"/v1/sessions/refresh":{"post":{"operationId":"refreshSession","summary":"Refresh a browser session","description":"Exchange a resume token for a fresh session pass. Call this from YOUR server when the browser reports its pass is about to expire — you decide whether the visitor is still entitled to the session. The resume token is never rotated: keep using the one POST /v1/sessions returned until it expires, then create a new session.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshSessionRequest"}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCredentials"}}}},"400":{"description":"The request body failed validation (`FST_ERR_VALIDATION`), or the resume token cannot be exchanged (`resume_token_invalid` / `resume_token_expired`). A bad token is never a 401 — your API key authenticated fine.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BadRequestErrorResponse"}}}},"401":{"description":"The organization API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnauthorizedErrorResponse"}}}},"403":{"description":"The key lacks the chat capability, its agent allowlist no longer covers the agent this session is bound to, or a browser session pass was presented — a pass can never renew itself (`forbidden_for_session_pass`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"429":{"description":"Refresh rate limit exceeded, or this session has been renewed as many times as it may be (`session_refresh_cap_exhausted` — terminal; create a new session).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"chat"}}},"/v1/threads/{threadId}/runs":{"post":{"operationId":"createRun","summary":"Create a run (non-streaming)","description":"Execute a conversation with the assistant and return the complete response. Automatically generates a thread title if this is the first message.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateThreadRunRequest"}}}},"parameters":[{"schema":{"description":"Unique identifier of the thread","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"threadId","required":true,"description":"Unique identifier of the thread"}],"security":[{"bearerAuth":[]},{"sessionPass":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateThreadRunResponse"}}}},"401":{"description":"The credential is missing, malformed, or expired. `code` discriminates the cause; only `pass_expired` is renewable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnauthorizedErrorResponse"}}}},"403":{"description":"The presented credential is not permitted to perform this action against this agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"The thread does not exist, or it is not accessible with the presented credential. Absent and inaccessible threads are deliberately indistinguishable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadNotFoundResponse"}}}},"422":{"description":"The request cannot be processed by the addressed agent: either its type cannot be executed by this API, or a message carries more file attachments than the agent's runtime accepts. Raised before the response begins, so it applies to the streaming variant too. A failure discovered *during* a turn cannot use this status — the response has already begun — and is reported per the streaming error contract instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnprocessableEntityResponse"}}}},"429":{"description":"Rate limit exceeded for this organization and agent. Retry after the number of seconds in the `Retry-After` header. Every response — not only a 429 — carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"chat"}}},"/v1/threads/{threadId}/runs/stream":{"post":{"operationId":"createRunStream","summary":"Create a streaming run","description":"Execute a conversation with the assistant and stream the response in real-time as newline-delimited JSON (NDJSON) — not Server-Sent Events; see the 200 response description. File attachments are automatically cleaned up after processing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateThreadRunRequest"}}}},"parameters":[{"schema":{"description":"Unique identifier of the thread","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"threadId","required":true,"description":"Unique identifier of the thread"}],"security":[{"bearerAuth":[]},{"sessionPass":[]}],"responses":{"200":{"description":"A newline-delimited JSON (NDJSON) stream: one complete JSON object per line, each terminated by `\\n`. Despite the `text/event-stream` media type this is **not** Server-Sent Events — there is no `data:` prefix and no blank-line record separator, so an off-the-shelf SSE parser will not read it. Split the body on `\\n` and `JSON.parse` each non-empty line, buffering any trailing partial line across reads: a line can straddle a transport chunk boundary. A `*_delta` event carries the whole value so far rather than an increment, so replace what you are holding instead of appending to it; note that `thread.message.delta` snapshots can transiently include tool-status text and are not guaranteed to grow monotonically. The stream normally ends with `{\"event\":\"done\"}` — a connection aborted or stalled mid-turn ends without one.","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/MessageEvent"}}}},"401":{"description":"The credential is missing, malformed, or expired. `code` discriminates the cause; only `pass_expired` is renewable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnauthorizedErrorResponse"}}}},"403":{"description":"The presented credential is not permitted to perform this action against this agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"The thread does not exist, or it is not accessible with the presented credential. Absent and inaccessible threads are deliberately indistinguishable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadNotFoundResponse"}}}},"422":{"description":"The request cannot be processed by the addressed agent: either its type cannot be executed by this API, or a message carries more file attachments than the agent's runtime accepts. Raised before the response begins, so it applies to the streaming variant too. A failure discovered *during* a turn cannot use this status — the response has already begun — and is reported per the streaming error contract instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnprocessableEntityResponse"}}}},"429":{"description":"Rate limit exceeded for this organization and agent. Retry after the number of seconds in the `Retry-After` header. Every response — not only a 429 — carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"chat"}}},"/v1/threads/{threadId}/messages":{"get":{"operationId":"listMessages","summary":"Get thread messages","description":"Retrieve the messages of a specific thread, including the thread title and message content with processed citations and file references. An assistant message carrying `interrupted` holds only the text produced before its turn ended without delivering a reply. A long thread returns its newest messages only, with `truncated` set.","parameters":[{"schema":{"description":"ID of the thread to retrieve messages from","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"path","name":"threadId","required":true,"description":"ID of the thread to retrieve messages from"}],"security":[{"bearerAuth":[]},{"sessionPass":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"truncated":{"description":"True when the thread holds more messages than were returned. The response carries the NEWEST messages, so the omitted ones are the oldest.","type":"boolean"},"thread":{"type":"object","properties":{"id":{"description":"Unique identifier of the thread","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"title":{"description":"Title of the thread, null if not set","anyOf":[{"type":"string"},{"type":"null"}]},"assistantId":{"description":"Unique identifier of the assistant associated with this thread","example":"08f1c3b3-f43b-41e6-8288-d438e98eea28","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"}},"required":["id","title","assistantId"],"additionalProperties":false},"messages":{"description":"Array of messages in the thread","example":[{"role":"assistant","content":"I'd be happy to help you write a business plan. A comprehensive business plan typically includes several key sections...","id":"msg_a1b2c3d4","traceId":"4bf92f3577b34da6a3ce929d0e0e4736"},{"role":"user","content":"Can you help me write a business plan?","id":"msg_e5f6g7h8","traceId":null}],"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ThreadMessage"}}},"required":["truncated","thread","messages"],"additionalProperties":false}}}},"401":{"description":"The credential is missing, malformed, or expired. `code` discriminates the cause; only `pass_expired` is renewable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnauthorizedErrorResponse"}}}},"403":{"description":"The presented credential is not permitted to perform this action against this agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"The thread does not exist, or it is not accessible with the presented credential. Absent and inaccessible threads are deliberately indistinguishable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadNotFoundResponse"}}}},"422":{"description":"The thread's owning agent has a type the public API cannot run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnprocessableEntityWithStatusResponse"}}}},"429":{"description":"The session's per-minute request budget is exhausted. Retry after the number of seconds in the `Retry-After` header. Charged only for a browser session pass; API-key reads are unbounded here.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped"}}},"/v1/threads":{"get":{"operationId":"listThreads","summary":"List threads for an assistant","description":"Retrieve a list of conversation threads for the specified assistant, ordered by creation date (most recent first)","parameters":[{"schema":{"description":"Unique identifier of the assistant","example":"0fade940-133f-49e6-bf4b-8f662186479b","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$"},"in":"query","name":"assistant_id","required":true,"description":"Unique identifier of the assistant"},{"schema":{"description":"Maximum number of threads to return in this page (1–100). Defaults to 100.","example":100,"default":100,"type":"integer","minimum":1,"maximum":100},"in":"query","name":"limit","description":"Maximum number of threads to return in this page (1–100). Defaults to 100."},{"schema":{"description":"Opaque pagination cursor. Pass the `nextCursor` from a previous response to fetch the next page of threads (ordered most-recent first). Omit on the first request.","type":"string","minLength":1,"maxLength":1024},"in":"query","name":"cursor","description":"Opaque pagination cursor. Pass the `nextCursor` from a previous response to fetch the next page of threads (ordered most-recent first). Omit on the first request."}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"threads":{"readOnly":true,"type":"array","items":{"$ref":"#/components/schemas/ThreadDetails"}},"nextCursor":{"description":"Opaque cursor for the next page, or null when there are no more threads. Pass it back as the `cursor` query parameter to retrieve the next page.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["threads","nextCursor"],"additionalProperties":false}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped"}},"post":{"operationId":"createThread","summary":"Create a new thread","description":"Create a new conversation thread for the specified assistant","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateThreadRequest"}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateThreadResponse"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"not_found"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded for this organization and agent. Retry after the number of seconds in the `Retry-After` header. Every response — not only a 429 — carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitErrorResponse"}}}}},"x-runbear-scope":{"endpointClass":"agent-scoped","requiredCapability":"chat"}}}},"servers":[{"url":"https://api.runbear.io","description":"API Server"}],"x-runbear-api-key-scopes":{"description":"An organization API key carries a scope: a set of capabilities and, optionally, an allowlist of agents it may touch. Every /v1 operation publishes the permission it requires as `x-runbear-scope`. Reads require only a valid key; mutations require the named capability. A key with an agent allowlist is additionally refused on organization-level settings and on any agent outside its list. A denial is a 403 whose `code` is one of `forbidden_by_key_role`, `forbidden_by_agent_allowlist`, `forbidden_org_endpoint_for_scoped_key`.","capabilities":{"chat":"Send messages to an agent and run threads.","manageAgents":"Create, update and delete agents and their tool integrations.","manageApiKeys":"Read and manage the organization's API keys. Never granted implicitly — a key without it is refused even on reads."},"endpointClasses":{"agent-scoped":"Addresses a specific agent. A key with an agent allowlist is refused for any agent outside it.","org-config":"Reads or writes organization-level settings. Refused outright for a key with an agent allowlist.","catalog":"Organization-independent catalog data. Neither gate applies."}}}