{ "openapi": "3.1.0", "info": { "title": "Timbal Platform API", "description": "Public API documentation for the Timbal platform", "license": { "name": "" }, "version": "2.0.0" }, "servers": [ { "url": "https://api.timbal.ai", "description": "Production" }, { "url": "https://api.dev.timbal.ai", "description": "Development" } ], "paths": { "/ace/{ace_uid}/jobs": { "get": { "tags": [ "ace" ], "description": "List jobs for an ACE, most recent first.", "operationId": "list", "parameters": [ { "name": "ace_uid", "in": "path", "description": "ACE uid (UUID).", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Max rows to return (clamped to 200). Defaults to 50.", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Jobs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListAceJobsResBody" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "ACE not found" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "ace" ], "description": "Enqueue a job against an ACE. Today: `regenerate` (playbook [re-]generation from the linked workforce's agent code file; the current playbook stays usable until the job commits a new one). The kind vocabulary grows server-side — future kinds include usage-driven adaptation.", "operationId": "enqueue", "parameters": [ { "name": "ace_uid", "in": "path", "description": "ACE uid (UUID).", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnqueueAceJobReqBody" } } }, "required": true }, "responses": { "202": { "description": "Job enqueued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnqueueJobResBody" } } } }, "400": { "description": "Bad request (e.g. unknown or non-enqueuable kind, unknown branch)" }, "403": { "description": "Forbidden" }, "404": { "description": "ACE not found, or no workforce linked" }, "409": { "description": "ACE already has a queued or running job, or multiple linked workforces and no app_id" } }, "security": [ { "bearer_auth": [] } ] } }, "/ace/{ace_uid}/jobs/{job_uid}": { "get": { "tags": [ "ace" ], "description": "Get a single ACE job by id.", "operationId": "get_one", "parameters": [ { "name": "ace_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "job_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Job", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AceJobView" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Job or ACE not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/ace/{ace_uid}/jobs/{job_uid}/cancel": { "post": { "tags": [ "ace" ], "description": "Cancel an active ACE job.", "operationId": "cancel", "parameters": [ { "name": "ace_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "job_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "204": { "description": "Cancel signal sent" }, "403": { "description": "Forbidden" }, "404": { "description": "Job not found" }, "409": { "description": "Job is not currently queued/running" } }, "security": [ { "bearer_auth": [] } ] } }, "/ace/{ace_uid}/jobs/{job_uid}/retry": { "post": { "tags": [ "ace" ], "description": "Retry a failed, cancelled, or errored ACE job.", "operationId": "retry", "parameters": [ { "name": "ace_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "job_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "202": { "description": "Retry enqueued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnqueueJobResBody" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Job not found" }, "409": { "description": "Source job not retriable, or ACE has a live job" } }, "security": [ { "bearer_auth": [] } ] } }, "/ace/{ace_uid}/policies": { "get": { "tags": [ "ace" ], "description": "List the policies declared on an ACE.", "operationId": "list", "parameters": [ { "name": "ace_uid", "in": "path", "description": "ACE uid (UUID).", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Policies", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListPoliciesResBody" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "ACE not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/ace/{ace_uid}/v1/chat/completions": { "post": { "tags": [ "ace" ], "description": "OpenAI-compatible chat completions endpoint for an ACE.", "operationId": "handler", "parameters": [ { "name": "ace_uid", "in": "path", "description": "ACE uid (UUID).", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Upstream response (JSON or SSE depending on `stream`)" }, "400": { "description": "Bad request" }, "401": { "description": "Missing or invalid credentials" }, "402": { "description": "Credits limit exceeded" }, "404": { "description": "ACE not found" }, "500": { "description": "Upstream provider error" } }, "security": [ { "bearer_auth": [] } ] } }, "/ace/{ace_uid}/vars": { "get": { "tags": [ "ace" ], "description": "List the variables declared on an ACE.", "operationId": "list", "parameters": [ { "name": "ace_uid", "in": "path", "description": "ACE uid (UUID).", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Variables", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListVarsResBody" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "ACE not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/files": { "post": { "tags": [ "files" ], "description": "Upload a short-lived file for temporary staging.", "operationId": "handler", "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "required": [ "file" ], "properties": { "file": { "type": "array", "items": { "type": "integer", "format": "int32", "minimum": 0 }, "description": "Binary contents of the file. Max 100 MB.", "contentMediaType": "application/octet-stream" } } } } }, "required": true }, "responses": { "200": { "description": "File uploaded", "headers": { "RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Max requests per window for this user." }, "RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Requests left in the current window." }, "RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Seconds until the current window resets." }, "X-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Limit`." }, "X-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Remaining`." }, "X-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Reset`." } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TempFile" } } } }, "413": { "description": "File exceeds 100MB limit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "429": { "description": "Per-user rate limit exceeded", "headers": { "RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Max requests per window for this user." }, "RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Requests left in the current window." }, "RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Seconds until the current window resets." }, "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds the client should wait before retrying." }, "X-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Limit`." }, "X-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Remaining`." }, "X-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Reset`." } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/me": { "patch": { "tags": [ "users" ], "description": "Patch the authenticated user's profile.", "operationId": "handler", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PatchMeReqBody" } } }, "required": true }, "responses": { "204": { "description": "Profile updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "400": { "description": "Validation failed or non-nullable field set to null", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/me/orgs": { "get": { "tags": [ "orgs" ], "description": "List organizations the authenticated user belongs to", "operationId": "handler", "parameters": [ { "name": "q", "in": "query", "description": "Optional search query to filter orgs by name", "required": false, "schema": { "type": "string" } }, { "name": "page_token", "in": "query", "description": "Page token", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Organizations listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListOrgsResult" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/me/photo": { "put": { "tags": [ "users" ], "description": "Upload and set the authenticated user's profile picture.", "operationId": "handler", "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "description": "Multipart form schema for the OpenAPI doc only (the handler reads the raw\n`file` part directly).", "required": [ "file" ], "properties": { "file": { "type": "array", "items": { "type": "integer", "format": "int32", "minimum": 0 }, "description": "Profile picture bytes. Must be an image; the type is detected from the\nfile content, not the filename or declared content type.", "contentMediaType": "application/octet-stream" } } } } }, "required": true }, "responses": { "200": { "description": "Profile picture updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdatePhotoResBody" } } } }, "400": { "description": "Missing file or unsupported image type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "413": { "description": "Image too large", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "users" ], "description": "Clear the authenticated user's profile picture.", "operationId": "delete", "responses": { "204": { "description": "Profile picture cleared", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/me/tokens": { "get": { "tags": [ "users" ], "description": "List the authenticated user's API credentials.", "operationId": "handler", "responses": { "200": { "description": "Credentials listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResBody" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "users" ], "description": "Create an API credential for the authenticated user.", "operationId": "handler", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReqBody" } } }, "required": true }, "responses": { "201": { "description": "Credential created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResBody" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "422": { "description": "Limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/me/tokens/{token_id}": { "delete": { "tags": [ "users" ], "description": "Revoke an API credential owned by the authenticated user.", "operationId": "handler", "parameters": [ { "name": "token_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Credential revoked", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs": { "post": { "tags": [ "orgs" ], "description": "Create a new organization.", "operationId": "handler", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOrgReqBody" } } }, "required": true }, "responses": { "204": { "description": "Organization created successfully", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "429": { "description": "Org limit reached", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}": { "get": { "tags": [ "orgs" ], "description": "Get an organization by ID", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Organization details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetOrgResBody" } } } } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "orgs" ], "description": "Partially update an organization", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EditOrgReqBody" } } }, "required": true }, "responses": { "204": { "description": "Organization updated successfully" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/alarms": { "get": { "tags": [ "alarms" ], "summary": "List metric alarms", "description": "The metric alarms you can see in this org, with current state and channels.\n\nFiltered per alarm, not per request: org-level alarms (credits, org-wide spend) need `alarms.read`, and an alarm tagged to a project needs `projects.alarms.read` on that project. Holding one and not the other returns the matching subset rather than a `403`, so a role scoped to a single project sees exactly that project's alarms.", "operationId": "list_org_alarms", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of alarms", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListOrgAlarmsResBody" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "alarms" ], "summary": "Create a metric alarm", "description": "Create a metric alarm with a threshold over evaluation periods.\n\nSet `denominator_metric_name` for a **rate** rather than a count: the datapoint becomes `metric_name / denominator_metric_name` and `threshold` reads as a fraction (`0.05` = 5%). Prefer this for anything that scales with traffic — a fixed error count pages at 3am once the org grows. Pair it with `min_sample_count` so a single failure in a quiet minute isn't a 100% error rate.\n\nBoth series must be binned on the same clock, since they are divided period by period. For outcome rates that means `app.run.terminal_count` — runs that *finished* in the period — and not `app.run.count`, which counts runs that *started* and includes ones still running. Mismatched pairs are rejected.\n\nRatio alarms also require `stat` `sum` or `count`. The stat is applied to each series and the two results divided, so only stats that add up across the minutes in a period come out as a rate — `avg` would divide two means and `min`/`max` would take their extremes from different minutes. Other stats are rejected rather than silently producing a number that isn't a rate.\n\nA sustained incident only ever notifies once, so repeat messages mean the alarm is flapping. Three levers fix that, and which one depends on the metric: `clear_threshold` (fire high, clear low) for continuous series like rates and latencies; `datapoints_to_alarm` for spiky ones that cross the line briefly; and `missing_data: \"ignore\"` for sparse ones, where a minute with no traffic is absence of evidence rather than a recovery.\n\nUse `GET /orgs/{org_id}/metrics/catalog` to see which metric names and labels this org is actually emitting. Two metrics won't be listed until you alarm on them: `org.credits.usage_pct` (percent of the billing period's prepaid budget consumed) and `org.credits.remaining` (credits left in it) are only sampled for orgs that have an enabled alarm on one, since the underlying read is the billing gate's and too heavy to run speculatively. Both are levels sampled once a minute, so use `max`, `avg` or `min` — `sum` would add one reading per minute in the period and is rejected. `org.credits.remaining` goes negative under overage.\n\nPercent and headroom are worth having separately: 95% of a large budget can still be thousands of credits, while 50% of a small one is one bad afternoon. For burn *volume* rather than budget position, alarm on `org.credits.spend` with `sum` — that one carries `project_id` and `workforce_id` dims, so it can scope to a single project or workforce the way a budget can't.\n\nFor latency, `stat` accepts any percentile from `p0.1` to `p99.9`, in tenths. Equivalent spellings are fine (`p95.0` is accepted and comes back as `p95`), but anything finer than a tenth is rejected rather than rounded, so an alarm never silently watches a different point than the one you asked for. These are exact, computed over the individual run durations rather than interpolated from bins, which is also why they are limited to `app.run.duration_ms`, cannot be a ratio, and cannot carry `label`, `project_env_id` or `dims.deployment_id` — a run row has no such column, so those filters would silently widen the alarm to everything. Prefer a high percentile over `avg` for latency: an average hides the tail that users actually notice, and hides it harder as traffic grows.\n\nTwo different project fields, gated separately. Top-level `project_id` is ownership — who may see and edit the alarm afterwards — and setting it requires `projects.alarms.manage` on that project, while leaving it out makes an org-level alarm and requires `alarms.manage`. `dims.project_id` only narrows which metric bins are read, but it still exposes that project's numbers through the alarm's notifications, so it requires `projects.alarms.read` on the project it names.", "operationId": "create_org_alarm", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAlarmReq" }, "examples": { "Credits budget above 80%": { "value": { "name": "Credits usage", "metric_name": "org.credits.usage_pct", "stat": "max", "period_seconds": 300, "comparison": "gte", "threshold": 80, "clear_threshold": 70, "datapoints_to_alarm": 1, "evaluation_periods": 1, "channel": { "type": "email", "config": { "to": "finance@example.com" } } } }, "Deployment down": { "value": { "name": "API down — production", "metric_name": "deployment.health", "dims": { "project_env_id": "559" }, "stat": "avg", "period_seconds": 120, "comparison": "lt", "threshold": 0.5, "missing_data": "breaching", "channel": { "type": "slack", "config": { "token": "xoxb-1234567890123-1234567890123", "channel": "C0123456789" } } } }, "Error count": { "value": { "name": "Support agent errors", "metric_name": "app.run.errors", "dims": { "workforce_id": "123" }, "stat": "sum", "period_seconds": 300, "comparison": "gte", "threshold": 5, "datapoints_to_alarm": 2, "evaluation_periods": 3, "channel": { "type": "email", "config": { "to": "ops@example.com" } } } }, "Error rate above 5%": { "value": { "name": "Support agent error rate", "metric_name": "app.run.errors", "denominator_metric_name": "app.run.terminal_count", "min_sample_count": 20, "dims": { "workforce_id": "123" }, "stat": "sum", "period_seconds": 300, "comparison": "gt", "threshold": 0.05, "clear_threshold": 0.03, "datapoints_to_alarm": 2, "evaluation_periods": 3, "channel": { "type": "email", "config": { "to": "ops@example.com" } } } }, "Fewer than 1000 credits left": { "value": { "name": "Credits headroom", "metric_name": "org.credits.remaining", "stat": "min", "period_seconds": 300, "comparison": "lt", "threshold": 1000, "clear_threshold": 5000, "datapoints_to_alarm": 1, "evaluation_periods": 1, "channel": { "type": "email", "config": { "to": "finance@example.com" } } } }, "Sparse metric, no false recovery": { "value": { "name": "Checkout tool failures", "metric_name": "trace.tool_errors", "dims": { "workforce_id": "123", "label": "charge_card" }, "stat": "sum", "period_seconds": 60, "comparison": "gt", "threshold": 5, "missing_data": "ignore", "channel": { "type": "slack", "config": { "token": "xoxb-1234567890123-1234567890123", "channel": "C0123456789" } } } }, "p99 latency": { "value": { "name": "Checkout p99 latency", "metric_name": "app.run.duration_ms", "dims": { "workforce_id": "123" }, "stat": "p99", "period_seconds": 300, "comparison": "gt", "threshold": 8000, "clear_threshold": 6000, "datapoints_to_alarm": 2, "evaluation_periods": 3, "channel": { "type": "email", "config": { "to": "ops@example.com" } } } } } } }, "required": true }, "responses": { "201": { "description": "Alarm and channel link created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAlarmOut" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/alarms/health": { "get": { "tags": [ "alarms" ], "summary": "Find alarms that stopped receiving data", "description": "For every enabled alarm, when the metric series behind it last produced a datapoint.\n\nAnswers the one question an alarm's own `state` cannot: is it still watching anything? Under the default `not_breaching` policy an alarm whose metric stopped being emitted — a deleted workforce, a disabled trace filter, a renamed metric — sits at `ok` indefinitely and looks identical to one that is genuinely healthy.\n\n`stale` marks silence lasting ten evaluation windows (minimum one hour), which is long enough that a quiet-but-live series won't trip it. A brand-new alarm reads as stale until its first datapoint, which is accurate: it cannot fire yet.\n\nFor a ratio alarm, `last_datapoint_at` is the **older** of the two series, since a period only yields a datapoint where both sides have one. A live numerator over a dead denominator is therefore reported as stale — every period resolves to a missing ratio, so the alarm is blind despite one of its series still flowing. `denominator_last_datapoint_at` tells you which side went quiet.\n\nCovers the same alarms `GET /orgs/{org_id}/alarms` returns for you, so `healthy` and `stale_count` describe your visible subset — a project-scoped caller gets their project's blind spots, not the org's.", "operationId": "get_org_alarms_health", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Per-alarm data health", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgAlarmsHealthResBody" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/alarms/{alarm_id}": { "get": { "tags": [ "alarms" ], "summary": "Get a metric alarm", "description": "One alarm's configuration, current state and linked channels.\n\nSame shape as an entry in `GET /orgs/{org_id}/alarms`, for refreshing a detail view without refetching the whole list.\n\nNeeds `alarms.read` for an org-level alarm, or `projects.alarms.read` on the owning project for a project alarm.", "operationId": "get_org_alarm", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "alarm_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The alarm", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AlarmOut" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Alarm not found for this org", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "alarms" ], "summary": "Delete a metric alarm", "description": "Delete a metric alarm and its channel links.\n\nNeeds `alarms.manage` for an org-level alarm, or `projects.alarms.manage` on the owning project for a project alarm.", "operationId": "delete_org_alarm", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "alarm_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Alarm deleted", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "alarms" ], "summary": "Update a metric alarm", "description": "Update alarm thresholds, evaluation settings, or enabled state.\n\n`clear_threshold` is the one field where `null` differs from omitting the key: send `null` to drop the hysteresis, omit it to leave it as is. It is validated against the resulting `threshold` and `comparison`, so patching either side of the pair alone can't invert them.\n\n`metric_name` and `denominator_metric_name` are not patchable: changing what an alarm watches would leave its state and history describing a different question, so define a new alarm instead.\n\n`enabled: true` requires at least one attached channel. Channels may be detached freely while an alarm is disabled, so this is what stops that from re-enabling an alarm that evaluates and records transitions with nowhere to notify.\n\nThe alarm's owning project is not patchable either, so the permission needed here is fixed for the life of the alarm: `alarms.manage` when it is org-level, `projects.alarms.manage` on the owner when it is not.", "operationId": "update_org_alarm", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "alarm_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateAlarmReq" } } }, "required": true }, "responses": { "204": { "description": "Alarm updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/alarms/{alarm_id}/channels": { "post": { "tags": [ "alarms" ], "summary": "Attach a channel to an alarm", "description": "Attach another notification channel to an alarm, so one condition reaches several destinations (page Slack and email the on-call, say).\n\nAccepts the same channel shape as alarm creation: `{ \"id\": \u003Cchannel id\u003E }` to reuse an existing channel, or inline `type` + `config` to create one. Inline channels identical to an existing row are deduped rather than duplicated.\n\nIdempotent — re-attaching a channel that is already linked returns `already_linked: true` and changes nothing.\n\nGated by the alarm, not the channel: `alarms.manage` for an org-level alarm, `projects.alarms.manage` on the owner for a project alarm. Channels themselves are org-wide, so a project-scoped caller can point their alarm at any existing channel — attaching one is a routing decision about their alarm, whereas creating or deleting the channel row needs `notification_channels.manage`.", "operationId": "add_org_alarm_channel", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "alarm_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateChannelReq" }, "examples": { "New Slack channel": { "value": { "type": "slack", "name": "oncall-pages", "config": { "token": "xoxb-1234567890123-1234567890123", "channel": "C0123456789" } } }, "Reuse an existing channel": { "value": { "id": "13" } } } } }, "required": true }, "responses": { "200": { "description": "Channel attached", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddAlarmChannelOut" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Alarm not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/alarms/{alarm_id}/channels/{channel_id}": { "delete": { "tags": [ "alarms" ], "summary": "Detach a channel from an alarm", "description": "Detach a channel from an alarm. The `NotificationChannels` row itself is left alone — other alarms and notification rules may still be using it.\n\nRemoving the **last** channel from an enabled alarm is rejected: it would keep evaluating and recording transitions while notifying nobody, which looks healthy from the outside. To swap a sole channel, attach the replacement first; to silence an alarm, `PATCH` it with `enabled: false`.", "operationId": "remove_org_alarm_channel", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "alarm_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "channel_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Channel detached", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "400": { "description": "Would leave an enabled alarm with no channels", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Alarm not found, or channel not linked to it", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/alarms/{alarm_id}/history": { "get": { "tags": [ "alarms" ], "summary": "List alarm state transitions", "description": "State transition history for an alarm, newest first.\n\nNeeds `alarms.read` for an org-level alarm, or `projects.alarms.read` on the owning project for a project alarm.", "operationId": "get_org_alarm_history", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "alarm_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Max transitions to return (newest first). Default 50, max 500.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } } ], "responses": { "200": { "description": "Transition history", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AlarmHistoryResBody" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/analytics/costs": { "get": { "tags": [ "analytics" ], "description": "Time-binned credits and USD spend across an org, grouped by product surface.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "group_by", "in": "query", "description": "Bucket size for aggregation (`minute`, `hour`, or `day`).", "required": false, "schema": { "$ref": "#/components/schemas/BinSize" } }, { "name": "from", "in": "query", "description": "Inclusive range start (epoch milliseconds). Defaults: 1h / 1d / 30d before `to` by `group_by`.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "to", "in": "query", "description": "Exclusive range end (epoch milliseconds). Defaults to now.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "user_id", "in": "query", "description": "Restrict to spend attributed to a specific user.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "project_id", "in": "query", "description": "Restrict to spend attributed to a single project. Omit for org-wide totals.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "resource_type", "in": "query", "description": "Restrict to one product surface (e.g. `composer`, `app_run`, `kb_query`,\n`kb_file_parsing`); `legacy` selects spend recorded before source\nattribution existed.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Costs analytics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgAnalyticsCostsBody" } } } }, "400": { "description": "Bad request" }, "403": { "description": "Forbidden" }, "500": { "description": "Error" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/analytics/usage": { "get": { "tags": [ "analytics" ], "description": "Time-binned run counts, user counts, and duration percentiles across an org.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "group_by", "in": "query", "description": "Bucket size for aggregation (`minute`, `hour`, or `day`).", "required": false, "schema": { "$ref": "#/components/schemas/BinSize" } }, { "name": "from", "in": "query", "description": "Inclusive range start (epoch milliseconds). Defaults: 1h / 1d / 30d before `to` by `group_by`.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "to", "in": "query", "description": "Exclusive range end (epoch milliseconds). Defaults to now.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "user_id", "in": "query", "description": "Restrict to a specific user’s runs.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "project_id", "in": "query", "description": "Restrict to a single project. Omit for org-wide totals.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage analytics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgAnalyticsUsageBody" } } } }, "400": { "description": "Bad request" }, "403": { "description": "Forbidden" }, "500": { "description": "Error" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/analytics/users": { "get": { "tags": [ "analytics" ], "description": "Per-user run counts and full-ledger spend aggregates across an org.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "from", "in": "query", "description": "Inclusive range start (epoch milliseconds).", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "to", "in": "query", "description": "Exclusive range end (epoch milliseconds).", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "user_id", "in": "query", "description": "Restrict to a specific user’s runs.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "project_id", "in": "query", "description": "Restrict to a single project. Omit for org-wide aggregates.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "page_token", "in": "query", "description": "Opaque offset for the next page (from the previous response’s `next_page_token`).", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "User analytics page", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgAnalyticsUsersBody" } } } }, "403": { "description": "Forbidden" }, "500": { "description": "Error" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/billing/budgets": { "get": { "tags": [ "billing" ], "description": "Read credit budgets for the organization.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "query", "description": "When set, return at most the project budget for this project (0 or 1 rows).", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "role_id", "in": "query", "description": "When set, return at most the role budget for this role (0 or 1 rows).", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Budgets", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BudgetListBody" } } } }, "400": { "description": "Invalid query" }, "403": { "description": "Forbidden" }, "404": { "description": "Filtered project or role not found" } }, "security": [ { "bearer_auth": [] } ] }, "put": { "tags": [ "billing" ], "description": "Replace the organization's full credit budget configuration.", "operationId": "put", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BudgetListBody" } } }, "required": true }, "responses": { "200": { "description": "Budgets saved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BudgetListBody" } } } }, "400": { "description": "Invalid request" }, "403": { "description": "Forbidden" }, "404": { "description": "Project or role not found" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "billing" ], "description": "Merge partial credit budget changes for the organization.", "operationId": "patch", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BudgetPatchBody" } } }, "required": true }, "responses": { "200": { "description": "Budgets saved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BudgetListBody" } } } }, "400": { "description": "Invalid request" }, "403": { "description": "Forbidden" }, "404": { "description": "Project or role not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/billing/compute": { "get": { "tags": [ "billing" ], "description": "Get purchased compute machines and the org's compute pool usage.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Compute machine fleet", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComputeFleetSummary" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "put": { "tags": [ "billing" ], "description": "Set the compute machine add-ons purchased by the organization.", "operationId": "put", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ComputeFleetReqBody" } } }, "required": true }, "responses": { "204": { "description": "Compute machines updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "422": { "description": "Unprocessable entity", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/billing/overage": { "get": { "tags": [ "billing" ], "description": "Get overage credit usage for the current billing period.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Overage usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OverageSummary" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "billing" ], "description": "Update overage billing settings for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BillingOverageReqBody" } } }, "required": true }, "responses": { "204": { "description": "Overage settings updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "422": { "description": "Unprocessable entity", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/channels": { "get": { "tags": [ "channels" ], "summary": "List delivery channels for the org", "description": "List the organization's delivery channels — the addresses alarms can notify (email inboxes, Slack channels).\n\nChannels carry no conditions of their own. What to watch and when to fire lives on the alarm; this is only where the message goes.", "operationId": "list_org_channels", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Channels for the org", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListOrgChannelsResBody" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "channels" ], "summary": "Create a delivery channel", "description": "Create a delivery channel for this org, or reuse an existing one.\n\nChannels dedupe on `(type, config)`: posting the same Slack channel twice returns the original row with `channel_action: \"reused\"` rather than creating a near-duplicate. Attach the returned `id` to an alarm via `POST /orgs/{org_id}/alarms/{alarm_id}/channels`.", "operationId": "create_org_channel", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateNotificationChannelReq" }, "examples": { "Email": { "value": { "type": "email", "name": "Finance inbox", "config": { "to": "finance@example.com" } } }, "Slack": { "value": { "type": "slack", "name": "Deploy alerts", "config": { "token": "xoxb-1234567890123-1234567890123", "channel": "C0123456789" } } } } } }, "required": true }, "responses": { "201": { "description": "Channel created or reused", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateNotificationChannelOut" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/channels/{channel_id}": { "delete": { "tags": [ "channels" ], "summary": "Delete a delivery channel", "description": "Delete a delivery channel for the organization.\n\nRefused with `409` while alarms still reference the channel; `force: true` deletes anyway and unlinks them. The one case `force` will not do is strip the last channel from an *enabled* alarm — that alarm would go on evaluating and recording state transitions with nowhere to send them. Attach a replacement channel or disable the alarm first.", "operationId": "delete_org_channel", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "channel_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "description": "Optional force-delete flag.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeleteChannelBody" } } }, "required": true }, "responses": { "204": { "description": "Channel deleted" }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors`", "description": "List connectors for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Connectors listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResBody" } } } }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/enrollment-tokens": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/enrollment-tokens`", "description": "Create a connector enrollment token.", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReqBody" } } }, "required": true }, "responses": { "201": { "description": "Token minted (raw value shown once)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResBody" } } } }, "400": { "description": "Invalid TTL" }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/jobs": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/jobs`", "description": "List connector jobs for the organization.", "operationId": "list", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "query", "description": "Filter to a single connector.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Jobs listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListJobsRes" } } } }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/syncs": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/syncs`", "description": "List connector syncs for the organization.", "operationId": "list", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "query", "description": "Filter to a single connector.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Syncs listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListSyncsRes" } } } }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}`", "description": "Get a connector by id.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Connector details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResBody" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/browse/columns": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/browse/columns`", "description": "List columns for a remote table.", "operationId": "columns", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connection_ref", "in": "query", "required": true, "schema": { "type": "string" } }, { "name": "schema", "in": "query", "required": true, "schema": { "type": "string" } }, { "name": "table", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Columns listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ColumnsRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/browse/connections": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/browse/connections`", "description": "List remote connections available to a connector.", "operationId": "connections", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Connection refs listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConnectionsRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/browse/filesystems": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/browse/filesystems`", "description": "List filesystem roots configured on a connector (names only). Requires a connector advertising fs:browse (0.1.27+).", "operationId": "filesystems", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Filesystem refs listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FilesystemsRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out / too old" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/browse/filesystems/entries": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/browse/filesystems/entries`", "description": "List one directory under a connector filesystem root, with size/mtime per entry, optional glob filter, sort, and bounded recursion (depth). Requires fs:browse (0.1.27+).", "operationId": "entries", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "filesystem_ref", "in": "query", "description": "Filesystem root ref on the node (from `/browse/filesystems`).", "required": true, "schema": { "type": "string" } }, { "name": "path", "in": "query", "description": "Directory relative to the root; omit for the root itself.", "required": false, "schema": { "type": "string" } }, { "name": "all", "in": "query", "description": "Include dotfiles.", "required": false, "schema": { "type": "boolean" } }, { "name": "sort", "in": "query", "description": "`name` (default) | `size` (largest first) | `mtime` (newest first).", "required": false, "schema": { "type": "string" } }, { "name": "glob", "in": "query", "description": "Filename glob (`*` and `?`), matched on entry names.", "required": false, "schema": { "type": "string" } }, { "name": "depth", "in": "query", "description": "`0` (default) = this directory only; `1..N` = bounded recursion that\nmany levels deeper (clamped node-side).", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "limit", "in": "query", "description": "Entry cap; the node clamps to its own ceiling and flags `truncated`.", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "timeout_ms", "in": "query", "description": "Node-side walk budget in milliseconds (default 20000, ceiling 30000).\n`0` / omit = node default. Channel wait is 35s so a full budget still\nreturns a truncated listing instead of `browse_timeout`.", "required": false, "schema": { "type": "integer", "format": "int64", "minimum": 0 } } ], "responses": { "200": { "description": "Directory listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FsLsRes" } } } }, "400": { "description": "Invalid request" }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out / too old" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/browse/filesystems/search": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/browse/filesystems/search`", "description": "Search file contents under a connector filesystem root with a line regex — bounded on files, matches, bytes, and time; binaries skipped. Runs entirely in-process on the node. Requires ConnectorsManage (reads file contents, same bar as ad-hoc SQL) and fs:browse (0.1.27+).", "operationId": "search", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "filesystem_ref", "in": "query", "description": "Filesystem root ref on the node (from `/browse/filesystems`).", "required": true, "schema": { "type": "string" } }, { "name": "path", "in": "query", "description": "Directory relative to the root; omit for the root itself.", "required": false, "schema": { "type": "string" } }, { "name": "pattern", "in": "query", "description": "Regex applied per line (Rust `regex` syntax; `(?i)` for\ncase-insensitive).", "required": true, "schema": { "type": "string" } }, { "name": "glob", "in": "query", "description": "Filename glob (`*` and `?`) restricting which files are scanned.", "required": false, "schema": { "type": "string" } }, { "name": "max_matches", "in": "query", "description": "Match cap; the node clamps to its own ceiling.", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "timeout_ms", "in": "query", "description": "Node-side scan budget in milliseconds (default 20000, ceiling 30000).\n`0` / omit = node default.", "required": false, "schema": { "type": "integer", "format": "int64", "minimum": 0 } } ], "responses": { "200": { "description": "Search completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FsGrepRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out / too old" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/browse/filesystems/summary": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/browse/filesystems/summary`", "description": "Summarize a directory tree on a connector filesystem root without listing it: file/dir counts, total bytes, largest files, extension histogram. The probe to run before a recursive copy. Requires fs:browse (0.1.27+).", "operationId": "summary", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "filesystem_ref", "in": "query", "description": "Filesystem root ref on the node (from `/browse/filesystems`).", "required": true, "schema": { "type": "string" } }, { "name": "path", "in": "query", "description": "Directory relative to the root; omit for the root itself.", "required": false, "schema": { "type": "string" } }, { "name": "timeout_ms", "in": "query", "description": "Node-side walk budget in milliseconds (default 20000, ceiling 30000).\n`0` / omit = node default.", "required": false, "schema": { "type": "integer", "format": "int64", "minimum": 0 } } ], "responses": { "200": { "description": "Tree summarized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FsDuRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out / too old" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/browse/table": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/browse/table`", "description": "Full introspection of one remote table: rich columns (defaults, identity, comments, precision), indexes, foreign keys, check constraints, table comment and size. Requires a connector advertising browse:describe (0.1.25+).", "operationId": "table", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connection_ref", "in": "query", "required": true, "schema": { "type": "string" } }, { "name": "schema", "in": "query", "required": true, "schema": { "type": "string" } }, { "name": "table", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Table described", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TableDetailRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out / too old" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/browse/tables": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/browse/tables`", "description": "List remote tables available to a connector.", "operationId": "tables", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connection_ref", "in": "query", "description": "Connection ref on the node (from `/browse/connections`).", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Tables listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TablesRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/filesystems/copy": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/filesystems/copy`", "description": "Copy a file or directory tree from a connector filesystem root into a knowledge base's document store. Store-only by default (parse: true to opt in). Requires fs:copy (0.1.27+).", "operationId": "copy", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CopyReq" } } }, "required": true }, "responses": { "202": { "description": "Copy job accepted and dispatched", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CopyRes" } } } }, "400": { "description": "Invalid request" }, "403": { "description": "Forbidden" }, "404": { "description": "Connector or KB not found" }, "422": { "description": "Connector offline / too old" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/jobs": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/jobs`", "description": "Dispatch a job to a connector.", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DispatchReq" } } }, "required": true }, "responses": { "202": { "description": "Job accepted and dispatched", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DispatchRes" } } } }, "400": { "description": "Invalid request" }, "403": { "description": "Forbidden" }, "404": { "description": "Connector or KB not found" }, "422": { "description": "Unprocessable entity" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/jobs/{job_id}/stop": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/jobs/{job_id}/stop`", "description": "Cancel a running extract job. The row is terminalized as `stopped` first\n(so the run is dead even if the connector is offline or never acks), then a\n`StopJob` command aborts the connector-side task best-effort. Idempotent:\nstopping an already-terminal job returns its current state.", "operationId": "stop", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "job_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Job stopped (or already terminal)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StopRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Job not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/local-config": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/local-config`", "description": "Push replacement connections/filesystems maps to a connector box.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LocalConfigReq" } } }, "required": true }, "responses": { "202": { "description": "Config push dispatched", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LocalConfigRes" } } } }, "400": { "description": "Empty payload (neither map present)" }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline (`code: connector_offline`)" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/query": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/query`", "description": "Run an ad-hoc SQL query against a connector's source and return the bounded result inline. Read-only by default (enforced node-side); write mode must also be allowed by the connection's local policy on the connector box. Requires a connector advertising query:sql (0.1.26+).", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QueryReq" } } }, "required": true }, "responses": { "200": { "description": "Query executed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QueryRes" } } } }, "400": { "description": "Invalid request" }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline / refused / timed out / too old" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/rebind": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/rebind`", "description": "Rebind a connector to a different knowledge base.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RebindReq" } } }, "required": true }, "responses": { "202": { "description": "Rebind dispatched", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RebindRes" } } } }, "400": { "description": "Invalid URL" }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found" }, "422": { "description": "Connector offline (`code: connector_offline`)" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/revoke": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/revoke`", "description": "Revoke a connector's credential and remove it from the fleet.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Connector revoked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RevokeRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector not found, or already revoked" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/syncs": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/syncs`", "description": "Create a connector sync configuration.", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSyncReq" } } }, "required": true }, "responses": { "201": { "description": "Sync created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSyncRes" } } } }, "400": { "description": "Invalid request" }, "403": { "description": "Forbidden" }, "404": { "description": "Connector or KB not found" }, "422": { "description": "Source or full-refresh extraction unsupported by connector" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/syncs/{sync_id}": { "get": { "tags": [ "connectors" ], "summary": "`GET /orgs/{org_id}/connectors/{connector_id}/syncs/{sync_id}`", "description": "Get a connector sync by id.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "sync_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Sync detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SyncDetailRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Sync not found" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "connectors" ], "summary": "`DELETE /orgs/{org_id}/connectors/{connector_id}/syncs/{sync_id}`", "description": "Delete a connector sync.", "operationId": "delete", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "sync_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Sync deleted" }, "403": { "description": "Forbidden" }, "404": { "description": "Sync not found" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "connectors" ], "summary": "`PATCH /orgs/{org_id}/connectors/{connector_id}/syncs/{sync_id}`", "description": "Update a connector sync.", "operationId": "update", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "sync_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateSyncReq" } } }, "required": true }, "responses": { "204": { "description": "Sync updated" }, "400": { "description": "Invalid request" }, "403": { "description": "Forbidden" }, "404": { "description": "Sync not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/syncs/{sync_id}/run": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/syncs/{sync_id}/run`", "description": "Run a connector sync immediately.", "operationId": "run_now", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "sync_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "202": { "description": "Run dispatched (`dispatched: true`) or queued for the instance holding the connector's socket (`dispatched: false`)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RunSyncRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Sync not found" }, "422": { "description": "Sync paused or auto-disabled (`sync_disabled`), or a run is already active (`run_active`)" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/connectors/{connector_id}/update": { "post": { "tags": [ "connectors" ], "summary": "`POST /orgs/{org_id}/connectors/{connector_id}/update`", "description": "Trigger a connector software update.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "connector_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateReq" } } }, "required": true }, "responses": { "200": { "description": "Connector already on the target version", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateRes" } } } }, "202": { "description": "Update dispatched", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateRes" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Connector or release version not found" }, "422": { "description": "Connector offline or too old to update remotely" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/contacts": { "get": { "tags": [ "orgs" ], "description": "Account-side contacts assigned to an organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Contacts for the organization", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListOrgContactsResBody" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/content/sign": { "post": { "tags": [ "content" ], "description": "Refresh a signed URL for stored content.", "operationId": "sign", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SignContentRequest" } } }, "required": true }, "responses": { "200": { "description": "Freshly-signed content URL", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SignContentResponse" } } } }, "400": { "description": "Malformed request body", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/credit-grants": { "get": { "tags": [ "billing" ], "description": "Credit grants awarded to an organization, most recent first.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Credit grants for the organization", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListCreditGrantsResBody" } } } }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/domains": { "get": { "tags": [ "orgs" ], "description": "List connected domains for an organization", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Domains listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListDomainsResBody" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "orgs" ], "description": "Add a custom domain to an organization", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDomainReqBody" } } }, "required": true }, "responses": { "204": { "description": "Domain created successfully" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/domains/{domain_id}": { "get": { "tags": [ "orgs" ], "description": "Get a custom domain with current DNS and certificate status.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "domain_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Domain details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Domain" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "orgs" ], "description": "Delete a domain", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "domain_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Domain deleted successfully" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/embedding-models": { "get": { "tags": [ "embeddings" ], "description": "List all available embedding models for the organization", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Array of embedding models", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListEmbeddingModelsResBody" }, "example": { "embedding_models": [ "text-embedding-ada-002", "text-embedding-3-small", "text-embedding-3-large" ] } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/actions": { "get": { "tags": [ "iam" ], "description": "Catalog of grantable IAM actions for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Action catalog visible to this org", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListActionsResBody" } } } }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/actions/{action}/users": { "get": { "tags": [ "iam" ], "description": "List members who effectively hold an org-wide IAM action.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "action", "in": "path", "description": "Org-wide IAM action key, for example `roles.manage`.", "required": true, "schema": { "type": "string" } }, { "name": "user_id", "in": "query", "description": "Restrict the report to a single member. Filtering to yourself\nrequires only org membership; other members require `users.read`.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "page_token", "in": "query", "description": "Page token for pagination. Pass back the `next_page_token` from the\nprevious response.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Members holding the action", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActionUsersResBody" } } } }, "403": { "description": "Forbidden" }, "422": { "description": "Unknown or non-org-wide action" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/check": { "post": { "tags": [ "iam" ], "description": "Simulate authorization checks against a user's effective grants.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckReqBody" } } }, "required": true }, "responses": { "200": { "description": "Per-check decisions + matched grants", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckResBody" } } } }, "403": { "description": "Forbidden" }, "422": { "description": "Invalid request" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/resources/{resource}/users": { "get": { "tags": [ "iam" ], "description": "List members with effective access to a resource, per action.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "resource", "in": "path", "description": "Concrete resource path, for example `projects:42` or\n`projects:42:envs:5`. No wildcards.", "required": true, "schema": { "type": "string" } }, { "name": "actions", "in": "query", "description": "Comma-separated action keys to evaluate (for example\n`projects.envs.deploy,projects.envs.logs`). Every action must target\nthe resource's kind. Omit to evaluate every action applicable to the\nresource.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "user_id", "in": "query", "description": "Restrict the report to a single member. Filtering to yourself\nrequires only org membership; other members require `users.read`.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "page_token", "in": "query", "description": "Page token for pagination. Pass back the `next_page_token` from the\nprevious response.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Members with access and their allowed actions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResourceUsersResBody" } } } }, "403": { "description": "Forbidden" }, "422": { "description": "Invalid resource or actions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/roles": { "get": { "tags": [ "iam" ], "description": "List system and custom roles for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Roles for the organization", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListOrgRolesResBody" } } } }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "iam" ], "description": "Create a custom role for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateRoleReqBody" } } }, "required": true }, "responses": { "201": { "description": "Role created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoleDetail" } } } }, "403": { "description": "Forbidden" }, "409": { "description": "A role with that name already exists in the organization" }, "422": { "description": "Unprocessable entity" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/roles/{role_id}": { "get": { "tags": [ "iam" ], "description": "Retrieve a role and the full set of grants it carries.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "role_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Role for the organization", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoleDetail" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Role not found" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "iam" ], "description": "Delete a custom organization role.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "role_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Role deleted" }, "403": { "description": "Forbidden or system role (immutable)" }, "404": { "description": "Role not found" }, "409": { "description": "Role is still attached to one or more members", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoleInUseConflict" } } } }, "422": { "description": "Unprocessable entity" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "iam" ], "description": "Partially update a custom organization role.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "role_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EditRoleReqBody" } } }, "required": true }, "responses": { "200": { "description": "Role updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoleDetail" } } } }, "403": { "description": "Forbidden or system role (immutable)" }, "404": { "description": "Role not found" }, "409": { "description": "A role with that name already exists" }, "422": { "description": "Unprocessable entity" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/users": { "get": { "tags": [ "iam" ], "description": "List members of an organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "q", "in": "query", "description": "Optional case-insensitive substring filter on user name or email.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "page_token", "in": "query", "description": "Page token for pagination. Pass back the `next_page_token` from the\nprevious response.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Organization members", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListOrgUsersResBody" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "iam" ], "description": "Invite one or more users to an organization", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InviteOrgUserReqBody" } } }, "required": true }, "responses": { "204": { "description": "User invited successfully" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "iam" ], "description": "Remove one or more members from an organization", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RemoveOrgUserReqBody" } } }, "required": true }, "responses": { "204": { "description": "Member(s) removed successfully", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/users/roles": { "put": { "tags": [ "iam" ], "description": "Replace role attachments for multiple members in one request.", "operationId": "bulk_handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BulkReplaceRolesReqBody" } } }, "required": true }, "responses": { "204": { "description": "Attachments updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Insufficient permissions" }, "422": { "description": "Invalid request" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/users/{user_id}/effective-grants": { "get": { "tags": [ "iam" ], "description": "List a member's effective IAM grants in the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "user_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Effective grants for the user", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EffectiveGrantsResBody" } } } }, "403": { "description": "Forbidden" }, "422": { "description": "Target user is not a member" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/iam/users/{user_id}/roles": { "put": { "tags": [ "iam" ], "description": "Replace a member's role attachments.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "user_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceRolesReqBody" } } }, "required": true }, "responses": { "204": { "description": "Attachments updated" }, "403": { "description": "Insufficient permissions" }, "422": { "description": "Invalid attachment" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/identity-providers": { "get": { "tags": [ "orgs" ], "description": "List SSO identity connections for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Connections listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListIdentityProvidersResBody" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "orgs" ], "description": "Create an SSO or directory identity connection for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateIdentityProviderReqBody" } } }, "required": true }, "responses": { "201": { "description": "Connection created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IdentityProviderView" } } } }, "409": { "description": "provider_key already in use" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/identity-providers/{provider_id}": { "get": { "tags": [ "orgs" ], "description": "Get an SSO identity connection by id.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "provider_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Connection", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IdentityProviderView" } } } }, "404": { "description": "Not found" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "orgs" ], "description": "Delete an SSO identity connection.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "provider_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Deleted" }, "404": { "description": "Not found" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "orgs" ], "description": "Update an SSO identity connection.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "provider_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateIdentityProviderReqBody" } } }, "required": true }, "responses": { "200": { "description": "Updated connection", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IdentityProviderView" } } } }, "404": { "description": "Not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/identity-providers/{provider_id}/default-role": { "put": { "tags": [ "orgs" ], "description": "Set or clear the SSO connection's default just-in-time role.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "provider_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetDefaultRoleReqBody" } } }, "required": true }, "responses": { "200": { "description": "Updated connection", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IdentityProviderView" } } } }, "404": { "description": "Not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/identity-providers/{provider_id}/group-mappings": { "get": { "tags": [ "orgs" ], "description": "List external-group to role mappings for a connection", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "provider_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Mappings listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListGroupRoleMappingsResBody" } } } }, "404": { "description": "Connection not found" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "orgs" ], "description": "Map an external IdP group to a role for this connection", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "provider_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateGroupRoleMappingReqBody" } } }, "required": true }, "responses": { "201": { "description": "Mapping created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GroupRoleMappingView" } } } }, "404": { "description": "Connection not found" }, "409": { "description": "Group already mapped for this connection" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/identity-providers/{provider_id}/group-mappings/{mapping_id}": { "delete": { "tags": [ "orgs" ], "description": "Delete a group-to-role mapping", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "provider_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "mapping_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Deleted" }, "404": { "description": "Not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2": { "get": { "tags": [ "k2" ], "description": "List knowledge bases in an organization", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "page_token", "in": "query", "description": "Page token for pagination", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Knowledge bases listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListK2Response" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "k2" ], "description": "Create a new knowledge base", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateK2Request" } } }, "required": true }, "responses": { "201": { "description": "Knowledge base created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateK2Response" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}": { "get": { "tags": [ "k2" ], "description": "Get knowledge base details", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Knowledge base details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2Detail" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "k2" ], "description": "Delete a knowledge base", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Knowledge base deleted" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "k2" ], "description": "Update a knowledge base.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EditK2Request" } } }, "required": true }, "responses": { "200": { "description": "Updated knowledge base", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2Detail" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/backups": { "get": { "tags": [ "k2" ], "description": "List backups for a knowledge base.", "operationId": "list", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "page_token", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Backup list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListBackupsResponse" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "k2" ], "description": "Create an on-demand backup of a knowledge base.", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateBackupRequest" } } }, "required": true }, "responses": { "201": { "description": "Backup accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KbBackupResponse" } } } }, "409": { "description": "KB is under maintenance or served by another host (no backup row created)" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/backups/{backup_id}": { "get": { "tags": [ "k2" ], "description": "Get a single backup.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "backup_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Backup details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KbBackupResponse" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/directories": { "post": { "tags": [ "k2" ], "description": "Create a virtual directory in the knowledge base", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateK2VirtualDirectoryRequest" } } }, "required": true }, "responses": { "200": { "description": "Folder already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateK2VirtualDirectoryResponse" } } } }, "201": { "description": "Folder created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateK2VirtualDirectoryResponse" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/files": { "get": { "tags": [ "k2" ], "description": "List files and folders in a knowledge base directory.", "operationId": "list", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "page_token", "in": "query", "description": "Page token for pagination", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "directory", "in": "query", "description": "Scope listing to the immediate contents of one folder, like a file browser:\nthe files directly in it plus a folder entry per immediate subfolder (one\nlevel only). Use `\"/\"` for the KB root. Omit to get a flat dump of every\nfile in the knowledge base at all depths. Otherwise a normalized path such\nas `docs/reports`.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "q", "in": "query", "description": "Case-insensitive substring filter on entry name. When set, results are a\nflat recursive search: `directory` scopes the search to that folder's\nsubtree (omit or use `\"/\"` to search the whole knowledge base) and no\nfolder entries are synthesized.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Files listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListK2FilesResponse" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "k2" ], "description": "Add a file to a knowledge base by upload or URL.", "operationId": "add", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "description": "Request body for adding a file to a knowledge base.\n\nProvide either `file` (multipart bytes) or `url` (http/https). Exactly one is required.", "required": [ "metadata" ], "properties": { "directory": { "type": [ "string", "null" ], "description": "Optional subdirectory path within the knowledge base." }, "file": { "type": [ "array", "null" ], "items": { "type": "integer", "format": "int32", "minimum": 0 }, "description": "File bytes (multipart `file` field). Mutually exclusive with `url`.", "contentMediaType": "application/octet-stream" }, "metadata": { "type": "object", "description": "Optional JSON metadata to attach to the file." }, "parse": { "type": [ "boolean", "null" ], "description": "When set, overrides whether the file is parsed and embedded on upload." }, "url": { "type": [ "string", "null" ], "description": "Public http/https URL for the server to fetch and ingest. Mutually exclusive with `file`." } } } } }, "required": true }, "responses": { "201": { "description": "File uploaded", "headers": { "RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Max requests per window for this user." }, "RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Requests left in the current window." }, "RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Seconds until the current window resets." }, "X-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Limit`." }, "X-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Remaining`." }, "X-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Reset`." } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2File" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "429": { "description": "Rate limit exceeded", "headers": { "RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Max requests per window for this user." }, "RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Requests left in the current window." }, "RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Seconds until the current window resets." }, "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds the client should wait before retrying." }, "X-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Limit`." }, "X-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Remaining`." }, "X-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Reset`." } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/files/{file_id}": { "get": { "tags": [ "k2" ], "description": "Get a file with its parsings and embeddings metadata", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "File details with parsings and embeddings", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetK2FileResponse" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "k2" ], "description": "Delete a file from a knowledge base", "operationId": "delete", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "File deleted" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/files/{file_id}/chunks": { "get": { "tags": [ "k2" ], "description": "List chunks for a knowledge base file in document order.", "operationId": "list", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "page_token", "in": "query", "description": "Cursor: pass `next_page_token` from the previous response to fetch\nthe next page. Treat the value as opaque.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "limit", "in": "query", "description": "Page size. Defaults to 100; max 500.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } } ], "responses": { "200": { "description": "Chunks listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListK2ChunksResponse" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "k2" ], "description": "Insert a new chunk into a knowledge base file.", "operationId": "insert", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InsertK2ChunkRequest" } } }, "required": true }, "responses": { "201": { "description": "Chunk inserted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2Chunk" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/files/{file_id}/chunks/{chunk_uid}": { "get": { "tags": [ "k2" ], "description": "Get a single chunk by uid.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "chunk_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Chunk", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2Chunk" } } } }, "404": { "description": "Chunk not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "k2" ], "description": "Delete a chunk from a knowledge base file.", "operationId": "delete", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "chunk_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "204": { "description": "Chunk deleted" }, "404": { "description": "Chunk not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "412": { "description": "Precondition failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "k2" ], "description": "Edit a chunk's content, embedding, or page range.", "operationId": "patch", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "chunk_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PatchK2ChunkRequest" } } }, "required": true }, "responses": { "200": { "description": "Chunk updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2Chunk" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "412": { "description": "Precondition failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/policies": { "get": { "tags": [ "k2" ], "description": "List access-shaping rules authored on a knowledge base.", "operationId": "list", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "table_name", "in": "query", "description": "Restrict to policies that target this exact table.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "enabled", "in": "query", "description": "Restrict to enabled or disabled rules. Omit for both.", "required": false, "schema": { "type": [ "boolean", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "When true, also return soft-deleted rules. Defaults to false.", "required": false, "schema": { "type": "boolean" } }, { "name": "page_token", "in": "query", "description": "Pagination cursor. Pass the previous response's `next_page_token`.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Policies listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListK2PoliciesResponse" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "k2" ], "description": "Author a new access-shaping rule on a knowledge base.", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateK2PolicyRequest" } } }, "required": true }, "responses": { "201": { "description": "Policy created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2Policy" } } } }, "400": { "description": "Invalid policy body", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/policies/governance-mode": { "put": { "tags": [ "k2" ], "description": "Set query-time governance mode for a knowledge base.", "operationId": "put", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetK2GovernanceModeRequest" } } }, "required": true }, "responses": { "200": { "description": "Updated governance mode", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2GovernanceModeResponse" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/policies/{policy_id}": { "get": { "tags": [ "k2" ], "description": "Fetch a single access-shaping rule by id.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Policy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2Policy" } } } }, "404": { "description": "Policy not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "k2" ], "description": "Soft-delete an access-shaping rule on a knowledge base.", "operationId": "delete", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Policy deleted" }, "404": { "description": "Policy not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "412": { "description": "Precondition failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "k2" ], "description": "Update an access-shaping rule on a knowledge base.", "operationId": "patch", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PatchK2PolicyRequest" } } }, "required": true }, "responses": { "200": { "description": "Policy updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2Policy" } } } }, "400": { "description": "Invalid body", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Policy not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "412": { "description": "Precondition failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/policies/{policy_id}/assignments": { "get": { "tags": [ "k2" ], "description": "List role bindings for an access-shaping rule.", "operationId": "list", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "role_id", "in": "query", "description": "Restrict to bindings for this role.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "enabled", "in": "query", "description": "Restrict to enabled or disabled bindings. Omit for both.", "required": false, "schema": { "type": [ "boolean", "null" ] } }, { "name": "include_revoked", "in": "query", "description": "When true, include revoked bindings. Defaults to false.", "required": false, "schema": { "type": "boolean" } }, { "name": "page_token", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Assignments listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListK2PolicyAssignmentsResponse" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "k2" ], "description": "Bind an access-shaping rule to a role.", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateK2PolicyAssignmentRequest" } } }, "required": true }, "responses": { "201": { "description": "Assignment created or re-attached", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2PolicyAssignment" } } } }, "400": { "description": "Invalid binding body", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Policy or role not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/policies/{policy_id}/assignments/{assignment_id}": { "get": { "tags": [ "k2" ], "description": "Fetch a single role binding for an access-shaping rule.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "assignment_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Assignment found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/K2PolicyAssignment" } } } }, "404": { "description": "Assignment not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "k2" ], "description": "Revoke a role binding on an access-shaping rule.", "operationId": "delete", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "assignment_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Assignment revoked" }, "404": { "description": "Assignment not found or already revoked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/query": { "post": { "tags": [ "k2" ], "description": "Execute a SQL query against the knowledge base", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QueryK2Request" } } }, "required": true }, "responses": { "200": { "description": "Query results as JSON", "content": { "application/json": { } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/restores": { "get": { "tags": [ "k2" ], "description": "List restore attempts for a knowledge base.", "operationId": "list", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "page_token", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Restore list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListRestoresResponse" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "k2" ], "description": "Restore a knowledge base from a completed backup.", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateRestoreRequest" } } }, "required": true }, "responses": { "201": { "description": "Restore accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KbRestoreResponse" } } } }, "409": { "description": "KB is already under maintenance (no restore row created)" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/restores/{restore_id}": { "get": { "tags": [ "k2" ], "description": "Get a single restore.", "operationId": "get", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "restore_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Restore details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KbRestoreResponse" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/schema": { "get": { "tags": [ "k2" ], "description": "Get the schema for a knowledge base", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "format", "in": "query", "description": "Response format: \"structured\" (default) or \"sql\"", "required": false, "schema": { "type": "string", "enum": [ "structured", "sql" ] } } ], "responses": { "200": { "description": "Schema", "content": { "application/json": { "schema": { "oneOf": [ { "$ref": "#/components/schemas/K2Schema", "description": "Structured schema with tables, columns, indexes, and constraints (default)" }, { "$ref": "#/components/schemas/K2SchemaSql", "description": "SQL DDL statements (CREATE TABLE, CREATE INDEX, etc.)" } ], "description": "Response for the schema endpoint — structured (default) or SQL DDL." } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/k2/{kb_id}/upload": { "post": { "tags": [ "k2" ], "description": "Upload a data file into a knowledge base.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "kb_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "description": "Multipart form with a file upload or a remote URL.", "content": { "multipart/form-data": { } } }, "responses": { "200": { "description": "Upload result", "headers": { "RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Max requests per window for this user." }, "RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Requests left in the current window." }, "RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Seconds until the current window resets." }, "X-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Limit`." }, "X-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Remaining`." }, "X-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Reset`." } }, "content": { "application/json": { } } }, "429": { "description": "Rate limit exceeded", "headers": { "RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Max requests per window for this user." }, "RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Requests left in the current window." }, "RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Seconds until the current window resets." }, "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds the client should wait before retrying." }, "X-RateLimit-Limit": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Limit`." }, "X-RateLimit-Remaining": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Remaining`." }, "X-RateLimit-Reset": { "schema": { "type": "integer" }, "description": "Legacy alias of `RateLimit-Reset`." } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/metrics": { "get": { "tags": [ "alarms" ], "summary": "Query a metric series", "description": "Time-bucketed count/sum/avg/min/max for one metric, with optional dimension filters.\n\nNeeds `analytics.read` for an unrestricted query. Passing `project_id` also accepts `projects.alarms.read` on that project, so a project-scoped role can read the series behind its own alarms.", "operationId": "get_org_metrics", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "name", "in": "query", "description": "Metric to read, e.g. `app.run.errors`, `deployment.health`.", "required": true, "schema": { "type": "string" } }, { "name": "period_seconds", "in": "query", "description": "Bucket size in seconds (multiple of 60). Default 60.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int32" } }, { "name": "from", "in": "query", "description": "Inclusive range start (epoch milliseconds). Default: 100 buckets before `to`.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "to", "in": "query", "description": "Exclusive range end (epoch milliseconds). Default: now.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "project_id", "in": "query", "description": "Filter to one project. Omit to aggregate across projects.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "project_env_id", "in": "query", "description": "Filter to one environment.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "deployment_id", "in": "query", "description": "Filter to one deployment.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "workforce_id", "in": "query", "description": "Filter to one agent/workflow app (`OrgsApps.id`).", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "label", "in": "query", "description": "Filter to one label — the span name behind a trace-derived metric\n(`llm`, `get_address`). Omit to sum across every label.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Metric series", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgMetricsResBody" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/metrics/catalog": { "get": { "tags": [ "alarms" ], "summary": "List observed metrics", "description": "Metric names and label values actually recorded for this org in the recent past. Use it to populate a metric picker: `GET /orgs/{org_id}/metrics` requires a name, and alarms reference names that only exist once something has emitted them.\n\n`origin` separates the two kinds: `system` metrics (`app.*`, `deployment.*`, `org.*`) are emitted by the platform and have no configuration, while `custom` ones come from a metric definition — see `definition_ids` for the config behind them.\n\nThis reports what is *flowing*, not what is configured, so the two can disagree in both directions: a definition that has never matched a span will not appear, and a deleted definition's series stays until its bins age out.\n\nNeeds `analytics.read` for the org-wide catalog. Passing `project_id` narrows it to series carrying that project's dimension and accepts `projects.alarms.read` there instead, so a project-scoped role gets a working metric picker. That view omits series with no project dimension, `org.credits.*` among them — which are org-level metrics that caller cannot alarm on anyway.", "operationId": "get_org_metrics_catalog", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "hours", "in": "query", "description": "How far back to look for observed metrics. Default 24, max 720.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "project_id", "in": "query", "description": "Only metrics carrying this project's dimension. Also lowers the\npermission needed from `analytics.read` to `projects.alarms.read` on\nthis project.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Observed metrics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgMetricsCatalogResBody" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/metrics/definitions": { "get": { "tags": [ "alarms" ], "summary": "List custom metric definitions", "description": "The org's custom metric definitions and their current predicates.\n\n`project_id` filters to what is *in effect* for that project, which includes org-wide definitions (those with no `project_id`) since they run against that project's runs too.\n\nThis lists configuration, not data. A definition that has never matched a span appears here but not in `GET /orgs/{org_id}/metrics/catalog`.\n\nFiltered per definition the same way `GET /orgs/{org_id}/alarms` is: org-wide definitions need `alarms.read`, project ones need `projects.alarms.read` on the owner. So a project-scoped caller sees their own definitions but not the org-wide ones that also run against their runs, even with `project_id` set.", "operationId": "list_org_metric_definitions", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "query", "description": "Only definitions in effect for this project. Omit for every definition\nin the org.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "List of definitions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMetricDefinitionsResBody" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "alarms" ], "summary": "Define a custom metric", "description": "Define a metric of your own, emitted as runs land. Once it exists it behaves like any platform metric: readable through `GET /orgs/{org_id}/metrics`, listed in the catalog with `origin: custom`, and alarmable with no extra setup.\n\nThe definition is a span predicate over each completed run's trace. Span paths are `{workforce}.{step}` and matching is on the **leaf**: use `llm` or `get_address`, not the full path. Predicate fields AND together and all are optional — omitting every one matches every non-root span.\n\n`metric_name` is forced under the reserved `trace.` prefix so a definition cannot shadow a platform series. Set `label_source` to `span_name` to break the metric out per step, then point an alarm at a single step with `dims.label`.\n\nDefinitions are **not retroactive**: matching happens as runs arrive, so a new definition only sees traces written after it. Dry-run it against stored traces first with `POST /orgs/{org_id}/metrics/definitions/preview`. Note also that only sum/count/avg/min/max are available on the result — percentiles are not derivable from metric bins.\n\nSet `project_id` to scope the definition to one project, which also makes it editable by holders of `projects.alarms.manage` there. Leaving it out defines an org-wide metric that runs against every project's traces, and needs `alarms.manage`.", "operationId": "create_org_metric_definition", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateMetricDefinitionReq" }, "examples": { "Failing tool calls, per tool": { "value": { "name": "Tool errors", "metric_name": "tool_errors", "has_error": true, "value_source": "count", "label_source": "span_name" } }, "Output token burn on LLM spans": { "value": { "name": "Output tokens", "metric_name": "output_tokens", "span_name": "llm", "value_source": "usage:output_text_tokens" } }, "Slow retrieval steps": { "value": { "name": "Slow lookups", "metric_name": "slow_lookup_ms", "span_name_prefix": "get_", "min_duration_ms": 2000, "value_source": "duration_ms", "label_source": "span_name" } } } } }, "required": true }, "responses": { "201": { "description": "Definition created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MetricDefinitionOut" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/metrics/definitions/preview": { "post": { "tags": [ "alarms" ], "summary": "Dry-run a custom metric definition", "description": "Run a candidate predicate against recent stored traces without saving it, and see what it would have recorded.\n\nDefinitions are not retroactive, so a saved predicate that matches nothing looks identical to one that matches nothing *yet*. This answers that before you commit: which spans matched, what values they'd contribute, and how many distinct labels the metric would carry.\n\nSamples the newest runs (20 by default, 50 max) — enough to tell a working predicate from a broken one, not a measurement of the true rate. Pass `workforce_id` to make the sample representative of the agent you're actually matching. This is the only endpoint that reads stored traces, which is why it is capped; do not poll it.\n\nBecause it returns trace content, `project_id` doubles as the permission target: omit it and the sample spans the whole org, which needs `alarms.manage`; set it and the sample is capped to that project, which needs `projects.alarms.manage` there. A caller scoped to one project must therefore pass it.", "operationId": "preview_org_metric_definition", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PreviewMetricDefinitionReq" }, "examples": { "Per-step latency": { "value": { "workforce_id": "42", "value_source": "duration_ms", "label_source": "span_name" } }, "Which tools are failing": { "value": { "workforce_id": "42", "has_error": true, "value_source": "count", "label_source": "span_name" } } } } }, "required": true }, "responses": { "200": { "description": "What the definition would record", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PreviewMetricDefinitionOut" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/metrics/definitions/{definition_id}": { "delete": { "tags": [ "alarms" ], "summary": "Delete a custom metric definition", "description": "Stop emitting a custom metric. Takes effect within one flush interval (~10s).\n\nBins the definition already wrote are kept — they are real observations — and age out with normal metric retention, so the series stays readable and keeps appearing in the catalog for a while with no definition behind it. Alarms pointing at the metric are left alone and will fall to `insufficient_data` once the series stops.\n\nNeeds `alarms.manage` for an org-wide definition, or `projects.alarms.manage` on the owning project for a project one.", "operationId": "delete_org_metric_definition", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "definition_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Definition deleted", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "alarms" ], "summary": "Rename or enable/disable a custom metric definition", "description": "Only the name and the enabled flag are mutable. The predicate and destination metric are fixed at creation: changing them would splice two different meanings into one series with nothing marking the seam, so a changed definition should be a new definition.\n\nDisabling stops new observations within one flush interval (~10s). Bins already written stay and age out with normal metric retention.\n\nThe owning project is not mutable either, so the permission needed here is fixed: `alarms.manage` for an org-wide definition, `projects.alarms.manage` on the owner for a project one.", "operationId": "update_org_metric_definition", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "definition_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMetricDefinitionReq" } } }, "required": true }, "responses": { "204": { "description": "Definition updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/models/policies": { "get": { "tags": [ "orgs" ], "summary": "List model policies", "description": "List the organization's LLM model and provider usage policies.", "operationId": "list_org_model_policies", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Policy rules for the org", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListOrgModelPoliciesResBody" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "orgs" ], "summary": "Create a model policy", "description": "Create a rule restricting which LLM providers or models the organization can use.", "operationId": "create_org_model_policy", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateModelPolicyBody" }, "examples": { "Disable a provider": { "value": { "provider": "byteplus" } }, "Disable one model": { "value": { "provider": "openai", "model_id": "gpt-5", "effect": "deny" } }, "Re-allow one model of a disabled provider": { "value": { "provider": "byteplus", "model_id": "seed-2-0-pro-260215", "effect": "allow" } } } } }, "required": true }, "responses": { "201": { "description": "Policy rule created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelPolicy" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "409": { "description": "Rule already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/models/policies/{policy_id}": { "delete": { "tags": [ "orgs" ], "summary": "Delete a model policy", "description": "Delete an LLM model or provider policy rule from the organization.", "operationId": "delete_org_model_policy", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Policy rule deleted", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/photo": { "put": { "tags": [ "orgs" ], "description": "Upload and set the organization's logo.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "description": "Multipart form schema for the OpenAPI doc only (the handler reads the raw\n`file` part directly).", "required": [ "file" ], "properties": { "file": { "type": "array", "items": { "type": "integer", "format": "int32", "minimum": 0 }, "description": "Org logo bytes. Must be an image; the type is detected from the file\ncontent, not the filename or declared content type.", "contentMediaType": "application/octet-stream" } } } } }, "required": true }, "responses": { "200": { "description": "Org logo updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateOrgPhotoResBody" } } } }, "400": { "description": "Missing file or unsupported image type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } }, "413": { "description": "Image too large", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "orgs" ], "description": "Clear the organization's logo.", "operationId": "delete", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Org logo cleared", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorMessage" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects": { "get": { "tags": [ "projects" ], "description": "List projects in an organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "view", "in": "query", "description": "Response detail level: \"list\" (default) returns a lightweight preview, \"full\" returns all project details", "required": false, "schema": { "type": "string", "enum": [ "list", "full" ] } } ], "responses": { "200": { "description": "Projects listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListProjectsResBody" } } } }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "projects" ], "description": "Create a new project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectReqBody" } } }, "required": true }, "responses": { "200": { "description": "Project created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectResBody" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}": { "get": { "tags": [ "projects" ], "description": "Get a project by ID.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Project details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectDetail" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "projects" ], "description": "Delete a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Project deleted" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "projects" ], "description": "Edit project metadata.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EditProjectReqBody" } } }, "required": true }, "responses": { "204": { "description": "Project updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "400": { "description": "Validation failed" }, "403": { "description": "Insufficient permissions" }, "422": { "description": "Name conflicts with an existing project" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/analytics/credits": { "get": { "tags": [ "analytics" ], "description": "Time-binned credits and USD cost breakdown for a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "group_by", "in": "query", "description": "Bucket size for aggregation (`minute`, `hour`, or `day`).", "required": false, "schema": { "$ref": "#/components/schemas/BinSize" } }, { "name": "from", "in": "query", "description": "Inclusive range start (epoch milliseconds). Defaults: 1h / 1d / 30d before `to` by `group_by`.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "to", "in": "query", "description": "Exclusive range end (epoch milliseconds). Defaults to now.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "user_id", "in": "query", "description": "Restrict to a specific user’s runs.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Credits analytics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectAnalyticsCreditsBody" } } } }, "400": { "description": "Bad request" }, "403": { "description": "Forbidden" }, "500": { "description": "Error" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/analytics/usage": { "get": { "tags": [ "analytics" ], "description": "Time-binned run counts, user counts, and duration percentiles for a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "group_by", "in": "query", "description": "Bucket size for aggregation (`minute`, `hour`, or `day`).", "required": false, "schema": { "$ref": "#/components/schemas/BinSize" } }, { "name": "from", "in": "query", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "to", "in": "query", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "user_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage analytics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectAnalyticsUsageBody" } } } }, "400": { "description": "Bad request" }, "403": { "description": "Forbidden" }, "500": { "description": "Error" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/analytics/users": { "get": { "tags": [ "analytics" ], "description": "Per-user run counts and project-attributed spend aggregates for a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "from", "in": "query", "description": "Inclusive range start (epoch milliseconds).", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "to", "in": "query", "description": "Exclusive range end (epoch milliseconds).", "required": true, "schema": { "type": "integer", "format": "int64" } }, { "name": "user_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "page_token", "in": "query", "description": "Opaque offset for the next page (from the previous response’s `next_page_token`).", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "User analytics page", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectAnalyticsUsersBody" } } } }, "403": { "description": "Forbidden" }, "500": { "description": "Error" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/auth": { "get": { "tags": [ "projects" ], "description": "Get app sign-in settings for a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "App auth settings", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectAuthSettings" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "projects" ], "description": "Toggle app sign-in for a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PatchAuthSettingsReqBody" } } }, "required": true }, "responses": { "204": { "description": "Settings updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/auth/providers/{provider}": { "put": { "tags": [ "projects" ], "description": "Enable, disable, or configure an app sign-in provider.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "provider", "in": "path", "description": "Sign-in method key (for example `email`, `google`, `microsoft`, `github`).", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PutAuthProviderReqBody" } } }, "required": true }, "responses": { "204": { "description": "Provider updated", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "400": { "description": "Unknown provider key" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/channels/{workforce}/{provider}": { "put": { "tags": [ "projects" ], "description": "Connect or update a messaging channel binding. Upserts on (workforce, provider); `credentials` is write-only — omit to keep the stored secrets, `null` to clear them, an object to replace them.", "operationId": "put", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component ref: manifest uid (canonical), numeric app id, or\nname — the server canonicalizes to the manifest uid.", "required": true, "schema": { "type": "string" } }, { "name": "provider", "in": "path", "description": "Channel provider key (for example `telegram`, `slack`).", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PutChannelReqBody" } } }, "required": true }, "responses": { "204": { "description": "Channel binding saved", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "400": { "description": "Unknown workforce or invalid credentials" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "projects" ], "description": "Disconnect a messaging channel binding, discarding its stored credentials.", "operationId": "delete", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component ref: manifest uid (canonical), numeric app id, or\nname — the server canonicalizes to the manifest uid.", "required": true, "schema": { "type": "string" } }, { "name": "provider", "in": "path", "description": "Channel provider key (for example `telegram`, `slack`).", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Channel binding removed", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Insufficient permissions" }, "404": { "description": "No such channel binding" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/duplicate": { "post": { "tags": [ "projects" ], "description": "Duplicate a project, copying its code and knowledge base structure.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DuplicateProjectReqBody" } } }, "required": true }, "responses": { "200": { "description": "Project duplicated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectResBody" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs": { "get": { "tags": [ "projects" ], "description": "List environments for a project with resolved per-component deploy config.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Environments listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListEnvsResBody" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "projects" ], "description": "Create a new environment for a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateEnvReqBody" } } }, "required": true }, "responses": { "201": { "description": "Environment created successfully" }, "400": { "description": "Invalid branch name or project has no repository" }, "403": { "description": "Insufficient permissions" }, "409": { "description": "Environment with that name already exists" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}": { "delete": { "tags": [ "projects" ], "description": "Delete an environment.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Environment deleted successfully" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/branch": { "patch": { "tags": [ "projects" ], "description": "Set or clear the source branch for an environment.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetEnvBranchReqBody" } } }, "required": true }, "responses": { "200": { "description": "Branch updated successfully" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/config": { "patch": { "tags": [ "projects" ], "description": "Update deploy configuration for an environment, including per-component overrides.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateEnvConfigReqBody" } } }, "required": true }, "responses": { "200": { "description": "Configuration updated successfully" }, "400": { "description": "Invalid component key or configuration value" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/deploy": { "post": { "tags": [ "projects" ], "description": "Deploy an environment to a revision.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeployEnvReqBody" } } }, "required": true }, "responses": { "202": { "description": "Deployment initiated" }, "400": { "description": "Rev does not exist in the project repo" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/deployments": { "get": { "tags": [ "projects" ], "description": "List deployments for an environment.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "component_id", "in": "query", "description": "Filter to a single workforce component by its numeric app id\n(the value the SDK reads from `TIMBAL_APP_ID`, also returned\nas `id` on each deployment in the response). Combines with\n`component_uid`: when both are set, rows must match both.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "component_uid", "in": "query", "description": "Filter to a single workforce component by its manifest uid\n(the `_id` field in `timbal.yaml`, also returned as `uid` on\neach deployment in the response). Display name is\ndeliberately not accepted as a filter — it's user-editable\nand not guaranteed unique within a project.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "status", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "trigger", "in": "query", "description": "Optional trigger filter. Accepts:\n * `latest` — return every row sharing the most recent\n trigger for this env; falls back to the latest row per\n component when the env has no trigger history.\n * a UUID — return every row produced by that trigger.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Deployments listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListDeploymentsResBody" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/domain": { "patch": { "tags": [ "projects" ], "description": "Attach, replace, or detach a custom domain for an environment.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetEnvDomainReqBody" } } }, "required": true }, "responses": { "200": { "description": "Domain updated successfully" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/evals/definitions": { "get": { "tags": [ "projects" ], "description": "List eval definitions (test cases from evals/*.yaml) per workforce component. Reads the env branch's worktree by default; pass ?rev= to read from git.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git rev to read definitions from (branch, tag, or SHA). When set,\ndefinitions come from git at that rev instead of the worktree.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "component_id", "in": "query", "description": "Filter to a single workforce component by its numeric app id\n(returned as `component_id`). Combines with `component_uid`: when\nboth are set, components must match both.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "component_uid", "in": "query", "description": "Filter to a single workforce component by its manifest uid (the\n`_id` field in `timbal.yaml`, returned as `component_uid`).", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Eval definitions listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListEvalDefinitionsResBody" } } } }, "400": { "description": "Unknown rev" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/evals/jobs": { "get": { "tags": [ "projects" ], "description": "List eval jobs (background eval generation) for an env, most recent first.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "component_id", "in": "query", "description": "Filter to one workforce component by its numeric app id.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "limit", "in": "query", "description": "Max rows to return (clamped to 200). Defaults to 50.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } } ], "responses": { "200": { "description": "Jobs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListEvalJobsResBody" } } } }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Environment not found" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "projects" ], "description": "Enqueue a background eval job (today: generate_initial — Claude-generate an initial eval suite for a workforce component, written to the env branch's worktree).", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnqueueEvalJobReqBody" } } }, "required": true }, "responses": { "202": { "description": "Job enqueued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EnqueueEvalJobResBody" } } } }, "400": { "description": "Missing component selector or unknown kind" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Component not found" }, "409": { "description": "Component already has a live eval job in this env" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/evals/jobs/{job_uid}": { "get": { "tags": [ "projects" ], "description": "Get a single eval job by uid.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "job_uid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Job", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EvalJobView" } } } }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Job not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/evals/runs": { "get": { "tags": [ "projects" ], "description": "List eval runs (deploy-gate and manual executions) for an environment.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "component_id", "in": "query", "description": "Filter to a single workforce component by its numeric app id\n(the value the SDK reads from `TIMBAL_APP_ID`, also returned as\n`component.id` on each run). Combines with `component_uid`: when\nboth are set, rows must match both.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "component_uid", "in": "query", "description": "Filter to a single workforce component by its manifest uid (the\n`_id` field in `timbal.yaml`, also returned as `component.uid` on\neach run). Display name is deliberately not accepted as a filter\n— it's user-editable and not guaranteed unique within a project.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "trigger", "in": "query", "description": "Optional trigger filter. Accepts:\n * `latest` — runs from the env's most recent deploy batch.\n * a UUID — runs from that deploy batch.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "trigger_type", "in": "query", "description": "Filter by what started the run: `deploy` (gate), `manual`\n(`POST .../evals/runs`), or `push` (`deploy_config.evals_on_push`\nCI runs). Orthogonal to `trigger` (a deploy-batch selector).", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "status", "in": "query", "description": "Filter by run status: `running`, `passed`, `failed`, or `error`.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_logs", "in": "query", "description": "Include the captured CLI stdout/stderr in each run. Off by\ndefault — logs can be hundreds of KB per run.", "required": false, "schema": { "type": "boolean" } }, { "name": "include_results", "in": "query", "description": "Include the structured per-eval results document in each run.\nOff by default for the same size reason as `include_logs`; the\nsingle-run GET always returns it.", "required": false, "schema": { "type": "boolean" } }, { "name": "limit", "in": "query", "description": "Max rows returned, newest first. Defaults to 50, capped at 200.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } } ], "responses": { "200": { "description": "Eval runs listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListEvalRunsResBody" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "projects" ], "description": "Manually run evals for a workforce component (no deploy). Defaults to the env worktree so uncommitted evals are included; pass source=git for a clean extract.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RunEvalsReqBody" } } }, "required": true }, "responses": { "202": { "description": "Eval run started", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RunEvalsResBody" } } } }, "400": { "description": "Missing component filter, bad source/rev combo, or unknown rev" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Component not found (in the project, worktree, or at the rev)" }, "422": { "description": "Component has no eval files under evals/" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/evals/runs/{eval_run_id}": { "get": { "tags": [ "projects" ], "description": "Get a single eval run, including its logs.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "eval_run_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Eval run fetched successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EvalRunDetail" } } } }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Eval run not found" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "projects" ], "description": "Delete an eval run from the history. Running runs cannot be deleted.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "eval_run_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Eval run deleted" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Eval run not found" }, "422": { "description": "Eval run is still running" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/evals/runs/{eval_run_id}/events": { "get": { "tags": [ "projects" ], "description": "Stream an in-flight eval run's JSONL events (cursor + long-poll). On `expired: true`, fall back to the single-run GET.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "eval_run_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "after", "in": "query", "description": "Last seen `seq` (exclusive). Default `0` = from the start.", "required": false, "schema": { "type": "integer", "format": "int64", "minimum": 0 } }, { "name": "limit", "in": "query", "description": "Max events per response (clamped to 1..=2000). Default 500.", "required": false, "schema": { "type": [ "integer", "null" ], "minimum": 0 } }, { "name": "wait_ms", "in": "query", "description": "Long-poll timeout in ms (clamped to 0..=30000). Default 0 (return\nimmediately). When \u003E0 and nothing is available past `after`, the\nrequest blocks until a new event arrives, the run completes, or\nthe timeout elapses.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64", "minimum": 0 } } ], "responses": { "200": { "description": "Event batch", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EvalRunEventsResponse" } } } }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Eval run not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/logs": { "get": { "tags": [ "projects" ], "description": "Fetch runtime logs for a deployed project component.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "component", "in": "query", "description": "Which component's logs to fetch. Shared vocabulary with\n`GET /preview/logs` (which 501s on `workforce`). `workforce`\nhere covers agent and workflow components interchangeably.\nResolves to the component's most recent deployment. Mutually\nexclusive with `deployment_id`; exactly one of the two must be\nprovided.", "required": false, "schema": { "oneOf": [ { "type": "null" }, { "type": "string", "description": "Routing selector for the deployable units a Timbal project owns:\nthe project-level frontend (`Ui`), the project-level backend (`Api`),\nand the N workforce components (`Workforce`, keyed on\n`manifest_id`).\n\nUsed as a `?component=` query parameter on every surface that acts\non one component at a time (`GET /preview/logs`,\n`GET /envs/{env}/logs`, etc.). Wire values are lowercase\n(`ui`/`api`/`workforce`). Surfaces that don't apply to a given\nvariant (e.g. previews don't run workforce components today) reject\nwith `501 NotImplemented` instead of forking the schema — clients\nrely on a single shared vocabulary.\n\nDistinct from [`AppType`], which is a **type discriminator** on\nworkforce rows (`Agent` vs `Workflow`) carried in response payloads.\n`ProjectComponent` collapses both into `Workforce` because every\nsurface that *selects* a workforce component keys on `manifest_id`,\nnot on the Agent-vs-Workflow distinction (the underlying log\npipeline, deployment shape, etc. are identical for both). Use\n[`From\u003CAppType\u003E`] to bridge: any workforce type — including the\nforward-compat `AppType::Unknown` catch-all — maps to\n`ProjectComponent::Workforce`.", "enum": [ "ui", "api", "workforce" ] } ] } }, { "name": "deployment_id", "in": "query", "description": "Fetch logs for one specific deployment (the `id` field in the\ndeployments-list response) instead of the component's latest.\nLets you read the runtime output of a failed or superseded\ndeployment post-mortem. Mutually exclusive with `component`.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "component_id", "in": "query", "description": "Numeric workforce app id (the value the SDK reads from\n`TIMBAL_APP_ID`, also returned as `id` on each deployment in\nthe deployments-list response). XOR with `component_uid`\nwhen `component=workforce`; forbidden for `ui` / `api`.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "component_uid", "in": "query", "description": "Workforce manifest uid (the `_id` field in `timbal.yaml`,\nalso returned as `uid` on each deployment in the\ndeployments-list response). XOR with `component_id`.\nDisplay name is deliberately not accepted as a selector —\nit's user-editable and not guaranteed unique within a\nproject.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "start_time", "in": "query", "description": "ms since epoch. Defaults to `end_time - 1h`.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "end_time", "in": "query", "description": "ms since epoch. Defaults to now.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "limit", "in": "query", "description": "Defaults to 50.", "required": false, "schema": { "type": [ "integer", "null" ], "minimum": 0 } }, { "name": "page_token", "in": "query", "description": "Pagination cursor from a prior response. Returned only when\ncursor-based pagination is available for the component's\nruntime; ignored otherwise.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Logs fetched", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Response" } } } }, "400": { "description": "Bad request" }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/metrics/{metric_type}": { "get": { "tags": [ "projects" ], "description": "Query runtime metrics for an environment.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "metric_type", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/MetricType" } }, { "name": "start_time", "in": "query", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "end_time", "in": "query", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } } ], "responses": { "200": { "description": "Metrics data" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/envs/{env_id}/stop": { "post": { "tags": [ "projects" ], "description": "Stop a running environment.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "202": { "description": "Stop initiated" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/k2": { "put": { "tags": [ "projects" ], "description": "Link a knowledge base to a project.", "operationId": "put", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkKbRequest" } } }, "required": true }, "responses": { "200": { "description": "Knowledge base linked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KbPreview" } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Knowledge base not found" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "projects" ], "description": "Unlink the knowledge base from a project.", "operationId": "delete", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Knowledge base unlinked" }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/runs": { "get": { "tags": [ "runs" ], "description": "List runs for a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "user_id", "in": "query", "description": "Filter runs by user ID", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "status", "in": "query", "description": "Filter runs by status", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "sentiment", "in": "query", "description": "Filter runs by sentiment", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "group_id", "in": "query", "description": "Filter runs by group ID", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "workforce_id", "in": "query", "description": "Filter runs by workforce ID", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "rev", "in": "query", "description": "Filter runs by the git branch they were executed against (e.g. `main`).\nRuns without a recorded branch are always included for backwards\ncompatibility with rows created before this field was tracked.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "from", "in": "query", "description": "Filter runs by start time (epoch timestamp in milliseconds)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" }, "example": 1729540800000 }, { "name": "to", "in": "query", "description": "Filter runs by end time (epoch timestamp in milliseconds)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" }, "example": 1729627200000 }, { "name": "metadata", "in": "query", "description": "Filter runs by metadata", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "roots", "in": "query", "description": "When `true`, return only thread roots (runs that start a conversation, i.e.\nhave no parent). For a root run, `group_id` equals its own `id`.", "required": false, "schema": { "type": "boolean" } }, { "name": "sort_by", "in": "query", "description": "Sort field (`id`, `created_at`, `duration_ms`, `cost_usd`, `cost_credits`)", "required": false, "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/RunSortBy" } ] } }, { "name": "sort_order", "in": "query", "description": "Sort direction (`asc` or `desc`; default `desc`)", "required": false, "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SortOrder" } ] } }, { "name": "page_token", "in": "query", "description": "Page token", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Runs listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListRunsResBody" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/runs/{run_id}": { "get": { "tags": [ "runs" ], "description": "Get a single project run by id or idempotency key.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "run_id", "in": "path", "description": "Platform run id or idempotency key.", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Run details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RunDetail" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/runs/{run_id}/reactions": { "get": { "tags": [ "runs" ], "description": "List reactions on a project run.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "run_id", "in": "path", "description": "Platform run id or idempotency key.", "required": true, "schema": { "type": "string" } }, { "name": "page_token", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Reactions listed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListReactionsResBody" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "runs" ], "description": "Add a reaction to a project run.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "run_id", "in": "path", "description": "Platform run id or idempotency key.", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewReactionReqBody" } } }, "required": true }, "responses": { "204": { "description": "Reaction created" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/vars": { "get": { "tags": [ "projects" ], "description": "List variables for a project.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "env_ids", "in": "query", "description": "Comma-separated list of environment IDs to filter by", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Variables listed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListVarsResBody" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "projects" ], "description": "Create a project variable.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateVarReqBody" } } }, "required": true }, "responses": { "201": { "description": "Variable created successfully" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/vars/batch": { "post": { "tags": [ "projects" ], "description": "Batch create project variables.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BatchCreateVarsReqBody" } } }, "required": true }, "responses": { "201": { "description": "Variables created successfully" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/vars/{var_id}": { "get": { "tags": [ "projects" ], "description": "Get a project variable by ID.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "var_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Variable details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Var" } } } }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "projects" ], "description": "Delete a project variable.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "var_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Variable deleted successfully" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "projects" ], "description": "Update a project variable.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "var_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateVarReqBody" } } }, "required": true }, "responses": { "204": { "description": "Variable updated successfully" }, "403": { "description": "Insufficient permissions" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/workforce": { "get": { "tags": [ "projects" ], "description": "List workforce components on a branch revision.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of workforce items", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListWorkforceResBody" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "projects" ], "description": "Create a workforce component on a branch revision.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWorkforceReqBody" } } }, "required": true }, "responses": { "201": { "description": "Workforce component created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWorkforceResponse" } } } } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "projects" ], "description": "Delete a workforce component on a branch revision.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeleteWorkforceReqBody" } } }, "required": true }, "responses": { "204": { "description": "Workforce component deleted", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/workforce/{workforce}/ace": { "put": { "tags": [ "ace" ], "description": "Link an existing ACE to a workforce component.", "operationId": "link", "parameters": [ { "name": "org_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "description": "Project id", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component: numeric id, manifest UUID, or name", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkAceReqBody" } } }, "required": true }, "responses": { "204": { "description": "ACE linked", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Forbidden" }, "404": { "description": "ACE or workforce not found" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "ace" ], "description": "Create an empty ACE (ready, empty playbook) and link it to a workforce component. Does not trigger playbook generation.", "operationId": "create", "parameters": [ { "name": "org_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "description": "Project id", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component: numeric id, manifest UUID, or name", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "responses": { "201": { "description": "Empty ACE created and linked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAceResBody" } } } }, "400": { "description": "Bad request" }, "403": { "description": "Forbidden" }, "404": { "description": "Workforce not found" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "ace" ], "description": "Detach the ACE linked to a workforce component.", "operationId": "unlink", "parameters": [ { "name": "org_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "description": "Project id", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component: numeric id, manifest UUID, or name", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "ACE unlinked", "content": { "application/json": { "schema": { "type": "null", "description": "Successful responses use HTTP 204 and do not include a body." } } } }, "403": { "description": "Forbidden" }, "404": { "description": "Workforce not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/projects/{project_id}/workforce/{workforce}/{*path}": { "get": { "tags": [ "projects" ], "description": "Proxy HTTP requests to a deployed workforce component.", "operationId": "workforce_proxy_get", "parameters": [ { "name": "org_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "description": "Project id", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component: numeric id, manifest UUID, or name", "required": true, "schema": { "type": "string" } }, { "name": "path", "in": "path", "description": "Sub-path on the deployment server.", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Response from the workforce deployment" }, "404": { "description": "No running deployment found for this component on this branch" }, "502": { "description": "Bad gateway" }, "504": { "description": "Gateway timeout" } }, "security": [ { "bearer_auth": [] } ] }, "put": { "tags": [ "projects" ], "description": "Proxy HTTP requests to a deployed workforce component.", "operationId": "workforce_proxy_put", "parameters": [ { "name": "org_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "description": "Project id", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component: numeric id, manifest UUID, or name", "required": true, "schema": { "type": "string" } }, { "name": "path", "in": "path", "description": "Sub-path on the deployment server.", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Response from the workforce deployment" }, "404": { "description": "No running deployment found for this component on this branch" }, "502": { "description": "Bad gateway" }, "504": { "description": "Gateway timeout" } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "projects" ], "description": "Proxy HTTP requests to a deployed workforce component.", "operationId": "workforce_proxy_post", "parameters": [ { "name": "org_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "description": "Project id", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component: numeric id, manifest UUID, or name", "required": true, "schema": { "type": "string" } }, { "name": "path", "in": "path", "description": "Sub-path on the deployment server.", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Response from the workforce deployment" }, "404": { "description": "No running deployment found for this component on this branch" }, "502": { "description": "Bad gateway" }, "504": { "description": "Gateway timeout" } }, "security": [ { "bearer_auth": [] } ] }, "delete": { "tags": [ "projects" ], "description": "Proxy HTTP requests to a deployed workforce component.", "operationId": "workforce_proxy_delete", "parameters": [ { "name": "org_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "description": "Project id", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component: numeric id, manifest UUID, or name", "required": true, "schema": { "type": "string" } }, { "name": "path", "in": "path", "description": "Sub-path on the deployment server.", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Response from the workforce deployment" }, "404": { "description": "No running deployment found for this component on this branch" }, "502": { "description": "Bad gateway" }, "504": { "description": "Gateway timeout" } }, "security": [ { "bearer_auth": [] } ] }, "patch": { "tags": [ "projects" ], "description": "Proxy HTTP requests to a deployed workforce component.", "operationId": "workforce_proxy_patch", "parameters": [ { "name": "org_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string" } }, { "name": "project_id", "in": "path", "description": "Project id", "required": true, "schema": { "type": "string" } }, { "name": "workforce", "in": "path", "description": "Workforce component: numeric id, manifest UUID, or name", "required": true, "schema": { "type": "string" } }, { "name": "path", "in": "path", "description": "Sub-path on the deployment server.", "required": true, "schema": { "type": "string" } }, { "name": "rev", "in": "query", "description": "Git branch name (for example `main`).", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Response from the workforce deployment" }, "404": { "description": "No running deployment found for this component on this branch" }, "502": { "description": "Bad gateway" }, "504": { "description": "Gateway timeout" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/scim-tokens": { "get": { "tags": [ "orgs" ], "description": "List SCIM tokens for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SCIM tokens", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListScimTokensResBody" } } } } }, "security": [ { "bearer_auth": [] } ] }, "post": { "tags": [ "orgs" ], "description": "Create a SCIM bearer token for the organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateScimTokenReqBody" } } }, "required": true }, "responses": { "201": { "description": "Token created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateScimTokenResBody" } } } } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/scim-tokens/{token_id}": { "delete": { "tags": [ "orgs" ], "description": "Revoke a SCIM token", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "token_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Token revoked" }, "404": { "description": "Token not found" } }, "security": [ { "bearer_auth": [] } ] } }, "/orgs/{org_id}/templates": { "get": { "tags": [ "templates" ], "description": "Public project template catalog available to this organization.", "operationId": "handler", "parameters": [ { "name": "org_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Published public project templates", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListTemplatesResBody" } } } }, "403": { "description": "Forbidden" } }, "security": [ { "bearer_auth": [] } ] } } }, "components": { "schemas": { "AccessAttribution": { "type": "object", "description": "Attribution for one allowed action: which role attachment contributed\nthe matching allow grant.\n\nSame shape as [`GrantAttribution`] plus the attachment's expiry —\n\"has access until Friday\" and \"has access\" are different findings in\nan access review.", "required": [ "role_id", "role_name" ], "properties": { "attachment_scope": { "type": [ "string", "null" ], "description": "Attachment-level scope in effect, or null when unscoped." }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the contributing role attachment expires, or null if permanent." }, "grant_resource": { "type": [ "string", "null" ], "description": "Resource pattern as authored on the role, pre-scope-intersection." }, "role_id": { "type": "string" }, "role_name": { "type": "string" } } }, "AceJobView": { "type": "object", "description": "Public view of a background job against an ACE.", "required": [ "uid", "kind", "status", "iteration_count", "tool_call_count", "queued_at" ], "properties": { "completed_at": { "type": [ "string", "null" ], "format": "date-time" }, "duration_ms": { "type": [ "integer", "null" ], "format": "int64" }, "error_message": { "type": [ "string", "null" ], "description": "Present when the job terminated unsuccessfully (`failed`, `error`, `cancelled`)." }, "iteration_count": { "type": "integer", "format": "int32" }, "kind": { "type": "string" }, "queued_at": { "type": "string", "format": "date-time" }, "started_at": { "type": [ "string", "null" ], "format": "date-time" }, "status": { "type": "string" }, "tool_call_count": { "type": "integer", "format": "int32" }, "uid": { "type": "string", "format": "uuid" } } }, "AcePolicy": { "allOf": [ { "type": "object", "description": "Unknown keys preserved for round-tripping." }, { "type": "object", "required": [ "id" ], "properties": { "action": { "type": "string" }, "condition": { "type": "string" }, "id": { "type": "string" }, "model": { "type": [ "string", "null" ], "description": "Upstream model to route to when this policy matches\n(`provider/model` form, e.g. `\"anthropic/claude-haiku-4-5\"`)." }, "provides": { "type": "array", "items": { "type": "string" } }, "requires": { }, "tool_action": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ToolAction" } ] } } } ], "description": "A single policy entry.\n\n- `condition` is the fuzzy trigger evaluated by LLM voters. Empty /\n absent means the policy is **requires-only**: decided deterministically\n at prefilter time, never sent to voters (this also enables the\n one-LLM-call routing fast path).\n- `requires` gates the policy on extracted context variables; see the\n rule vocabulary in [`crate::matcher`].\n- `provides` deduplicates: a policy is skipped when every var it provides\n is already present in context.\n- `model` routes the proxied request to a different upstream model when\n this policy matches (first matched policy with a `model` wins)." }, "AceVar": { "allOf": [ { "type": "object", "description": "Unknown keys preserved for round-tripping." }, { "type": "object", "required": [ "id" ], "properties": { "choices": { "type": [ "array", "null" ], "items": { "type": "string" } }, "description": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "match_mode": { "type": [ "string", "null" ] } } } ], "description": "A single variable declaration.\n\n- `id` is the human-readable stable key (e.g. `\"flow\"`, `\"presupuesto_max\"`).\n- `choices`, when present, restricts the variable to an enum of string values.\n- `match_mode` tweaks how eval-side matching compares extracted vs expected\n values (e.g. `\"semantic\"`); inference ignores it." }, "ActionInfo": { "type": "object", "required": [ "key", "label", "description" ], "properties": { "description": { "type": "string", "description": "One-sentence description of what the action allows." }, "key": { "type": "string", "description": "Action key to grant on a role." }, "label": { "type": "string", "description": "Short label for display." }, "resource": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ActionResourceInfo", "description": "Resource shape for typed actions, or null when the action is org-wide." } ] } } }, "ActionResourceInfo": { "type": "object", "required": [ "kind", "segments", "template" ], "properties": { "kind": { "type": "string", "description": "Stable wire name for the resource kind (for example `project` or `project_env`)." }, "segments": { "type": "array", "items": { "type": "string" }, "description": "Ordered segment names that make up the resource path template." }, "template": { "type": "string", "description": "Example resource path with `{id}` placeholders." } } }, "ActionUsersResBody": { "type": "object", "required": [ "users" ], "properties": { "next_page_token": { "type": [ "string", "null" ], "description": "Token to fetch the next page, or null if this is the last page." }, "users": { "type": "array", "items": { "$ref": "#/components/schemas/UserAccess" }, "description": "Members who effectively hold the action. May hold fewer entries\nthan the page window even when more pages exist." } } }, "AddAlarmChannelOut": { "type": "object", "required": [ "channel_id", "channel_action", "already_linked" ], "properties": { "already_linked": { "type": "boolean", "description": "`true` when this channel was already attached, so the call changed\nnothing. Linking is idempotent — retries must not create duplicates,\nwhich would notify the same destination twice per transition." }, "channel_action": { "$ref": "#/components/schemas/ChannelAction", "description": "How the underlying `NotificationChannels` row was resolved: referenced\nby `id`, deduped onto an identical existing row, or inserted." }, "channel_id": { "type": "integer", "format": "int64" } } }, "AlarmComparison": { "type": "string", "enum": [ "gt", "gte", "lt", "lte" ] }, "AlarmDataHealth": { "type": "object", "description": "An enabled alarm and when the series behind it last produced a datapoint.", "required": [ "id", "name", "metric_name", "state", "stale" ], "properties": { "denominator_last_datapoint_at": { "type": [ "string", "null" ], "format": "date-time" }, "denominator_metric_name": { "type": [ "string", "null" ], "description": "Set only for ratio alarms, so a caller can tell which side went quiet." }, "id": { "type": "integer", "format": "int64" }, "last_datapoint_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When this alarm could last have evaluated a period.\n\nFor a ratio alarm this is the *older* of the two series, because\n`ratio_datapoints` yields a datapoint only where both sides have one —\nreporting the numerator alone would call an alarm healthy while every\nperiod actually resolves to missing.\n\n`null` = no evaluable period within the metric retention horizon, which\nfor a ratio alarm includes \"one of the two series never reported\"." }, "metric_name": { "type": "string" }, "name": { "type": "string" }, "stale": { "type": "boolean", "description": "The series has been silent long enough that the alarm is almost\ncertainly watching something that no longer exists.\n\nSilence is counted from the alarm's creation when that is later than\n`last_datapoint_at`, so a freshly created alarm is not accused of being\nblind before it has had a chance to see anything. Same judgement\n`crate::alarms::staleness` notifies on." }, "state": { "$ref": "#/components/schemas/AlarmState" } } }, "AlarmDims": { "type": "object", "description": "Metric dimension filters. Omitted = aggregate across that dimension.\n\nNot `Copy` since `label` is owned.", "properties": { "deployment_id": { "type": [ "string", "null" ] }, "label": { "type": [ "string", "null" ], "description": "`Metrics.label` — the span name behind a trace-derived metric. Scopes\nthe alarm to one tool/step instead of the sum over every span the\nfilter matched." }, "project_env_id": { "type": [ "string", "null" ] }, "project_id": { "type": [ "string", "null" ] }, "workforce_id": { "type": [ "string", "null" ], "description": "Agent / workflow app (`OrgsApps.id`)." } } }, "AlarmHistoryResBody": { "type": "object", "title": "AlarmHistoryResponse", "description": "Wrapper for **GET** `/orgs/{org_id}/alarms/{alarm_id}/history`.", "required": [ "history" ], "properties": { "history": { "type": "array", "items": { "$ref": "#/components/schemas/AlarmStateHistoryOut" } } } }, "AlarmOut": { "type": "object", "required": [ "id", "name", "metric_name", "min_sample_count", "dims", "stat", "period_seconds", "comparison", "threshold", "datapoints_to_alarm", "evaluation_periods", "missing_data", "state", "enabled", "channels" ], "properties": { "channels": { "type": "array", "items": { "$ref": "#/components/schemas/NotificationChannelOut" } }, "clear_threshold": { "type": [ "number", "null" ], "format": "double", "description": "Set when this alarm uses hysteresis; see [`CreateAlarmReq`]." }, "comparison": { "$ref": "#/components/schemas/AlarmComparison" }, "datapoints_to_alarm": { "type": "integer", "format": "int32" }, "denominator_metric_name": { "type": [ "string", "null" ], "description": "Set when this is a ratio alarm; see [`CreateAlarmReq`]." }, "dims": { "$ref": "#/components/schemas/AlarmDims" }, "enabled": { "type": "boolean" }, "evaluation_periods": { "type": "integer", "format": "int32" }, "id": { "type": "integer", "format": "int64" }, "metric_name": { "type": "string" }, "min_sample_count": { "type": "integer", "format": "int64" }, "missing_data": { "$ref": "#/components/schemas/MissingDataPolicy" }, "name": { "type": "string" }, "period_seconds": { "type": "integer", "format": "int32" }, "project_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Project this alarm belongs to; omitted for org-level alarms." }, "stat": { "$ref": "#/components/schemas/AlarmStat" }, "state": { "$ref": "#/components/schemas/AlarmState" }, "state_changed_at": { "type": [ "string", "null" ], "format": "date-time" }, "threshold": { "type": "number", "format": "double" } } }, "AlarmStat": { "type": "string", "description": "Aggregation applied to each evaluation period. Percentiles run from p0.1 to p99.9 in tenths; equivalent spellings such as p95.0 are accepted and returned canonically as p95, while a finer value such as p95.05 is rejected rather than rounded. They are exact rather than interpolated from bins, so they are only available on app.run.duration_ms and cannot be used with denominator_metric_name.", "examples": [ "p99" ], "pattern": "^(avg|sum|count|min|max|p\\d+(\\.\\d+)?)$" }, "AlarmState": { "type": "string", "enum": [ "ok", "alarm", "insufficient_data" ] }, "AlarmStateHistoryOut": { "type": "object", "required": [ "id", "from_state", "to_state", "created_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "from_state": { "$ref": "#/components/schemas/AlarmState" }, "id": { "type": "integer", "format": "int64" }, "reason": { "type": [ "object", "null" ], "description": "Evaluation evidence: per-period values, threshold, breaching count." }, "to_state": { "$ref": "#/components/schemas/AlarmState" } } }, "AllowedAction": { "type": "object", "description": "One action a principal is effectively allowed to perform, with the\nrole attachments that grant it.", "required": [ "action", "via" ], "properties": { "action": { "type": "string", "description": "IAM action key (for example `projects.envs.deploy`)." }, "via": { "type": "array", "items": { "$ref": "#/components/schemas/AccessAttribution" }, "description": "Role attachments contributing a matching allow grant." } } }, "AppType": { "type": "string", "description": "Read/output enum for a workforce component's type.\n\nTolerant on deserialization (`#[serde(other)]`) because this type is reconstructed\nfrom DB rows via two paths that both must not fail on unknown values:\n 1. [`AppType::try_from`] — used by `FromRow` impls reading `OrgsApps.type` directly.\n 2. `serde_json::from_value` — used by handlers that build workforce JSON via\n `json_build_object('type', oa.type, ...)` (runs list, deployments, etc.) and\n then deserialize into `WorkforcePreview` / `RunPreview`.\n\nNew workforce types written by `on_push` (or older ones removed from this enum) must\nnot break list/get endpoints, hence `Unknown` as a catch-all.\n\n**Do not use this for API request bodies** — see [`AppTypeInput`] for the strict\ninput variant that rejects unknowns at the deserialization boundary.", "enum": [ "agent", "workflow", "unknown" ] }, "AttachmentReq": { "type": "object", "description": "A single (role, scope) attachment in the desired state.\n\n`scope` is an optional hierarchical resource path (`projects:42`,\n`projects:42:envs:5`). `null` / omitted = unscoped (the role's grants\napply as-written). The same role may appear multiple times with\ndifferent scopes — the unique key on `OrgUserRoles` is\n`(org, user, role, scope) NULLS NOT DISTINCT`.", "required": [ "role_id" ], "properties": { "role_id": { "type": "integer", "format": "int64" }, "scope": { "type": [ "string", "null" ] } } }, "AuthProviderState": { "type": "object", "description": "State of a single sign-in method on the settings screen.", "required": [ "provider", "enabled", "configured" ], "properties": { "configured": { "type": "boolean", "description": "Whether provider-specific settings (e.g. a bring-your-own OAuth app) have\nbeen supplied. `false` means the method runs on Timbal's defaults." }, "enabled": { "type": "boolean", "description": "Whether end users can sign in with this method." }, "provider": { "type": "string", "description": "Provider key (for example `email`, `google`, `microsoft`, `github`)." } } }, "BTreeMap": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "object", "description": "Replace the column value with a SQL literal expression (e.g. `'***'`).", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "redact" ] }, "value": { "type": "string" } } }, { "type": "object", "description": "Non-keyed hash. Use `pseudonymize` for stronger guarantees.", "required": [ "algorithm", "type" ], "properties": { "algorithm": { "$ref": "#/components/schemas/HashAlg" }, "type": { "type": "string", "enum": [ "hash" ] } } }, { "type": "object", "description": "HMAC-keyed deterministic pseudonym. Stable across queries that share `key_ref`.", "required": [ "key_ref", "algorithm", "type" ], "properties": { "algorithm": { "$ref": "#/components/schemas/HashAlg" }, "key_ref": { "type": "string" }, "type": { "type": "string", "enum": [ "pseudonymize" ] } } }, { "type": "object", "description": "Truncate a string column to `length` characters, optionally pad-suffixed.", "required": [ "length", "type" ], "properties": { "length": { "type": "integer", "format": "int32", "minimum": 0 }, "pad": { "type": [ "string", "null" ] }, "type": { "type": "string", "enum": [ "truncate" ] } } }, { "type": "object", "description": "Format-preserving redaction of a payment account number.", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "pan_last4" ] } } }, { "type": "object", "description": "Email with the local part hidden (`***@example.com`).", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "email_domain_only" ] } } }, { "type": "object", "description": "Generalize a date or timestamp to the start of the given unit.", "required": [ "unit", "type" ], "properties": { "type": { "type": "string", "enum": [ "date_trunc" ] }, "unit": { "$ref": "#/components/schemas/DateTruncUnit" } } }, { "type": "object", "description": "Cap a numeric column at a maximum value.", "required": [ "max", "type" ], "properties": { "max": { "type": "number", "format": "double" }, "type": { "type": "string", "enum": [ "cap" ] } } }, { "type": "object", "description": "Power-user pattern replacement.", "required": [ "pattern", "replacement", "type" ], "properties": { "pattern": { "type": "string" }, "replacement": { "type": "string" }, "type": { "type": "string", "enum": [ "regexp_replace" ] } } } ], "description": "Per-column transformation applied to query results when this rule matches.\n\nThe full vocabulary is reserved at the API boundary so future deployments\ncan add masks without breaking existing clients. Only `redact`, `hash`,\nand `truncate` are accepted by the current release; the others return\n`400` until enforcement ships." }, "propertyNames": { "type": "string" } }, "BatchCreateVarsReqBody": { "type": "object", "required": [ "vars" ], "properties": { "env_ids": { "type": [ "array", "null" ], "items": { "type": "integer", "format": "int64" } }, "vars": { "type": "array", "items": { "$ref": "#/components/schemas/VarInput" } } } }, "BillingOverageReqBody": { "type": "object", "required": [ "enabled" ], "properties": { "cap_credits": { "type": [ "integer", "null" ], "format": "int64", "description": "Max overage credits the user allows (null = unlimited)." }, "enabled": { "type": "boolean" } } }, "BinSize": { "type": "string", "enum": [ "minute", "hour", "day" ] }, "Budget": { "type": "object", "description": "Credit budget on a project (shared pool) or role (per attached user).", "required": [ "budget_type", "limit_credits" ], "properties": { "budget_type": { "type": "string" }, "created_at": { "type": [ "string", "null" ], "format": "date-time" }, "current_credits": { "type": [ "number", "null" ], "format": "double" }, "id": { "type": [ "string", "null" ] }, "limit_credits": { "type": "string" }, "period_end": { "type": [ "string", "null" ], "format": "date-time" }, "period_start": { "type": [ "string", "null" ], "format": "date-time" }, "project_id": { "type": [ "string", "null" ] }, "project_name": { "type": [ "string", "null" ] }, "role_id": { "type": [ "string", "null" ] }, "role_name": { "type": [ "string", "null" ] }, "updated_at": { "type": [ "string", "null" ], "format": "date-time" } } }, "BudgetListBody": { "type": "object", "required": [ "budgets" ], "properties": { "budgets": { "type": "array", "items": { "$ref": "#/components/schemas/Budget" } } } }, "BudgetPatchBody": { "type": "object", "description": "Partial budget update — merge rows without touching other configured targets.", "properties": { "budgets": { "type": "array", "items": { "$ref": "#/components/schemas/BudgetPatchInput" } } } }, "BudgetPatchInput": { "type": "object", "description": "One budget change in a PATCH merge. `limit_credits: null` removes the budget.", "required": [ "budget_type" ], "properties": { "budget_type": { "type": "string", "description": "`project` or `role`." }, "limit_credits": { "type": [ "string", "null" ], "description": "When null, removes the budget for this target. When set, must be \u003E 0." }, "project_id": { "type": [ "string", "null" ] }, "role_id": { "type": [ "string", "null" ] } } }, "BulkReplaceRolesReqBody": { "type": "object", "required": [ "users" ], "properties": { "users": { "type": "array", "items": { "$ref": "#/components/schemas/UserRolesReq" }, "description": "Per-member desired attachment sets. Applied atomically: if any entry\nis rejected the whole request fails and nothing is written. A member\nmay not appear twice and may not be the caller." } } }, "ChannelAction": { "type": "string", "description": "How the request was wired to `NotificationChannels`.", "enum": [ "linked", "reused", "created" ] }, "CheckConstraintView": { "type": "object", "required": [ "name", "definition" ], "properties": { "definition": { "type": "string", "description": "The check expression, verbatim from the source." }, "name": { "type": "string" } } }, "CheckInput": { "type": "object", "required": [ "action" ], "properties": { "action": { "type": "string", "description": "IAM action key (for example `projects.envs.deploy`)." }, "resource": { "type": [ "string", "null" ], "description": "Concrete resource path for typed actions, or omit for org-wide actions." } } }, "CheckReqBody": { "type": "object", "required": [ "checks" ], "properties": { "checks": { "type": "array", "items": { "$ref": "#/components/schemas/CheckInput" }, "description": "Authorization checks to evaluate. Up to 50 per request." }, "user_id": { "type": [ "string", "null" ], "description": "Target user to evaluate. Defaults to the caller." } } }, "CheckResBody": { "type": "object", "required": [ "user_id", "results" ], "properties": { "results": { "type": "array", "items": { "$ref": "#/components/schemas/CheckResult" }, "description": "One result per input check, in input order." }, "user_id": { "type": "string", "description": "Echoes the evaluated user id (input or caller)." } } }, "CheckResult": { "type": "object", "required": [ "action", "decision", "matched_allows", "matched_denies" ], "properties": { "action": { "type": "string" }, "decision": { "$ref": "#/components/schemas/Decision" }, "matched_allows": { "type": "array", "items": { "$ref": "#/components/schemas/GrantAttribution" }, "description": "Grants that matched as `allow`. Empty for `no_allow` / `superadmin`." }, "matched_denies": { "type": "array", "items": { "$ref": "#/components/schemas/GrantAttribution" }, "description": "Grants that matched as `deny`. Non-empty only for `deny_overrides`." }, "resource": { "type": [ "string", "null" ] } } }, "CloudWatchLogEvent": { "type": "object", "description": "A single log event from CloudWatch Logs.", "required": [ "timestamp", "message", "log_stream" ], "properties": { "log_stream": { "type": "string", "description": "The log stream name this event came from." }, "message": { "type": "string", "description": "The log message content." }, "timestamp": { "type": "integer", "format": "int64", "description": "Timestamp in milliseconds since epoch." } } }, "ColumnView": { "type": "object", "required": [ "name", "data_type", "nullable", "cursor_candidate" ], "properties": { "comment": { "type": [ "string", "null" ], "description": "Column description from the source's own doc mechanism (`COMMENT ON`,\n`MS_Description`, `COLUMN_COMMENT`)." }, "cursor_candidate": { "type": "boolean", "description": "Usable as the extract job's `cursor_column`." }, "data_type": { "type": "string" }, "default": { "type": [ "string", "null" ], "description": "Column default expression, verbatim from the source\n(`nextval('t_id_seq')`, `(getdate())`, …). `null` = no default, or a\npre-0.1.25 node." }, "generated": { "type": [ "boolean", "null" ], "description": "Computed/generated column." }, "identity": { "type": [ "boolean", "null" ], "description": "Auto-assigned by the source (identity / serial / auto_increment) —\nthe ideal extract cursor when integer-typed." }, "max_length": { "type": [ "integer", "null" ], "format": "int64", "description": "Declared max character length for string types; `-1` = unbounded\n(`varchar(max)`, `text`)." }, "name": { "type": "string" }, "nullable": { "type": "boolean" }, "numeric_precision": { "type": [ "integer", "null" ], "format": "int32", "description": "Numeric precision (total digits)." }, "numeric_scale": { "type": [ "integer", "null" ], "format": "int32", "description": "Numeric scale (fraction digits)." }, "pk_position": { "type": [ "integer", "null" ], "format": "int32", "description": "1-based position in the table's primary key, or `null` if not a key\ncolumn. Order matters — it's the merge key for upsert syncs and the\nkeyset tiebreaker, both of which need composite columns in declared\norder. Always `null` from nodes older than key discovery; tell \"no PK\"\nfrom \"old node\" by node version, not by an all-`null` column set.", "minimum": 0 }, "unique": { "type": [ "boolean", "null" ], "description": "`true` when the column alone is guaranteed unique (sole key of a unique\nindex or the PK) — a unique cursor keeps incremental extraction on the\ncheap scalar path; a non-unique one needs a PK tie-breaker. `null` from\nnodes older than the hint (0.1.25): unknown, not \"not unique\"." } } }, "ColumnsRes": { "type": "object", "required": [ "columns" ], "properties": { "columns": { "type": "array", "items": { "$ref": "#/components/schemas/ColumnView" } } } }, "ComponentConfigEntry": { "type": "object", "description": "Per-component deploy override stored under\n`ProjectEnvs.deploy_config.components[key]`. When set, the entry is the\nGROUND TRUTH for that component: its config resolves as type defaults +\nthis entry only (env flat keys and app-level `OrgsApps.deploy_config` are\nskipped), and `deploy_mode` here overrides both the app and env modes.", "properties": { "cpu": { "type": [ "integer", "null" ], "format": "int32" }, "deploy_mode": { "type": [ "string", "null" ], "description": "'ecs' | 'serverless' | 'disabled'" }, "desired_count": { "type": [ "integer", "null" ], "format": "int32" }, "ephemeral_storage": { "type": [ "integer", "null" ], "format": "int32" }, "memory": { "type": [ "integer", "null" ], "format": "int32" } }, "additionalProperties": false }, "ComponentEvals": { "type": "object", "description": "A workforce component and the evals defined in its `evals/` dir.", "required": [ "component_dir", "evals" ], "properties": { "component_dir": { "type": "string", "description": "Component directory name under `workforce/`." }, "component_id": { "type": [ "string", "null" ], "description": "`OrgsApps.id`, when the repo component matches a registered app.\nUse as `component_id` for `POST .../evals/runs`." }, "component_name": { "type": [ "string", "null" ], "description": "App name in the platform, when registered." }, "component_uid": { "type": [ "string", "null" ], "description": "`_id` from the component's `timbal.yaml` (`component_uid` for\n`POST .../evals/runs`)." }, "evalconf": { "description": "Parsed `evalconf.yaml` (from `evals/` or the component root),\nwhen present. Its `runnable` key is the per-component default." }, "evals": { "type": "array", "items": { "$ref": "#/components/schemas/EvalDefinition" } }, "parse_errors": { "type": "array", "items": { "type": "string" }, "description": "Files that exist but failed to parse as eval YAML (path → error)." }, "warnings": { "type": "array", "items": { "type": "string" }, "description": "Non-fatal issues the CLI would hit: duplicate eval names (hard\nerror, fails the gate), missing names, unknown validator\nkeywords, missing runnable." } } }, "ComputeAmount": { "type": "object", "description": "A compute amount expressed in both pool dimensions.", "required": [ "cpu_units", "memory_mib" ], "properties": { "cpu_units": { "type": "integer", "format": "int64", "description": "Fargate cpu units (1 vCPU = 1024)." }, "memory_mib": { "type": "integer", "format": "int64", "description": "Memory in MiB." } } }, "ComputeFleetReqBody": { "type": "object", "required": [ "machines" ], "properties": { "machines": { "type": "object", "description": "Desired machine count per size (e.g. `{\"medium\": 1, \"xlarge\": 2}`).\nSizes omitted from the map are set to zero.", "additionalProperties": { "type": "integer", "format": "int64" }, "propertyNames": { "type": "string" } } } }, "ComputeFleetSummary": { "type": "object", "description": "The org's compute pool: purchased machines, total capacity, and current draw.", "required": [ "machines", "in_use" ], "properties": { "in_use": { "$ref": "#/components/schemas/ComputeAmount", "description": "Pool currently drawn by active deployments." }, "machines": { "type": "array", "items": { "$ref": "#/components/schemas/ComputeMachineStatus" } }, "pool": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ComputeAmount", "description": "Total pool capacity from purchased machines. `null` = unlimited\n(admin-granted)." } ] } } }, "ComputeMachineStatus": { "type": "object", "description": "One machine size in the catalog, with the org's purchased quantity.", "required": [ "slug", "vcpu", "memory_mib", "monthly_price_cents", "purchased" ], "properties": { "memory_mib": { "type": "integer", "format": "int32", "description": "Memory per machine in MiB." }, "monthly_price_cents": { "type": "integer", "format": "int64", "description": "Monthly price per machine in euro cents, before tax." }, "purchased": { "type": "integer", "format": "int64", "description": "Machines of this size currently purchased." }, "slug": { "type": "string", "description": "Machine size identifier (`medium`, `large`, `xlarge`, `2xlarge`, `4xlarge`)." }, "vcpu": { "type": "integer", "format": "int32", "description": "Virtual CPUs per machine." } } }, "ConnectionsRes": { "type": "object", "required": [ "connections" ], "properties": { "connections": { "type": "array", "items": { "type": "string" }, "description": "Connection refs configured on the node (names only; DSNs stay local)." } } }, "ConnectorView": { "type": "object", "required": [ "id", "capabilities", "connected", "online", "enrolled_at" ], "properties": { "arch": { "type": [ "string", "null" ] }, "capabilities": { "type": "array", "items": { "type": "string" } }, "connected": { "type": "boolean", "description": "Last known DB-side connected flag (survives monolith restarts)." }, "enrolled_at": { "type": "string", "format": "date-time" }, "hostname": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "last_seen_at": { "type": [ "string", "null" ], "format": "date-time" }, "name": { "type": [ "string", "null" ] }, "online": { "type": "boolean", "description": "Live socket on *this* monolith instance right now." }, "os": { "type": [ "string", "null" ] }, "version": { "type": [ "string", "null" ] } } }, "CopyReq": { "type": "object", "required": [ "filesystem_ref", "kb_id" ], "properties": { "directory": { "type": [ "string", "null" ], "description": "KB directory files land under (root when omitted). A recursive copy\nrecreates the tree below it." }, "filesystem_ref": { "type": "string", "description": "Filesystem root ref on the node (from `/browse/filesystems`)." }, "kb_id": { "type": "integer", "format": "int64", "description": "Target KB (numeric id, same as the `/k2` routes)." }, "max_files": { "type": [ "integer", "null" ], "format": "int32", "description": "Job cap on files shipped. Omit for the node default (5000).", "minimum": 0 }, "max_total_bytes": { "type": [ "integer", "null" ], "format": "int64", "description": "Job cap on aggregate raw bytes. Omit for the node default (2 GiB).", "minimum": 0 }, "metadata": { "type": "object", "description": "Metadata stamped onto every landed file." }, "parse": { "type": "boolean", "description": "Parse + embed after storing. Default `false` — copy is store-only; the\nKB's auto-processing setting never applies to connector copies." }, "path": { "type": "string", "description": "Path relative to the root: a file, or a directory when `recursive`.\nEmpty / omitted / whitespace = the filesystem root (same as the\nconnector's `CopyFileJob` / browse verbs)." }, "recursive": { "type": "boolean", "description": "`true` = `path` is a directory: walk it and stream every regular file\n(symlinks skipped). Copying a directory without it is refused node-side." } } }, "CopyRes": { "type": "object", "required": [ "job_id" ], "properties": { "job_id": { "type": "string" } } }, "Cost": { "type": "object", "required": [ "id", "name", "unit", "usd", "credits" ], "properties": { "credits": { "type": "number", "format": "double" }, "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "unit": { "type": "string" }, "usd": { "type": "number", "format": "double" } } }, "CostBin": { "type": "object", "required": [ "interval_starts_at", "interval_ends_at", "costs" ], "properties": { "costs": { "type": "array", "items": { "$ref": "#/components/schemas/Cost" } }, "interval_ends_at": { "type": "integer", "format": "int64" }, "interval_starts_at": { "type": "integer", "format": "int64" } } }, "CreateAceResBody": { "type": "object", "description": "Response body for the empty-create route. Generation is explicit —\nsee `POST /ace/{ace_uid}/jobs`.", "required": [ "ace_uid" ], "properties": { "ace_uid": { "type": "string", "format": "uuid" } } }, "CreateAlarmOut": { "type": "object", "required": [ "id", "channel_id", "channel_action" ], "properties": { "channel_action": { "$ref": "#/components/schemas/ChannelAction" }, "channel_id": { "type": "integer", "format": "int64" }, "id": { "type": "integer", "format": "int64" } } }, "CreateAlarmReq": { "type": "object", "description": "Body for **POST** `/orgs/{org_id}/alarms`.", "required": [ "name", "metric_name", "stat", "comparison", "threshold", "channel" ], "properties": { "channel": { "$ref": "#/components/schemas/CreateChannelReq", "description": "Channel: inline `type` + `config`, or reuse with `{ \"id\": \u003Cchannel id\u003E }` (same org)." }, "clear_threshold": { "type": [ "number", "null" ], "format": "double", "description": "Hysteresis: once in `alarm`, a period only stops counting as breaching\nonce it clears *this* value rather than `threshold`. Must sit on the\nnon-breaching side of `threshold` — below it for `gt`/`gte`, above for\n`lt`/`lte`.\n\nFire at `0.05` and clear at `0.03`, and a metric hovering on 5% produces\none transition instead of one per swing. Without it the only defences\nagainst flapping are a longer `period_seconds` or a higher\n`datapoints_to_alarm`, both of which also delay the *first* detection." }, "comparison": { "$ref": "#/components/schemas/AlarmComparison" }, "datapoints_to_alarm": { "type": "integer", "format": "int32", "description": "Datapoints that must breach out of the last `evaluation_periods`." }, "denominator_metric_name": { "type": [ "string", "null" ], "description": "Turns the alarm into a **ratio** condition: each period's datapoint\nbecomes `metric_name / denominator_metric_name`, read with the same\ndims, stat and period. `threshold` is then a rate — `0.05` for a 5%\nerror rate, not `5`.\n\nPair it with `min_sample_count`; see that field." }, "dims": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AlarmDims" } ] }, "evaluation_periods": { "type": "integer", "format": "int32" }, "metric_name": { "type": "string", "description": "Metric to watch, e.g. `app.run.errors`, `deployment.health`,\n`org.credits.spend`. The numerator when `denominator_metric_name` is set." }, "min_sample_count": { "type": "integer", "format": "int64", "description": "Minimum denominator for a ratio period to count. Below it (or at zero)\nthe period has no datapoint and follows `missing_data`.\n\nExists because ratios are meaningless on tiny samples: 1 error out of 1\nrun is 100%. Set it to the smallest traffic level you'd actually act on." }, "missing_data": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/MissingDataPolicy", "description": "Omit to get a policy chosen from the metric: `ignore` for `trace.*`\n(sparse — a gap is absence of data, not a recovery) and `not_breaching`\nfor everything else." } ] }, "name": { "type": "string" }, "period_seconds": { "type": "integer", "format": "int32", "description": "Length of one evaluation period in seconds (multiple of 60, \u003E= 60)." }, "project_id": { "type": [ "string", "null" ], "description": "Scope the alarm to a project. Omit for an org-level alarm." }, "stat": { "$ref": "#/components/schemas/AlarmStat" }, "threshold": { "type": "number", "format": "double" } } }, "CreateBackupRequest": { "type": "object", "properties": { "dry_run": { "type": "boolean", "description": "When omitted or when the request has no JSON body, treated as `false`." }, "force": { "type": "boolean", "description": "Create the backup even if the knowledge base is currently served by\nanother host. Defaults to `false`, in which case such requests are\nrejected with `409 Conflict`." } } }, "CreateChannelReq": { "type": "object", "description": "Channel reference embedded in another resource's create body (alarms).\nEither reuse by `id`, or supply `type` + `config` inline.", "properties": { "config": { "type": "object", "description": "Omitted or null when linking by `id` only." }, "id": { "type": [ "string", "null" ], "description": "Existing `NotificationChannels.id` for this org. When set, `type` / `config` / `name` are ignored." }, "name": { "type": [ "string", "null" ] }, "type": { "$ref": "#/components/schemas/NotificationChannelType" } } }, "CreateDomainReqBody": { "type": "object", "required": [ "domain" ], "properties": { "domain": { "type": "string", "description": "Custom domain name", "example": "custom.timbal.ai" } } }, "CreateEnvReqBody": { "type": "object", "required": [ "name", "color" ], "properties": { "color": { "type": "string" }, "description": { "type": [ "string", "null" ] }, "name": { "type": "string" } } }, "CreateGroupRoleMappingReqBody": { "type": "object", "description": "Add an external-group → role mapping to a connection.", "required": [ "external_group", "role_id" ], "properties": { "external_group": { "type": "string", "description": "External group identifier exactly as the IdP emits it." }, "role_id": { "type": "integer", "format": "int64", "description": "Target Timbal role id. Accepts a number or a stringified id." } } }, "CreateIdentityProviderReqBody": { "type": "object", "description": "Create an OIDC identity-provider connection for an org.", "required": [ "provider_key" ], "properties": { "allowed_domains": { "type": "array", "items": { "type": "string" }, "description": "Email domains eligible for JIT auto-provisioning. Empty = no JIT." }, "client_id": { "type": [ "string", "null" ], "description": "OAuth client id registered with the IdP. Required for `oidc`." }, "client_secret": { "type": [ "string", "null" ], "description": "OAuth client secret. Sealed at rest with the org DEK; never returned.\nRequired for `oidc`." }, "default_role_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Optional catch-all role for JIT members whose group claim matched no\nmapping. When omitted, such members are added with no role (a bare\nmember, pending an admin grant) rather than an implicit default.\nAccepts a number or a stringified id (`2227` or `\"2227\"`)." }, "display_name": { "type": [ "string", "null" ], "description": "Human-readable label for the login button / admin UI." }, "enabled": { "type": [ "boolean", "null" ], "description": "Whether the connection is active. Defaults to true." }, "groups_claim": { "type": [ "string", "null" ], "description": "Claim carrying group membership. Defaults to `groups`." }, "issuer": { "type": [ "string", "null" ], "description": "IdP issuer / discovery base; `/.well-known/openid-configuration` is\nfetched from here. **Required for `oidc`; ignored for `directory`.**", "example": "https://acme.okta.com" }, "kind": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/IdentityProviderKind", "description": "Connection kind. Defaults to `oidc` (backward-compatible). Use\n`directory` for a login-less SCIM connection: no issuer/client creds\nrequired, it only anchors SCIM group→role mappings + the catch-all role." } ] }, "provider_key": { "type": "string", "description": "Stable, URL-safe handle used in the login URL\n(`/auth/sso/{provider_key}`) and the signed OAuth state. Lowercase\nletters/digits/hyphens; must not collide with the built-in social\nproviders. Globally unique.", "example": "acme" }, "scopes": { "type": [ "string", "null" ], "description": "Space-separated scopes. Defaults to `openid email profile`." } } }, "CreateK2PolicyAssignmentRequest": { "type": "object", "required": [ "role_id" ], "properties": { "combine_mode": { "$ref": "#/components/schemas/K2PolicyCombineMode" }, "enabled": { "type": "boolean" }, "priority": { "type": "integer", "format": "int32" }, "role_id": { "type": "string" }, "valid_from": { "type": [ "string", "null" ], "format": "date-time" }, "valid_until": { "type": [ "string", "null" ], "format": "date-time" } } }, "CreateK2PolicyRequest": { "type": "object", "required": [ "name", "row_filter_dsl" ], "properties": { "audit_level": { "$ref": "#/components/schemas/K2PolicyAuditLevel" }, "break_glass_allowed": { "type": "boolean" }, "column_masks": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BTreeMap" } ] }, "compliance_tags": { "type": "array", "items": { "type": "string" } }, "description": { "type": [ "string", "null" ] }, "enabled": { "type": "boolean", "description": "Defaults to true; set false to author the rule in a draft state." }, "external_id": { "type": [ "string", "null" ] }, "labels": { "type": "object", "description": "Free-form key/value labels." }, "name": { "type": "string", "description": "Operator-facing label." }, "purpose_tags": { "type": "array", "items": { "type": "string" } }, "row_filter_dsl": { "type": "object", "description": "Row predicate JSON. Stored opaquely in this release." }, "source": { "$ref": "#/components/schemas/K2PolicySource" }, "table_name": { "type": [ "string", "null" ], "description": "Target table within the knowledge base. Omit to apply to every table." } } }, "CreateK2Request": { "type": "object", "properties": { "name": { "type": [ "string", "null" ], "description": "Name for the new knowledge base" } } }, "CreateK2Response": { "type": "object", "required": [ "id", "uid", "name", "path" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "path": { "type": "string" }, "uid": { "type": "string" } } }, "CreateK2VirtualDirectoryRequest": { "type": "object", "required": [ "directory" ], "properties": { "directory": { "type": "string", "description": "Folder path, same format as the `directory` field on file upload (e.g. `docs/reports`)." } } }, "CreateK2VirtualDirectoryResponse": { "type": "object", "required": [ "directory", "placeholder_file_id", "created" ], "properties": { "created": { "type": "boolean", "description": "`true` if this call created the folder, `false` if it already existed." }, "directory": { "type": "string" }, "placeholder_file_id": { "type": "string", "description": "Listing id for this folder; remove it with `DELETE /orgs/{org_id}/k2/{kb_id}/files/{file_id}`." } } }, "CreateMetricDefinitionReq": { "type": "object", "description": "Body for **POST** `/orgs/{org_id}/metrics/definitions`.\n\nEvery predicate field is optional and they AND together. All omitted means\n\"every non-root span\", which paired with `label_source: span_name` gives a\nper-step call count — a reasonable first definition.", "required": [ "name", "metric_name" ], "properties": { "has_error": { "type": [ "boolean", "null" ], "description": "`true` = only errored spans, `false` = only clean ones, omitted = both." }, "label_source": { "type": "string", "description": "`none` (default) or `span_name` to break the metric out per step." }, "metric_name": { "type": "string", "description": "Destination metric. `trace.` is prepended when missing." }, "min_duration_ms": { "type": [ "integer", "null" ], "format": "int32", "description": "Only spans at least this slow. Spans still running never match." }, "name": { "type": "string", "description": "Human label for the definition itself, unique within the org." }, "project_id": { "type": [ "string", "null" ], "description": "Scope to one project. Omit to apply across the org." }, "source": { "$ref": "#/components/schemas/MetricDefinitionSource", "description": "Defaults to `trace_span`, the only source today." }, "span_name": { "type": [ "string", "null" ], "description": "Exact span name — the leaf of the span path (`llm`, `get_address`),\nnot the full `{workforce}.{step}`." }, "span_name_prefix": { "type": [ "string", "null" ], "description": "Span-name prefix, for matching a family of tools (`get_`)." }, "status_code": { "type": [ "string", "null" ] }, "value_source": { "type": "string", "description": "`count` (default), `duration_ms`, or `usage:\u003Ckey\u003E`." } } }, "CreateModelPolicyBody": { "type": "object", "description": "Request body for `POST /orgs/{org_id}/models/policies`.", "required": [ "provider" ], "properties": { "effect": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ModelPolicyEffect", "description": "Rule effect. Defaults to `deny`." } ] }, "model_id": { "type": [ "string", "null" ], "description": "Model to target. Omit to target every model of the provider." }, "provider": { "type": "string", "description": "Model provider slug, e.g. `byteplus`, `openai`." } } }, "CreateNotificationChannelOut": { "type": "object", "required": [ "id", "channel_action" ], "properties": { "channel_action": { "$ref": "#/components/schemas/ChannelAction" }, "id": { "type": "integer", "format": "int64" } } }, "CreateNotificationChannelReq": { "type": "object", "description": "Body for **POST** `/orgs/{org_id}/channels` (standalone channel; same validation as an inline alarm channel, no `id`).", "properties": { "config": { "type": "object" }, "name": { "type": [ "string", "null" ] }, "type": { "$ref": "#/components/schemas/NotificationChannelType" } } }, "CreateOrgReqBody": { "type": "object", "required": [ "name" ], "properties": { "livemode": { "type": [ "boolean", "null" ], "description": "Stripe live mode for billing. Superadmin-only; ignored for other callers." }, "name": { "type": "string" } } }, "CreateProjectReqBody": { "type": "object", "required": [ "origin" ], "properties": { "name": { "type": [ "string", "null" ] }, "origin": { "$ref": "#/components/schemas/ProjectOrigin" } } }, "CreateProjectResBody": { "type": "object", "required": [ "id", "name" ], "properties": { "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } } }, "CreateRestoreRequest": { "type": "object", "required": [ "source_backup_id" ], "properties": { "source_backup_id": { "type": "string" } } }, "CreateRoleReqBody": { "type": "object", "required": [ "name" ], "properties": { "description": { "type": [ "string", "null" ] }, "grants": { "type": "array", "items": { "$ref": "#/components/schemas/RoleGrant" }, "description": "Grants this role carries. Empty list is allowed (creates a no-op\nrole; admin can extend it later)." }, "name": { "type": "string", "description": "Role name. Must be unique within the org. Reserved system names\n(`admin`, `developer`, `billing`, `member`, `user`) are rejected." } } }, "CreateScimTokenReqBody": { "type": "object", "description": "Create a SCIM token for an org.", "properties": { "label": { "type": [ "string", "null" ], "description": "Human label for the admin UI (e.g. \"Entra prod\")." }, "provider_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Optional IdP connection to bind this token to. When set, SCIM group\npushes resolve roles through that connection's group→role mappings;\nwhen omitted the token does membership-only SCIM (auto add/remove)." } } }, "CreateScimTokenResBody": { "allOf": [ { "$ref": "#/components/schemas/ScimTokenView" }, { "type": "object", "required": [ "token", "base_url" ], "properties": { "base_url": { "type": "string", "description": "The base URL the IdP should target, e.g. `https://api.timbal.ai/scim/v2`." }, "token": { "type": "string", "description": "The bearer token to paste into the IdP's SCIM config. Shown once." } } } ], "description": "Create response: the only time the plaintext token is ever returned. The\ncaller (IdP admin) must copy `token` now — it can't be retrieved later." }, "CreateSyncReq": { "type": "object", "required": [ "kb_id", "dest_table", "source", "interval_secs" ], "properties": { "dest_table": { "type": "string", "description": "Destination table inside the KB. Created by the first run when it\ndoesn't exist yet; when it does, `existing_dest` decides whether the\nsync continues it or rebuilds it." }, "existing_dest": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ExistingDest", "description": "How to treat a `dest_table` that already exists. Defaults to `adopt`.\nOnly meaningful for an incremental sync — a full-refresh one replaces the\ndestination on every run by definition." } ] }, "initial_cursor": { "type": [ "object", "null" ], "description": "Checkpoint to continue an existing `dest_table` from, overriding the one\nread off the table itself. Only valid when the table exists and\n`existing_dest` is `adopt` — for a table the sync still has to build,\nuse `start_cursor`. Same shape as `start_cursor`." }, "interval_secs": { "type": "integer", "format": "int64", "description": "Seconds between run *starts*. The scheduler ticks every 30s, so smaller\nvalues effectively mean \"every tick\"." }, "kb_id": { "type": "integer", "format": "int64", "description": "Target KB (numeric id, same as the `/k2` routes)." }, "key_columns": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Ordered destination `PRIMARY KEY` columns. Omit for a keyless table. The\nfirst run declares the key; later runs then **merge** on it (upsert) so an\nupstream update — or a re-pulled boundary row from a non-unique cursor —\noverwrites in place instead of duplicating. Key columns are auto-added to\na `columns` subset, so they only need to exist on the source table. Source\nthese from the browse columns' `pk_position`." }, "name": { "type": [ "string", "null" ], "description": "Operator label." }, "source": { "$ref": "#/components/schemas/SourceBody" }, "start_cursor": { "type": [ "object", "null" ], "description": "Optional lower bound for the **first** run when it builds the table:\nonly rows with `cursor_column \u003E= start_cursor` are pulled (e.g. seed a\ntimestamp to backfill \"from last month on\" instead of the whole table).\nIgnored on later runs — the advancing cursor takes over — and ignored\nwhen the sync adopts an existing table. Shape matches the job `cursor`\n(e.g. `{\"kind\":\"timestamp\",\"value\":\"2026-06-01T00:00:00Z\"}`). Not valid\non a full-refresh sync (no `cursor_column` to bound)." } } }, "CreateSyncRes": { "type": "object", "required": [ "sync_id", "adopted_dest_table", "key_columns" ], "properties": { "adopted_dest_table": { "type": "boolean", "description": "`true` when the sync continues an existing destination table instead of\nbuilding it on the first run." }, "initial_cursor": { "type": [ "object", "null" ], "description": "The checkpoint the first run resumes from when the destination was\nadopted; `null` otherwise (including an adopted table that was empty)." }, "key_columns": { "type": "array", "items": { "type": "string" }, "description": "Primary-key columns the sync will merge on. Inherited from an adopted\ntable's own key when the request didn't declare one." }, "sync_id": { "type": "string" } } }, "CreateVarReqBody": { "type": "object", "required": [ "type", "name", "value" ], "properties": { "description": { "type": [ "string", "null" ] }, "env_ids": { "type": [ "array", "null" ], "items": { "type": "integer", "format": "int64" } }, "name": { "type": "string" }, "type": { "$ref": "#/components/schemas/VarType" }, "value": { "type": "string" } } }, "CreateWorkforceReqBody": { "type": "object", "properties": { "name": { "type": [ "string", "null" ], "description": "Optional display name for the new component. If omitted, a unique name is generated." }, "type": { "type": "string", "description": "Either `agent` or `workflow`. Defaults to `agent`." } } }, "CreateWorkforceResponse": { "type": "object", "description": "Response returned when a new workforce component is created.", "required": [ "id", "uid", "type", "name", "path" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "path": { "type": "string", "description": "Path to the new component inside the repository worktree (for example `workforce/my-agent`)." }, "type": { "type": "string" }, "uid": { "type": "string", "description": "Identifier assigned in the project manifest for this component." } } }, "CreditGrant": { "type": "object", "description": "A single credit grant on an organization.", "required": [ "uid", "source", "source_metadata", "amount_credits", "consumed_credits", "starts_at", "created_at" ], "properties": { "amount_credits": { "type": "integer", "format": "int64", "description": "Credits awarded by this grant. Always positive; corrections ship as a\nseparate grant rather than a negative amount." }, "consumed_credits": { "type": "integer", "format": "int64", "description": "Credits already drawn from this grant by attributed costs. Bounded by\n`amount_credits`; remaining headroom is `amount_credits - consumed_credits`." }, "created_at": { "type": "string", "format": "date-time", "description": "Grant creation timestamp." }, "exhausted_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Set once the grant has been fully consumed by usage; `null` while\nthe grant still has unspent credits or hasn't been reconciled yet." }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the grant stops being spendable. `null` = never expires." }, "granted_by_user_id": { "type": [ "integer", "null" ], "format": "int64", "description": "User who triggered the grant. `null` for system-issued grants." }, "source": { "type": "string", "description": "Where the grant came from (e.g. `onboarding`, `promo`, `support`,\n`referral`, `refund`)." }, "source_metadata": { "description": "Source-specific payload. Shape depends on `source`." }, "starts_at": { "type": "string", "format": "date-time", "description": "When the grant became (or will become) spendable." }, "uid": { "type": "string", "format": "uuid", "description": "Stable public identifier for this grant." } } }, "DateTruncUnit": { "type": "string", "description": "Granularity for the `date_trunc` mask.", "enum": [ "year", "quarter", "month", "week", "day" ] }, "Decision": { "type": "string", "enum": [ "allow", "deny_overrides", "no_allow", "superadmin" ] }, "DeleteChannelBody": { "type": "object", "properties": { "force": { "type": [ "boolean", "null" ], "description": "When `true`, delete even if alarms reference this channel (cascading\nunlink). Still refused when it would leave an enabled alarm with no\nchannels." } } }, "DeleteWorkforceReqBody": { "type": "object", "required": [ "workforce" ], "properties": { "workforce": { "type": "string", "description": "Component to delete: numeric id, manifest UUID (`uid`), or configured name." } } }, "DeployEnvReqBody": { "type": "object", "properties": { "rev": { "type": [ "string", "null" ] } } }, "DeploymentDetail": { "type": "object", "description": "Public-API representation of a single deployment row, returned by the\nenv-scoped deployments list endpoint. Flattens the runtime config\n(cpu/memory/...) inline rather than nesting under `config` — frontend\nconsumes the fields directly.", "required": [ "id", "type", "project_env_id", "target", "status", "created_at", "updated_at" ], "properties": { "build_finished_at": { "type": [ "string", "null" ], "format": "date-time" }, "build_logs": { "type": [ "string", "null" ] }, "build_started_at": { "type": [ "string", "null" ], "format": "date-time" }, "cpu": { "type": [ "integer", "null" ], "format": "int32" }, "created_at": { "type": "string", "format": "date-time" }, "desired_count": { "type": [ "integer", "null" ], "format": "int32" }, "domain": { "type": [ "string", "null" ] }, "ephemeral_storage": { "type": [ "integer", "null" ], "format": "int32" }, "id": { "type": "integer", "format": "int64" }, "memory": { "type": [ "integer", "null" ], "format": "int32" }, "project_env_id": { "type": "integer", "format": "int64" }, "status": { "type": "string" }, "status_detail": { "type": [ "string", "null" ] }, "target": { "$ref": "#/components/schemas/DeploymentTarget" }, "type": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "DeploymentTarget": { "type": "object", "description": "Image/version pointer embedded in [`DeploymentDetail::target`]. Distinct\nfrom [`crate::deployments::models::DeployTarget`] (the domain-layer spec\ncarrying image URIs / platform). This shape is the public-API view of\nwhat a deployment is *of*.", "required": [ "type", "id" ], "properties": { "commit": { }, "id": { "type": "integer", "format": "int64" }, "manifest_id": { "type": [ "string", "null" ] }, "type": { "type": "string" } } }, "DispatchReq": { "type": "object", "required": [ "kb_id", "dest_table", "source" ], "properties": { "batch_rows": { "type": [ "integer", "null" ], "format": "int32", "description": "Target rows per batch. Defaults to 5000.", "minimum": 0 }, "cursor": { "type": [ "object", "null" ], "description": "Resume checkpoint; omit for a full initial extract." }, "dest_table": { "type": "string", "description": "Destination table inside the KB." }, "kb_id": { "type": "integer", "format": "int64", "description": "Target KB (numeric id, same as the `/k2` routes)." }, "key_columns": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Ordered destination `PRIMARY KEY` columns. Omit for a keyless table.\nHonored when the run builds the table (`create`/`replace`). Key columns\nare auto-added to a `source.columns` subset, so they only need to exist\non the source table. Source these from the browse columns' `pk_position`\nfor a faithful copy of the source key." }, "mode": { "type": [ "string", "null" ], "description": "`create` | `append` | `replace` | `upsert`. Defaults to `create`.\n`upsert` merges each batch on `key_columns` (rows with an existing key are\noverwritten, new keys inserted); requires non-empty `key_columns`. If the\ndestination table doesn't exist yet, the first upsert builds it keyed." }, "pacing": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PacingBody", "description": "Optional load-shaping for gentle extraction against busy source systems.\nOmit for no throttle." } ] }, "placement": { "type": [ "string", "null" ], "description": "Where the KB's data lives: `hosted` (control-plane KB, the default) or\n`local` (a KB runtime inside the connector's environment — requires the\nconnector to advertise the `kb:local` capability)." }, "source": { "$ref": "#/components/schemas/SourceBody" } } }, "DispatchRes": { "type": "object", "required": [ "job_id" ], "properties": { "job_id": { "type": "string" } } }, "Domain": { "type": "object", "required": [ "id", "domain", "validation_records", "validation_status", "created_at", "updated_at" ], "properties": { "created_at": { "type": "integer", "format": "int64", "description": "Creation timestamp in epoch milliseconds" }, "domain": { "type": "string", "description": "Custom domain name" }, "id": { "type": "string", "description": "Unique domain identifier" }, "project_env": { "description": "Project environment this domain is linked to, if any" }, "updated_at": { "type": "integer", "format": "int64", "description": "Last update timestamp in epoch milliseconds" }, "validation_records": { "type": "array", "items": { "$ref": "#/components/schemas/ValidationRecord" }, "description": "DNS records required for SSL certificate validation" }, "validation_status": { "$ref": "#/components/schemas/ValidationStatus", "description": "Current SSL certificate validation status" } } }, "DuplicateProjectReqBody": { "type": "object", "properties": { "name": { "type": [ "string", "null" ], "description": "Name for the new project. Defaults to the source name with a \" copy\"\nsuffix, de-duplicated within the organization." } } }, "EditK2Request": { "type": "object", "properties": { "auto_processing_enabled": { "type": [ "boolean", "null" ], "description": "Toggle the automatic parsing, chunking, and embedding pipeline for new file uploads. When false, uploads are stored as-is. Existing files are not affected." }, "backup_enabled": { "type": [ "boolean", "null" ], "description": "DEPRECATED and ignored: backups are system-managed for every KB; this\nflag gates nothing. Accepted for old clients, never applied.", "deprecated": true }, "backup_retention_days": { "type": [ "integer", "null" ], "format": "int32", "description": "DEPRECATED and ignored: snapshot retention is system-managed\n(keep-last-N). Accepted for old clients, never applied.", "deprecated": true }, "backup_s3_bucket": { "type": [ "string", "null" ] }, "backup_s3_key_prefix": { "type": [ "string", "null" ] }, "backup_schedule_cron": { "type": [ "string", "null" ], "description": "DEPRECATED and ignored: superseded by `backup_window_utc_hour`.\nAccepted for old clients, never applied.", "deprecated": true }, "backup_window_utc_hour": { "type": [ "integer", "null" ], "format": "int32", "description": "UTC hour (0–23) when this KB's fixed daily backup may run.\nSet `null` to reset to the fleet default (01:00 UTC)." }, "description": { "type": [ "string", "null" ] }, "name": { "type": [ "string", "null" ] } } }, "EditOrgReqBody": { "type": "object", "properties": { "banner_url": { "type": [ "string", "null" ], "description": "URL of the organization's banner image", "deprecated": true }, "contact_email": { "type": [ "string", "null" ], "description": "Contact email address" }, "contact_name": { "type": [ "string", "null" ], "description": "Contact person's name" }, "contact_phone": { "type": [ "string", "null" ], "description": "Contact phone number" }, "country": { "type": [ "string", "null" ], "description": "ISO 3166-1 alpha-2 country code" }, "description": { "type": [ "string", "null" ], "description": "Organization description" }, "name": { "type": [ "string", "null" ], "description": "Organization name" } } }, "EditProjectReqBody": { "type": "object", "properties": { "description": { "type": [ "string", "null" ] }, "is_public_template": { "type": [ "boolean", "null" ] }, "name": { "type": [ "string", "null" ] }, "search_text": { "type": [ "string", "null" ] }, "template_description": { "type": [ "string", "null" ] }, "use_platform_iam": { "type": [ "boolean", "null" ] } } }, "EditRoleReqBody": { "type": "object", "properties": { "description": { "type": [ "string", "null" ], "description": "Human-readable description. Pass `null` to clear." }, "grants": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/RoleGrant" }, "description": "Full replacement of the role's grant set." }, "name": { "type": [ "string", "null" ], "description": "New role name. Reserved system names rejected." } } }, "EffectiveGrant": { "type": "object", "required": [ "effect", "action", "via" ], "properties": { "action": { "type": "string" }, "effect": { "$ref": "#/components/schemas/GrantEffect" }, "resource": { "type": [ "string", "null" ], "description": "Scope-intersected resource pattern for this grant." }, "via": { "$ref": "#/components/schemas/GrantAttribution", "description": "Role that contributed this grant." } } }, "EffectiveGrantsResBody": { "type": "object", "required": [ "user_id", "is_superadmin", "grants" ], "properties": { "grants": { "type": "array", "items": { "$ref": "#/components/schemas/EffectiveGrant" }, "description": "Effective grants for the user, with role attribution." }, "is_superadmin": { "type": "boolean", "description": "Whether the target user is a platform superadmin." }, "user_id": { "type": "string", "description": "Echoes the target user id." } } }, "EmbeddingModel": { "type": "string" }, "EnqueueAceJobReqBody": { "type": "object", "description": "Request body for `POST /ace/{ace_uid}/jobs`. `kind` selects the work;\nthe vocabulary lives in [`AceJobKind`] and grows server-side without\nnew endpoints (usage-window adaptation, policy scaffolding, ...).", "properties": { "app_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Disambiguates which linked workforce (`OrgsApps.id`) supplies the\nagent source when the ACE is attached to more than one. Optional\nwhen exactly one workforce is linked." }, "kind": { "type": [ "string", "null" ], "description": "Job kind. Defaults to `\"regenerate\"` (playbook [re-]generation\nfrom the linked workforce's agent code file)." }, "rev": { "type": [ "string", "null" ], "description": "Git branch to read the agent source from. Defaults to the\nproject repository's HEAD branch." } } }, "EnqueueEvalJobReqBody": { "type": "object", "properties": { "commit": { "type": "boolean", "description": "Commit the generated file to the env branch when the job\nsucceeds. Default false: the file lands uncommitted in the\nworktree for review (manual runs see it; the deploy gate needs a\ncommit)." }, "component_id": { "type": [ "string", "null" ], "description": "Workforce component by numeric app id (the `TIMBAL_APP_ID` value;\nnumber or string). At least one of `component_id` /\n`component_uid` is required; when both are set they must resolve\nto the same component." }, "component_uid": { "type": [ "string", "null" ], "description": "Workforce component by manifest uid (the `_id` in `timbal.yaml`)." }, "guidance": { "type": [ "string", "null" ], "description": "Optional steer for the generator, e.g. \"focus on the refund flow\"." }, "kind": { "type": [ "string", "null" ], "description": "Job kind. Defaults to `\"generate_initial\"` (the only kind today;\nthe vocabulary grows server-side without new endpoints)." } } }, "EnqueueEvalJobResBody": { "type": "object", "description": "Response body returned by the enqueue endpoint. The HTTP status is\n`202 Accepted` — poll `GET .../evals/jobs/{job_uid}` for terminal\nstate (a succeeded `generate_initial` job's file then shows up on\n`GET .../evals/definitions` with `committed: false` unless the job\ncommitted).", "required": [ "job_uid", "kind", "status" ], "properties": { "job_uid": { "type": "string", "format": "uuid" }, "kind": { "type": "string", "description": "Job kind (e.g. `\"generate_initial\"`)." }, "status": { "type": "string", "description": "Always `queued` at accept time." } } }, "EnqueueJobResBody": { "type": "object", "description": "Response body returned by any endpoint that enqueues a new job. The\nHTTP status is `202 Accepted` — poll `GET /ace/{ace_uid}/jobs/{job_uid}`\nfor terminal state.", "required": [ "ace_uid", "job_uid", "kind" ], "properties": { "ace_uid": { "type": "string", "format": "uuid" }, "job_uid": { "type": "string", "format": "uuid" }, "kind": { "type": "string", "description": "Job kind (e.g. `\"generate_initial\"`, `\"regenerate\"`)." } } }, "EnvPreview": { "type": "object", "required": [ "id", "name", "color" ], "properties": { "color": { "type": "string", "description": "Environment color" }, "id": { "type": "string", "description": "Environment identifier" }, "last_deployment_status": { "type": [ "string", "null" ], "description": "Status of the latest deployment in this environment" }, "name": { "type": "string", "description": "Environment name" } } }, "ErrorMessage": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (e.g. `ALREADY_EXISTS`, `BAD_REQUEST`)." }, "message": { "type": "string", "description": "Human-readable description." } } }, "EvalDefinition": { "type": "object", "description": "One eval test case parsed from a YAML file. Field-for-field mirror of\n`timbal.evals.models.Eval` plus provenance.", "required": [ "tags", "validators", "file", "committed", "spec" ], "properties": { "committed": { "type": "boolean", "description": "Whether the file content is committed at the branch head. Always\ntrue when reading from git; from the worktree, false means the\ndeploy gate won't see this version until it's committed (manual\nruns default to the worktree and will)." }, "description": { "type": [ "string", "null" ] }, "effective_runnable": { "type": [ "string", "null" ], "description": "`runnable` with the `evalconf.yaml` fallback resolved — what the\nCLI will actually load. Null means the CLI has nothing to run and\nthe eval will error." }, "env": { "description": "Env var overrides applied to the eval subprocess (`env` key)." }, "file": { "type": "string", "description": "Repo-relative path of the YAML file this eval lives in." }, "name": { "type": [ "string", "null" ], "description": "Eval name. Required by the CLI — a missing name fails the run." }, "params": { "description": "Input params passed to the runnable (`params` key), e.g. `prompt`." }, "runnable": { "type": [ "string", "null" ], "description": "FQN of the runnable under test as written in this entry, e.g.\n`../agent.py::agent`. Null when the entry relies on the\n`evalconf.yaml` default." }, "spec": { "description": "The full raw eval entry as parsed YAML (lossless ground truth)." }, "tags": { "type": "array", "items": { "type": "string" } }, "timeout": { "type": [ "number", "null" ], "format": "double", "description": "Per-eval timeout in ms, when set." }, "validators": { "type": "array", "items": { "$ref": "#/components/schemas/ValidatorSummary" }, "description": "Flattened assertions (value + flow validators) for display.\nThe authoritative form stays in `spec`." } } }, "EvalJobView": { "type": "object", "description": "Public view of a background eval job.", "required": [ "uid", "kind", "status", "component_id", "output", "queued_at" ], "properties": { "completed_at": { "type": [ "string", "null" ], "format": "date-time" }, "component_id": { "type": "string", "description": "Component the job writes evals for (`OrgsApps.id`) — same\nidentifier accepted as `component_id` on the other eval routes." }, "duration_ms": { "type": [ "integer", "null" ], "format": "int64" }, "error_message": { "type": [ "string", "null" ], "description": "Present when the job terminated unsuccessfully (`failed`, `error`)." }, "kind": { "type": "string", "description": "Job kind (e.g. `\"generate_initial\"`)." }, "output": { "description": "Kind-specific result payload; `{}` until the job succeeds. For\n`generate_initial`: files, eval_count, eval_names, summary,\ncommitted, commit_sha." }, "queued_at": { "type": "string", "format": "date-time" }, "started_at": { "type": [ "string", "null" ], "format": "date-time" }, "status": { "type": "string", "description": "`queued | running | succeeded | failed | error`." }, "uid": { "type": "string", "format": "uuid" } } }, "EvalRunComponent": { "type": "object", "description": "The workforce component an eval run targets. Same identifiers the\ndeployments list exposes on its `target` object: `id` is\n`OrgsApps.id` (accepted as `component_id` filters/body params), `uid`\nis the manifest `_id` from `timbal.yaml` (accepted as\n`component_uid`). `name`/`type` are display metadata; `uid`/`name`/\n`type` go NULL if the app row was deleted after the run.", "required": [ "id" ], "properties": { "id": { "type": "string" }, "name": { "type": [ "string", "null" ] }, "type": { "type": [ "string", "null" ], "description": "`agent` | `workflow`." }, "uid": { "type": [ "string", "null" ] } } }, "EvalRunDetail": { "type": "object", "description": "One eval run against a workforce component (deploy gate or manual).", "required": [ "id", "component", "trigger_type", "status", "started_at", "created_at" ], "properties": { "commit_hash": { "type": [ "string", "null" ], "description": "Git commit SHA the evals executed against." }, "component": { "$ref": "#/components/schemas/EvalRunComponent", "description": "The workforce component the evals ran against." }, "created_at": { "type": "string", "format": "date-time" }, "deployment_id": { "type": [ "string", "null" ], "description": "The `Deployments` row this run gated. NULL for manual runs." }, "finished_at": { "type": [ "string", "null" ], "format": "date-time" }, "id": { "type": "string" }, "logs": { "type": [ "string", "null" ], "description": "Captured CLI output (only when `include_logs=true`)." }, "results": { "description": "Structured per-eval results (timbal \u003E= 2.2.9): a flat array of\nper-eval objects — params/output/usage/validator verdicts/captured\noutput. On the list endpoint only when `include_results=true`;\nNULL for runs that predate structured capture or died before the\nreport." }, "started_at": { "type": "string", "format": "date-time" }, "status": { "type": "string", "description": "`running` | `passed` | `failed` | `error`." }, "status_detail": { "type": [ "string", "null" ], "description": "Short human summary, e.g. \"1 failed, 2 passed in 12.40s\"." }, "trigger_id": { "type": [ "string", "null" ], "description": "Deploy batch id — matches `Deployments.trigger_id`." }, "trigger_type": { "type": "string", "description": "What started the run: `deploy` | `manual` | `push`." } } }, "EvalRunEvent": { "type": "object", "description": "One streamed CLI event. `data` is the parsed JSONL line (or a JSON\nstring if the line wasn't valid JSON — contract violation, kept for\ndebugging). `seq` is 1-based and monotonic within a run.", "required": [ "seq", "data" ], "properties": { "data": { }, "seq": { "type": "integer", "format": "int64", "minimum": 0 } } }, "EvalRunEventsResponse": { "type": "object", "required": [ "eval_run_id", "events", "next_cursor", "done", "expired" ], "properties": { "done": { "type": "boolean", "description": "`true` once the run has finished and all buffered events up to\nthe terminal one have been returned." }, "eval_run_id": { "type": "string" }, "events": { "type": "array", "items": { "$ref": "#/components/schemas/EvalRunEvent" } }, "expired": { "type": "boolean", "description": "`true` when the run's in-memory buffer is no longer available\n(dropped on completion, never existed on this instance, or the\nowning process died). Terminal but **possibly incomplete** — do\nnot treat as a clean end-of-stream; re-fetch\n`GET …/evals/runs/{id}` for `status` + the full `results`." }, "next_cursor": { "type": "integer", "format": "int64", "description": "Pass as `after` on the next poll. Equals the last returned seq,\nor the request's `after` when the batch is empty.", "minimum": 0 } } }, "EvalRunSource": { "type": "string", "description": "Where to read the component source + eval YAML from for a manual run.", "enum": [ "worktree", "git" ] }, "ExistingDest": { "type": "string", "description": "What to do when `dest_table` already holds data — typically because a\none-off job extracted it and the sync is being added afterwards to keep it\nfresh.", "enum": [ "adopt", "replace" ] }, "FilesystemsRes": { "type": "object", "required": [ "filesystems" ], "properties": { "filesystems": { "type": "array", "items": { "type": "string" }, "description": "Filesystem root refs configured on the node (names only; the real\npaths they map to stay local)." } } }, "ForeignKeyView": { "type": "object", "required": [ "name", "columns", "ref_schema", "ref_table", "ref_columns" ], "properties": { "columns": { "type": "array", "items": { "type": "string" }, "description": "`columns[i]` references `ref_columns[i]`." }, "name": { "type": "string" }, "on_delete": { "type": [ "string", "null" ] }, "on_update": { "type": [ "string", "null" ] }, "ref_columns": { "type": "array", "items": { "type": "string" } }, "ref_schema": { "type": "string" }, "ref_table": { "type": "string" } } }, "FsDuRes": { "type": "object", "required": [ "file_count", "dir_count", "total_bytes", "truncated", "largest", "by_extension", "max_depth" ], "properties": { "by_extension": { "type": "array", "items": { "$ref": "#/components/schemas/FsExtStatView" }, "description": "Per-extension rollup, by bytes descending." }, "dir_count": { "type": "integer", "format": "int64", "minimum": 0 }, "file_count": { "type": "integer", "format": "int64", "minimum": 0 }, "largest": { "type": "array", "items": { "$ref": "#/components/schemas/FsLargestFileView" }, "description": "Top-N files by size, descending." }, "max_depth": { "type": "integer", "format": "int32", "description": "Deepest directory level seen (the walk root = 0).", "minimum": 0 }, "total_bytes": { "type": "integer", "format": "int64", "description": "Sum of regular-file sizes seen (symlinks excluded).", "minimum": 0 }, "truncated": { "type": "boolean", "description": "The walk hit a cap — every count is a floor, not a total." }, "truncated_reason": { "type": [ "string", "null" ] } } }, "FsEntryView": { "type": "object", "required": [ "name", "path", "kind" ], "properties": { "kind": { "type": "string", "description": "`file` | `dir` | `symlink` | `other`." }, "mtime_epoch_secs": { "type": [ "integer", "null" ], "format": "int64", "description": "Modification time (unix epoch seconds)." }, "name": { "type": "string", "description": "Bare entry name." }, "path": { "type": "string", "description": "Root-relative path — feed it back into ls/du/grep or a copy." }, "size_bytes": { "type": [ "integer", "null" ], "format": "int64", "description": "Regular files only; `null` for directories/symlinks/other.", "minimum": 0 } } }, "FsExtStatView": { "type": "object", "required": [ "extension", "count", "bytes" ], "properties": { "bytes": { "type": "integer", "format": "int64", "minimum": 0 }, "count": { "type": "integer", "format": "int64", "minimum": 0 }, "extension": { "type": "string", "description": "Lowercased, no dot; extensionless files roll up under `\"\"`." } } }, "FsGrepMatchView": { "type": "object", "required": [ "path", "line_number", "line" ], "properties": { "line": { "type": "string", "description": "The matching line (length-capped node-side)." }, "line_number": { "type": "integer", "format": "int64", "description": "1-based.", "minimum": 0 }, "path": { "type": "string", "description": "Root-relative path." } } }, "FsGrepRes": { "type": "object", "required": [ "matches", "files_scanned", "files_matched", "truncated" ], "properties": { "files_matched": { "type": "integer", "format": "int64", "minimum": 0 }, "files_scanned": { "type": "integer", "format": "int64", "minimum": 0 }, "matches": { "type": "array", "items": { "$ref": "#/components/schemas/FsGrepMatchView" } }, "truncated": { "type": "boolean", "description": "A cap bit (matches, files, bytes, or time) — `matches` is a prefix." } } }, "FsLargestFileView": { "type": "object", "required": [ "path", "size_bytes" ], "properties": { "path": { "type": "string", "description": "Root-relative path." }, "size_bytes": { "type": "integer", "format": "int64", "minimum": 0 } } }, "FsLsRes": { "type": "object", "required": [ "entries", "truncated" ], "properties": { "entries": { "type": "array", "items": { "$ref": "#/components/schemas/FsEntryView" } }, "truncated": { "type": "boolean", "description": "The entry cap bit — `entries` is a prefix of the real listing." } } }, "GetK2FileResponse": { "allOf": [ { "$ref": "#/components/schemas/K2File" }, { "type": "object", "required": [ "parsings", "embeddings" ], "properties": { "embeddings": { "type": "array", "items": { "$ref": "#/components/schemas/K2FileEmbedding" } }, "parsings": { "type": "array", "items": { "$ref": "#/components/schemas/K2FileParsing" } } } } ] }, "GetOrgResBody": { "type": "object", "required": [ "org" ], "properties": { "org": { "$ref": "#/components/schemas/Org" } } }, "GrantAttribution": { "type": "object", "description": "Attribution for a single grant: which role contributed it, what\nattachment-level scope was in effect, and the resource pattern as\nauthored on the role (pre-scope-intersection).\n\nShared by `POST /iam/check` (matched_allows / matched_denies) and\n`GET /iam/users/{id}/effective-grants` (the `via` field on each row).\n\nTo derive the effective resource a grant matched against, compute\n`resource_pattern_intersect(grant_resource, attachment_scope)`. When\n`attachment_scope` is `null`, the effective resource equals\n`grant_resource`.", "required": [ "role_id", "role_name" ], "properties": { "attachment_scope": { "type": [ "string", "null" ] }, "grant_resource": { "type": [ "string", "null" ] }, "role_id": { "type": "string" }, "role_name": { "type": "string" } } }, "GrantEffect": { "type": "string", "description": "Effect of a [`RoleGrant`]. `deny` wins at eval time.", "enum": [ "allow", "deny" ] }, "GroupRoleMappingView": { "type": "object", "description": "View of a group→role mapping.", "required": [ "id", "provider_id", "external_group", "role_id", "created_at", "updated_at" ], "properties": { "created_at": { "type": "integer", "format": "int64" }, "external_group": { "type": "string" }, "id": { "type": "string" }, "provider_id": { "type": "string" }, "role_id": { "type": "string" }, "updated_at": { "type": "integer", "format": "int64" } } }, "HashAlg": { "type": "string", "description": "Hash family for `hash` / `pseudonymize` masks.", "enum": [ "sha256", "sha512" ] }, "IdentityProviderKind": { "type": "string", "description": "Which provider implementation drives a connection's login flow. Mirrors the\n`kind` CHECK in `db/init.sql`; widened additively as kinds ship (`oidc`\nfirst, `saml` later).", "enum": [ "oidc", "saml", "directory" ] }, "IdentityProviderView": { "type": "object", "description": "Masked view of a connection. Never includes the client secret.", "required": [ "id", "org_id", "kind", "provider_key", "allowed_domains", "client_secret_set", "enabled", "enforced", "created_at", "updated_at" ], "properties": { "allowed_domains": { "type": "array", "items": { "type": "string" } }, "client_id": { "type": [ "string", "null" ], "description": "OIDC client id. `null` for non-OIDC kinds." }, "client_secret_set": { "type": "boolean", "description": "Whether a client secret is configured. The secret itself is never\nreturned." }, "created_at": { "type": "integer", "format": "int64" }, "default_role_id": { "type": [ "string", "null" ], "description": "Catch-all role granted to JIT members with no matching group mapping.\n`null` = no catch-all role." }, "display_name": { "type": [ "string", "null" ] }, "enabled": { "type": "boolean" }, "enforced": { "type": "boolean", "description": "Read-only here: SSO enforcement isn't configurable via the API yet." }, "groups_claim": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "issuer": { "type": [ "string", "null" ], "description": "OIDC issuer. `null` for non-OIDC kinds (e.g. SAML), whose connection\ndetails live in kind-specific fields added when those kinds ship." }, "kind": { "type": "string" }, "org_id": { "type": "string" }, "provider_key": { "type": "string" }, "scopes": { "type": [ "string", "null" ] }, "updated_at": { "type": "integer", "format": "int64" } } }, "IndexView": { "type": "object", "required": [ "name", "unique", "primary", "columns" ], "properties": { "columns": { "type": "array", "items": { "type": "string" }, "description": "Key columns in index order." }, "kind": { "type": [ "string", "null" ], "description": "Source-native kind (`btree`, `CLUSTERED`, `FULLTEXT`, …)." }, "name": { "type": "string" }, "primary": { "type": "boolean", "description": "Backs the table's `PRIMARY KEY`." }, "unique": { "type": "boolean" } } }, "InsertK2ChunkRequest": { "type": "object", "required": [ "content" ], "properties": { "after_uid": { "type": [ "string", "null" ], "format": "uuid", "description": "Place the new chunk immediately after this `chunk_uid`. Mutually\nexclusive with `before_uid`. If neither is set, the chunk is\nappended at the end of the file." }, "before_uid": { "type": [ "string", "null" ], "format": "uuid", "description": "Place the new chunk immediately before this `chunk_uid`. Mutually\nexclusive with `after_uid`." }, "content": { "type": "string" }, "embed": { "type": [ "string", "null" ], "description": "Text used for vector / full-text indexing. Defaults to `content`\nwhen omitted; provide an explicit value to keep an\nindexing-optimized variant distinct from the user-visible text." }, "page_end": { "type": [ "integer", "null" ], "format": "int32" }, "page_start": { "type": [ "integer", "null" ], "format": "int32" } } }, "IntegrationPreview": { "type": "object", "required": [ "id", "provider", "name" ], "properties": { "id": { "type": "string", "description": "Integration identifier" }, "logo_url": { "type": [ "string", "null" ], "description": "Integration logo URL" }, "name": { "type": "string", "description": "Integration display name" }, "provider": { "type": "string", "description": "Integration provider key" } } }, "InviteOrgUserReqBody": { "type": "object", "properties": { "email": { "type": [ "string", "null" ], "description": "Single email address to invite. Legacy shape — prefer `emails`.\nMerged with `emails` when both are provided." }, "emails": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Email addresses to invite to the organization." }, "send_email": { "type": "boolean", "description": "Whether to send an invitation email to each invitee. Defaults to `true`." } } }, "JobView": { "type": "object", "required": [ "id", "connector_id", "kb_uid", "kind", "dest_table", "mode", "state", "rows_emitted", "created_at", "updated_at" ], "properties": { "connector_id": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "dest_table": { "type": "string" }, "duration_ms": { "type": [ "integer", "null" ], "format": "int64", "description": "Run duration in ms — to `finished_at`, or to \"now\" for a live run." }, "finished_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the run reached a terminal state; `null` while still active." }, "id": { "type": "string" }, "kb_uid": { "type": "string" }, "kind": { "type": "string", "description": "`extract` (row batches into a KB table) or `fs_copy` (files into the\nKB document store; `rows_emitted` counts landed files)." }, "message": { "type": [ "string", "null" ] }, "mode": { "type": "string" }, "rows_emitted": { "type": "integer", "format": "int64" }, "rows_per_sec": { "type": [ "number", "null" ], "format": "double", "description": "Average landed throughput over the run window; `null` until measurable." }, "started_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the run first reported progress (excludes time queued)." }, "state": { "type": "string" }, "sync_id": { "type": [ "string", "null" ], "description": "Parent sync this run belongs to; `null` for one-off manual dispatches." }, "updated_at": { "type": "string", "format": "date-time" } } }, "K2Chunk": { "type": "object", "required": [ "uid", "kb_file_id", "ordinal", "content", "embed", "blocks", "index_status", "revision", "source", "created_at", "updated_at" ], "properties": { "blocks": { "type": "object", "description": "Source-document layout metadata (e.g. bounding boxes, page coords)\nwhen available. `null` for chunks created or edited by the user." }, "content": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "embed": { "type": "string" }, "index_error": { "type": [ "string", "null" ] }, "index_status": { "type": "string", "description": "Indexing state for search (`pending`, `indexing`, `indexed`, or `failed`)." }, "indexed_at": { "type": [ "string", "null" ], "format": "date-time" }, "kb_file_id": { "type": "string" }, "ordinal": { "type": "string", "description": "Ordering key within the file." }, "page_end": { "type": [ "integer", "null" ], "format": "int32" }, "page_start": { "type": [ "integer", "null" ], "format": "int32" }, "revision": { "type": "string", "description": "Revision token for optimistic concurrency on update and delete." }, "source": { "type": "string", "description": "Origin of the chunk: `parser`, `user_edit`, or `insert`." }, "uid": { "type": "string", "format": "uuid", "description": "Stable per-chunk identity." }, "updated_at": { "type": "string", "format": "date-time" } } }, "K2ChunkSummary": { "type": "object", "description": "List-endpoint payload. Same fields as [`K2Chunk`] except `blocks`,\nwhich is omitted to keep list responses small. Fetch a single chunk\nby `uid` to retrieve `blocks`.", "required": [ "uid", "kb_file_id", "ordinal", "content", "embed", "index_status", "revision", "source", "created_at", "updated_at" ], "properties": { "content": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "embed": { "type": "string" }, "index_error": { "type": [ "string", "null" ] }, "index_status": { "type": "string" }, "indexed_at": { "type": [ "string", "null" ], "format": "date-time" }, "kb_file_id": { "type": "string" }, "ordinal": { "type": "string" }, "page_end": { "type": [ "integer", "null" ], "format": "int32" }, "page_start": { "type": [ "integer", "null" ], "format": "int32" }, "revision": { "type": "string" }, "source": { "type": "string" }, "uid": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" } } }, "K2Column": { "type": "object", "required": [ "name", "data_type", "is_nullable" ], "properties": { "data_type": { "type": "string" }, "is_nullable": { "type": "boolean" }, "name": { "type": "string" } } }, "K2Constraint": { "type": "object", "required": [ "constraint_type" ], "properties": { "columns": { "type": "array", "items": { "type": "string" }, "description": "Columns involved (for PK, UNIQUE, NOT_NULL). Empty for CHECK." }, "constraint_type": { "$ref": "#/components/schemas/K2ConstraintType" }, "expression": { "type": [ "string", "null" ], "description": "CHECK expression, if applicable." }, "foreign_keys": { "type": "array", "items": { "$ref": "#/components/schemas/K2ForeignKey" }, "description": "Foreign key references, if applicable." } } }, "K2ConstraintType": { "type": "string", "enum": [ "PRIMARY_KEY", "UNIQUE", "FOREIGN_KEY", "CHECK", "NOT_NULL" ] }, "K2Detail": { "type": "object", "required": [ "id", "uid", "name", "data_size_bytes", "table_count", "row_count", "vector_count", "index_count", "auto_processing_enabled", "governance_mode", "backup_enabled", "created_at", "updated_at" ], "properties": { "auto_processing_enabled": { "type": "boolean", "description": "When false, file uploads to this knowledge base are stored as-is and skipped by the automatic parsing, chunking, and embedding pipeline." }, "backup_enabled": { "type": "boolean", "description": "DEPRECATED: backups are system-managed for every KB (idle teardown +\ndaily window pass); this flag gates nothing. Still returned for\nexisting clients; PATCH ignores it.", "deprecated": true }, "backup_last_completed_at": { "type": [ "string", "null" ], "format": "date-time" }, "backup_last_error": { "type": [ "string", "null" ] }, "backup_last_started_at": { "type": [ "string", "null" ], "format": "date-time" }, "backup_last_status": { "type": [ "string", "null" ] }, "backup_retention_days": { "type": [ "integer", "null" ], "format": "int32" }, "backup_s3_bucket": { "type": [ "string", "null" ] }, "backup_s3_key_prefix": { "type": [ "string", "null" ] }, "backup_schedule_cron": { "type": [ "string", "null" ], "description": "DEPRECATED: never had a cron behind it; superseded by\n`backup_window_utc_hour`. Still returned for existing clients; PATCH\nignores it.", "deprecated": true }, "backup_window_utc_hour": { "type": [ "integer", "null" ], "format": "int32", "description": "UTC hour (0–23) of this KB's daily backup window; `null` = fleet\ndefault (01:00 UTC). The daily cadence itself is fixed." }, "created_at": { "type": "string", "format": "date-time" }, "data_size_bytes": { "type": "integer", "format": "int64", "minimum": 0 }, "description": { "type": [ "string", "null" ] }, "governance_mode": { "$ref": "#/components/schemas/K2GovernanceMode", "description": "Query-time governance mode. Toggle via `PUT …/k2/{kb_id}/policies/governance-mode` (`k2.policies.manage`)." }, "id": { "type": "integer", "format": "int64" }, "index_count": { "type": "integer", "format": "int64", "minimum": 0 }, "name": { "type": "string" }, "row_count": { "type": "integer", "format": "int64", "minimum": 0 }, "table_count": { "type": "integer", "format": "int64", "minimum": 0 }, "uid": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" }, "vector_count": { "type": "integer", "format": "int64", "minimum": 0 } } }, "K2File": { "type": "object", "required": [ "id", "uid", "kb_id", "name", "content_type", "content_length", "metadata", "parse_state", "url", "created_at", "updated_at" ], "properties": { "content_length": { "type": "integer", "format": "int64" }, "content_type": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "directory": { "type": [ "string", "null" ] }, "id": { "type": "integer", "format": "int64" }, "kb_id": { "type": "integer", "format": "int64" }, "metadata": { }, "name": { "type": "string" }, "parse_state": { "type": "string", "description": "Pipeline state for parsing + embedding.\n\nOne of `pending` (pipeline in flight), `success` (parse + embed both completed),\n`failed` (latest attempt failed), or `skipped` (format unsupported, never parsed).\nUnsupported files are stored as-is; the indicator lets clients flag them in listings\nrather than rejecting the upload." }, "signed_url": { "type": [ "string", "null" ], "description": "CloudFront signed URL on the new CDN for private content. Omitted when\nsigning is unavailable or the object is public." }, "uid": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" }, "url": { "type": "string", "description": "**Deprecated:** prefer `signed_url` when present. Kept for old clients.", "deprecated": true } } }, "K2FileEmbedding": { "type": "object", "required": [ "id", "kb_file_id", "provider", "model", "status", "created_at", "updated_at" ], "properties": { "chunk_count": { "type": [ "integer", "null" ], "format": "int32" }, "cost_usd": { "type": [ "number", "null" ], "format": "double" }, "created_at": { "type": "string", "format": "date-time" }, "error": { "type": [ "string", "null" ] }, "id": { "type": "integer", "format": "int64" }, "kb_file_id": { "type": "integer", "format": "int64" }, "model": { "type": "string" }, "parsing_id": { "type": [ "integer", "null" ], "format": "int64" }, "provider": { "type": "string" }, "status": { "type": "string" }, "token_count": { "type": [ "integer", "null" ], "format": "int32" }, "updated_at": { "type": "string", "format": "date-time" } } }, "K2FileParsing": { "type": "object", "required": [ "id", "kb_file_id", "provider", "status", "created_at", "updated_at" ], "properties": { "chunk_count": { "type": [ "integer", "null" ], "format": "int32" }, "cost_usd": { "type": [ "number", "null" ], "format": "double" }, "created_at": { "type": "string", "format": "date-time" }, "error": { "type": [ "string", "null" ] }, "id": { "type": "integer", "format": "int64" }, "kb_file_id": { "type": "integer", "format": "int64" }, "num_pages": { "type": [ "integer", "null" ], "format": "int32" }, "provider": { "type": "string" }, "provider_job_id": { "type": [ "string", "null" ] }, "s3_bucket": { "type": [ "string", "null" ] }, "s3_key": { "type": [ "string", "null" ] }, "status": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "K2ForeignKey": { "type": "object", "required": [ "column", "ref_table", "ref_column" ], "properties": { "column": { "type": "string" }, "ref_column": { "type": "string" }, "ref_table": { "type": "string" } } }, "K2GovernanceMode": { "type": "string", "description": "Per-KB query governance mode.", "enum": [ "off", "shadow", "enforce" ] }, "K2GovernanceModeResponse": { "type": "object", "required": [ "governance_mode" ], "properties": { "governance_mode": { "$ref": "#/components/schemas/K2GovernanceMode" } } }, "K2Index": { "type": "object", "required": [ "name", "table_name", "columns", "is_unique" ], "properties": { "columns": { "type": "array", "items": { "type": "string" } }, "is_unique": { "type": "boolean" }, "name": { "type": "string" }, "table_name": { "type": "string" } } }, "K2Policy": { "type": "object", "required": [ "id", "kb_id", "name", "enabled", "row_filter_dsl", "compliance_tags", "purpose_tags", "audit_level", "break_glass_allowed", "source", "labels", "revision", "created_at", "updated_at" ], "properties": { "audit_level": { "$ref": "#/components/schemas/K2PolicyAuditLevel" }, "break_glass_allowed": { "type": "boolean", "description": "Whether sessions may bypass the rule via a logged escalation." }, "column_masks": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BTreeMap", "description": "Per-column transformation map. Null means no masks.\n`{\"col\": {\"type\":\"redact\"}}` is the canonical \"hide this column\"." } ] }, "compliance_tags": { "type": "array", "items": { "type": "string" }, "description": "Compliance classifications (e.g. `hipaa.phi`, `pci.pan`)." }, "created_at": { "type": "string", "format": "date-time" }, "description": { "type": [ "string", "null" ] }, "enabled": { "type": "boolean", "description": "When false, the rule body is inactive everywhere it is bound." }, "external_id": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "kb_id": { "type": "string" }, "labels": { "type": "object", "description": "Free-form key/value labels." }, "name": { "type": "string", "description": "Operator-facing label." }, "purpose_tags": { "type": "array", "items": { "type": "string" }, "description": "Purpose-of-use bindings (e.g. `treatment`, `research`)." }, "revision": { "type": "integer", "format": "int32", "description": "Revision token for optimistic concurrency on update and delete." }, "row_filter_dsl": { "type": "object", "description": "Row predicate authored as JSON. Stored opaquely in this release." }, "source": { "$ref": "#/components/schemas/K2PolicySource" }, "table_name": { "type": [ "string", "null" ], "description": "Target table within the knowledge base. Null applies to every table." }, "updated_at": { "type": "string", "format": "date-time" } } }, "K2PolicyAssignment": { "type": "object", "required": [ "id", "policy_id", "role_id", "enabled", "priority", "combine_mode", "granted_at", "created_at", "updated_at" ], "properties": { "combine_mode": { "$ref": "#/components/schemas/K2PolicyCombineMode" }, "created_at": { "type": "string", "format": "date-time" }, "enabled": { "type": "boolean" }, "granted_at": { "type": "string", "format": "date-time" }, "granted_by": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "policy_id": { "type": "string" }, "priority": { "type": "integer", "format": "int32" }, "revoked_at": { "type": [ "string", "null" ], "format": "date-time" }, "revoked_by": { "type": [ "string", "null" ] }, "role_id": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" }, "valid_from": { "type": [ "string", "null" ], "format": "date-time" }, "valid_until": { "type": [ "string", "null" ], "format": "date-time" } } }, "K2PolicyAuditLevel": { "type": "string", "description": "Audit verbosity for matches against this rule.", "enum": [ "none", "normal", "verbose" ] }, "K2PolicyCombineMode": { "type": "string", "description": "Postgres-RLS-style combination semantic for a policy binding.", "enum": [ "restrictive", "permissive" ] }, "K2PolicySource": { "type": "string", "description": "Provenance of the rule.", "enum": [ "manual", "imported", "derived" ] }, "K2Preview": { "type": "object", "required": [ "id", "uid", "name", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "data_size_bytes": { "type": [ "integer", "null" ], "format": "int64", "minimum": 0 }, "description": { "type": [ "string", "null" ] }, "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "uid": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "K2Schema": { "type": "object", "required": [ "tables" ], "properties": { "tables": { "type": "array", "items": { "$ref": "#/components/schemas/K2Table" } } } }, "K2SchemaSql": { "type": "object", "required": [ "statements" ], "properties": { "statements": { "type": "array", "items": { "type": "string" }, "description": "DDL statements (CREATE TABLE, CREATE INDEX, etc.)" } } }, "K2Table": { "type": "object", "required": [ "name", "source", "columns", "indexes", "constraints", "estimated_row_count" ], "properties": { "columns": { "type": "array", "items": { "$ref": "#/components/schemas/K2Column" } }, "constraints": { "type": "array", "items": { "$ref": "#/components/schemas/K2Constraint" } }, "estimated_row_count": { "type": "integer", "format": "int64", "minimum": 0 }, "indexes": { "type": "array", "items": { "$ref": "#/components/schemas/K2Index" } }, "name": { "type": "string" }, "schema": { "type": [ "string", "null" ] }, "source": { "$ref": "#/components/schemas/K2TableSource" } } }, "K2TableSource": { "type": "string", "enum": [ "primary", "vectors" ] }, "KbBackupResponse": { "type": "object", "required": [ "id", "kb_id", "status", "triggered_by", "dry_run", "started_at" ], "properties": { "bytes_uploaded": { "type": [ "integer", "null" ], "format": "int64" }, "completed_at": { "type": [ "string", "null" ], "format": "date-time" }, "dry_run": { "type": "boolean" }, "error": { "type": [ "string", "null" ] }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" }, "id": { "type": "string" }, "kb_id": { "type": "string" }, "started_at": { "type": "string", "format": "date-time" }, "status": { "type": "string" }, "triggered_by": { "type": "string" } } }, "KbPreview": { "type": "object", "required": [ "id", "uid", "name" ], "properties": { "description": { "type": [ "string", "null" ], "description": "Knowledge base description" }, "id": { "type": "string", "description": "Knowledge base identifier" }, "name": { "type": "string", "description": "Knowledge base name" }, "uid": { "type": "string", "description": "Knowledge base unique identifier" } } }, "KbRestoreResponse": { "type": "object", "required": [ "id", "kb_id", "source_backup_id", "status", "triggered_by", "started_at" ], "properties": { "bytes_downloaded": { "type": [ "integer", "null" ], "format": "int64" }, "completed_at": { "type": [ "string", "null" ], "format": "date-time" }, "error": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "kb_id": { "type": "string" }, "source_backup_id": { "type": "string" }, "started_at": { "type": "string", "format": "date-time" }, "status": { "type": "string" }, "triggered_by": { "type": "string" } } }, "LinkAceReqBody": { "type": "object", "description": "Request body for linking an existing ACE to a workforce.", "required": [ "ace_uid" ], "properties": { "ace_uid": { "type": "string", "format": "uuid", "description": "`uid` of an existing ACE in the same organization." } } }, "LinkKbRequest": { "type": "object", "required": [ "kb_id" ], "properties": { "kb_id": { "type": "string", "description": "ID of the K2 knowledge base to link to this project" } } }, "ListAceJobsResBody": { "type": "object", "required": [ "jobs", "total" ], "properties": { "jobs": { "type": "array", "items": { "$ref": "#/components/schemas/AceJobView" } }, "total": { "type": "string" } } }, "ListActionsResBody": { "type": "object", "required": [ "actions" ], "properties": { "actions": { "type": "array", "items": { "$ref": "#/components/schemas/ActionInfo" }, "description": "Grantable actions for the organization." } } }, "ListBackupsResponse": { "type": "object", "required": [ "backups" ], "properties": { "backups": { "type": "array", "items": { "$ref": "#/components/schemas/KbBackupResponse" } }, "next_page_token": { "type": [ "string", "null" ] } } }, "ListCreditGrantsResBody": { "type": "object", "required": [ "credit_grants" ], "properties": { "credit_grants": { "type": "array", "items": { "$ref": "#/components/schemas/CreditGrant" } } } }, "ListDeploymentsResBody": { "type": "object", "required": [ "deployments" ], "properties": { "deployments": { "type": "array", "items": { "$ref": "#/components/schemas/DeploymentDetail" } } } }, "ListDomainsResBody": { "type": "object", "required": [ "domains" ], "properties": { "domains": { "type": "array", "items": { "$ref": "#/components/schemas/Domain" } } } }, "ListEmbeddingModelsResBody": { "type": "object", "required": [ "embedding_models" ], "properties": { "embedding_models": { "type": "array", "items": { "$ref": "#/components/schemas/EmbeddingModel" } } } }, "ListEnvsResBody": { "type": "object", "required": [ "envs" ], "properties": { "envs": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectEnv" } } } }, "ListEvalDefinitionsResBody": { "type": "object", "required": [ "source", "rev", "commit_hash", "components" ], "properties": { "commit_hash": { "type": "string", "description": "Head commit of that rev. With `source = \"worktree\"`, uncommitted\nfile changes are NOT part of this commit — check per-file\n`committed` flags." }, "components": { "type": "array", "items": { "$ref": "#/components/schemas/ComponentEvals" } }, "rev": { "type": "string", "description": "Branch (worktree) or rev (git) the definitions were read from." }, "source": { "type": "string", "description": "Where definitions were read from: `worktree` or `git`." } } }, "ListEvalJobsResBody": { "type": "object", "required": [ "jobs", "total" ], "properties": { "jobs": { "type": "array", "items": { "$ref": "#/components/schemas/EvalJobView" } }, "total": { "type": "string" } } }, "ListEvalRunsResBody": { "type": "object", "required": [ "eval_runs" ], "properties": { "eval_runs": { "type": "array", "items": { "$ref": "#/components/schemas/EvalRunDetail" } } } }, "ListGroupRoleMappingsResBody": { "type": "object", "required": [ "group_role_mappings" ], "properties": { "group_role_mappings": { "type": "array", "items": { "$ref": "#/components/schemas/GroupRoleMappingView" } } } }, "ListIdentityProvidersResBody": { "type": "object", "required": [ "identity_providers" ], "properties": { "identity_providers": { "type": "array", "items": { "$ref": "#/components/schemas/IdentityProviderView" } } } }, "ListJobsRes": { "type": "object", "required": [ "jobs" ], "properties": { "jobs": { "type": "array", "items": { "$ref": "#/components/schemas/JobView" } } } }, "ListK2ChunksResponse": { "type": "object", "required": [ "chunks" ], "properties": { "chunks": { "type": "array", "items": { "$ref": "#/components/schemas/K2ChunkSummary" } }, "next_page_token": { "type": [ "string", "null" ] } } }, "ListK2FilesResponse": { "type": "object", "required": [ "files" ], "properties": { "files": { "type": "array", "items": { "$ref": "#/components/schemas/K2File" } }, "next_page_token": { "type": [ "string", "null" ] } } }, "ListK2PoliciesResponse": { "type": "object", "required": [ "policies" ], "properties": { "next_page_token": { "type": [ "string", "null" ] }, "policies": { "type": "array", "items": { "$ref": "#/components/schemas/K2Policy" } } } }, "ListK2PolicyAssignmentsResponse": { "type": "object", "required": [ "assignments" ], "properties": { "assignments": { "type": "array", "items": { "$ref": "#/components/schemas/K2PolicyAssignment" } }, "next_page_token": { "type": [ "string", "null" ] } } }, "ListK2Response": { "type": "object", "required": [ "k2" ], "properties": { "k2": { "type": "array", "items": { "$ref": "#/components/schemas/K2Preview" } }, "next_page_token": { "type": [ "string", "null" ] } } }, "ListMetricDefinitionsResBody": { "type": "object", "title": "ListOrgMetricDefinitionsResponse", "description": "Wrapper for **GET** `/orgs/{org_id}/metrics/definitions`.", "required": [ "definitions" ], "properties": { "definitions": { "type": "array", "items": { "$ref": "#/components/schemas/MetricDefinitionOut" } } } }, "ListOrgAlarmsResBody": { "type": "object", "title": "ListOrgAlarmsResponse", "description": "Wrapper for **GET** `/orgs/{org_id}/alarms`.", "required": [ "alarms" ], "properties": { "alarms": { "type": "array", "items": { "$ref": "#/components/schemas/AlarmOut" } } } }, "ListOrgChannelsResBody": { "type": "object", "title": "ListOrgChannelsResponse", "required": [ "channels" ], "properties": { "channels": { "type": "array", "items": { "$ref": "#/components/schemas/NotificationChannelOut" } } } }, "ListOrgContactsResBody": { "type": "object", "required": [ "contacts" ], "properties": { "contacts": { "type": "array", "items": { "$ref": "#/components/schemas/OrgContact" } } } }, "ListOrgModelPoliciesResBody": { "type": "object", "title": "ListOrgModelPoliciesResponse", "required": [ "policies" ], "properties": { "policies": { "type": "array", "items": { "$ref": "#/components/schemas/ModelPolicy" } } } }, "ListOrgRolesResBody": { "type": "object", "required": [ "roles" ], "properties": { "roles": { "type": "array", "items": { "$ref": "#/components/schemas/RolePreview" }, "description": "Roles available to this organization — system rows first, then\ncustom rows alphabetically by name." } } }, "ListOrgUsersResBody": { "type": "object", "required": [ "org_users" ], "properties": { "next_page_token": { "type": [ "string", "null" ], "description": "Token to fetch the next page, or null if this is the last page" }, "org_users": { "type": "array", "items": { "$ref": "#/components/schemas/OrgUser" }, "description": "List of users in the organization" } } }, "ListOrgsResult": { "type": "object", "required": [ "orgs" ], "properties": { "next_page_token": { "type": [ "string", "null" ], "description": "Next page token" }, "orgs": { "type": "array", "items": { "$ref": "#/components/schemas/OrgPreview" }, "description": "List of organizations" } } }, "ListPoliciesResBody": { "type": "object", "required": [ "policies" ], "properties": { "policies": { "type": "array", "items": { "$ref": "#/components/schemas/AcePolicy" } } } }, "ListProjectsResBody": { "oneOf": [ { "type": "object", "required": [ "projects" ], "properties": { "projects": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectPreview" } } } }, { "type": "object", "required": [ "projects" ], "properties": { "projects": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectDetail" } } } } ] }, "ListReactionsResBody": { "type": "object", "required": [ "reactions" ], "properties": { "next_page_token": { "type": [ "string", "null" ] }, "reactions": { "type": "array", "items": { "$ref": "#/components/schemas/Reaction" } } } }, "ListRestoresResponse": { "type": "object", "required": [ "restores" ], "properties": { "next_page_token": { "type": [ "string", "null" ] }, "restores": { "type": "array", "items": { "$ref": "#/components/schemas/KbRestoreResponse" } } } }, "ListRunsResBody": { "type": "object", "required": [ "runs" ], "properties": { "next_page_token": { "type": [ "string", "null" ], "description": "Cursor for the next page" }, "runs": { "type": "array", "items": { "$ref": "#/components/schemas/RunPreview" }, "description": "List of runs" } } }, "ListScimTokensResBody": { "type": "object", "required": [ "scim_tokens" ], "properties": { "scim_tokens": { "type": "array", "items": { "$ref": "#/components/schemas/ScimTokenView" } } } }, "ListSyncsRes": { "type": "object", "required": [ "syncs" ], "properties": { "syncs": { "type": "array", "items": { "$ref": "#/components/schemas/SyncView" } } } }, "ListTemplatesResBody": { "type": "object", "required": [ "templates" ], "properties": { "templates": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectTemplate" } } } }, "ListVarsResBody": { "type": "object", "required": [ "vars" ], "properties": { "vars": { "type": "array", "items": { "$ref": "#/components/schemas/Var" } } } }, "ListWorkforceResBody": { "type": "object", "description": "Workforce components on the git branch given by `rev`. The `url` field is set only when the component has a **running** deployment for that branch.", "required": [ "workforce" ], "properties": { "workforce": { "type": "array", "items": { "$ref": "#/components/schemas/WorkforcePreview" } } } }, "LocalConfigReq": { "type": "object", "properties": { "connections": { "type": "object", "description": "`connection_ref` → connection object, same shape as the `connections`\nmap in the connector's `config.json` (e.g. `{ \"kind\": \"postgres\",\n\"dsn\": \"...\", \"query\": \"read\" }`). When present, **replaces** the\nconnector's whole local connections map. Absent = keep local." }, "filesystems": { "type": "object", "description": "`filesystem_ref` → filesystem root object, same shape as the\n`filesystems` map in `config.json` (e.g. `{ \"path\": \"/srv/exports\" }`).\nWhen present, **replaces** the connector's whole local filesystems map.\nAbsent = keep local." } } }, "LocalConfigRes": { "type": "object", "required": [ "dispatched", "connections", "filesystems" ], "properties": { "connections": { "type": "boolean", "description": "Which maps were included in the push." }, "dispatched": { "type": "boolean", "description": "Always true on a 202 — the connector validates/acks asynchronously\nover the channel and restarts to apply; watch the fleet listing for it\nto reconnect." }, "filesystems": { "type": "boolean" } } }, "MetricBinOut": { "type": "object", "description": "One aggregated time bucket of a metric series.", "required": [ "ts", "count", "sum" ], "properties": { "avg": { "type": [ "number", "null" ], "format": "double" }, "count": { "type": "integer", "format": "int64", "description": "Observations in the bucket." }, "max": { "type": [ "number", "null" ], "format": "double" }, "min": { "type": [ "number", "null" ], "format": "double" }, "sum": { "type": "number", "format": "double" }, "ts": { "type": "integer", "format": "int64", "description": "Bucket start (epoch milliseconds)." } } }, "MetricCatalogEntry": { "type": "object", "description": "One metric name observed in the window, with the labels seen under it.", "required": [ "name", "origin", "definition_ids", "labels", "label_count", "observations", "last_seen" ], "properties": { "definition_ids": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Definitions feeding this series, for linking a custom metric to the\nconfig behind it. Empty for system metrics, and for a custom series\nwhose definition was deleted while its bins age out." }, "label_count": { "type": "integer", "format": "int64", "description": "Distinct labels observed, even when `labels` was truncated. A number\nfar above the cap means a filter is minting labels from something\nunbounded." }, "labels": { "type": "array", "items": { "type": "string" }, "description": "Distinct `label` values observed, capped — see `label_count` for the\ntrue total. Empty for metrics that don't use the label dimension." }, "last_seen": { "type": "integer", "format": "int64", "description": "Most recent bin (epoch milliseconds)." }, "name": { "type": "string" }, "observations": { "type": "integer", "format": "int64", "description": "Observations recorded in the window." }, "origin": { "$ref": "#/components/schemas/MetricOrigin", "description": "`system` for platform series, `custom` for org-defined ones." } } }, "MetricDefinitionOut": { "type": "object", "required": [ "id", "name", "metric_name", "source", "value_source", "label_source", "enabled", "created_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "enabled": { "type": "boolean" }, "has_error": { "type": [ "boolean", "null" ] }, "id": { "type": "integer", "format": "int64" }, "label_source": { "type": "string", "description": "`none` or `span_name`." }, "metric_name": { "type": "string" }, "min_duration_ms": { "type": [ "integer", "null" ], "format": "int32" }, "name": { "type": "string" }, "project_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Project scope; omitted when the filter applies to the whole org." }, "source": { "$ref": "#/components/schemas/MetricDefinitionSource", "description": "Always `trace_span` today; see [`MetricDefinitionSource`]." }, "span_name": { "type": [ "string", "null" ] }, "span_name_prefix": { "type": [ "string", "null" ] }, "status_code": { "type": [ "string", "null" ] }, "value_source": { "type": "string", "description": "`count`, `duration_ms`, or `usage:\u003Ckey\u003E`." } } }, "MetricDefinitionSource": { "type": "string", "description": "Where a definition draws its observations from.\n\nOne variant today. It is in the payload from the start so that adding a\nsecond source is an additive change to this enum instead of a new resource\nalongside `/metrics/definitions` — the reason the endpoint is named for\nmetrics rather than for traces.", "enum": [ "trace_span" ] }, "MetricOrigin": { "type": "string", "description": "Who defines a metric series.\n\nThe distinction the API cares about is editability, not data source: system\nseries are emitted by the crons and probes and have no configuration to\nshow, custom ones are backed by a definition the org can change.", "enum": [ "system", "custom" ] }, "MissingDataPolicy": { "type": "string", "enum": [ "not_breaching", "breaching", "insufficient", "ignore" ] }, "ModelPolicy": { "type": "object", "description": "An organization policy rule restricting LLM provider or model usage.", "required": [ "id", "provider", "effect", "created_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "created_by_user_id": { "type": [ "string", "null" ], "description": "User who created the rule." }, "effect": { "$ref": "#/components/schemas/ModelPolicyEffect" }, "id": { "type": "string" }, "model_id": { "type": [ "string", "null" ], "description": "Model targeted by the rule. Omitted when the rule covers the whole\nprovider." }, "provider": { "type": "string", "description": "Model provider slug, e.g. `byteplus`, `openai`." } } }, "ModelPolicyEffect": { "type": "string", "description": "Whether a policy rule allows or denies its target. A model-level rule\nbeats a provider-level rule; `deny` beats `allow` at the same specificity.", "enum": [ "allow", "deny" ] }, "NewReactionReqBody": { "type": "object", "required": [ "sentiment" ], "properties": { "feedback": { "type": [ "string", "null" ] }, "sentiment": { "type": "string" } } }, "NotificationChannelOut": { "type": "object", "required": [ "id", "type", "config" ], "properties": { "config": { "type": "object" }, "id": { "type": "integer", "format": "int64" }, "name": { "type": [ "string", "null" ] }, "type": { "$ref": "#/components/schemas/NotificationChannelType" } } }, "NotificationChannelType": { "type": "string", "enum": [ "email", "slack" ] }, "Org": { "type": "object", "required": [ "id", "name", "plan", "plan_metadata", "overage_enabled", "billing_suspended", "plan_cancel_at_period_end", "created_at", "role" ], "properties": { "banner_url": { "type": [ "string", "null" ] }, "billing_suspended": { "type": "boolean", "description": "`true` when billing is suspended because a finalized invoice charge\nfailed and is still unpaid. While suspended, credit-consuming requests\nare blocked until the outstanding invoice is paid." }, "contact_email": { "type": [ "string", "null" ] }, "contact_name": { "type": [ "string", "null" ] }, "contact_phone": { "type": [ "string", "null" ] }, "country": { "type": [ "string", "null" ] }, "created_at": { "type": "string", "format": "date-time" }, "description": { "type": [ "string", "null" ] }, "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "overage_cap_credits": { "type": [ "integer", "null" ], "format": "int64" }, "overage_enabled": { "type": "boolean" }, "overage_rate_cents_per_1k": { "type": [ "integer", "null" ], "format": "int64", "description": "Metered-overage rate in cents per 1,000 credits. Self-serve plans return\nthe fixed tier default; enterprise returns the negotiated rate when\nconfigured; `null` on free or when overage is unavailable." }, "overage_threshold_usd": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum outstanding overage (whole USD dollars) allowed before an\ninterim invoice is issued. Self-serve plans return the fixed tier\ndefault (1× monthly subscription); enterprise returns the negotiated\nvalue when configured; `null` when no interim threshold applies." }, "photo_url": { "type": [ "string", "null" ] }, "plan": { "type": "string" }, "plan_cancel_at": { "type": [ "integer", "null" ], "format": "int64", "description": "Unix timestamp (seconds) of the scheduled plan cancellation; `null` when\nno cancellation is pending." }, "plan_cancel_at_period_end": { "type": "boolean", "description": "`true` between the moment a user schedules a plan cancellation in the\nBilling Portal and the final cancellation taking effect." }, "plan_metadata": { }, "plan_period": { "type": [ "string", "null" ], "description": "Billing cadence of the active plan: `\"month\"` or `\"year\"`. `null` on the\nfree plan (no active subscription)." }, "plan_renews_at": { "type": [ "integer", "null" ], "format": "int64", "description": "Unix timestamp (seconds) when the current billing period ends and the\nplan renews. `null` on the free plan (no active subscription). When\n`plan_cancel_at_period_end` is `true`, the plan ends at this time instead\nof renewing." }, "role": { "type": "string" } } }, "OrgAlarmsHealthResBody": { "type": "object", "title": "OrgAlarmsHealthResponse", "description": "Wrapper for **GET** `/orgs/{org_id}/alarms/health`.", "required": [ "healthy", "stale_count", "alarms" ], "properties": { "alarms": { "type": "array", "items": { "$ref": "#/components/schemas/AlarmDataHealth" } }, "healthy": { "type": "boolean", "description": "`false` when any enabled alarm is `stale`." }, "stale_count": { "type": "integer", "format": "int64", "description": "How many of `alarms` are stale, so a caller can alert on the count\nwithout walking the list." } } }, "OrgAnalyticsCostsBody": { "type": "object", "required": [ "group_by", "from", "to", "bins" ], "properties": { "bins": { "type": "array", "items": { "$ref": "#/components/schemas/SourceBin" } }, "from": { "type": "integer", "format": "int64" }, "group_by": { "$ref": "#/components/schemas/BinSize" }, "to": { "type": "integer", "format": "int64" } } }, "OrgAnalyticsUsageBody": { "type": "object", "required": [ "group_by", "from", "to", "bins" ], "properties": { "bins": { "type": "array", "items": { "$ref": "#/components/schemas/UsageBin" } }, "from": { "type": "integer", "format": "int64" }, "group_by": { "$ref": "#/components/schemas/BinSize" }, "to": { "type": "integer", "format": "int64" } } }, "OrgAnalyticsUsersBody": { "type": "object", "required": [ "from", "to", "users" ], "properties": { "from": { "type": "integer", "format": "int64" }, "next_page_token": { "type": [ "string", "null" ] }, "to": { "type": "integer", "format": "int64" }, "users": { "type": "array", "items": { "$ref": "#/components/schemas/UserRow" } } } }, "OrgContact": { "type": "object", "required": [ "id", "type", "name", "channels" ], "properties": { "channels": { "type": "array", "items": { "$ref": "#/components/schemas/OrgContactChannel" }, "description": "Ways to reach this contact." }, "id": { "type": "string", "description": "Unique contact identifier." }, "name": { "type": "string", "description": "Display name (e.g. \"Jane Doe\")." }, "photo_url": { "type": [ "string", "null" ], "description": "Optional profile photo URL." }, "title": { "type": [ "string", "null" ], "description": "Optional job title (e.g. \"Senior AI Solutions Architect\")." }, "type": { "$ref": "#/components/schemas/OrgContactType", "description": "Role this contact plays for the org." } } }, "OrgContactChannel": { "type": "object", "required": [ "kind", "value" ], "properties": { "kind": { "$ref": "#/components/schemas/OrgContactChannelKind" }, "label": { "type": [ "string", "null" ], "description": "Optional display label like \"Mobile\" or \"Work\"." }, "primary": { "type": "boolean", "description": "Marks the preferred channel of this kind when multiple are listed." }, "value": { "type": "string", "description": "Channel-specific identifier: email address, E.164 phone number, slack\nhandle, calendly URL, etc. Format is enforced by the channel kind." } } }, "OrgContactChannelKind": { "type": "string", "enum": [ "email", "phone", "whatsapp", "telegram", "slack", "calendly", "linkedin", "signal", "other" ] }, "OrgContactType": { "type": "string", "description": "Role a contact plays for the org. Free-form on the wire/DB so new roles\ncan be introduced without a migration; unknown values fall back to `Other`.", "enum": [ "aisa", "account_executive", "account_manager", "csm", "other" ] }, "OrgMetricsCatalogResBody": { "type": "object", "title": "OrgMetricsCatalogResponse", "description": "Wrapper for **GET** `/orgs/{org_id}/metrics/catalog`.", "required": [ "hours", "metrics" ], "properties": { "hours": { "type": "integer", "format": "int64" }, "metrics": { "type": "array", "items": { "$ref": "#/components/schemas/MetricCatalogEntry" } } } }, "OrgMetricsResBody": { "type": "object", "title": "OrgMetricsResponse", "description": "Wrapper for **GET** `/orgs/{org_id}/metrics`.", "required": [ "name", "period_seconds", "from", "to", "bins" ], "properties": { "bins": { "type": "array", "items": { "$ref": "#/components/schemas/MetricBinOut" }, "description": "Buckets with data, ascending; empty buckets are omitted." }, "from": { "type": "integer", "format": "int64", "description": "Range start (epoch milliseconds)." }, "name": { "type": "string" }, "period_seconds": { "type": "integer", "format": "int32" }, "to": { "type": "integer", "format": "int64", "description": "Range end (epoch milliseconds)." } } }, "OrgPreview": { "type": "object", "required": [ "id", "name", "plan", "n_projects", "role", "created_at" ], "properties": { "banner_url": { "type": [ "string", "null" ], "description": "URL of the organization's banner image", "deprecated": true }, "created_at": { "type": "integer", "format": "int64", "description": "Creation timestamp in epoch milliseconds" }, "description": { "type": [ "string", "null" ], "description": "Organization description" }, "id": { "type": "string", "description": "Unique organization identifier" }, "n_projects": { "type": "integer", "format": "int64", "description": "Number of projects in the organization" }, "name": { "type": "string", "description": "Organization name" }, "photo_url": { "type": [ "string", "null" ], "description": "URL of the organization's profile photo" }, "plan": { "type": "string", "description": "Subscription plan" }, "role": { "type": "string", "description": "Authenticated user's role in the organization" } } }, "OrgUser": { "type": "object", "required": [ "email", "role", "roles", "pending" ], "properties": { "email": { "type": "string", "description": "User's email address" }, "id": { "type": [ "string", "null" ], "description": "Unique user identifier. Null only for legacy pending invites created\nbefore invites allocated a user up front; use `pending` to detect\nnot-yet-registered members." }, "name": { "type": [ "string", "null" ], "description": "User's display name" }, "pending": { "type": "boolean", "description": "True when the member was invited but hasn't completed signup yet. Such\nmembers can still have roles assigned ahead of their first login." }, "photo_url": { "type": [ "string", "null" ], "description": "URL of the user's profile photo" }, "role": { "type": "string", "description": "Legacy single-role text. Kept for backward compatibility; new\nintegrations should rely on `roles`." }, "roles": { "type": "array", "items": { "$ref": "#/components/schemas/RolePreview" }, "description": "Roles currently attached to this membership. Empty for members with no\nrole attachments (including freshly invited users)." } } }, "OverageSummary": { "type": "object", "description": "Customer-facing overage usage summary for the current credits period.\n\n`used_credits = invoiced_credits + pending_credits`. `invoiced_credits` is\nthe real metered overage billed on finalized invoices this period (see\n[`overage_summary`]); `pending_credits` is the headline \"extra usage you'll\nbe billed for\" number, and a non-zero `invoiced_credits` means an interim\n(threshold-driven) invoice has already billed part of this period.", "required": [ "enabled", "used_credits", "invoiced_credits", "pending_credits" ], "properties": { "cap_credits": { "type": [ "integer", "null" ], "format": "int64", "description": "Org-configured ceiling on overage credits for the period. `null` means\nunlimited (or no cap configured); only meaningful when `enabled`." }, "enabled": { "type": "boolean", "description": "Whether usage-based overage billing is currently enabled for the org." }, "invoiced_credits": { "type": "integer", "format": "int64", "description": "Overage credits already included on a finalized invoice this period." }, "pending_credits": { "type": "integer", "format": "int64", "description": "Overage credits accrued this period that have not been invoiced yet." }, "period_end": { "type": [ "string", "null" ], "format": "date-time", "description": "End of the current credits period — when pending overage bills if no\ninterim invoice fires first. `null` when there is no metered window." }, "period_start": { "type": [ "string", "null" ], "format": "date-time", "description": "Start of the current credits period. `null` when the org has no metered\nbilling window (e.g. free plan with no period anchor)." }, "rate_cents_per_1k": { "type": [ "integer", "null" ], "format": "int64", "description": "Metered overage rate in cents per 1,000 credits. `null` when overage\npricing is unavailable for the plan." }, "threshold_usd": { "type": [ "integer", "null" ], "format": "int64", "description": "Outstanding overage value (whole USD) that triggers an interim invoice.\n`null` means overage bills only at the end of the period." }, "used_credits": { "type": "integer", "format": "int64", "description": "Total overage credits consumed this period (`invoiced` + `pending`)." } } }, "PacingBody": { "type": "object", "description": "Request mirror of [`Pacing`]. All fields optional; absent == unthrottled.", "properties": { "batch_delay_ms": { "type": [ "integer", "null" ], "format": "int64", "description": "Sleep (ms) between batches. `0`/omitted = none.", "minimum": 0 }, "max_dop": { "type": [ "integer", "null" ], "format": "int32", "description": "SQL Server only: `OPTION (MAXDOP n)` to cap server-side query\nparallelism. `1` pins single-threaded. Ignored by other sources.", "minimum": 0 }, "max_rows_per_sec": { "type": [ "integer", "null" ], "format": "int32", "description": "Cap on sustained rows/sec across the job. Omit = unlimited.", "minimum": 0 }, "read_uncommitted": { "type": [ "boolean", "null" ], "description": "SQL Server only: read with `READ UNCOMMITTED` (no shared locks, never\nblocks the source's OLTP; dirty reads OK for snapshots). No-op elsewhere." } } }, "PatchAuthSettingsReqBody": { "type": "object", "description": "Body for `PATCH …/auth` — flip the master sign-in switch for the app.", "required": [ "enabled" ], "properties": { "enabled": { "type": "boolean", "description": "Whether the deployed app requires end-user sign-in." } } }, "PatchK2ChunkRequest": { "type": "object", "properties": { "content": { "type": [ "string", "null" ] }, "embed": { "type": [ "string", "null" ], "description": "Text used for vector / full-text indexing. When `content` is\nprovided and `embed` is omitted, `embed` is auto-set to the new\n`content`. Send an explicit value to keep an indexing-optimized\nvariant distinct from the user-visible text." }, "page_end": { "type": [ "integer", "null" ], "format": "int32" }, "page_start": { "type": [ "integer", "null" ], "format": "int32", "description": "Tri-state: omit to leave unchanged, send `null` to clear, send an\ninteger to set." } } }, "PatchK2PolicyRequest": { "type": "object", "properties": { "audit_level": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/K2PolicyAuditLevel" } ] }, "break_glass_allowed": { "type": [ "boolean", "null" ] }, "column_masks": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BTreeMap", "description": "Omit to leave unchanged; send `null` to clear all masks." } ] }, "compliance_tags": { "type": [ "array", "null" ], "items": { "type": "string" } }, "description": { "type": [ "string", "null" ], "description": "Omit to leave unchanged; send `null` to clear." }, "enabled": { "type": [ "boolean", "null" ] }, "external_id": { "type": [ "string", "null" ] }, "labels": { }, "name": { "type": [ "string", "null" ] }, "purpose_tags": { "type": [ "array", "null" ], "items": { "type": "string" } }, "row_filter_dsl": { "description": "Omit to leave unchanged; send `null` to clear the row filter." }, "source": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/K2PolicySource" } ] }, "table_name": { "type": [ "string", "null" ], "description": "Omit to leave unchanged; send `null` to apply to every table." } } }, "PatchMeReqBody": { "type": "object", "properties": { "access_request_data": { "description": "Free-form access-request metadata. Merged (shallow) into the existing\nstored object server-side." }, "lang": { "type": [ "string", "null" ], "description": "Preferred language (ISO 639-1, e.g. `en`). Cannot be set to null." }, "name": { "type": [ "string", "null" ], "description": "Display name. 1–64 characters. Cannot be set to null." }, "phone": { "type": [ "string", "null" ], "description": "Phone number. Pass null to clear." } } }, "PreviewLabelOut": { "type": "object", "description": "What the filter would have recorded for one label.", "required": [ "count", "sum", "min", "max" ], "properties": { "count": { "type": "integer", "format": "int64" }, "label": { "type": [ "string", "null" ], "description": "`null` when `label_source` is `none`." }, "max": { "type": "number", "format": "double" }, "min": { "type": "number", "format": "double" }, "sum": { "type": "number", "format": "double" } } }, "PreviewMetricDefinitionOut": { "type": "object", "required": [ "runs_sampled", "runs_matched", "observations", "labels", "samples" ], "properties": { "labels": { "type": "array", "items": { "$ref": "#/components/schemas/PreviewLabelOut" }, "description": "Per-label aggregates, exactly as they'd land in `Metrics`. More than a\nhandful of entries here means `label_source: span_name` over a\nhigh-cardinality predicate — every label is another bin per minute." }, "observations": { "type": "integer", "format": "int64", "description": "Total matching spans across the sample." }, "runs_matched": { "type": "integer", "format": "int64", "description": "Of those, how many produced at least one observation." }, "runs_sampled": { "type": "integer", "format": "int64", "description": "Runs with a trace that were actually inspected." }, "samples": { "type": "array", "items": { "$ref": "#/components/schemas/PreviewSampleOut" } } } }, "PreviewMetricDefinitionReq": { "type": "object", "description": "Body for **POST** `/orgs/{org_id}/metrics/definitions/preview`.\n\nThe same predicate fields as create, minus everything about persistence.", "properties": { "has_error": { "type": [ "boolean", "null" ] }, "label_source": { "type": "string" }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Runs to inspect, newest first. Default 20, max 50." }, "min_duration_ms": { "type": [ "integer", "null" ], "format": "int32" }, "project_id": { "type": [ "string", "null" ], "description": "Sample runs from one project only." }, "span_name": { "type": [ "string", "null" ] }, "span_name_prefix": { "type": [ "string", "null" ] }, "status_code": { "type": [ "string", "null" ] }, "value_source": { "type": "string" }, "workforce_id": { "type": [ "string", "null" ], "description": "Sample runs from one agent/workflow (`OrgsApps.id`). Strongly\nrecommended: it makes the sample representative of what you're\nfiltering, instead of whatever the org ran most recently." } } }, "PreviewSampleOut": { "type": "object", "description": "One matched span, for eyeballing that the predicate hit what was intended.", "required": [ "run_id", "span_name", "value" ], "properties": { "run_id": { "type": "integer", "format": "int64" }, "span_name": { "type": "string" }, "value": { "type": "number", "format": "double" } } }, "PrincipalKind": { "type": "string", "description": "Whether a principal is a person or a platform-managed machine identity\n(for example a project's service credential).", "enum": [ "human", "service" ] }, "ProjectAnalyticsCreditsBody": { "type": "object", "required": [ "group_by", "from", "to", "bins" ], "properties": { "bins": { "type": "array", "items": { "$ref": "#/components/schemas/CostBin" } }, "from": { "type": "integer", "format": "int64" }, "group_by": { "$ref": "#/components/schemas/BinSize" }, "to": { "type": "integer", "format": "int64" } } }, "ProjectAnalyticsUsageBody": { "type": "object", "required": [ "group_by", "from", "to", "bins" ], "properties": { "bins": { "type": "array", "items": { "$ref": "#/components/schemas/UsageBin" } }, "from": { "type": "integer", "format": "int64" }, "group_by": { "$ref": "#/components/schemas/BinSize" }, "to": { "type": "integer", "format": "int64" } } }, "ProjectAnalyticsUsersBody": { "type": "object", "required": [ "from", "to", "users" ], "properties": { "from": { "type": "integer", "format": "int64" }, "next_page_token": { "type": [ "string", "null" ] }, "to": { "type": "integer", "format": "int64" }, "users": { "type": "array", "items": { "$ref": "#/components/schemas/UserRow" } } } }, "ProjectAuthSettings": { "type": "object", "description": "Full app-auth configuration for a project. Drives the settings UI.", "required": [ "enabled", "providers" ], "properties": { "enabled": { "type": "boolean", "description": "Master switch: whether the deployed app requires end-user sign-in at all.\nWhen false the app is public and `providers` is moot until it's turned on." }, "providers": { "type": "array", "items": { "$ref": "#/components/schemas/AuthProviderState" }, "description": "Every known sign-in method with its current state, in a stable order." } } }, "ProjectChannel": { "type": "object", "description": "One channel binding as returned on the project payload. Topology only —\ncredentials are never included here.", "required": [ "provider", "workforce" ], "properties": { "configured": { "type": "boolean", "description": "Whether credentials for this binding are stored platform-side." }, "enabled": { "type": "boolean", "description": "Soft toggle from the UI. Omitted/`true` means the channel is on; `false`\nkeeps the workforce mapping so it can be re-enabled without reconfiguring." }, "provider": { "type": "string", "description": "Channel provider id (for example `telegram`, `slack`)." }, "workforce": { "type": "string", "description": "Workforce component the channel talks to — always the component's\nmanifest uid on read." } } }, "ProjectDetail": { "type": "object", "required": [ "id", "name", "has_ui", "role", "use_platform_iam", "is_public_template", "template_uses", "publishable_api_key", "environments", "knowledge_bases", "integrations", "auth_enabled", "auth_providers", "channels", "created_at", "updated_at" ], "properties": { "auth_enabled": { "type": "boolean", "description": "Master sign-in switch for the deployed app: when false the app is public,\nwhen true it requires end-user sign-in via `auth_providers`." }, "auth_providers": { "type": "array", "items": { "type": "string" }, "description": "Enabled end-user sign-in methods for the project's deployed app login\nscreen (for example `email`, `google`, `microsoft`, `github`). Empty when\nno sign-in method has been turned on." }, "channels": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectChannel" }, "description": "Messaging channel topology for the deployed app (provider → workforce).\nEmpty when no channels are connected. Topology and configuration state\nonly; credentials are never included." }, "created_at": { "type": "integer", "format": "int64", "description": "Creation timestamp in epoch milliseconds" }, "default_role": { "type": [ "string", "null" ], "description": "Project's default role. All organization members will be assigned this role by default for this project" }, "description": { "type": [ "string", "null" ], "description": "Project description" }, "environments": { "type": "array", "items": { "$ref": "#/components/schemas/EnvPreview" }, "description": "Project environments with their latest deployment status" }, "has_ui": { "type": "boolean", "description": "Whether the project has a UI interface" }, "id": { "type": "string", "description": "Unique project identifier" }, "integrations": { "type": "array", "items": { "$ref": "#/components/schemas/IntegrationPreview" }, "description": "Integrations active in this project" }, "is_public_template": { "type": "boolean", "description": "Whether the project is a public template" }, "knowledge_bases": { "type": "array", "items": { "$ref": "#/components/schemas/KbPreview" }, "description": "Knowledge bases connected to this project (new KB system only)" }, "name": { "type": "string", "description": "Project name" }, "publishable_api_key": { "type": "string", "description": "Publishable API key for this project" }, "repository_url": { "type": [ "string", "null" ], "description": "URL of the project's source code repository. When null, the project does not have source code available" }, "role": { "type": "string", "description": "**Deprecated — will be removed.** Always `\"admin\"` for backwards-compatible\nresponse shape. Caller permissions are determined by v2 IAM grants, not\nthis field. Use `/orgs/{org_id}/iam/check` or effective-grants instead." }, "screenshot_signed_url": { "type": [ "string", "null" ], "description": "CloudFront-signed screenshot URL, minted per response (TTL-bound).\nPresent only when the banner is a Timbal-hosted screenshot (private\n`orgs/{}/projects/{}/screenshots/*` prefix) and signing is configured.\n\nNOTE: screenshots live under a *private* prefix, so this URL is signed\nand short-lived. If a banner ever needs to live on a public / cacheable\nsurface (timbal.ai landing pages, OG/meta image tags, emails — anywhere\nthe URL is cached or can't be re-minted per request), copy the object to\na public prefix (e.g. `orgs/{org_id}/assets/...`) and serve that\nunsigned instead of signing this one." }, "screenshot_url": { "type": [ "string", "null" ], "description": "**Deprecated:** prefer `screenshot_signed_url` when present.", "deprecated": true }, "search_text": { "type": [ "string", "null" ], "description": "Text corpus used for semantic similarity matching when recommending templates." }, "template_description": { "type": [ "string", "null" ], "description": "Public-facing description shown when the project is listed as a template." }, "template_uses": { "type": "integer", "format": "int64", "description": "Number of times this template has been used" }, "updated_at": { "type": "integer", "format": "int64", "description": "Last update timestamp in epoch milliseconds" }, "use_platform_iam": { "type": "boolean", "description": "Whether the project uses the platform's IAM system for access control" } } }, "ProjectEnv": { "type": "object", "required": [ "id", "name", "color", "subdomain", "components", "created_at", "updated_at" ], "properties": { "branch": { "type": [ "string", "null" ] }, "color": { "type": "string" }, "components": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectEnvComponent" }, "description": "Effective per-component deploy configuration after resolution." }, "created_at": { "type": "string", "format": "date-time" }, "custom_domain": { }, "description": { "type": [ "string", "null" ] }, "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "subdomain": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ProjectEnvComponent": { "type": "object", "description": "Effective deploy configuration for one component of an environment.", "required": [ "component", "type", "deploy_mode" ], "properties": { "component": { "type": "string", "description": "`\"api\"` or the workforce `OrgsApps.id` as a string. This is the key\nto use in `PATCH .../config` `components`." }, "cpu": { "type": [ "integer", "null" ], "format": "int32", "description": "NULL unless the component deploys to ECS (resources only apply there)." }, "deploy_mode": { "type": "string" }, "desired_count": { "type": [ "integer", "null" ], "format": "int32" }, "ephemeral_storage": { "type": [ "integer", "null" ], "format": "int32" }, "memory": { "type": [ "integer", "null" ], "format": "int32" }, "name": { "type": [ "string", "null" ] }, "type": { "type": "string", "description": "'api' | 'agent' | 'workflow'" } } }, "ProjectOrigin": { "oneOf": [ { "type": "object", "required": [ "project_id", "type" ], "properties": { "project_id": { "type": "integer", "format": "int64" }, "type": { "type": "string", "enum": [ "Template" ] } } }, { "type": "object", "required": [ "type" ], "properties": { "agents": { "type": "array", "items": { "type": "string" }, "description": "Agent directory names to scaffold under `workforce/`. Omit for an\nempty workforce directory." }, "kb_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Knowledge base to attach to the project. Provide an existing KB's\nid to link it, or omit to auto-create an empty one." }, "type": { "type": "string", "enum": [ "Scratch" ] }, "with_ui": { "type": "boolean", "description": "Include the default web UI scaffold. Requires at least one entry in\n`agents` (workflows alone do not use the web UI)." }, "workflows": { "type": "array", "items": { "type": "string" }, "description": "Workflow directory names to scaffold under `workforce/`." } } } ] }, "ProjectPreview": { "type": "object", "required": [ "id", "name", "role", "created_at", "is_public_template", "template_uses" ], "properties": { "created_at": { "type": "integer", "format": "int64", "description": "Creation timestamp in epoch milliseconds" }, "default_role": { "type": [ "string", "null" ], "description": "Project's default role. All organization members will be assigned this role by default for this project" }, "description": { "type": [ "string", "null" ], "description": "Project description" }, "id": { "type": "string", "description": "Unique project identifier" }, "is_public_template": { "type": "boolean", "description": "Whether the project is a public template" }, "name": { "type": "string", "description": "Project name" }, "role": { "type": "string", "description": "**Deprecated — will be removed.** Always `\"admin\"` for backwards-compatible\nresponse shape. Caller permissions are determined by v2 IAM grants, not\nthis field. Use `/orgs/{org_id}/iam/check` or effective-grants instead." }, "screenshot_signed_url": { "type": [ "string", "null" ], "description": "CloudFront-signed screenshot URL, minted per response (TTL-bound).\nPresent only for Timbal-hosted screenshots (private prefix) when signing\nis configured. To use a banner on a public/cacheable surface, copy the\nobject to a public prefix (`orgs/{org_id}/assets/...`) and serve unsigned." }, "screenshot_url": { "type": [ "string", "null" ], "description": "**Deprecated:** prefer `screenshot_signed_url` when present.", "deprecated": true }, "template_uses": { "type": "integer", "format": "int64", "description": "Number of times this template has been used" } } }, "ProjectTemplate": { "type": "object", "description": "A published public project template. Instantiate it via\n`POST /orgs/{org_id}/projects` with\n`{ \"origin\": { \"type\": \"Template\", \"project_id\": \u003Cid\u003E } }`.", "required": [ "id", "name", "has_ui", "template_uses", "created_at" ], "properties": { "created_at": { "type": "integer", "format": "int64", "description": "Creation timestamp in epoch milliseconds." }, "description": { "type": [ "string", "null" ], "description": "Short description of what the template provides." }, "has_ui": { "type": "boolean", "description": "Whether the template includes a web UI." }, "id": { "type": "string", "description": "Project id to pass as `project_id` when creating from this template." }, "name": { "type": "string", "description": "Template display name." }, "screenshot_signed_url": { "type": [ "string", "null" ], "description": "CloudFront-signed screenshot URL, minted per response (TTL-bound).\nPresent only for Timbal-hosted screenshots (private prefix) when signing\nis configured. To put a template banner on a public/cacheable surface\n(e.g. the timbal.ai marketing site), copy the object to a public prefix\n(`orgs/{org_id}/assets/...`) and serve that unsigned instead." }, "screenshot_url": { "type": [ "string", "null" ], "description": "**Deprecated:** prefer `screenshot_signed_url` when present.", "deprecated": true }, "search_text": { "type": [ "string", "null" ], "description": "Text corpus used for semantic similarity matching when recommending templates." }, "template_description": { "type": [ "string", "null" ], "description": "Public-facing description shown in the template catalog." }, "template_uses": { "type": "integer", "format": "int64", "description": "Number of times this template has been instantiated." } } }, "PutAuthProviderReqBody": { "type": "object", "description": "Body for `PUT …/auth/providers/{provider}` — upsert one sign-in method.", "required": [ "enabled" ], "properties": { "enabled": { "type": "boolean", "description": "Turn the sign-in method on or off." } } }, "PutChannelReqBody": { "type": "object", "description": "Body of `PUT .../channels/{workforce}/{provider}` (upsert one binding).", "properties": { "credentials": { "type": [ "object", "null" ], "description": "Provider secrets, **write-only** (never returned on any read). Omit to\nkeep the stored credentials for this binding; `null` clears them; an\nobject replaces them. Telegram: `token` (+ optional `secret_token`).\nSlack: `bot_token` + `signing_secret`.", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "enabled": { "type": "boolean", "description": "Soft toggle; defaults to `true`." } } }, "QueryColumnView": { "type": "object", "required": [ "name", "data_type" ], "properties": { "data_type": { "type": "string", "description": "Source-native type name (`int4`, `nvarchar`, `decimal`, …)." }, "name": { "type": "string" } } }, "QueryK2Request": { "type": "object", "required": [ "sql" ], "properties": { "explain": { "type": "boolean", "description": "When true, runs EXPLAIN ANALYZE and includes the query plan in the response." }, "params": { "type": "array", "items": { }, "description": "Optional query parameters bound to SQL placeholders ($1, $2, …)." }, "sql": { "type": "string", "description": "SQL query to execute against the knowledge base.\nUse $1, $2, etc. for parameter placeholders." } } }, "QueryReq": { "type": "object", "required": [ "connection_ref", "sql" ], "properties": { "connection_ref": { "type": "string", "description": "Connection ref on the node (from `/browse/connections`)." }, "max_rows": { "type": [ "integer", "null" ], "format": "int32", "description": "Row cap on the returned result. Defaults to 500, ceiling 10000.", "minimum": 0 }, "mode": { "type": [ "string", "null" ], "description": "`read` (default) | `write`. `read` is enforced node-side with\nengine-level read-only semantics; `write` additionally requires the\nconnection's local policy (`connections.json`) to allow writes." }, "sql": { "type": "string", "description": "The SQL to run. One statement on MySQL; multi-statement batches work on\nPostgres and SQL Server (the **last** result set is returned; on\nPostgres that's the last *row-returning* set — zero-row sets are\ninvisible to the node's driver — while SQL Server returns the true\nlast set even when empty)." }, "timeout_ms": { "type": [ "integer", "null" ], "format": "int64", "description": "Node-side execution budget in milliseconds. Defaults to 30000,\nceiling 60000.", "minimum": 0 } } }, "QueryRes": { "type": "object", "required": [ "columns", "rows", "row_count", "truncated" ], "properties": { "columns": { "type": "array", "items": { "$ref": "#/components/schemas/QueryColumnView" } }, "row_count": { "type": "integer", "minimum": 0 }, "rows": { "type": "array", "items": { "type": "array", "items": { "type": "object" } }, "description": "Row-major, aligned with `columns`. Cells are plain JSON scalars:\nnumbers stay numbers, exact decimals and timestamps are strings,\nbinary is `0x`-prefixed hex, NULL is `null`." }, "rows_affected": { "type": [ "integer", "null" ], "format": "int64", "description": "Rows changed by non-row-returning statements, when the engine reports\nit (Postgres/MySQL; `null` on SQL Server = unknown, not zero).", "minimum": 0 }, "truncated": { "type": "boolean", "description": "The node's row or byte cap bit — `rows` is a prefix of the real result." } } }, "Reaction": { "type": "object", "required": [ "id", "user", "sentiment", "created_at" ], "properties": { "created_at": { "type": "integer", "format": "int64" }, "feedback": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "sentiment": { "type": "string" }, "user": { "$ref": "#/components/schemas/UserRef" } } }, "RebindReq": { "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string", "description": "New channel URL to dial, e.g. `wss://api.timbal.ai/v1/connect/channel`." } } }, "RebindRes": { "type": "object", "required": [ "url", "dispatched" ], "properties": { "dispatched": { "type": "boolean", "description": "Always true on a 202 — the connector acks/reverts asynchronously over\nthe channel; watch the fleet listing for it to reconnect." }, "url": { "type": "string" } } }, "RelationalSourceBody": { "type": "object", "description": "Shared shape for the relational sources (Postgres, SQL Server, MySQL).\n`schema` defaults per-source (`public` / `dbo` / the connection DSN's\ndefault database — on MySQL `schema` *is* the database name).", "required": [ "connection_ref", "table" ], "properties": { "columns": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Projection; omit for all columns." }, "connection_ref": { "type": "string", "description": "Name of a connection in the connector's local `connections.json`.\nThe DSN itself never leaves the connector box." }, "cursor_column": { "type": [ "string", "null" ], "description": "Monotonic column for incremental extraction (`id`, `updated_at`, ...).\nOmit for a *snapshot* (full-scan) pass over the whole table, unordered\nand with no checkpoint/resume — for tables with no usable cursor\n(requires the connector to advertise `extract:snapshot`, 0.1.25+). On a\nsync that makes every run a full refresh of the destination." }, "schema": { "type": [ "string", "null" ], "description": "Source schema; defaults to `public` (Postgres) / `dbo` (SQL Server)." }, "table": { "type": "string", "description": "Source table to extract." } } }, "RemoveOrgUserReqBody": { "type": "object", "properties": { "email": { "type": [ "string", "null" ], "description": "Email address of the user to remove from the organization. Merged with\n`emails` when both are provided." }, "emails": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Email addresses to remove in one request. When non-empty, batch\nremoval is used and not-found addresses are skipped." } } }, "ReplaceRolesReqBody": { "type": "object", "required": [ "attachments" ], "properties": { "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/AttachmentReq" }, "description": "Desired attachment set for this member. Attachments present today\nbut not in the list are detached; new ones are attached. An empty\nlist detaches everything. Duplicate `(role_id, scope)` pairs are\nignored." } } }, "ReqBody": { "type": "object", "properties": { "name": { "type": [ "string", "null" ], "description": "Operator label (\"warehouse-pg box\")." }, "ttl_secs": { "type": [ "integer", "null" ], "format": "int64", "description": "Token lifetime in seconds. Default 86400 (24h), max 30 days." } } }, "ResBody": { "type": "object", "required": [ "token_id", "token", "expires_at" ], "properties": { "expires_at": { "type": "string", "format": "date-time" }, "token": { "type": "string", "description": "Raw enrollment token, shown once in the response." }, "token_id": { "type": "string" } } }, "ResourceUsersResBody": { "type": "object", "required": [ "actions", "users" ], "properties": { "actions": { "type": "array", "items": { "type": "string" }, "description": "Action keys that were evaluated, in evaluation order." }, "next_page_token": { "type": [ "string", "null" ], "description": "Token to fetch the next page, or null if this is the last page." }, "users": { "type": "array", "items": { "$ref": "#/components/schemas/UserAccess" }, "description": "Members with at least one allowed action on the resource. May hold\nfewer entries than the page window even when more pages exist." } } }, "Response": { "type": "object", "description": "Resolved window echoed back so the client can paginate / refresh\nwithout re-deriving the defaults the server applied.", "required": [ "events", "start_time", "end_time", "limit" ], "properties": { "end_time": { "type": "integer", "format": "int64" }, "events": { "type": "array", "items": { "$ref": "#/components/schemas/CloudWatchLogEvent" } }, "limit": { "type": "integer", "minimum": 0 }, "next_page_token": { "type": [ "string", "null" ] }, "start_time": { "type": "integer", "format": "int64" } } }, "RevokeRes": { "type": "object", "required": [ "connector_id", "disconnected", "stopped_syncs" ], "properties": { "connector_id": { "type": "string" }, "disconnected": { "type": "boolean", "description": "Whether a live channel connection was torn down here. `false` just means\nthe box was already offline — its credential is dead either way, so a\nreconnect is refused." }, "stopped_syncs": { "type": "integer", "format": "int64", "description": "Enabled syncs that were pointing at this connector. They are left in\nplace but stop dispatching, since picking due syncs skips revoked\nconnectors. Recreate them against a replacement connector — recreating\nagainst the same `dest_table` adopts the rows already there." } } }, "RoleDetail": { "type": "object", "description": "A role with its full grant set.", "required": [ "id", "name", "source", "grants", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "description": { "type": [ "string", "null" ] }, "grants": { "type": "array", "items": { "$ref": "#/components/schemas/RoleGrant" }, "description": "Domain grants this role carries. May be empty." }, "id": { "type": "string" }, "name": { "type": "string" }, "source": { "$ref": "#/components/schemas/RoleSource" }, "updated_at": { "type": "string", "format": "date-time" } } }, "RoleGrant": { "type": "object", "description": "A single grant on a role — `(effect, action, resource?, condition?)`.\n\n`resource` is `None` for `ResourceKind::None` actions (`users.read`),\nor a hierarchical path like `projects:42:envs:5` (or `projects:42:envs:*`)\nfor typed actions.\n\n`condition` is opaque JSON reserved for future ABAC; ignored by the\nevaluator in v1, accepted and stored as-is by writes.", "required": [ "effect", "action" ], "properties": { "action": { "type": "string" }, "condition": { }, "effect": { "$ref": "#/components/schemas/GrantEffect" }, "resource": { "type": [ "string", "null" ] } } }, "RoleInUseConflict": { "type": "object", "description": "Returned when `DELETE /orgs/{org_id}/iam/roles/{role_id}` is called while\nthe role is still attached to one or more members.", "required": [ "code", "message", "user_ids" ], "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "user_ids": { "type": "array", "items": { "type": "string" }, "description": "Members currently holding this role via `OrgUserRoles`." } } }, "RolePreview": { "type": "object", "description": "Compact role record returned by listing endpoints. Fetch a single\nrole to retrieve the full grant set.", "required": [ "id", "name", "source", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "description": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "name": { "type": "string", "description": "Role name. Unique per `(org_id)` for custom roles, globally unique\nfor system roles." }, "source": { "$ref": "#/components/schemas/RoleSource" }, "updated_at": { "type": "string", "format": "date-time" } } }, "RoleSource": { "type": "string", "description": "Whether a role is a built-in preset or defined by the organization.\n`system` roles are read-only; `custom` roles can be edited or deleted\nby an organization admin.", "enum": [ "system", "custom" ] }, "RunDetail": { "type": "object", "required": [ "id", "user", "status", "cost_usd", "cost_credits", "created_at", "idempotency_key" ], "properties": { "cost_credits": { "type": "number", "format": "double" }, "cost_usd": { "type": "number", "format": "double" }, "created_at": { "type": "string", "format": "date-time" }, "duration_ms": { "type": [ "integer", "null" ], "format": "int64" }, "group_id": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "idempotency_key": { "type": "string" }, "last_reaction_sentiment": { "type": [ "string", "null" ] }, "parent_id": { "type": [ "string", "null" ] }, "status": { "type": "string" }, "status_detail": { }, "trace": { }, "user": { "$ref": "#/components/schemas/UserRef" } }, "additionalProperties": { } }, "RunEvalsReqBody": { "type": "object", "properties": { "component_id": { "type": [ "string", "null" ], "description": "Workforce component by numeric app id (the `TIMBAL_APP_ID` value;\nnumber or string). At least one of `component_id` / `component_uid`\nis required; when both are set, they must resolve to the same\ncomponent." }, "component_uid": { "type": [ "string", "null" ], "description": "Workforce component by manifest uid (the `_id` in `timbal.yaml`)." }, "rev": { "type": [ "string", "null" ], "description": "Git rev to extract when `source = \"git\"` (branch, tag, or SHA).\nDefaults to the env's tracked branch. Rejected when\n`source = \"worktree\"`." }, "source": { "$ref": "#/components/schemas/EvalRunSource", "description": "`worktree` (default) or `git`. Worktree includes uncommitted\nevals; git is a clean extract at `rev`." } } }, "RunEvalsResBody": { "type": "object", "required": [ "eval_run_id", "status" ], "properties": { "eval_run_id": { "type": "string", "description": "Id of the created eval run. Stream `GET .../evals/runs/{eval_run_id}/events`\nor poll `GET .../evals/runs/{eval_run_id}`." }, "status": { "type": "string", "description": "Always `running` at accept time." } } }, "RunPreview": { "type": "object", "required": [ "id", "user", "workforce", "status", "cost_usd", "cost_credits", "created_at", "idempotency_key" ], "properties": { "cost_credits": { "type": "number", "format": "double" }, "cost_usd": { "type": "number", "format": "double" }, "created_at": { "type": "string", "format": "date-time" }, "duration_ms": { "type": [ "integer", "null" ], "format": "int64" }, "group_id": { "type": [ "string", "null" ] }, "id": { "type": "string" }, "idempotency_key": { "type": "string" }, "last_reaction_sentiment": { "type": [ "string", "null" ] }, "parent_id": { "type": [ "string", "null" ] }, "status": { "type": "string" }, "user": { "$ref": "#/components/schemas/UserRef" }, "workforce": { "$ref": "#/components/schemas/WorkforcePreview" } } }, "RunSyncRes": { "type": "object", "required": [ "sync_id", "dispatched" ], "properties": { "dispatched": { "type": "boolean", "description": "`true`: a run left for the connector on this request; `job_id` is set.\n`false`: the connector's socket lives on another control-plane instance\n(or the box is briefly offline), so the run was queued instead — the\ninstance holding the socket dispatches it on its next scheduler tick\n(~30s), or on reconnect." }, "job_id": { "type": [ "string", "null" ], "description": "The dispatched run's `ConnectorJobs` id — poll it via the jobs routes.\n`null` when the run was queued (`dispatched: false`); the queued run's\njob appears at the top of `recent_runs` once it fires." }, "sync_id": { "type": "string" } } }, "ScimTokenView": { "type": "object", "description": "Masked view of a SCIM token. Never includes the secret.", "required": [ "id", "org_id", "enabled", "created_at", "updated_at" ], "properties": { "created_at": { "type": "integer", "format": "int64" }, "enabled": { "type": "boolean" }, "id": { "type": "string" }, "label": { "type": [ "string", "null" ] }, "last_used_at": { "type": [ "integer", "null" ], "format": "int64" }, "org_id": { "type": "string" }, "provider_id": { "type": [ "string", "null" ] }, "updated_at": { "type": "integer", "format": "int64" } } }, "SetDefaultRoleReqBody": { "type": "object", "description": "Body for the dedicated default-role endpoint. The field is required but may\nbe `null` to clear the catch-all role (no separate \"unset\" verb needed).", "properties": { "role_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Target role id, or `null` to remove the catch-all (group-mapping-only).\nAccepts a number or a stringified id." } } }, "SetEnvBranchReqBody": { "type": "object", "properties": { "name": { "type": [ "string", "null" ], "description": "When null, the branch will be cleared" } } }, "SetEnvDomainReqBody": { "type": "object", "properties": { "domain_id": { "type": [ "integer", "null" ], "format": "int64" } } }, "SetK2GovernanceModeRequest": { "type": "object", "required": [ "governance_mode" ], "properties": { "governance_mode": { "$ref": "#/components/schemas/K2GovernanceMode" } } }, "SignContentRequest": { "type": "object", "description": "Request to mint a fresh CDN URL for a stored content object.", "required": [ "url" ], "properties": { "url": { "type": "string", "description": "A content URL previously returned by the API (signed or unsigned), or a\nbare object key. The server resolves it back to a known object it owns,\nre-checks your access, and mints a fresh URL — useful when a cached\nsigned URL has expired and you want a new one without re-fetching the\nwhole parent resource." } } }, "SignContentResponse": { "type": "object", "description": "A freshly-minted CDN URL pair for a stored content object.", "required": [ "url" ], "properties": { "signed_url": { "type": [ "string", "null" ], "description": "CloudFront signed URL for private content. Omitted when the object is\npublic or signing is unavailable." }, "url": { "type": "string", "description": "Legacy unsigned CDN URL. Populated for backwards compatibility; prefer\n`signed_url` when present." } } }, "SourceBin": { "type": "object", "required": [ "interval_starts_at", "interval_ends_at", "sources" ], "properties": { "interval_ends_at": { "type": "integer", "format": "int64" }, "interval_starts_at": { "type": "integer", "format": "int64" }, "sources": { "type": "array", "items": { "$ref": "#/components/schemas/SourceCosts" } } } }, "SourceBody": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/RelationalSourceBody" }, { "type": "object", "required": [ "kind" ], "properties": { "kind": { "type": "string", "enum": [ "postgres" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/RelationalSourceBody" }, { "type": "object", "required": [ "kind" ], "properties": { "kind": { "type": "string", "enum": [ "sql_server" ] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/RelationalSourceBody" }, { "type": "object", "required": [ "kind" ], "properties": { "kind": { "type": "string", "enum": [ "mysql" ] } } } ] } ], "description": "The source half of a dispatch, tagged by `kind`. Each variant maps to a\n`SourceSpec` and gates on the connector advertising the matching\n`source:\u003Ckind\u003E` capability. Request shape:\n`\"source\": { \"kind\": \"sql_server\", \"connection_ref\": \"...\", \"table\": \"...\", \"cursor_column\": \"...\" }`." }, "SourceCost": { "type": "object", "description": "One cost type's spend within a source group. Unlike [`Cost`], `usd` is\nnullable: credits-only surfaces never expose a dollar figure.", "required": [ "id", "name", "unit", "credits" ], "properties": { "credits": { "type": "number", "format": "double" }, "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "unit": { "type": "string", "description": "Metered unit (`tokens`, `seconds`, ...) for surfaces with a dollar\nprice; `credits` for credits-only surfaces." }, "usd": { "type": [ "number", "null" ], "format": "double", "description": "Dollar spend. `null` for credits-only surfaces (`composer`, `kb_*`),\nwhich are priced in credits." } } }, "SourceCosts": { "type": "object", "description": "Spend for one product surface (`resource_type` on the credit ledger)\nwithin a bin, with the per-cost-type breakdown nested.", "required": [ "resource_type", "credits", "costs" ], "properties": { "costs": { "type": "array", "items": { "$ref": "#/components/schemas/SourceCost" } }, "credits": { "type": "number", "format": "double" }, "resource_type": { "type": "string", "description": "Product surface that produced the spend (`app_run`, `composer`,\n`kb_query`, `kb_file_parsing`, `kb_file_embedding`, `transcription`,\n`message`, `ace_run`, `org_api_request`, `project_api_request`), or\n`legacy` for rows recorded before source attribution existed." }, "usd": { "type": [ "number", "null" ], "format": "double", "description": "Dollar spend. `null` for credits-only surfaces (`composer`, `kb_*`),\nwhich are priced in credits." } } }, "StopRes": { "type": "object", "required": [ "job_id", "state" ], "properties": { "job_id": { "type": "string" }, "state": { "type": "string", "description": "Job state after the stop: `stopped` if this call terminalized it, else\nthe terminal state it already had (idempotent re-stops included)." } } }, "SyncDetailRes": { "type": "object", "required": [ "sync", "stats", "recent_runs" ], "properties": { "recent_runs": { "type": "array", "items": { "$ref": "#/components/schemas/SyncRunView" } }, "stats": { "$ref": "#/components/schemas/SyncStatsView" }, "sync": { "$ref": "#/components/schemas/SyncView" } } }, "SyncRunView": { "type": "object", "description": "One historical run of a sync, with derived timing.", "required": [ "job_id", "state", "rows_emitted", "created_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "duration_ms": { "type": [ "integer", "null" ], "format": "int64" }, "finished_at": { "type": [ "string", "null" ], "format": "date-time" }, "job_id": { "type": "string" }, "message": { "type": [ "string", "null" ] }, "rows_emitted": { "type": "integer", "format": "int64" }, "rows_per_sec": { "type": [ "number", "null" ], "format": "double" }, "started_at": { "type": [ "string", "null" ], "format": "date-time" }, "state": { "type": "string" } } }, "SyncStatsView": { "type": "object", "description": "Rollup of a sync's run history (from its `ConnectorJobs`).", "required": [ "runs_total", "runs_completed", "runs_failed", "rows_total" ], "properties": { "rows_total": { "type": "integer", "format": "int64" }, "runs_completed": { "type": "integer", "format": "int64" }, "runs_failed": { "type": "integer", "format": "int64" }, "runs_total": { "type": "integer", "format": "int64" } } }, "SyncView": { "type": "object", "required": [ "id", "connector_id", "source_kind", "connection_ref", "source_schema", "source_table", "key_columns", "kb_uid", "dest_table", "interval_secs", "enabled", "has_cursor", "consecutive_failures", "created_at", "updated_at" ], "properties": { "connection_ref": { "type": "string" }, "connector_id": { "type": "string" }, "consecutive_failures": { "type": "integer", "format": "int32", "description": "Failed runs since the last completed one. Non-zero means retries are\nbacking off (the effective interval doubles per failure, capped at an\nhour); at 10 the sync is disabled with `disabled_reason` set." }, "created_at": { "type": "string", "format": "date-time" }, "cursor_column": { "type": [ "string", "null" ], "description": "`null` for a full-refresh sync: it has no checkpoint, so every run\nre-reads the source table and rebuilds `dest_table`." }, "dest_table": { "type": "string" }, "disabled_reason": { "type": [ "string", "null" ], "description": "Why the control plane disabled this sync (auto-disable after consecutive\nfailures, last error included). `null` when `enabled`, and for operator\npauses. Cleared on re-enable." }, "enabled": { "type": "boolean" }, "has_cursor": { "type": "boolean", "description": "Whether the sync holds a resume checkpoint — committed by a landed batch,\nor seeded at creation when it adopted an existing destination table. Its\nnext run resumes rather than rebuilding. The raw cursor is intentionally\nnot exposed." }, "id": { "type": "string" }, "interval_secs": { "type": "integer", "format": "int32" }, "kb_uid": { "type": "string" }, "key_columns": { "type": "array", "items": { "type": "string" }, "description": "Ordered destination primary-key columns; empty for a keyless table." }, "last_run_at": { "type": [ "string", "null" ], "format": "date-time" }, "last_state": { "type": [ "string", "null" ] }, "last_success_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last time a run reached `completed`; `null` if it has never succeeded." }, "name": { "type": [ "string", "null" ] }, "seconds_since_success": { "type": [ "integer", "null" ], "format": "int64", "description": "Freshness/lag: seconds since the last successful run. `null` if never\nsucceeded. Compare against `interval_secs` to spot a stalling sync." }, "source_kind": { "type": "string" }, "source_schema": { "type": "string" }, "source_table": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "TableDetailRes": { "type": "object", "required": [ "schema", "name", "approx_rows", "columns", "indexes", "foreign_keys", "check_constraints" ], "properties": { "approx_rows": { "type": "integer", "format": "int64", "description": "Planner estimate; `-1` when unknown." }, "check_constraints": { "type": "array", "items": { "$ref": "#/components/schemas/CheckConstraintView" } }, "columns": { "type": "array", "items": { "$ref": "#/components/schemas/ColumnView" } }, "comment": { "type": [ "string", "null" ], "description": "Table description from the source's own doc mechanism." }, "foreign_keys": { "type": "array", "items": { "$ref": "#/components/schemas/ForeignKeyView" } }, "indexes": { "type": "array", "items": { "$ref": "#/components/schemas/IndexView" } }, "name": { "type": "string" }, "schema": { "type": "string" }, "size_bytes": { "type": [ "integer", "null" ], "format": "int64", "description": "Total on-disk size (data + indexes) in bytes, when the source reports one." } } }, "TableView": { "type": "object", "required": [ "schema", "name", "approx_rows" ], "properties": { "approx_rows": { "type": "integer", "format": "int64", "description": "Planner estimate; `-1` when the table was never analyzed." }, "name": { "type": "string" }, "schema": { "type": "string" } } }, "TablesRes": { "type": "object", "required": [ "tables" ], "properties": { "tables": { "type": "array", "items": { "$ref": "#/components/schemas/TableView" } } } }, "TempFile": { "type": "object", "description": "Short-lived upload metadata returned by POST /files.", "required": [ "name", "content_type", "content_length", "url", "created_at", "expires_at" ], "properties": { "content_length": { "type": "integer", "format": "int64", "description": "Size of the uploaded payload in bytes." }, "content_type": { "type": "string", "description": "MIME type as reported by the client." }, "created_at": { "type": "string", "format": "date-time", "description": "Time the file was uploaded." }, "expires_at": { "type": "string", "format": "date-time", "description": "When the download URL is expected to stop working (~24h after upload)." }, "name": { "type": "string", "description": "Original filename (sanitized — slashes / control characters replaced)." }, "url": { "type": "string", "description": "Download URL. Anyone with this URL can fetch the file until it expires." } } }, "Token": { "type": "object", "description": "User credential (API key or future kinds).", "required": [ "id", "kind", "name", "hint", "createdAt" ], "properties": { "createdAt": { "type": "integer", "format": "int64", "description": "Creation time as epoch milliseconds." }, "hint": { "type": "string", "description": "Masked secret for display (prefix and suffix only)." }, "id": { "type": "string", "description": "Credential identifier." }, "kind": { "type": "string", "description": "Credential kind (currently `api_key`)." }, "name": { "type": "string", "description": "Display name chosen at creation." }, "org_id": { "type": [ "string", "null" ], "description": "Organization the credential is scoped to. Omitted for legacy full-access keys." }, "scope": { "type": [ "string", "null" ], "description": "IAM scope path (e.g. `projects:42`). Omitted for legacy full-access keys." }, "secret": { "type": [ "string", "null" ], "description": "Full secret value. Present only in the create response; omitted on list." } } }, "ToolAction": { "allOf": [ { "type": "object", "description": "Unknown keys preserved for round-tripping." }, { "type": "object", "required": [ "tool" ], "properties": { "confirmation": { "type": "string", "description": "Matcher-confidence gate: `none` (prefilter alone suffices),\n`majority` (default), or `unanimous` (all voters must agree)." }, "params": { "type": "object" }, "tool": { "type": "string" } } } ], "description": "Deterministic tool invocation attached to a policy. `params` values of\nthe form `\"$var_id\"` are resolved from extracted context variables at\ninference time; `$var_id` tokens embedded in longer strings (template\nparams, e.g. a SQL string) interpolate in place." }, "UpdateAlarmReq": { "type": "object", "description": "Body for **PATCH** `/orgs/{org_id}/alarms/{alarm_id}` — all fields optional.", "properties": { "clear_threshold": { "type": [ "number", "null" ], "format": "double", "description": "Double-option so `null` clears the hysteresis and an absent key leaves\nit alone — a plain `Option` can't tell those apart." }, "comparison": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AlarmComparison" } ] }, "datapoints_to_alarm": { "type": [ "integer", "null" ], "format": "int32" }, "enabled": { "type": [ "boolean", "null" ] }, "evaluation_periods": { "type": [ "integer", "null" ], "format": "int32" }, "min_sample_count": { "type": [ "integer", "null" ], "format": "int64" }, "missing_data": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/MissingDataPolicy" } ] }, "name": { "type": [ "string", "null" ] }, "period_seconds": { "type": [ "integer", "null" ], "format": "int32" }, "stat": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AlarmStat" } ] }, "threshold": { "type": [ "number", "null" ], "format": "double" } } }, "UpdateEnvConfigReqBody": { "type": "object", "required": [ "components" ], "properties": { "components": { "type": "object", "description": "Per-component overrides, keyed by `\"api\"` or a workforce\n`OrgsApps.id`. Each entry sent REPLACES the stored entry wholesale\n(it is the ground truth for that component); `null` removes the\nentry so the component falls back to the env/app-level layering.\nKeys not present in the map are left untouched.", "additionalProperties": { "$ref": "#/components/schemas/ComponentConfigEntry" }, "propertyNames": { "type": "string" } }, "cpu": { "type": [ "integer", "null" ], "format": "int32" }, "desired_count": { "type": [ "integer", "null" ], "format": "int32" }, "ephemeral_storage": { "type": [ "integer", "null" ], "format": "int32" }, "evals": { "type": [ "boolean", "null" ], "description": "Deploy-time eval gate (GitHub-Actions-style required check):\n`true` arms it for every workforce component in this env — deploys\nrun the component's committed evals first and fail on a non-pass.\n`false` disarms. Omit to leave unchanged. Per-component override\nlives on `OrgsApps.deploy_config.evals`." }, "evals_on_push": { "type": [ "boolean", "null" ], "description": "Push-triggered CI eval runs: `true` runs the eval suite of every\ncomponent with eval files on each push to this env's branch —\nreport-only (`trigger_type = 'push'` on the runs), gates nothing.\nPer component, skipped when that component's deploy gate is armed\n(env- or app-level `evals`), since the gate already runs those\nevals on the push-triggered redeploy. Omit to leave unchanged." }, "memory": { "type": [ "integer", "null" ], "format": "int32" } } }, "UpdateIdentityProviderReqBody": { "type": "object", "description": "Update a connection. All fields optional; absent = unchanged. `client_secret`\nis write-only — supply it only to rotate.", "properties": { "allowed_domains": { "type": [ "array", "null" ], "items": { "type": "string" } }, "client_id": { "type": [ "string", "null" ] }, "client_secret": { "type": [ "string", "null" ] }, "display_name": { "type": [ "string", "null" ] }, "enabled": { "type": [ "boolean", "null" ] }, "groups_claim": { "type": [ "string", "null" ] }, "issuer": { "type": [ "string", "null" ] }, "scopes": { "type": [ "string", "null" ] } } }, "UpdateMetricDefinitionReq": { "type": "object", "description": "Body for **PATCH** `/orgs/{org_id}/metrics/definitions/{id}`.\n\nOnly the knobs that are safe to change in place. The predicate and the\ndestination metric are immutable: editing them would splice two different\nmeanings into one series with no marker at the seam, so a changed\ndefinition should be a new definition.", "properties": { "enabled": { "type": [ "boolean", "null" ] }, "name": { "type": [ "string", "null" ] } } }, "UpdateOrgPhotoResBody": { "type": "object", "required": [ "photo_url" ], "properties": { "photo_url": { "type": "string", "description": "Public URL of the newly stored org logo." } } }, "UpdatePhotoResBody": { "type": "object", "required": [ "photo_url" ], "properties": { "photo_url": { "type": "string", "description": "Public URL of the newly stored profile picture." } } }, "UpdateReq": { "type": "object", "properties": { "version": { "type": [ "string", "null" ], "description": "Target version (`0.1.3` or `v0.1.3`). Omit for the published `latest`." } } }, "UpdateRes": { "type": "object", "required": [ "target_version", "artifact", "dispatched" ], "properties": { "artifact": { "type": "string", "description": "Release artifact selected for the connector's platform." }, "dispatched": { "type": "boolean", "description": "`false` when the connector already reports the target version (no-op)." }, "target_version": { "type": "string", "description": "Bare semver the connector was told to move to." } } }, "UpdateSyncReq": { "type": "object", "properties": { "enabled": { "type": [ "boolean", "null" ], "description": "Pause (`false`) / resume (`true`). Pausing preserves the cursor." }, "interval_secs": { "type": [ "integer", "null" ], "format": "int64", "description": "New interval in seconds." } } }, "UpdateVarReqBody": { "type": "object", "properties": { "description": { "type": [ "string", "null" ] }, "env_ids": { "type": [ "array", "null" ], "items": { "type": "integer", "format": "int64" } }, "value": { "type": [ "string", "null" ] } } }, "UsageBin": { "type": "object", "required": [ "interval_starts_at", "interval_ends_at", "n_success", "n_warning", "n_error", "n_running", "n_timeout", "n_users" ], "properties": { "interval_ends_at": { "type": "integer", "format": "int64" }, "interval_starts_at": { "type": "integer", "format": "int64" }, "n_error": { "type": "integer", "format": "int64" }, "n_running": { "type": "integer", "format": "int64" }, "n_success": { "type": "integer", "format": "int64" }, "n_timeout": { "type": "integer", "format": "int64" }, "n_users": { "type": "integer", "format": "int64" }, "n_warning": { "type": "integer", "format": "int64", "description": "Completed runs where an intermediate step errored. Disjoint from both\n`n_success` and `n_error`, so totals still add up." }, "p50": { "type": [ "number", "null" ], "format": "double" }, "p90": { "type": [ "number", "null" ], "format": "double" }, "p95": { "type": [ "number", "null" ], "format": "double" }, "p99": { "type": [ "number", "null" ], "format": "double" } } }, "UserAccess": { "type": "object", "description": "A principal with effective access, as returned by the reverse-lookup\nendpoints (`GET /iam/resources/{resource}/users` and\n`GET /iam/actions/{action}/users`).\n\nOnly principals with at least one allowed action appear. Deny-beats-allow\nis already applied: an action covered by both an allow and a deny grant\nis not listed. Platform superadmins are not included unless they also\nhold explicit role attachments.", "required": [ "user_id", "kind", "allowed_actions" ], "properties": { "allowed_actions": { "type": "array", "items": { "$ref": "#/components/schemas/AllowedAction" }, "description": "Actions this principal is effectively allowed to perform, with\nattribution." }, "email": { "type": [ "string", "null" ] }, "kind": { "$ref": "#/components/schemas/PrincipalKind" }, "name": { "type": [ "string", "null" ] }, "user_id": { "type": "string" } } }, "UserRef": { "type": "object", "required": [ "id", "name", "email" ], "properties": { "email": { "type": "string" }, "id": { "type": "string" }, "name": { "type": "string" }, "photo_url": { "type": [ "string", "null" ] } } }, "UserRolesReq": { "type": "object", "description": "One member's desired attachment set in a bulk request.", "required": [ "user_id", "attachments" ], "properties": { "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/AttachmentReq" }, "description": "Desired attachment set for this member. Same semantics as the\nsingle-member endpoint: a full replace, an empty list detaches\neverything, duplicate `(role_id, scope)` pairs are ignored." }, "user_id": { "type": "integer", "format": "int64" } } }, "UserRow": { "type": "object", "required": [ "user_id", "user_name", "user_email", "n_success", "n_warning", "n_error", "n_running", "n_timeout", "usd", "credits" ], "properties": { "credits": { "type": "number", "format": "double", "description": "Total credit spend across all surfaces." }, "n_error": { "type": "integer", "format": "int64" }, "n_running": { "type": "integer", "format": "int64" }, "n_success": { "type": "integer", "format": "int64" }, "n_timeout": { "type": "integer", "format": "int64" }, "n_warning": { "type": "integer", "format": "int64", "description": "Completed runs where an intermediate step errored. Disjoint from both\n`n_success` and `n_error`, so totals still add up." }, "usd": { "type": "number", "format": "double", "description": "Dollar spend, excluding credits-only surfaces (composer, knowledge-base\noperations) which are priced in credits." }, "user_email": { "type": "string" }, "user_id": { "type": "integer", "format": "int64" }, "user_name": { "type": "string" }, "user_photo_url": { "type": [ "string", "null" ] } } }, "ValidationRecord": { "type": "object", "required": [ "type", "name", "value" ], "properties": { "name": { "type": "string", "description": "DNS record name" }, "type": { "type": "string", "description": "DNS record type (e.g. `CNAME`)" }, "value": { "type": "string", "description": "DNS record value" } } }, "ValidationStatus": { "type": "string", "description": "SSL certificate validation status", "enum": [ "pending", "issued", "inactive", "expired", "revoked", "failed", "validationtimedout" ] }, "ValidatorSummary": { "type": "object", "description": "One assertion extracted from an eval entry, flattened for display.", "required": [ "target", "name", "value" ], "properties": { "name": { "type": "string", "description": "Validator keyword as written, e.g. `contains!`, `seq!`,\n`not_semantic!`." }, "target": { "type": "string", "description": "Dot-path of what's being validated, relative to the eval root —\ne.g. `output`, `get_datetime.input.timezone`. Empty for\nvalidators attached directly to the root (e.g. a top-level\n`seq!`)." }, "value": { "description": "The expected value / steps list, as written in the YAML." } } }, "Var": { "type": "object", "required": [ "id", "name", "value", "envs" ], "properties": { "applies_to_all_envs": { "type": "boolean", "description": "Whether the variable applies to every environment, including\nenvironments created later." }, "description": { "type": [ "string", "null" ] }, "envs": { "type": "array", "items": { "$ref": "#/components/schemas/VarEnv" } }, "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" }, "value": { "$ref": "#/components/schemas/VarValue" } } }, "VarEnv": { "type": "object", "required": [ "id", "name", "color" ], "properties": { "color": { "type": "string" }, "id": { "type": "integer", "format": "int64" }, "name": { "type": "string" } } }, "VarInput": { "type": "object", "required": [ "type", "name", "value" ], "properties": { "description": { "type": [ "string", "null" ] }, "name": { "type": "string" }, "type": { "$ref": "#/components/schemas/VarType" }, "value": { "type": "string" } } }, "VarType": { "type": "string", "enum": [ "plain", "secret" ] }, "VarValue": { "oneOf": [ { "type": "object", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "plain" ] }, "value": { "type": "string" } } }, { "type": "object", "required": [ "type" ], "properties": { "decrypted": { "type": [ "string", "null" ] }, "preview": { "type": [ "string", "null" ] }, "type": { "type": "string", "enum": [ "secret" ] } } } ] }, "WorkforcePreview": { "type": "object", "required": [ "id", "type", "name" ], "properties": { "deleted_at": { "type": [ "integer", "null" ], "format": "int64", "description": "Set when the workforce component has been deleted. Only returned from endpoints that include soft-deleted rows (e.g. runs list)." }, "description": { "type": [ "string", "null" ], "description": "Optional short description." }, "id": { "type": "string", "description": "Identifier of this workforce component within the project." }, "name": { "type": "string", "description": "Display name of the component." }, "type": { "$ref": "#/components/schemas/AppType", "description": "Component category (for example agent or workflow)." }, "uid": { "type": [ "string", "null" ], "description": "Stable identifier from the project manifest (`timbal.yaml`), when defined." }, "url": { "type": [ "string", "null" ], "description": "When present, the authenticated Timbal API URL used to call this component’s **running** deployment (for example from the list-workforce response). Omitted where the response does not expose a callable URL, such as on project detail." } } } }, "securitySchemes": { "bearer_auth": { "type": "http", "scheme": "bearer", "description": "Timbal API key. Obtain your API key from the Timbal platform settings. See [Authentication](/api-reference/authentication) for more information." } } }, "tags": [ { "name": "ace", "description": "Action Control Engine (ACE) operations" }, { "name": "alarms", "description": "Metric series and threshold alarms" }, { "name": "analytics", "description": "Org and project analytics" }, { "name": "billing", "description": "Subscriptions, usage, and payment-related operations" }, { "name": "channels", "description": "Delivery channels alarms notify through" }, { "name": "content", "description": "Re-sign stored content URLs" }, { "name": "files", "description": "File operations" }, { "name": "iam", "description": "IAM — actions, roles, users, and authorization introspection" }, { "name": "k2", "description": "Knowledge Bases v2 operations" }, { "name": "orgs", "description": "Organization operations" }, { "name": "projects", "description": "Project operations" }, { "name": "runs", "description": "Execution operations" }, { "name": "templates", "description": "Public project template catalog" }, { "name": "users", "description": "Authenticated user profile" } ] }