diff --git a/.changeset/platform-create-update-commands.md b/.changeset/platform-create-update-commands.md new file mode 100644 index 0000000..a476f9d --- /dev/null +++ b/.changeset/platform-create-update-commands.md @@ -0,0 +1,5 @@ +--- +"@outlit/cli": patch +--- + +Add resource-first platform action CLI commands for agent create/update, automation create/update, signal create/update, and destination create/update. diff --git a/docs/ai-integrations/mcp.mdx b/docs/ai-integrations/mcp.mdx index f79d1c4..f2e13e6 100644 --- a/docs/ai-integrations/mcp.mdx +++ b/docs/ai-integrations/mcp.mdx @@ -1,6 +1,6 @@ --- title: "MCP Integration" -description: "Connect remote MCP clients to Outlit with your workspace URL and OAuth" +description: "Connect remote MCP clients to Outlit with your workspace URL, OAuth, or scoped API keys" --- ## What is the Outlit MCP Server? @@ -11,11 +11,13 @@ The Outlit CLI is not required for MCP setup. Use the workspace MCP URL directly ## Authentication Model -Outlit's remote MCP endpoint uses OAuth-based authentication. In practice that means: +Outlit's remote MCP endpoint uses OAuth-based authentication for customer-intelligence tools. In practice that means: - you add the workspace MCP URL to your client - you do not paste API keys or bearer headers into config files - the client opens an OAuth sign-in flow and stores the resulting session +Platform configuration tools use API-key authentication today. Use an API key with `agents:read` for read-only configuration tools and `agents:write` for write tools. + ## Connect Your MCP Client @@ -43,7 +45,7 @@ Outlit's remote MCP endpoint uses OAuth-based authentication. In practice that m } ``` - No `Authorization` header is needed. + No `Authorization` header is needed for OAuth-based customer-intelligence tools. After you add the server, your client should prompt you to sign in to Outlit and authorize access for that workspace. @@ -61,6 +63,43 @@ Outlit's remote MCP endpoint uses OAuth-based authentication. In practice that m Use [Agent Skills](/ai-integrations/skills) for coding agents like Claude Code, Codex, and Gemini CLI. Use MCP when your primary surface is an MCP client such as Cursor, VS Code, or another remote-MCP connector. +## Platform Configuration Over MCP + +Platform configuration tools inspect and mutate agents, automations, signals, and destinations. These tools require API-key authentication because they execute scoped platform actions. + + + + Open [Settings > CLI & MCP](https://app.outlit.ai/settings/workspace/mcp) and create an API key for agent configuration. The key must include `agents:read` for read tools and `agents:write` for write tools. + + + For MCP clients that support custom headers or headless bearer-token setup, configure the same workspace MCP URL with an `Authorization` header: + + ```json + { + "mcpServers": { + "outlit": { + "url": "https://mcp.outlit.ai/w//mcp", + "headers": { + "Authorization": "Bearer ok_your_api_key" + } + } + } + } + ``` + + + Ask your client: + + ```text + List my Outlit agent templates. + ``` + + + + + Do not add API keys to OAuth-only client configs. If your MCP client cannot send bearer headers, use the CLI or REST API for platform configuration actions. + + ## What Tools Are Available? | Tool | What it does | Example prompt | @@ -93,20 +132,27 @@ API-key authenticated MCP clients can also inspect and manage selected agent and | `outlit_agent_list_available_actions` | List available agent configuration actions | | `outlit_agent_list` | List configured agents | | `outlit_agent_get` | Get one configured agent | -| `outlit_agent_create_from_template` | Create supported template resources in draft mode | +| `outlit_agent_create` | Create an agent | +| `outlit_agent_update` | Update one configured agent | | `outlit_agent_enable` | Enable one configured agent | | `outlit_agent_disable` | Disable one configured agent | | `outlit_agent_rename` | Rename one configured agent | | `outlit_automation_list` | List configured automations | | `outlit_automation_get` | Get one configured automation | +| `outlit_automation_create` | Create an agent automation from an `agentId` | +| `outlit_automation_update` | Update an agent automation from an `agentId` | | `outlit_automation_enable` | Enable one configured automation | | `outlit_automation_disable` | Disable one configured automation | | `outlit_automation_archive` | Archive one configured automation | | `outlit_signal_list` | List configured automation signals | | `outlit_signal_get` | Get one configured automation signal | +| `outlit_signal_create` | Create one automation signal | +| `outlit_signal_update` | Update one automation signal | | `outlit_signal_archive` | Archive one configured automation signal | | `outlit_destination_list` | List configured automation destinations with masked configuration | | `outlit_destination_get` | Get one configured automation destination with masked configuration | +| `outlit_destination_create` | Create one automation destination | +| `outlit_destination_update` | Update one automation destination | | `outlit_destination_enable` | Enable one configured automation destination | | `outlit_destination_disable` | Disable one configured automation destination | | `outlit_destination_archive` | Archive one configured automation destination | diff --git a/docs/ai-integrations/platform-actions.mdx b/docs/ai-integrations/platform-actions.mdx index aec832c..c5aa018 100644 --- a/docs/ai-integrations/platform-actions.mdx +++ b/docs/ai-integrations/platform-actions.mdx @@ -17,27 +17,46 @@ Use platform actions for Outlit-hosted agents, automations, signals, and destina Each surface calls the same platform action contracts. The transport changes, but the intent does not: the API exposes the canonical route, the CLI wraps that route for terminal use, and MCP exposes the same operation as an agent tool. +## Naming Model + +Platform actions use resource-first names so humans and agents can predict what to call next: + +| Surface | Pattern | Example | +|---------|---------|---------| +| CLI | `outlit ` | `outlit agents update --instructions "..."` +| REST API | Standard resource routes | `PATCH /api/agents/{id}` | +| MCP | `_` tool names | `outlit_agent_update` | + +Subtypes and templates are inputs, not command names. For example, use `outlit agents create --template churn` to create a template-backed agent, and use `outlit destinations create --type webhook` to create a webhook destination. + +Agent and destination updates patch only the fields provided. Automation and signal updates currently take full configuration bodies, so agents should read the current resource first, preserve fields they do not intend to change, and then send the updated body. + ## Current Scope The current platform action set focuses on the Agents and Automations areas of the Outlit platform. | Area | Read actions | Write actions | |------|--------------|---------------| -| Agents | List templates, list available actions, list agents, get one agent | Create a supported agent template draft, enable, disable, rename | -| Automations | List automations, get one automation | Enable, disable, archive | -| Signals | List configured automation signals, get one signal | Archive | -| Destinations | List configured destinations, get one destination with masked configuration | Enable, disable, archive | +| Agents | List templates, list available actions, list agents, get one agent | Create, update, enable, disable, rename | +| Automations | List automations, get one automation | Create, update, enable, disable, archive | +| Signals | List configured automation signals, get one signal | Create, update, archive | +| Destinations | List configured destinations, get one destination with masked configuration | Create, update, enable, disable, archive | For example, a CLI user or agent can create a draft template and then explicitly enable or disable lifecycle resources: ```bash -outlit agents create-from-template churn --json -outlit agents enable agent_123 --json +outlit agents create --template churn --json +outlit agents create --type custom --display-name "Renewal risk" --instructions "Find risk" --surface-criteria "Surface risky customers" --json +outlit signals create --file ./signal.json --json +outlit automations create --file ./automation.json --json +outlit agents enable 10000000-0000-4000-8000-000000000004 --json outlit automations disable 10000000-0000-4000-8000-000000000001 --json ``` Template creation creates supported template resources in `draft` mode. Draft creation does not enable an automation, add schedules, add external destinations, or send notifications by itself. Lifecycle write actions mutate only the named resource state. +Automation create and update actions are agent-centered. Callers provide `agentId`; update bodies also provide `name`, `enabled`, and `triggerType` explicitly. Outlit maps the agent ID to the hosted-agent processor internally and does not require callers to construct raw processor JSON. + ## Safety Model Platform actions are designed to make configuration inspectable before they make it broadly mutable. @@ -69,8 +88,11 @@ A coding agent or MCP client can use platform actions to inspect what exists, ch ```bash outlit agents templates --json outlit agents actions --json -outlit agents create-from-template churn --json -outlit agents enable agent_123 --json +outlit agents create --template churn --json +outlit agents update 10000000-0000-4000-8000-000000000004 --instructions "Prioritize recent support escalations" --json +outlit destinations create --type webhook --name "Customer ops" --url https://hooks.example.com/outlit --json +outlit destinations update 10000000-0000-4000-8000-000000000003 --type webhook --name "Customer ops" --json +outlit agents enable 10000000-0000-4000-8000-000000000004 --json outlit agents list --json outlit automations list --json outlit automations enable 10000000-0000-4000-8000-000000000001 --json @@ -88,20 +110,27 @@ This workflow lets the agent discover available templates, understand supported | `GET /api/agent-actions` | List available agent configuration actions | | `GET /api/agents` | List configured agents | | `GET /api/agents/{id}` | Get one configured agent | -| `POST /api/agents` | Create an agent from a supported template | +| `POST /api/agents` | Create an agent | +| `PATCH /api/agents/{id}` | Update one configured agent | | `POST /api/agents/{id}/enable` | Enable one configured agent | | `POST /api/agents/{id}/disable` | Disable one configured agent | | `POST /api/agents/{id}/rename` | Rename one configured agent | | `GET /api/automations` | List configured automations | +| `POST /api/automations` | Create an agent automation | | `GET /api/automations/{id}` | Get one configured automation | +| `PATCH /api/automations/{id}` | Update one agent automation | | `POST /api/automations/{id}/enable` | Enable one configured automation | | `POST /api/automations/{id}/disable` | Disable one configured automation | | `POST /api/automations/{id}/archive` | Archive one configured automation | | `GET /api/signals` | List configured automation signals | +| `POST /api/signals` | Create one automation signal | | `GET /api/signals/{id}` | Get one configured automation signal | +| `PATCH /api/signals/{id}` | Update one automation signal | | `POST /api/signals/{id}/archive` | Archive one configured automation signal | | `GET /api/destinations` | List configured automation destinations with masked configuration | | `GET /api/destinations/{id}` | Get one configured automation destination with masked configuration | +| `POST /api/destinations` | Create one automation destination | +| `PATCH /api/destinations/{id}` | Update one automation destination | | `POST /api/destinations/{id}/enable` | Enable one configured automation destination | | `POST /api/destinations/{id}/disable` | Disable one configured automation destination | | `POST /api/destinations/{id}/archive` | Archive one configured automation destination | diff --git a/docs/cli/commands.mdx b/docs/cli/commands.mdx index c69e954..d1174fe 100644 --- a/docs/cli/commands.mdx +++ b/docs/cli/commands.mdx @@ -562,7 +562,8 @@ outlit agents list [flags] outlit agents get [flags] outlit agents templates [flags] outlit agents actions [flags] -outlit agents create-from-template churn [flags] +outlit agents create [flags] +outlit agents update [flags] outlit agents enable [flags] outlit agents disable [flags] outlit agents rename [flags] @@ -572,17 +573,22 @@ outlit agents rename [flags] ```bash outlit agents list --json -outlit agents get agent_123 --json +outlit agents get 10000000-0000-4000-8000-000000000004 --json outlit agents templates --json outlit agents actions --json -outlit agents create-from-template churn --json -outlit agents enable agent_123 --json -outlit agents disable agent_123 --json -outlit agents rename agent_123 "Churn prevention" --json +outlit agents create --template churn --json +outlit agents create --type custom --display-name "Renewal risk" --instructions "Find risk" --surface-criteria "Surface risky customers" --json +outlit agents update 10000000-0000-4000-8000-000000000004 --display-name "Renewal risk" --json +outlit agents update 10000000-0000-4000-8000-000000000004 --instructions "Prioritize recent escalations" --json +outlit agents update 10000000-0000-4000-8000-000000000004 --action-keys send_slack_notification --json +outlit agents update 10000000-0000-4000-8000-000000000004 --clear-action-keys --json +outlit agents enable 10000000-0000-4000-8000-000000000004 --json +outlit agents disable 10000000-0000-4000-8000-000000000004 --json +outlit agents rename 10000000-0000-4000-8000-000000000004 "Churn prevention" --json ``` - `create-from-template` creates supported template resources in draft mode. `enable`, `disable`, and `rename` require an API key with `agents:write`. + `agents create --template` creates supported template resources in draft mode. `agents update` patches only the fields you pass. Use `--clear-action-keys` to remove all action keys. Agent write commands require an API key with `agents:write`. ## Automations @@ -592,6 +598,10 @@ Inspect configured platform automations. ```bash outlit automations list [flags] outlit automations get [flags] +outlit automations create --data [flags] +outlit automations create --file [flags] +outlit automations update --data [flags] +outlit automations update --file [flags] outlit automations enable [flags] outlit automations disable [flags] outlit automations archive [flags] @@ -602,22 +612,30 @@ outlit automations archive [flags] ```bash outlit automations list --json outlit automations get 10000000-0000-4000-8000-000000000001 --json +outlit automations create --file ./automation.json --json +outlit automations update 10000000-0000-4000-8000-000000000001 --file ./automation.json --json outlit automations enable 10000000-0000-4000-8000-000000000001 --json outlit automations disable 10000000-0000-4000-8000-000000000001 --json outlit automations archive 10000000-0000-4000-8000-000000000001 --json ``` +Automation create bodies must include `agentId`, `name`, and `triggerType`. Update bodies must include `agentId`, `name`, `enabled`, and `triggerType`. The API maps that agent ID to the internal hosted-agent processor; callers do not provide raw processor JSON. + ### JSON Response -Automation commands return command envelopes. List results are under `result.data.automations`; get, enable, and disable results are under `result.data.automation`. Archive results return `result.data.automation.id` and `result.data.automation.archivedAt`. +Automation commands return command envelopes. List results are under `result.data.automations`; get, create, update, enable, and disable results are under `result.data.automation`. Archive results return `result.data.automation.id` and `result.data.automation.archivedAt`. ## Signals -Inspect and archive configured automation signals. +Inspect and configure automation signals. ```bash outlit signals list [flags] outlit signals get [flags] +outlit signals create --data [flags] +outlit signals create --file [flags] +outlit signals update --data [flags] +outlit signals update --file [flags] outlit signals archive [flags] ``` @@ -626,10 +644,12 @@ outlit signals archive [flags] ```bash outlit signals list --json outlit signals get 10000000-0000-4000-8000-000000000002 --json +outlit signals create --file ./signal.json --json +outlit signals update 10000000-0000-4000-8000-000000000002 --file ./signal.json --json outlit signals archive 10000000-0000-4000-8000-000000000002 --json ``` -Signal list results are under `result.data.signals`; get results are under `result.data.signal`. Archive results return `result.data.signal.id` and `result.data.signal.archivedAt`. +Signal list results are under `result.data.signals`; get, create, and update results are under `result.data.signal`. Archive results return `result.data.signal.id` and `result.data.signal.archivedAt`. ## Destinations @@ -638,6 +658,8 @@ Inspect and manage configured automation destinations with masked configuration ```bash outlit destinations list [flags] outlit destinations get [flags] +outlit destinations create [flags] +outlit destinations update [flags] outlit destinations enable [flags] outlit destinations disable [flags] outlit destinations archive [flags] @@ -648,12 +670,14 @@ outlit destinations archive [flags] ```bash outlit destinations list --json outlit destinations get 10000000-0000-4000-8000-000000000003 --json +outlit destinations create --type webhook --name "Customer ops" --url https://hooks.example.com/outlit --json +outlit destinations update 10000000-0000-4000-8000-000000000003 --type webhook --name "Customer ops" --json outlit destinations enable 10000000-0000-4000-8000-000000000003 --json outlit destinations disable 10000000-0000-4000-8000-000000000003 --json outlit destinations archive 10000000-0000-4000-8000-000000000003 --json ``` -Destination list results are under `result.data.destinations`; get, enable, and disable results are under `result.data.destination`. Archive results return `result.data.destination.id` and `result.data.destination.archivedAt`. Raw destination secrets and unmasked provider configuration are not returned. +Destination list results are under `result.data.destinations`; get, create, update, enable, and disable results are under `result.data.destination`. `destinations update` patches only the fields you pass. Archive results return `result.data.destination.id` and `result.data.destination.archivedAt`. Raw destination secrets and unmasked provider configuration are not returned. ## SQL diff --git a/docs/openapi.json b/docs/openapi.json index a5194f5..343123b 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -250,39 +250,52 @@ }, "post": { "tags": ["Platform API"], - "summary": "Create agent from template", - "description": "Create an Outlit agent from a supported template. The initial template mode is draft-only: created resources are inert until explicitly configured in the platform.", - "operationId": "createAgentFromTemplate", + "summary": "Create agent", + "description": "Create an Outlit agent. Use type=template for supported templates or type=custom for a custom hosted agent.", + "operationId": "createAgent", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateAgentFromTemplateRequest" + "$ref": "#/components/schemas/CreateAgentRequest" }, - "example": { - "source": { - "type": "template", - "templateKey": "churn" + "examples": { + "template": { + "summary": "Create from template", + "value": { + "type": "template", + "templateKey": "churn", + "mode": "draft" + } }, - "mode": "draft" + "custom": { + "summary": "Create custom agent", + "value": { + "type": "custom", + "displayName": "Renewal risk", + "instructions": "Find risk.", + "surfaceCriteria": "Surface risky customers.", + "actionKeys": ["send_slack_notification"] + } + } } } } }, "responses": { "200": { - "description": "Agent template resources were created in draft mode.", + "description": "Agent was created.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateAgentFromTemplateCommandSuccess" + "$ref": "#/components/schemas/CreateAgentCommandSuccess" } } } }, "400": { - "description": "Invalid JSON or unsupported template request.", + "description": "Invalid JSON or unsupported agent create request.", "content": { "application/json": { "schema": { @@ -305,7 +318,7 @@ } }, "409": { - "description": "The requested template already exists for the organization.", + "description": "The requested template or agent conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -318,7 +331,7 @@ "$ref": "#/components/responses/InternalServerError" }, "503": { - "description": "The platform could not verify the created resources and rolled back the request.", + "description": "The platform could not complete the command.", "content": { "application/json": { "schema": { @@ -396,6 +409,107 @@ } } } + }, + "patch": { + "tags": ["Platform API"], + "summary": "Update agent", + "description": "Patch one configured Outlit agent. Only provided fields are changed.", + "operationId": "updateAgent", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Agent ID.", + "schema": { + "type": "string", + "minLength": 1 + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAgentRequest" + }, + "example": { + "displayName": "Renewal risk", + "instructions": "Prioritize recent support escalations.", + "actionKeys": ["send_slack_notification"] + } + } + } + }, + "responses": { + "200": { + "description": "Agent was updated.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAgentCommandSuccess" + } + } + } + }, + "400": { + "description": "The request body failed command validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent write scope.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "404": { + "description": "No resource was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "409": { + "description": "The requested change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + } + } } }, "/api/integrations": { @@ -876,42 +990,44 @@ } } } - } - }, - "/api/automations/{id}": { - "get": { + }, + "post": { "tags": ["Platform API"], - "summary": "Get automation", - "description": "Get one configured Outlit automation by id. Read-only and does not include run history.", - "operationId": "getAutomation", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "description": "Automation ID to fetch.", - "schema": { - "type": "string", - "format": "uuid" + "summary": "Create automation", + "description": "Create an agent automation. Provide agentId; Outlit maps it to the hosted-agent processor internally.", + "operationId": "createAutomation", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateAutomationRequest" + }, + "example": { + "agentId": "10000000-0000-4000-8000-000000000004", + "name": "Churn response", + "description": null, + "enabled": false, + "triggerType": "SIGNAL_OCCURRENCE", + "signalIds": ["10000000-0000-4000-8000-000000000002"], + "destinationIds": [] + } } } - ], + }, "responses": { "200": { - "description": "The configured automation was returned.", + "description": "Automation was created.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetAutomationCommandSuccess" + "$ref": "#/components/schemas/CreateAutomationCommandSuccess" } } } }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "description": "The API key is valid but does not have the required agent read scope.", + "400": { + "description": "The request body failed command validation.", "content": { "application/json": { "schema": { @@ -920,8 +1036,11 @@ } } }, - "404": { - "description": "No automation was found for the authenticated organization and requested id.", + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent write scope.", "content": { "application/json": { "schema": { @@ -930,11 +1049,8 @@ } } }, - "500": { - "$ref": "#/components/responses/InternalServerError" - }, - "503": { - "description": "The platform could not get the automation.", + "404": { + "description": "No resource was found for the authenticated organization and requested id.", "content": { "application/json": { "schema": { @@ -942,32 +1058,9 @@ } } } - } - } - } - }, - "/api/signals": { - "get": { - "tags": ["Platform API"], - "summary": "List signals", - "description": "List configured Outlit automation signals for the authenticated organization. Read-only.", - "operationId": "listSignals", - "responses": { - "200": { - "description": "Configured signals were returned.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListSignalsCommandSuccess" - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" }, - "403": { - "description": "The API key is valid but does not have the required agent read scope.", + "409": { + "description": "The requested change conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -980,7 +1073,7 @@ "$ref": "#/components/responses/InternalServerError" }, "503": { - "description": "The platform could not list signals.", + "description": "The platform could not complete the command.", "content": { "application/json": { "schema": { @@ -992,19 +1085,31 @@ } } }, - "/api/destinations": { + "/api/automations/{id}": { "get": { "tags": ["Platform API"], - "summary": "List destinations", - "description": "List configured Outlit automation destinations with masked configuration only. Read-only.", - "operationId": "listDestinations", + "summary": "Get automation", + "description": "Get one configured Outlit automation by id. Read-only and does not include run history.", + "operationId": "getAutomation", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Automation ID to fetch.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], "responses": { "200": { - "description": "Configured destinations were returned.", + "description": "The configured automation was returned.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListDestinationsCommandSuccess" + "$ref": "#/components/schemas/GetAutomationCommandSuccess" } } } @@ -1022,11 +1127,21 @@ } } }, + "404": { + "description": "No automation was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, "500": { "$ref": "#/components/responses/InternalServerError" }, "503": { - "description": "The platform could not list destinations.", + "description": "The platform could not get the automation.", "content": { "application/json": { "schema": { @@ -1036,33 +1151,60 @@ } } } - } - }, - "/api/agents/{id}/enable": { - "post": { + }, + "patch": { "tags": ["Platform API"], - "summary": "Enable agent", - "description": "Enable one configured Outlit agent by id. Does not run the agent immediately.", - "operationId": "enableAgent", + "summary": "Update automation", + "description": "Update an agent automation with a full configuration body. Provide agentId, name, enabled, and triggerType; Outlit maps agentId to the hosted-agent processor internally.", + "operationId": "updateAutomation", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Agent ID.", + "description": "Automation ID.", "schema": { "type": "string", - "minLength": 1 + "format": "uuid" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAutomationRequest" + }, + "example": { + "agentId": "10000000-0000-4000-8000-000000000004", + "name": "Churn response", + "description": null, + "enabled": false, + "triggerType": "SIGNAL_OCCURRENCE", + "signalIds": ["10000000-0000-4000-8000-000000000002"], + "destinationIds": [] + } + } + } + }, "responses": { "200": { - "description": "Enable agent completed.", + "description": "Automation was updated.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EnableAgentCommandSuccess" + "$ref": "#/components/schemas/UpdateAutomationCommandSuccess" + } + } + } + }, + "400": { + "description": "The request body failed command validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" } } } @@ -1090,6 +1232,16 @@ } } }, + "409": { + "description": "The requested change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, "500": { "$ref": "#/components/responses/InternalServerError" }, @@ -1102,45 +1254,23 @@ } } } - }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommandErrorEnvelope" - } - } - } } } } }, - "/api/agents/{id}/disable": { - "post": { + "/api/signals": { + "get": { "tags": ["Platform API"], - "summary": "Disable agent", - "description": "Disable one configured Outlit agent by id. Disabled agents will not run from schedules or automations.", - "operationId": "disableAgent", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "description": "Agent ID.", - "schema": { - "type": "string", - "minLength": 1 - } - } - ], + "summary": "List signals", + "description": "List configured Outlit automation signals for the authenticated organization. Read-only.", + "operationId": "listSignals", "responses": { "200": { - "description": "Disable agent completed.", + "description": "Configured signals were returned.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DisableAgentCommandSuccess" + "$ref": "#/components/schemas/ListSignalsCommandSuccess" } } } @@ -1149,17 +1279,7 @@ "$ref": "#/components/responses/Unauthorized" }, "403": { - "description": "The API key is valid but does not have the required agent write scope.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommandErrorEnvelope" - } - } - } - }, - "404": { - "description": "No resource was found for the authenticated organization and requested id.", + "description": "The API key is valid but does not have the required agent read scope.", "content": { "application/json": { "schema": { @@ -1172,17 +1292,7 @@ "$ref": "#/components/responses/InternalServerError" }, "503": { - "description": "The platform could not complete the command.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommandErrorEnvelope" - } - } - } - }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", + "description": "The platform could not list signals.", "content": { "application/json": { "schema": { @@ -1192,33 +1302,41 @@ } } } - } - }, - "/api/agents/{id}/rename": { + }, "post": { "tags": ["Platform API"], - "summary": "Rename agent", - "description": "Rename one configured Outlit agent display name.", - "operationId": "renameAgent", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "description": "Agent ID.", - "schema": { - "type": "string", - "minLength": 1 + "summary": "Create signal", + "description": "Create a UI-managed Outlit automation signal.", + "operationId": "createSignal", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignalRequest" + }, + "example": { + "kind": "EVENT_MATCH", + "name": "Workspace inactive", + "description": null, + "definition": { + "grain": "customer", + "subjectResolver": "event_customer", + "eventNames": ["workspace_inactive"], + "propertyConditions": [], + "conditionMode": "ALL" + } + } } } - ], + }, "responses": { "200": { - "description": "Rename agent completed.", + "description": "Signal was created.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RenameAgentCommandSuccess" + "$ref": "#/components/schemas/CreateSignalCommandSuccess" } } } @@ -1256,6 +1374,16 @@ } } }, + "409": { + "description": "The requested change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, "500": { "$ref": "#/components/responses/InternalServerError" }, @@ -1268,9 +1396,45 @@ } } } + } + } + } + }, + "/api/destinations": { + "get": { + "tags": ["Platform API"], + "summary": "List destinations", + "description": "List configured Outlit automation destinations with masked configuration only. Read-only.", + "operationId": "listDestinations", + "responses": { + "200": { + "description": "Configured destinations were returned.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListDestinationsCommandSuccess" + } + } + } }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent read scope.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not list destinations.", "content": { "application/json": { "schema": { @@ -1279,44 +1443,47 @@ } } } - }, + } + }, + "post": { + "tags": ["Platform API"], + "summary": "Create destination", + "description": "Create one automation destination. Responses include masked configuration only.", + "operationId": "createDestination", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RenameAgentRequest" + "$ref": "#/components/schemas/CreateDestinationRequest" + }, + "example": { + "type": "WEBHOOK_ENDPOINT", + "name": "Customer ops", + "description": null, + "enabled": true, + "url": "https://hooks.example.com/outlit" } } } - } - } - }, - "/api/automations/{id}/enable": { - "post": { - "tags": ["Platform API"], - "summary": "Enable automation", - "description": "Enable one configured Outlit automation by id after validating required resources.", - "operationId": "enableAutomation", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "description": "Automation ID.", - "schema": { - "type": "string", - "format": "uuid" - } - } - ], + }, "responses": { "200": { - "description": "Enable automation completed.", + "description": "Destination was created.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EnableAutomationCommandSuccess" + "$ref": "#/components/schemas/CreateDestinationCommandSuccess" + } + } + } + }, + "400": { + "description": "The request body failed command validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" } } } @@ -1344,11 +1511,8 @@ } } }, - "500": { - "$ref": "#/components/responses/InternalServerError" - }, - "503": { - "description": "The platform could not complete the command.", + "409": { + "description": "The requested change conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -1357,8 +1521,11 @@ } } }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", "content": { "application/json": { "schema": { @@ -1370,31 +1537,31 @@ } } }, - "/api/automations/{id}/disable": { + "/api/agents/{id}/enable": { "post": { "tags": ["Platform API"], - "summary": "Disable automation", - "description": "Disable one configured Outlit automation by id.", - "operationId": "disableAutomation", + "summary": "Enable agent", + "description": "Enable one configured Outlit agent by id. Does not run the agent immediately.", + "operationId": "enableAgent", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Automation ID.", + "description": "Agent ID.", "schema": { "type": "string", - "format": "uuid" + "minLength": 1 } } ], "responses": { "200": { - "description": "Disable automation completed.", + "description": "Enable agent completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DisableAutomationCommandSuccess" + "$ref": "#/components/schemas/EnableAgentCommandSuccess" } } } @@ -1422,11 +1589,8 @@ } } }, - "500": { - "$ref": "#/components/responses/InternalServerError" - }, - "503": { - "description": "The platform could not complete the command.", + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -1435,8 +1599,11 @@ } } }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", "content": { "application/json": { "schema": { @@ -1448,31 +1615,31 @@ } } }, - "/api/automations/{id}/archive": { + "/api/agents/{id}/disable": { "post": { "tags": ["Platform API"], - "summary": "Archive automation", - "description": "Archive one UI-managed Outlit automation by id. Archived automations are disabled and removed from normal lists.", - "operationId": "archiveAutomation", + "summary": "Disable agent", + "description": "Disable one configured Outlit agent by id. Disabled agents will not run from schedules or automations.", + "operationId": "disableAgent", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Automation ID.", + "description": "Agent ID.", "schema": { "type": "string", - "format": "uuid" + "minLength": 1 } } ], "responses": { "200": { - "description": "Archive automation completed.", + "description": "Disable agent completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ArchiveAutomationCommandSuccess" + "$ref": "#/components/schemas/DisableAgentCommandSuccess" } } } @@ -1500,11 +1667,8 @@ } } }, - "500": { - "$ref": "#/components/responses/InternalServerError" - }, - "503": { - "description": "The platform could not complete the command.", + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -1513,8 +1677,11 @@ } } }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", "content": { "application/json": { "schema": { @@ -1526,31 +1693,41 @@ } } }, - "/api/signals/{id}": { - "get": { + "/api/agents/{id}/rename": { + "post": { "tags": ["Platform API"], - "summary": "Get signal", - "description": "Get one configured Outlit automation signal by id. Read-only.", - "operationId": "getSignal", + "summary": "Rename agent", + "description": "Rename one configured Outlit agent display name.", + "operationId": "renameAgent", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Signal ID.", + "description": "Agent ID.", "schema": { "type": "string", - "format": "uuid" + "minLength": 1 } } ], "responses": { "200": { - "description": "Get signal completed.", + "description": "Rename agent completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetSignalCommandSuccess" + "$ref": "#/components/schemas/RenameAgentCommandSuccess" + } + } + } + }, + "400": { + "description": "The request body failed command validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" } } } @@ -1559,7 +1736,7 @@ "$ref": "#/components/responses/Unauthorized" }, "403": { - "description": "The API key is valid but does not have the required agent read scope.", + "description": "The API key is valid but does not have the required agent write scope.", "content": { "application/json": { "schema": { @@ -1569,7 +1746,17 @@ } }, "404": { - "description": "No signal was found for the authenticated organization and requested id.", + "description": "No resource was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -1591,21 +1778,31 @@ } } } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RenameAgentRequest" + } + } + } } } }, - "/api/signals/{id}/archive": { + "/api/automations/{id}/enable": { "post": { "tags": ["Platform API"], - "summary": "Archive signal", - "description": "Archive one UI-managed Outlit automation signal by id.", - "operationId": "archiveSignal", + "summary": "Enable automation", + "description": "Enable one configured Outlit automation by id after validating required resources.", + "operationId": "enableAutomation", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Signal ID.", + "description": "Automation ID.", "schema": { "type": "string", "format": "uuid" @@ -1614,11 +1811,11 @@ ], "responses": { "200": { - "description": "Archive signal completed.", + "description": "Enable automation completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ArchiveSignalCommandSuccess" + "$ref": "#/components/schemas/EnableAutomationCommandSuccess" } } } @@ -1646,11 +1843,8 @@ } } }, - "500": { - "$ref": "#/components/responses/InternalServerError" - }, - "503": { - "description": "The platform could not complete the command.", + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -1659,8 +1853,11 @@ } } }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", "content": { "application/json": { "schema": { @@ -1672,18 +1869,18 @@ } } }, - "/api/destinations/{id}": { - "get": { + "/api/automations/{id}/disable": { + "post": { "tags": ["Platform API"], - "summary": "Get destination", - "description": "Get one configured Outlit automation destination by id with masked configuration only. Read-only.", - "operationId": "getDestination", + "summary": "Disable automation", + "description": "Disable one configured Outlit automation by id.", + "operationId": "disableAutomation", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Destination ID.", + "description": "Automation ID.", "schema": { "type": "string", "format": "uuid" @@ -1692,11 +1889,11 @@ ], "responses": { "200": { - "description": "Get destination completed.", + "description": "Disable automation completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetDestinationCommandSuccess" + "$ref": "#/components/schemas/DisableAutomationCommandSuccess" } } } @@ -1705,7 +1902,7 @@ "$ref": "#/components/responses/Unauthorized" }, "403": { - "description": "The API key is valid but does not have the required agent read scope.", + "description": "The API key is valid but does not have the required agent write scope.", "content": { "application/json": { "schema": { @@ -1715,7 +1912,17 @@ } }, "404": { - "description": "No destination was found for the authenticated organization and requested id.", + "description": "No resource was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -1740,18 +1947,18 @@ } } }, - "/api/destinations/{id}/enable": { + "/api/automations/{id}/archive": { "post": { "tags": ["Platform API"], - "summary": "Enable destination", - "description": "Enable one configured Outlit automation destination by id. Does not test or send to the destination.", - "operationId": "enableDestination", + "summary": "Archive automation", + "description": "Archive one UI-managed Outlit automation by id. Archived automations are disabled and removed from normal lists.", + "operationId": "archiveAutomation", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Destination ID.", + "description": "Automation ID.", "schema": { "type": "string", "format": "uuid" @@ -1760,11 +1967,11 @@ ], "responses": { "200": { - "description": "Enable destination completed.", + "description": "Archive automation completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EnableDestinationCommandSuccess" + "$ref": "#/components/schemas/ArchiveAutomationCommandSuccess" } } } @@ -1792,11 +1999,8 @@ } } }, - "500": { - "$ref": "#/components/responses/InternalServerError" - }, - "503": { - "description": "The platform could not complete the command.", + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", "content": { "application/json": { "schema": { @@ -1805,8 +2009,11 @@ } } }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", "content": { "application/json": { "schema": { @@ -1818,18 +2025,18 @@ } } }, - "/api/destinations/{id}/disable": { - "post": { + "/api/signals/{id}": { + "get": { "tags": ["Platform API"], - "summary": "Disable destination", - "description": "Disable one configured Outlit automation destination by id.", - "operationId": "disableDestination", + "summary": "Get signal", + "description": "Get one configured Outlit automation signal by id. Read-only.", + "operationId": "getSignal", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Destination ID.", + "description": "Signal ID.", "schema": { "type": "string", "format": "uuid" @@ -1838,11 +2045,11 @@ ], "responses": { "200": { - "description": "Disable destination completed.", + "description": "Get signal completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DisableDestinationCommandSuccess" + "$ref": "#/components/schemas/GetSignalCommandSuccess" } } } @@ -1851,7 +2058,7 @@ "$ref": "#/components/responses/Unauthorized" }, "403": { - "description": "The API key is valid but does not have the required agent write scope.", + "description": "The API key is valid but does not have the required agent read scope.", "content": { "application/json": { "schema": { @@ -1861,7 +2068,7 @@ } }, "404": { - "description": "No resource was found for the authenticated organization and requested id.", + "description": "No signal was found for the authenticated organization and requested id.", "content": { "application/json": { "schema": { @@ -1882,45 +2089,65 @@ } } } - }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CommandErrorEnvelope" - } - } - } } } - } - }, - "/api/destinations/{id}/archive": { - "post": { + }, + "patch": { "tags": ["Platform API"], - "summary": "Archive destination", - "description": "Archive one configured Outlit automation destination by id. Archived destinations are disabled and removed from normal lists.", - "operationId": "archiveDestination", + "summary": "Update signal", + "description": "Update one UI-managed Outlit automation signal with a full signal configuration body.", + "operationId": "updateSignal", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Destination ID.", + "description": "Signal ID.", "schema": { "type": "string", "format": "uuid" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSignalRequest" + }, + "example": { + "kind": "EVENT_MATCH", + "name": "Workspace inactive", + "description": null, + "definition": { + "grain": "customer", + "subjectResolver": "event_customer", + "eventNames": ["workspace_inactive"], + "propertyConditions": [], + "conditionMode": "ALL" + } + } + } + } + }, "responses": { "200": { - "description": "Archive destination completed.", + "description": "Signal was updated.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ArchiveDestinationCommandSuccess" + "$ref": "#/components/schemas/UpdateSignalCommandSuccess" + } + } + } + }, + "400": { + "description": "The request body failed command validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" } } } @@ -1948,6 +2175,16 @@ } } }, + "409": { + "description": "The requested change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, "500": { "$ref": "#/components/responses/InternalServerError" }, @@ -1960,9 +2197,44 @@ } } } + } + } + } + }, + "/api/signals/{id}/archive": { + "post": { + "tags": ["Platform API"], + "summary": "Archive signal", + "description": "Archive one UI-managed Outlit automation signal by id.", + "operationId": "archiveSignal", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Signal ID.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Archive signal completed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ArchiveSignalCommandSuccess" + } + } + } }, - "409": { - "description": "The requested lifecycle change conflicts with the current platform state.", + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent write scope.", "content": { "application/json": { "schema": { @@ -1970,1841 +2242,2877 @@ } } } - } - } - } - } - }, - "components": { - "securitySchemes": { - "bearerAuth": { - "type": "http", - "scheme": "bearer", - "description": "Outlit API key using the Bearer ok_... format." - } - }, - "headers": { - "RateLimitLimit": { - "description": "Maximum requests allowed in the current window.", - "schema": { - "type": "integer", - "example": 100 - } - }, - "RateLimitRemaining": { - "description": "Requests remaining in the current window.", - "schema": { - "type": "integer", - "example": 95 - } - }, - "RateLimitReset": { - "description": "Unix timestamp when the current rate limit window resets.", - "schema": { - "type": "integer", - "example": 1699999999 + }, + "404": { + "description": "No resource was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + } } } }, - "responses": { - "BadRequest": { - "description": "Invalid request body or parameters.", - "content": { - "application/json": { + "/api/destinations/{id}": { + "get": { + "tags": ["Platform API"], + "summary": "Get destination", + "description": "Get one configured Outlit automation destination by id with masked configuration only. Read-only.", + "operationId": "getDestination", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Destination ID.", "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "example": { - "error": "Invalid request" + "type": "string", + "format": "uuid" } } - } - }, - "Unauthorized": { - "description": "Invalid or missing API key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "example": { - "error": "Invalid credentials" + ], + "responses": { + "200": { + "description": "Get destination completed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetDestinationCommandSuccess" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent read scope.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "404": { + "description": "No destination was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } } } } }, - "PlanLimit": { - "description": "Plan API-call limit reached.", - "content": { - "application/json": { + "patch": { + "tags": ["Platform API"], + "summary": "Update destination", + "description": "Update one automation destination. Responses include masked configuration only.", + "operationId": "updateDestination", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Destination ID.", "schema": { - "$ref": "#/components/schemas/PlanLimitError" + "type": "string", + "format": "uuid" } } - } - }, - "PlanConnectionLimit": { - "description": "Plan integration connection limit reached.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PlanConnectionLimitError" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateDestinationRequest" + }, + "example": { + "type": "WEBHOOK_ENDPOINT", + "name": "Customer ops", + "description": null, + "enabled": true + } } } - } - }, - "InternalServerError": { - "description": "Internal server error.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "example": { - "error": "Internal server error" + }, + "responses": { + "200": { + "description": "Destination was updated.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateDestinationCommandSuccess" + } + } + } + }, + "400": { + "description": "The request body failed command validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent write scope.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "404": { + "description": "No resource was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "409": { + "description": "The requested change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } } } } } }, - "schemas": { - "ValidateApiKeySuccess": { - "type": "object", - "required": ["valid", "organizationId"], - "properties": { - "valid": { - "type": "boolean", - "const": true - }, - "organizationId": { - "type": "string" - }, - "createdById": { - "type": ["string", "null"] - } + "/api/destinations/{id}/enable": { + "post": { + "tags": ["Platform API"], + "summary": "Enable destination", + "description": "Enable one configured Outlit automation destination by id. Does not test or send to the destination.", + "operationId": "enableDestination", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Destination ID.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Enable destination completed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EnableDestinationCommandSuccess" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent write scope.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "404": { + "description": "No resource was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + } + } + } + }, + "/api/destinations/{id}/disable": { + "post": { + "tags": ["Platform API"], + "summary": "Disable destination", + "description": "Disable one configured Outlit automation destination by id.", + "operationId": "disableDestination", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Destination ID.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Disable destination completed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisableDestinationCommandSuccess" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent write scope.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "404": { + "description": "No resource was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + } + } + } + }, + "/api/destinations/{id}/archive": { + "post": { + "tags": ["Platform API"], + "summary": "Archive destination", + "description": "Archive one configured Outlit automation destination by id. Archived destinations are disabled and removed from normal lists.", + "operationId": "archiveDestination", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Destination ID.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "Archive destination completed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ArchiveDestinationCommandSuccess" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "description": "The API key is valid but does not have the required agent write scope.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "404": { + "description": "No resource was found for the authenticated organization and requested id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "409": { + "description": "The requested lifecycle change conflicts with the current platform state.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "503": { + "description": "The platform could not complete the command.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommandErrorEnvelope" + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "description": "Outlit API key using the Bearer ok_... format." + } + }, + "headers": { + "RateLimitLimit": { + "description": "Maximum requests allowed in the current window.", + "schema": { + "type": "integer", + "example": 100 + } + }, + "RateLimitRemaining": { + "description": "Requests remaining in the current window.", + "schema": { + "type": "integer", + "example": 95 + } + }, + "RateLimitReset": { + "description": "Unix timestamp when the current rate limit window resets.", + "schema": { + "type": "integer", + "example": 1699999999 + } + } + }, + "responses": { + "BadRequest": { + "description": "Invalid request body or parameters.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Invalid request" + } + } + } + }, + "Unauthorized": { + "description": "Invalid or missing API key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Invalid credentials" + } + } + } + }, + "PlanLimit": { + "description": "Plan API-call limit reached.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PlanLimitError" + } + } + } + }, + "PlanConnectionLimit": { + "description": "Plan integration connection limit reached.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PlanConnectionLimitError" + } + } + } + }, + "InternalServerError": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Internal server error" + } + } + } + } + }, + "schemas": { + "ValidateApiKeySuccess": { + "type": "object", + "required": ["valid", "organizationId"], + "properties": { + "valid": { + "type": "boolean", + "const": true + }, + "organizationId": { + "type": "string" + }, + "createdById": { + "type": ["string", "null"] + } + }, + "additionalProperties": false + }, + "ToolCallRequest": { + "type": "object", + "required": ["tool"], + "properties": { + "tool": { + "type": "string", + "description": "Customer intelligence tool name from @outlit/tools.", + "enum": [ + "outlit_list_customers", + "outlit_list_users", + "outlit_list_workspace_users", + "outlit_get_customer", + "outlit_get_timeline", + "outlit_list_facts", + "outlit_get_fact", + "outlit_get_source", + "outlit_list_sources", + "outlit_search_customer_context", + "outlit_query", + "outlit_schema", + "outlit_send_notification" + ] + }, + "input": { + "type": "object", + "description": "Tool-specific input object validated against the shared @outlit/tools contract.", + "additionalProperties": true, + "default": {} + } + }, + "additionalProperties": false + }, + "CommandResource": { + "type": "object", + "required": ["type", "id"], + "properties": { + "type": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "additionalProperties": false + }, + "CommandResultBase": { + "type": "object", + "required": ["operationId", "status", "resources", "data", "warnings"], + "properties": { + "operationId": { + "type": "string" + }, + "status": { + "type": "string", + "const": "completed" + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CommandResource" + } + }, + "data": { + "type": "object", + "additionalProperties": true + }, + "warnings": { + "type": "array", + "items": { + "type": "string" + } + }, + "auditId": { + "type": "string" + } + }, + "additionalProperties": false + }, + "CommandErrorEnvelope": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "error"], + "properties": { + "ok": { + "type": "boolean", + "const": false + }, + "commandId": { + "type": "string" + }, + "commandVersion": { + "type": "integer", + "minimum": 1 + }, + "error": { + "type": "object", + "required": ["code", "message", "correlationId", "retryable"], + "properties": { + "code": { + "type": "string", + "enum": [ + "validation_failed", + "authorization_denied", + "conflict", + "not_found", + "rate_limited", + "transient_failure" + ] + }, + "message": { + "type": "string" + }, + "correlationId": { + "type": "string" + }, + "retryable": { + "type": "boolean" + }, + "details": { + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "AgentTemplateKey": { + "type": "string", + "enum": ["churn"] + }, + "AgentTemplateMode": { + "type": "string", + "enum": ["draft"] + }, + "AgentTemplateSummary": { + "type": "object", + "required": [ + "key", + "version", + "name", + "description", + "creates", + "defaultMode", + "supportedModes" + ], + "properties": { + "key": { + "$ref": "#/components/schemas/AgentTemplateKey" + }, + "version": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "creates": { + "type": "array", + "items": { + "type": "string", + "enum": ["agent", "signal", "automation"] + } + }, + "defaultMode": { + "$ref": "#/components/schemas/AgentTemplateMode" + }, + "supportedModes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AgentTemplateMode" + } + } + }, + "additionalProperties": false + }, + "AgentActionSummary": { + "type": "object", + "required": ["key", "version", "label", "category", "subjectTypes"], + "properties": { + "key": { + "type": "string" + }, + "version": { + "type": "integer", + "minimum": 1 + }, + "label": { + "type": "string" + }, + "category": { + "type": "string" + }, + "subjectTypes": { + "type": "array", + "items": { + "type": "string", + "enum": ["CUSTOMER"] + } + } + }, + "additionalProperties": false + }, + "AgentStatus": { + "type": "string", + "enum": ["ENABLED", "DISABLED"] + }, + "AgentScheduleSummary": { + "type": "object", + "required": ["enabled", "nextRunAt", "lastRunAt", "lastSuccessfulRunAt"], + "properties": { + "enabled": { + "type": "boolean" + }, + "nextRunAt": { + "type": ["string", "null"], + "format": "date-time" + }, + "lastRunAt": { + "type": ["string", "null"], + "format": "date-time" + }, + "lastSuccessfulRunAt": { + "type": ["string", "null"], + "format": "date-time" + } + }, + "additionalProperties": false + }, + "AgentSummary": { + "type": "object", + "required": [ + "id", + "agentKey", + "displayName", + "status", + "templateVersion", + "actionKeys", + "schedule", + "createdAt", + "updatedAt" + ], + "properties": { + "id": { + "type": "string" + }, + "agentKey": { + "type": "string" + }, + "displayName": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/AgentStatus" + }, + "templateVersion": { + "type": "string" + }, + "actionKeys": { + "type": "array", + "items": { + "type": "string" + } + }, + "schedule": { + "$ref": "#/components/schemas/AgentScheduleSummary" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "ListAgentTemplatesCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true + }, + "commandId": { + "type": "string", + "const": "agent.listTemplates" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "agent.templates.list" + }, + "data": { + "type": "object", + "required": ["templates"], + "properties": { + "templates": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AgentTemplateSummary" + } + } + }, + "additionalProperties": false + } + } + } + ] + } + }, + "additionalProperties": false + }, + "ListAgentActionsCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true + }, + "commandId": { + "type": "string", + "const": "agent.listAvailableActions" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "agent.availableActions.list" + }, + "data": { + "type": "object", + "required": ["actions"], + "properties": { + "actions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AgentActionSummary" + } + } + }, + "additionalProperties": false + } + } + } + ] + } + }, + "additionalProperties": false + }, + "ListAgentsCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true + }, + "commandId": { + "type": "string", + "const": "agent.list" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "agent.list" + }, + "data": { + "type": "object", + "required": ["agents"], + "properties": { + "agents": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AgentSummary" + } + } + }, + "additionalProperties": false + } + } + } + ] + } + }, + "additionalProperties": false + }, + "GetAgentCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true + }, + "commandId": { + "type": "string", + "const": "agent.get" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "agent.get" + }, + "data": { + "type": "object", + "required": ["agent"], + "properties": { + "agent": { + "$ref": "#/components/schemas/AgentSummary" + } + }, + "additionalProperties": false + } + } + } + ] + } + }, + "additionalProperties": false + }, + "CreateAgentTemplateRequest": { + "type": "object", + "required": ["type", "templateKey"], + "properties": { + "type": { + "type": "string", + "const": "template" + }, + "templateKey": { + "$ref": "#/components/schemas/AgentTemplateKey" + }, + "mode": { + "$ref": "#/components/schemas/AgentTemplateMode" + } + }, + "additionalProperties": false + }, + "CreateAgentRequest": { + "oneOf": [ + { + "$ref": "#/components/schemas/CreateAgentTemplateRequest" + }, + { + "$ref": "#/components/schemas/CreateAgentCustomRequest" + } + ] + }, + "CreateAgentCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true + }, + "commandId": { + "type": "string", + "const": "agent.create" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "agent.create" + }, + "data": { + "type": "object", + "required": ["agent"], + "properties": { + "agent": { + "$ref": "#/components/schemas/AgentSummary" + } + }, + "additionalProperties": false + } + } + } + ] + } }, "additionalProperties": false }, - "ToolCallRequest": { + "ProviderId": { + "type": "string", + "description": "Public integration provider ID.", + "enum": [ + "hubspot", + "attio", + "slack", + "fireflies", + "granola", + "google-calendar", + "google-mail", + "posthog", + "stripe", + "supabase", + "clerk", + "pylon" + ] + }, + "Integration": { "type": "object", - "required": ["tool"], + "required": ["id", "name", "category", "status"], "properties": { - "tool": { + "id": { + "$ref": "#/components/schemas/ProviderId" + }, + "name": { + "type": "string" + }, + "category": { "type": "string", - "description": "Customer intelligence tool name from @outlit/tools.", - "enum": [ - "outlit_list_customers", - "outlit_list_users", - "outlit_list_workspace_users", - "outlit_get_customer", - "outlit_get_timeline", - "outlit_list_facts", - "outlit_get_fact", - "outlit_get_source", - "outlit_list_sources", - "outlit_search_customer_context", - "outlit_query", - "outlit_schema", - "outlit_send_notification" - ] + "examples": ["billing", "crm", "analytics"] }, - "input": { - "type": "object", - "description": "Tool-specific input object validated against the shared @outlit/tools contract.", - "additionalProperties": true, - "default": {} + "status": { + "type": "string", + "enum": ["connected", "not_connected"] + }, + "connectionId": { + "type": ["string", "null"] + }, + "lastDataReceivedAt": { + "type": ["string", "null"], + "format": "date-time" + }, + "syncStatus": { + "type": ["string", "null"], + "examples": ["SUCCESS"] + }, + "errorMessage": { + "type": ["string", "null"] } }, "additionalProperties": false }, - "CommandResource": { + "IntegrationCapabilitiesResponse": { + "oneOf": [ + { + "$ref": "#/components/schemas/ProviderCapabilityEnvelope" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ProviderCapability" + } + } + ] + }, + "ProviderCapabilityEnvelope": { "type": "object", - "required": ["type", "id"], + "required": ["provider"], "properties": { - "type": { - "type": "string" - }, - "id": { - "type": "string" + "provider": { + "$ref": "#/components/schemas/ProviderCapability" } }, "additionalProperties": false }, - "CommandResultBase": { + "ProviderCapability": { "type": "object", - "required": ["operationId", "status", "resources", "data", "warnings"], + "required": ["cliName", "providerId", "setupMode"], "properties": { - "operationId": { + "cliName": { "type": "string" }, - "status": { + "providerId": { + "$ref": "#/components/schemas/ProviderId" + }, + "setupMode": { "type": "string", - "const": "completed" + "examples": ["direct_api_key", "browser_session"] }, - "resources": { + "credentialType": { + "type": ["string", "null"], + "examples": ["api_token"] + }, + "requiredFields": { "type": "array", "items": { - "$ref": "#/components/schemas/CommandResource" + "$ref": "#/components/schemas/ProviderCredentialField" } }, - "data": { - "type": "object", - "additionalProperties": true - }, - "warnings": { + "commands": { "type": "array", "items": { "type": "string" } }, - "auditId": { + "postConnectSteps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProviderPostConnectStep" + } + } + }, + "additionalProperties": true + }, + "ProviderCredentialField": { + "type": "object", + "required": ["key", "label"], + "properties": { + "key": { + "type": "string" + }, + "label": { + "type": "string" + }, + "secret": { + "type": "boolean" + } + }, + "additionalProperties": true + }, + "ProviderPostConnectStep": { + "type": "object", + "required": ["id", "required", "supported"], + "properties": { + "id": { + "type": "string", + "examples": ["webhook-setup", "mappings"] + }, + "required": { + "type": "boolean" + }, + "supported": { + "type": "boolean" + }, + "command": { + "type": "string" + } + }, + "additionalProperties": true + }, + "IntegrationSetupStepRequest": { + "type": "object", + "required": ["provider", "step"], + "properties": { + "provider": { + "$ref": "#/components/schemas/ProviderId" + }, + "step": { + "type": "string", + "minLength": 1, + "examples": ["mappings", "webhooks"] + }, + "config": { + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": false + }, + "IntegrationConnectRequest": { + "type": "object", + "required": ["provider"], + "properties": { + "provider": { + "$ref": "#/components/schemas/ProviderId" + }, + "config": { + "type": "object", + "description": "Direct credential config. Omit to create a browser-auth connection session.", + "additionalProperties": true + } + }, + "additionalProperties": false + }, + "IntegrationDisconnectRequest": { + "type": "object", + "required": ["provider"], + "properties": { + "provider": { + "$ref": "#/components/schemas/ProviderId" + } + }, + "additionalProperties": false + }, + "IntegrationDirectConnectionResponse": { + "type": "object", + "required": ["connected", "connectionId", "alreadyConnected"], + "properties": { + "connected": { + "type": "boolean" + }, + "connectionId": { "type": "string" + }, + "alreadyConnected": { + "type": "boolean" } }, "additionalProperties": false }, - "CommandErrorEnvelope": { + "IntegrationDisconnectResponse": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "error"], + "required": ["success"], "properties": { - "ok": { + "success": { "type": "boolean", - "const": false - }, - "commandId": { - "type": "string" - }, - "commandVersion": { - "type": "integer", - "minimum": 1 - }, - "error": { - "type": "object", - "required": ["code", "message", "correlationId", "retryable"], - "properties": { - "code": { - "type": "string", - "enum": [ - "validation_failed", - "authorization_denied", - "conflict", - "not_found", - "rate_limited", - "transient_failure" - ] - }, - "message": { - "type": "string" - }, - "correlationId": { - "type": "string" - }, - "retryable": { - "type": "boolean" - }, - "details": { - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": false + "const": true } }, "additionalProperties": false }, - "AgentTemplateKey": { - "type": "string", - "enum": ["churn"] - }, - "AgentTemplateMode": { - "type": "string", - "enum": ["draft"] - }, - "AgentTemplateSummary": { + "IntegrationDisconnectNotConnectedResponse": { "type": "object", - "required": [ - "key", - "version", - "name", - "description", - "creates", - "defaultMode", - "supportedModes" - ], + "required": ["success", "message"], "properties": { - "key": { - "$ref": "#/components/schemas/AgentTemplateKey" - }, - "version": { - "type": "string" - }, - "name": { - "type": "string" + "success": { + "type": "boolean", + "const": false }, - "description": { + "message": { "type": "string" - }, - "creates": { - "type": "array", - "items": { - "type": "string", - "enum": ["agent", "signal", "automation"] - } - }, - "defaultMode": { - "$ref": "#/components/schemas/AgentTemplateMode" - }, - "supportedModes": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AgentTemplateMode" - } } }, "additionalProperties": false }, - "AgentActionSummary": { + "IntegrationBrowserSessionResponse": { "type": "object", - "required": ["key", "version", "label", "category", "subjectTypes"], + "required": ["sessionId", "connectUrl", "alreadyConnected"], "properties": { - "key": { - "type": "string" - }, - "version": { - "type": "integer", - "minimum": 1 - }, - "label": { + "sessionId": { "type": "string" }, - "category": { - "type": "string" + "connectUrl": { + "type": "string", + "format": "uri" }, - "subjectTypes": { - "type": "array", - "items": { - "type": "string", - "enum": ["CUSTOMER"] - } + "alreadyConnected": { + "type": "boolean" } }, "additionalProperties": false }, - "AgentStatus": { - "type": "string", - "enum": ["ENABLED", "DISABLED"] - }, - "AgentScheduleSummary": { + "IntegrationConnectionStatusResponse": { "type": "object", - "required": ["enabled", "nextRunAt", "lastRunAt", "lastSuccessfulRunAt"], + "required": ["status", "provider"], "properties": { - "enabled": { - "type": "boolean" - }, - "nextRunAt": { - "type": ["string", "null"], - "format": "date-time" + "status": { + "type": "string", + "enum": ["pending", "connected", "failed", "expired"] }, - "lastRunAt": { - "type": ["string", "null"], - "format": "date-time" + "provider": { + "$ref": "#/components/schemas/ProviderId" }, - "lastSuccessfulRunAt": { - "type": ["string", "null"], - "format": "date-time" + "error": { + "type": "string" } }, "additionalProperties": false }, - "AgentSummary": { + "IntegrationSyncStatusResponse": { "type": "object", - "required": [ - "id", - "agentKey", - "displayName", - "status", - "templateVersion", - "actionKeys", - "schedule", - "createdAt", - "updatedAt" - ], + "required": ["provider", "name", "category", "status", "syncs"], "properties": { - "id": { - "type": "string" + "provider": { + "$ref": "#/components/schemas/ProviderId" }, - "agentKey": { + "name": { "type": "string" }, - "displayName": { + "category": { "type": "string" }, "status": { - "$ref": "#/components/schemas/AgentStatus" - }, - "templateVersion": { - "type": "string" + "type": "string", + "enum": ["connected", "not_connected"] }, - "actionKeys": { + "syncs": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/IntegrationSync" } + } + }, + "additionalProperties": false + }, + "IntegrationSync": { + "type": "object", + "required": ["model", "status"], + "properties": { + "model": { + "type": "string" }, - "schedule": { - "$ref": "#/components/schemas/AgentScheduleSummary" - }, - "createdAt": { + "status": { "type": "string", - "format": "date-time" + "examples": ["SUCCESS", "FAILED", "PENDING"] }, - "updatedAt": { - "type": "string", + "lastSyncedAt": { + "type": ["string", "null"], "format": "date-time" + }, + "errorMessage": { + "type": ["string", "null"] } }, "additionalProperties": false }, - "ListAgentTemplatesCommandSuccess": { + "IngestEventsRequest": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "required": ["events"], "properties": { - "ok": { - "type": "boolean", - "const": true - }, - "commandId": { + "visitorId": { "type": "string", - "const": "agent.listTemplates" - }, - "commandVersion": { - "type": "integer", - "const": 1 - }, - "correlationId": { - "type": "string" + "format": "uuid", + "description": "Browser visitor identifier. Required for client tracking." }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" - }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "agent.templates.list" - }, - "data": { - "type": "object", - "required": ["templates"], - "properties": { - "templates": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AgentTemplateSummary" - } - } - }, - "additionalProperties": false - } - } - } - ] + "source": { + "type": "string", + "enum": ["client", "server", "integration"], + "default": "client" + }, + "userIdentity": { + "$ref": "#/components/schemas/UserIdentity" + }, + "customerIdentity": { + "$ref": "#/components/schemas/CustomerIdentity" + }, + "events": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { + "$ref": "#/components/schemas/IngestEvent" + } } }, "additionalProperties": false }, - "ListAgentActionsCommandSuccess": { + "UserIdentity": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "ok": { - "type": "boolean", - "const": true - }, - "commandId": { + "email": { "type": "string", - "const": "agent.listAvailableActions" - }, - "commandVersion": { - "type": "integer", - "const": 1 + "format": "email" }, - "correlationId": { + "userId": { "type": "string" }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" - }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "agent.availableActions.list" - }, - "data": { - "type": "object", - "required": ["actions"], - "properties": { - "actions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AgentActionSummary" - } - } - }, - "additionalProperties": false - } - } - } - ] + "traits": { + "$ref": "#/components/schemas/JsonObject" } }, "additionalProperties": false }, - "ListAgentsCommandSuccess": { + "CustomerIdentity": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "ok": { - "type": "boolean", - "const": true - }, - "commandId": { - "type": "string", - "const": "agent.list" - }, - "commandVersion": { - "type": "integer", - "const": 1 - }, - "correlationId": { + "customerId": { "type": "string" }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" - }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "agent.list" - }, - "data": { - "type": "object", - "required": ["agents"], - "properties": { - "agents": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AgentSummary" - } - } - }, - "additionalProperties": false - } - } - } - ] + "customerTraits": { + "$ref": "#/components/schemas/JsonObject" } }, "additionalProperties": false }, - "GetAgentCommandSuccess": { + "IngestEvent": { + "oneOf": [ + { + "$ref": "#/components/schemas/PageviewEvent" + }, + { + "$ref": "#/components/schemas/CustomEvent" + }, + { + "$ref": "#/components/schemas/FormEvent" + }, + { + "$ref": "#/components/schemas/IdentifyEvent" + }, + { + "$ref": "#/components/schemas/EngagementEvent" + }, + { + "$ref": "#/components/schemas/CalendarEvent" + }, + { + "$ref": "#/components/schemas/StageEvent" + }, + { + "$ref": "#/components/schemas/BillingEvent" + } + ] + }, + "BaseEventFields": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "required": ["type"], "properties": { - "ok": { - "type": "boolean", - "const": true + "type": { + "type": "string" }, - "commandId": { + "timestamp": { + "type": "number", + "description": "Unix timestamp in milliseconds." + }, + "url": { "type": "string", - "const": "agent.get" + "format": "uri" }, - "commandVersion": { - "type": "integer", - "const": 1 + "path": { + "type": "string" }, - "correlationId": { + "referrer": { "type": "string" }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" + "utm": { + "$ref": "#/components/schemas/UtmParameters" + } + } + }, + "PageviewEvent": { + "allOf": [ + { + "$ref": "#/components/schemas/BaseEventFields" + }, + { + "type": "object", + "required": ["type"], + "properties": { + "type": { + "const": "pageview" }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "agent.get" - }, - "data": { - "type": "object", - "required": ["agent"], - "properties": { - "agent": { - "$ref": "#/components/schemas/AgentSummary" - } - }, - "additionalProperties": false - } - } + "title": { + "type": "string" } - ] + } } - }, - "additionalProperties": false + ] }, - "CreateAgentFromTemplateRequest": { - "type": "object", - "required": ["source"], - "properties": { - "source": { + "CustomEvent": { + "allOf": [ + { + "$ref": "#/components/schemas/BaseEventFields" + }, + { + "type": "object", + "required": ["type", "eventName"], + "properties": { + "type": { + "const": "custom" + }, + "eventName": { + "type": "string" + }, + "properties": { + "$ref": "#/components/schemas/JsonObject" + } + } + } + ] + }, + "FormEvent": { + "allOf": [ + { + "$ref": "#/components/schemas/BaseEventFields" + }, + { + "type": "object", + "required": ["type"], + "properties": { + "type": { + "const": "form" + }, + "formId": { + "type": "string" + }, + "formFields": { + "$ref": "#/components/schemas/JsonObject" + } + } + } + ] + }, + "IdentifyEvent": { + "allOf": [ + { + "$ref": "#/components/schemas/BaseEventFields" + }, + { "type": "object", - "required": ["type", "templateKey"], + "required": ["type"], "properties": { "type": { + "const": "identify" + }, + "email": { "type": "string", - "const": "template" + "format": "email" + }, + "userId": { + "type": "string" + }, + "customerId": { + "type": "string" + }, + "traits": { + "$ref": "#/components/schemas/JsonObject" }, - "templateKey": { - "$ref": "#/components/schemas/AgentTemplateKey" + "customerTraits": { + "$ref": "#/components/schemas/JsonObject" } - }, - "additionalProperties": false - }, - "mode": { - "$ref": "#/components/schemas/AgentTemplateMode" + } } - }, - "additionalProperties": false + ] }, - "CreateAgentFromTemplateCommandSuccess": { - "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], - "properties": { - "ok": { - "type": "boolean", - "const": true - }, - "commandId": { - "type": "string", - "const": "agent.createFromTemplate" - }, - "commandVersion": { - "type": "integer", - "const": 1 - }, - "correlationId": { - "type": "string" + "EngagementEvent": { + "allOf": [ + { + "$ref": "#/components/schemas/BaseEventFields" }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" + { + "type": "object", + "required": ["type", "activeTimeMs", "totalTimeMs", "sessionId"], + "properties": { + "type": { + "const": "engagement" }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "agent.template.create" - }, - "data": { - "type": "object", - "required": [ - "agentId", - "templateKey", - "templateVersion", - "mode", - "created", - "safety" - ], - "properties": { - "agentId": { - "type": "string" - }, - "templateKey": { - "$ref": "#/components/schemas/AgentTemplateKey" - }, - "templateVersion": { - "type": "string" - }, - "mode": { - "$ref": "#/components/schemas/AgentTemplateMode" - }, - "created": { - "type": "boolean" - }, - "safety": { - "type": "object", - "required": [ - "actionGrantsAdded", - "destinationsAdded", - "schedulesAdded", - "externalEgressAdded", - "enabledAutomation" - ], - "properties": { - "actionGrantsAdded": { - "type": "array", - "items": { - "type": "string" - } - }, - "destinationsAdded": { - "type": "array", - "items": { - "type": "string" - } - }, - "schedulesAdded": { - "type": "array", - "items": { - "type": "string" - } - }, - "externalEgressAdded": { - "type": "array", - "items": { - "type": "string" - } - }, - "enabledAutomation": { - "type": "boolean" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - } + "activeTimeMs": { + "type": "number", + "minimum": 0 + }, + "totalTimeMs": { + "type": "number", + "minimum": 0 + }, + "sessionId": { + "type": "string", + "format": "uuid" } - ] + } } - }, - "additionalProperties": false - }, - "ProviderId": { - "type": "string", - "description": "Public integration provider ID.", - "enum": [ - "hubspot", - "attio", - "slack", - "fireflies", - "granola", - "google-calendar", - "google-mail", - "posthog", - "stripe", - "supabase", - "clerk", - "pylon" ] }, - "Integration": { - "type": "object", - "required": ["id", "name", "category", "status"], - "properties": { - "id": { - "$ref": "#/components/schemas/ProviderId" - }, - "name": { - "type": "string" - }, - "category": { - "type": "string", - "examples": ["billing", "crm", "analytics"] - }, - "status": { - "type": "string", - "enum": ["connected", "not_connected"] - }, - "connectionId": { - "type": ["string", "null"] - }, - "lastDataReceivedAt": { - "type": ["string", "null"], - "format": "date-time" - }, - "syncStatus": { - "type": ["string", "null"], - "examples": ["SUCCESS"] + "CalendarEvent": { + "allOf": [ + { + "$ref": "#/components/schemas/BaseEventFields" }, - "errorMessage": { - "type": ["string", "null"] + { + "type": "object", + "required": ["type", "provider"], + "properties": { + "type": { + "const": "calendar" + }, + "provider": { + "type": "string", + "enum": ["cal.com", "calendly", "unknown"] + }, + "eventType": { + "type": "string" + }, + "startTime": { + "type": "string", + "format": "date-time" + }, + "endTime": { + "type": "string", + "format": "date-time" + }, + "duration": { + "type": "number" + }, + "isRecurring": { + "type": "boolean" + }, + "inviteeEmail": { + "type": "string", + "format": "email" + }, + "inviteeName": { + "type": "string" + } + } } - }, - "additionalProperties": false + ] }, - "IntegrationCapabilitiesResponse": { - "oneOf": [ + "StageEvent": { + "allOf": [ { - "$ref": "#/components/schemas/ProviderCapabilityEnvelope" + "$ref": "#/components/schemas/BaseEventFields" }, { "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/ProviderCapability" + "required": ["type", "stage"], + "properties": { + "type": { + "const": "stage" + }, + "stage": { + "type": "string", + "enum": ["activated", "engaged", "inactive"] + }, + "properties": { + "$ref": "#/components/schemas/JsonObject" + } } } ] }, - "ProviderCapabilityEnvelope": { - "type": "object", - "required": ["provider"], - "properties": { - "provider": { - "$ref": "#/components/schemas/ProviderCapability" - } - }, - "additionalProperties": false - }, - "ProviderCapability": { - "type": "object", - "required": ["cliName", "providerId", "setupMode"], - "properties": { - "cliName": { - "type": "string" - }, - "providerId": { - "$ref": "#/components/schemas/ProviderId" - }, - "setupMode": { - "type": "string", - "examples": ["direct_api_key", "browser_session"] - }, - "credentialType": { - "type": ["string", "null"], - "examples": ["api_token"] - }, - "requiredFields": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ProviderCredentialField" - } - }, - "commands": { - "type": "array", - "items": { - "type": "string" - } + "BillingEvent": { + "allOf": [ + { + "$ref": "#/components/schemas/BaseEventFields" }, - "postConnectSteps": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ProviderPostConnectStep" + { + "type": "object", + "required": ["type", "status"], + "properties": { + "type": { + "const": "billing" + }, + "status": { + "type": "string", + "enum": ["trialing", "paid", "churned"] + }, + "customerId": { + "type": "string" + }, + "stripeCustomerId": { + "type": "string" + }, + "properties": { + "$ref": "#/components/schemas/JsonObject" + } } } - }, - "additionalProperties": true + ] }, - "ProviderCredentialField": { + "UtmParameters": { "type": "object", - "required": ["key", "label"], "properties": { - "key": { + "source": { "type": "string" }, - "label": { + "medium": { "type": "string" }, - "secret": { - "type": "boolean" + "campaign": { + "type": "string" + }, + "term": { + "type": "string" + }, + "content": { + "type": "string" } }, + "additionalProperties": false + }, + "JsonObject": { + "type": "object", "additionalProperties": true }, - "ProviderPostConnectStep": { + "IngestEventsSuccess": { "type": "object", - "required": ["id", "required", "supported"], + "required": ["success"], "properties": { - "id": { - "type": "string", - "examples": ["webhook-setup", "mappings"] - }, - "required": { - "type": "boolean" - }, - "supported": { - "type": "boolean" - }, - "command": { - "type": "string" + "success": { + "type": "boolean", + "const": true } }, "additionalProperties": true }, - "IntegrationSetupStepRequest": { + "IngestEventsError": { "type": "object", - "required": ["provider", "step"], + "required": ["success", "message"], "properties": { - "provider": { - "$ref": "#/components/schemas/ProviderId" + "success": { + "type": "boolean", + "const": false }, - "step": { - "type": "string", - "minLength": 1, - "examples": ["mappings", "webhooks"] + "message": { + "type": "string" }, - "config": { - "type": "object", - "additionalProperties": true + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } } }, - "additionalProperties": false + "additionalProperties": true }, - "IntegrationConnectRequest": { + "ValidationIssue": { "type": "object", - "required": ["provider"], + "required": ["path", "message"], "properties": { - "provider": { - "$ref": "#/components/schemas/ProviderId" + "path": { + "type": "array", + "items": { + "type": ["string", "number"] + } }, - "config": { - "type": "object", - "description": "Direct credential config. Omit to create a browser-auth connection session.", - "additionalProperties": true + "message": { + "type": "string" } }, "additionalProperties": false }, - "IntegrationDisconnectRequest": { + "ErrorResponse": { "type": "object", - "required": ["provider"], + "required": ["error"], "properties": { - "provider": { - "$ref": "#/components/schemas/ProviderId" + "error": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationIssue" + } } }, - "additionalProperties": false + "additionalProperties": true }, - "IntegrationDirectConnectionResponse": { + "PlanLimitError": { "type": "object", - "required": ["connected", "connectionId", "alreadyConnected"], + "required": ["error", "code"], "properties": { - "connected": { - "type": "boolean" + "error": { + "type": "string" }, - "connectionId": { + "code": { + "type": "string", + "examples": ["api_limit_exceeded"] + }, + "plan": { "type": "string" }, - "alreadyConnected": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "IntegrationDisconnectResponse": { - "type": "object", - "required": ["success"], - "properties": { - "success": { - "type": "boolean", - "const": true + "feature": { + "type": "string", + "examples": ["api_calls"] + }, + "resetAt": { + "type": "number" } }, - "additionalProperties": false + "additionalProperties": true }, - "IntegrationDisconnectNotConnectedResponse": { + "PlanConnectionLimitError": { "type": "object", - "required": ["success", "message"], + "required": ["error", "code"], "properties": { - "success": { - "type": "boolean", - "const": false + "error": { + "type": "string" }, - "message": { + "code": { + "type": "string", + "examples": ["plan_connection_limit_exceeded"] + }, + "feature": { + "type": "string", + "examples": ["integration_connections"] + }, + "plan": { "type": "string" + }, + "currentConnections": { + "type": "integer" + }, + "limit": { + "type": "integer" } }, - "additionalProperties": false + "additionalProperties": true }, - "IntegrationBrowserSessionResponse": { + "PlatformActionManagedBy": { + "type": "string", + "enum": ["UI", "CODE"] + }, + "SignalKind": { + "type": "string", + "enum": ["EVENT_MATCH", "EVENT_PATTERN"] + }, + "AutomationTriggerType": { + "type": "string", + "enum": ["SIGNAL_OCCURRENCE", "SCHEDULE"] + }, + "AutomationOutcomeType": { + "type": "string", + "enum": ["DIRECT_DELIVERY", "AGENT_PROCESSOR"] + }, + "AutomationMatchMode": { + "type": "string", + "enum": ["ANY", "ALL", "AT_LEAST"] + }, + "AutomationRunStatus": { + "type": "string", + "enum": [ + "PENDING", + "SKIPPED", + "RUNNING_PROCESSOR", + "READY_FOR_DELIVERY", + "PENDING_DELIVERY", + "DELIVERED", + "PARTIAL_FAILURE", + "FAILED" + ] + }, + "DestinationProvider": { + "type": "string", + "enum": ["SLACK", "OUTPOST", "WEBHOOK"] + }, + "DestinationKind": { + "type": "string", + "enum": ["SLACK_CHANNEL", "WEBHOOK_ENDPOINT"] + }, + "DestinationSyncStatus": { + "type": "string", + "enum": ["PENDING_PROVIDER_SYNC", "SYNCED", "PROVIDER_ERROR", "DISABLED_BY_PROVIDER"] + }, + "SignalRead": { "type": "object", - "required": ["sessionId", "connectUrl", "alreadyConnected"], + "required": [ + "id", + "key", + "managedBy", + "name", + "description", + "kind", + "definition", + "schemaVersion", + "configHash", + "archivedAt", + "createdAt", + "updatedAt" + ], "properties": { - "sessionId": { + "id": { + "type": "string", + "format": "uuid" + }, + "key": { + "type": "string" + }, + "managedBy": { + "$ref": "#/components/schemas/PlatformActionManagedBy" + }, + "name": { + "type": "string" + }, + "description": { + "type": ["string", "null"] + }, + "kind": { + "$ref": "#/components/schemas/SignalKind" + }, + "definition": {}, + "schemaVersion": { "type": "string" }, - "connectUrl": { + "configHash": { + "type": ["string", "null"] + }, + "archivedAt": { + "type": ["string", "null"], + "format": "date-time" + }, + "createdAt": { "type": "string", - "format": "uri" + "format": "date-time" }, - "alreadyConnected": { - "type": "boolean" + "updatedAt": { + "type": "string", + "format": "date-time" } }, "additionalProperties": false }, - "IntegrationConnectionStatusResponse": { + "DestinationRead": { "type": "object", - "required": ["status", "provider"], + "required": [ + "id", + "key", + "name", + "description", + "provider", + "kind", + "enabled", + "maskedConfig", + "syncStatus", + "lastSyncedAt", + "providerErrorCode", + "providerErrorMessage", + "isDefault", + "schemaVersion", + "configHash", + "archivedAt", + "createdAt", + "updatedAt" + ], "properties": { - "status": { + "id": { "type": "string", - "enum": ["pending", "connected", "failed", "expired"] - }, - "provider": { - "$ref": "#/components/schemas/ProviderId" + "format": "uuid" }, - "error": { + "key": { "type": "string" - } - }, - "additionalProperties": false - }, - "IntegrationSyncStatusResponse": { - "type": "object", - "required": ["provider", "name", "category", "status", "syncs"], - "properties": { - "provider": { - "$ref": "#/components/schemas/ProviderId" }, "name": { "type": "string" }, - "category": { - "type": "string" + "description": { + "type": ["string", "null"] }, - "status": { - "type": "string", - "enum": ["connected", "not_connected"] + "provider": { + "$ref": "#/components/schemas/DestinationProvider" }, - "syncs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IntegrationSync" - } - } - }, - "additionalProperties": false - }, - "IntegrationSync": { - "type": "object", - "required": ["model", "status"], - "properties": { - "model": { - "type": "string" + "kind": { + "$ref": "#/components/schemas/DestinationKind" }, - "status": { - "type": "string", - "examples": ["SUCCESS", "FAILED", "PENDING"] + "enabled": { + "type": "boolean" + }, + "maskedConfig": { + "anyOf": [ + { + "type": "object", + "additionalProperties": true + }, + { + "type": "null" + } + ] + }, + "syncStatus": { + "$ref": "#/components/schemas/DestinationSyncStatus" }, "lastSyncedAt": { "type": ["string", "null"], "format": "date-time" }, - "errorMessage": { + "providerErrorCode": { "type": ["string", "null"] - } - }, - "additionalProperties": false - }, - "IngestEventsRequest": { - "type": "object", - "required": ["events"], - "properties": { - "visitorId": { - "type": "string", - "format": "uuid", - "description": "Browser visitor identifier. Required for client tracking." }, - "source": { - "type": "string", - "enum": ["client", "server", "integration"], - "default": "client" + "providerErrorMessage": { + "type": ["string", "null"] }, - "userIdentity": { - "$ref": "#/components/schemas/UserIdentity" + "isDefault": { + "type": "boolean" }, - "customerIdentity": { - "$ref": "#/components/schemas/CustomerIdentity" + "schemaVersion": { + "type": "string" }, - "events": { - "type": "array", - "minItems": 1, - "maxItems": 100, - "items": { - "$ref": "#/components/schemas/IngestEvent" - } - } - }, - "additionalProperties": false - }, - "UserIdentity": { - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" + "configHash": { + "type": ["string", "null"] }, - "userId": { - "type": "string" + "archivedAt": { + "type": ["string", "null"], + "format": "date-time" }, - "traits": { - "$ref": "#/components/schemas/JsonObject" + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" } }, "additionalProperties": false }, - "CustomerIdentity": { + "AutomationRead": { "type": "object", + "required": [ + "id", + "key", + "managedBy", + "name", + "description", + "enabled", + "triggerType", + "triggerJson", + "audienceFilterJson", + "agentId", + "matchMode", + "schemaVersion", + "configHash", + "archivedAt", + "lastRunAt", + "lastRunStatus", + "nextRunAt", + "createdAt", + "updatedAt", + "signals", + "destinations", + "activeSignalCount", + "activeDestinationCount" + ], "properties": { - "customerId": { - "type": "string" - }, - "customerTraits": { - "$ref": "#/components/schemas/JsonObject" - } - }, - "additionalProperties": false - }, - "IngestEvent": { - "oneOf": [ - { - "$ref": "#/components/schemas/PageviewEvent" - }, - { - "$ref": "#/components/schemas/CustomEvent" - }, - { - "$ref": "#/components/schemas/FormEvent" - }, - { - "$ref": "#/components/schemas/IdentifyEvent" - }, - { - "$ref": "#/components/schemas/EngagementEvent" + "id": { + "type": "string", + "format": "uuid" }, - { - "$ref": "#/components/schemas/CalendarEvent" + "key": { + "type": "string" }, - { - "$ref": "#/components/schemas/StageEvent" + "managedBy": { + "$ref": "#/components/schemas/PlatformActionManagedBy" }, - { - "$ref": "#/components/schemas/BillingEvent" - } - ] - }, - "BaseEventFields": { - "type": "object", - "required": ["type"], - "properties": { - "type": { + "name": { "type": "string" }, - "timestamp": { - "type": "number", - "description": "Unix timestamp in milliseconds." + "description": { + "type": ["string", "null"] }, - "url": { - "type": "string", - "format": "uri" + "enabled": { + "type": "boolean" }, - "path": { - "type": "string" + "triggerType": { + "$ref": "#/components/schemas/AutomationTriggerType" + }, + "triggerJson": {}, + "audienceFilterJson": {}, + "matchMode": { + "$ref": "#/components/schemas/AutomationMatchMode" }, - "referrer": { + "schemaVersion": { "type": "string" }, - "utm": { - "$ref": "#/components/schemas/UtmParameters" - } - } - }, - "PageviewEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseEventFields" + "configHash": { + "type": ["string", "null"] }, - { - "type": "object", - "required": ["type"], - "properties": { - "type": { - "const": "pageview" - }, - "title": { - "type": "string" - } - } - } - ] - }, - "CustomEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseEventFields" + "archivedAt": { + "type": ["string", "null"], + "format": "date-time" }, - { - "type": "object", - "required": ["type", "eventName"], - "properties": { - "type": { - "const": "custom" - }, - "eventName": { - "type": "string" - }, - "properties": { - "$ref": "#/components/schemas/JsonObject" - } - } - } - ] - }, - "FormEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseEventFields" + "lastRunAt": { + "type": ["string", "null"], + "format": "date-time" }, - { - "type": "object", - "required": ["type"], - "properties": { - "type": { - "const": "form" - }, - "formId": { - "type": "string" + "lastRunStatus": { + "anyOf": [ + { + "$ref": "#/components/schemas/AutomationRunStatus" }, - "formFields": { - "$ref": "#/components/schemas/JsonObject" + { + "type": "null" } - } - } - ] - }, - "IdentifyEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseEventFields" + ] }, - { - "type": "object", - "required": ["type"], - "properties": { - "type": { - "const": "identify" - }, - "email": { - "type": "string", - "format": "email" - }, - "userId": { - "type": "string" - }, - "customerId": { - "type": "string" - }, - "traits": { - "$ref": "#/components/schemas/JsonObject" - }, - "customerTraits": { - "$ref": "#/components/schemas/JsonObject" - } - } - } - ] - }, - "EngagementEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseEventFields" + "nextRunAt": { + "type": ["string", "null"], + "format": "date-time" }, - { - "type": "object", - "required": ["type", "activeTimeMs", "totalTimeMs", "sessionId"], - "properties": { - "type": { - "const": "engagement" - }, - "activeTimeMs": { - "type": "number", - "minimum": 0 - }, - "totalTimeMs": { - "type": "number", - "minimum": 0 - }, - "sessionId": { - "type": "string", - "format": "uuid" - } + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "signals": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SignalRead" } - } - ] - }, - "CalendarEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseEventFields" }, - { - "type": "object", - "required": ["type", "provider"], - "properties": { - "type": { - "const": "calendar" - }, - "provider": { - "type": "string", - "enum": ["cal.com", "calendly", "unknown"] - }, - "eventType": { - "type": "string" - }, - "startTime": { - "type": "string", - "format": "date-time" - }, - "endTime": { - "type": "string", - "format": "date-time" - }, - "duration": { - "type": "number" - }, - "isRecurring": { - "type": "boolean" - }, - "inviteeEmail": { - "type": "string", - "format": "email" - }, - "inviteeName": { - "type": "string" - } + "destinations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DestinationRead" } + }, + "activeSignalCount": { + "type": "integer", + "minimum": 0 + }, + "activeDestinationCount": { + "type": "integer", + "minimum": 0 + }, + "agentId": { + "type": ["string", "null"], + "format": "uuid" } - ] + }, + "additionalProperties": false }, - "StageEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseEventFields" + "ListAutomationsCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true }, - { - "type": "object", - "required": ["type", "stage"], - "properties": { - "type": { - "const": "stage" - }, - "stage": { - "type": "string", - "enum": ["activated", "engaged", "inactive"] + "commandId": { + "type": "string", + "const": "automation.list" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" }, - "properties": { - "$ref": "#/components/schemas/JsonObject" + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "automation.list" + }, + "data": { + "type": "object", + "required": ["automations"], + "properties": { + "automations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AutomationRead" + } + } + }, + "additionalProperties": false + } + } } - } + ] } - ] + }, + "additionalProperties": false }, - "BillingEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseEventFields" + "GetAutomationCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true }, - { - "type": "object", - "required": ["type", "status"], - "properties": { - "type": { - "const": "billing" - }, - "status": { - "type": "string", - "enum": ["trialing", "paid", "churned"] - }, - "customerId": { - "type": "string" - }, - "stripeCustomerId": { - "type": "string" + "commandId": { + "type": "string", + "const": "automation.get" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" }, - "properties": { - "$ref": "#/components/schemas/JsonObject" + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "automation.get" + }, + "data": { + "type": "object", + "required": ["automation"], + "properties": { + "automation": { + "$ref": "#/components/schemas/AutomationRead" + } + }, + "additionalProperties": false + } + } } - } + ] } - ] + }, + "additionalProperties": false }, - "UtmParameters": { + "ListSignalsCommandSuccess": { "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "source": { - "type": "string" + "ok": { + "type": "boolean", + "const": true }, - "medium": { - "type": "string" + "commandId": { + "type": "string", + "const": "signal.list" }, - "campaign": { - "type": "string" + "commandVersion": { + "type": "integer", + "const": 1 }, - "term": { + "correlationId": { "type": "string" }, - "content": { - "type": "string" + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "signal.list" + }, + "data": { + "type": "object", + "required": ["signals"], + "properties": { + "signals": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SignalRead" + } + } + }, + "additionalProperties": false + } + } + } + ] } }, "additionalProperties": false }, - "JsonObject": { - "type": "object", - "additionalProperties": true - }, - "IngestEventsSuccess": { + "ListDestinationsCommandSuccess": { "type": "object", - "required": ["success"], + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "success": { + "ok": { "type": "boolean", "const": true + }, + "commandId": { + "type": "string", + "const": "destination.list" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "destination.list" + }, + "data": { + "type": "object", + "required": ["destinations"], + "properties": { + "destinations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DestinationRead" + } + } + }, + "additionalProperties": false + } + } + } + ] } }, - "additionalProperties": true + "additionalProperties": false }, - "IngestEventsError": { + "ArchivedResource": { "type": "object", - "required": ["success", "message"], + "required": ["id", "archivedAt"], "properties": { - "success": { - "type": "boolean", - "const": false - }, - "message": { - "type": "string" + "id": { + "type": "string", + "minLength": 1 }, - "errors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ValidationIssue" - } + "archivedAt": { + "type": "string", + "format": "date-time" } }, - "additionalProperties": true + "additionalProperties": false }, - "ValidationIssue": { + "RenameAgentRequest": { "type": "object", - "required": ["path", "message"], + "required": ["displayName"], "properties": { - "path": { - "type": "array", - "items": { - "type": ["string", "number"] - } + "displayName": { + "type": "string", + "minLength": 1, + "maxLength": 120 + } + }, + "additionalProperties": false + }, + "EnableAgentCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true }, - "message": { + "commandId": { + "type": "string", + "const": "agent.enable" + }, + "commandVersion": { + "type": "integer", + "const": 1 + }, + "correlationId": { "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "agent.enable" + }, + "data": { + "type": "object", + "required": ["agent"], + "properties": { + "agent": { + "$ref": "#/components/schemas/AgentSummary" + } + }, + "additionalProperties": false + } + } + } + ] } }, "additionalProperties": false }, - "ErrorResponse": { - "type": "object", - "required": ["error"], - "properties": { - "error": { - "type": "string" - }, - "details": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ValidationIssue" - } - } - }, - "additionalProperties": true - }, - "PlanLimitError": { + "DisableAgentCommandSuccess": { "type": "object", - "required": ["error", "code"], + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "error": { - "type": "string" + "ok": { + "type": "boolean", + "const": true }, - "code": { + "commandId": { "type": "string", - "examples": ["api_limit_exceeded"] + "const": "agent.disable" }, - "plan": { - "type": "string" + "commandVersion": { + "type": "integer", + "const": 1 }, - "feature": { - "type": "string", - "examples": ["api_calls"] + "correlationId": { + "type": "string" }, - "resetAt": { - "type": "number" + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "agent.disable" + }, + "data": { + "type": "object", + "required": ["agent"], + "properties": { + "agent": { + "$ref": "#/components/schemas/AgentSummary" + } + }, + "additionalProperties": false + } + } + } + ] } }, - "additionalProperties": true + "additionalProperties": false }, - "PlanConnectionLimitError": { + "RenameAgentCommandSuccess": { "type": "object", - "required": ["error", "code"], + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "error": { - "type": "string" + "ok": { + "type": "boolean", + "const": true }, - "code": { + "commandId": { "type": "string", - "examples": ["plan_connection_limit_exceeded"] + "const": "agent.rename" }, - "feature": { - "type": "string", - "examples": ["integration_connections"] + "commandVersion": { + "type": "integer", + "const": 1 }, - "plan": { + "correlationId": { "type": "string" }, - "currentConnections": { - "type": "integer" - }, - "limit": { - "type": "integer" + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "agent.rename" + }, + "data": { + "type": "object", + "required": ["agent"], + "properties": { + "agent": { + "$ref": "#/components/schemas/AgentSummary" + } + }, + "additionalProperties": false + } + } + } + ] } }, - "additionalProperties": true - }, - "PlatformActionManagedBy": { - "type": "string", - "enum": ["UI", "CODE"] - }, - "SignalKind": { - "type": "string", - "enum": ["EVENT_MATCH", "EVENT_PATTERN"] - }, - "AutomationTriggerType": { - "type": "string", - "enum": ["SIGNAL_OCCURRENCE", "SCHEDULE"] - }, - "AutomationOutcomeType": { - "type": "string", - "enum": ["DIRECT_DELIVERY", "AGENT_PROCESSOR"] - }, - "AutomationMatchMode": { - "type": "string", - "enum": ["ANY", "ALL", "AT_LEAST"] - }, - "AutomationRunStatus": { - "type": "string", - "enum": [ - "PENDING", - "SKIPPED", - "RUNNING_PROCESSOR", - "READY_FOR_DELIVERY", - "PENDING_DELIVERY", - "DELIVERED", - "PARTIAL_FAILURE", - "FAILED" - ] - }, - "DestinationProvider": { - "type": "string", - "enum": ["SLACK", "OUTPOST", "WEBHOOK"] - }, - "DestinationKind": { - "type": "string", - "enum": ["SLACK_CHANNEL", "WEBHOOK_ENDPOINT"] - }, - "DestinationSyncStatus": { - "type": "string", - "enum": ["PENDING_PROVIDER_SYNC", "SYNCED", "PROVIDER_ERROR", "DISABLED_BY_PROVIDER"] + "additionalProperties": false }, - "SignalRead": { + "EnableAutomationCommandSuccess": { "type": "object", - "required": [ - "id", - "key", - "managedBy", - "name", - "description", - "kind", - "definition", - "schemaVersion", - "configHash", - "archivedAt", - "createdAt", - "updatedAt" - ], + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "key": { - "type": "string" - }, - "managedBy": { - "$ref": "#/components/schemas/PlatformActionManagedBy" - }, - "name": { - "type": "string" + "ok": { + "type": "boolean", + "const": true }, - "description": { - "type": ["string", "null"] + "commandId": { + "type": "string", + "const": "automation.enable" }, - "kind": { - "$ref": "#/components/schemas/SignalKind" + "commandVersion": { + "type": "integer", + "const": 1 }, - "definition": {}, - "schemaVersion": { + "correlationId": { "type": "string" }, - "configHash": { - "type": ["string", "null"] - }, - "archivedAt": { - "type": ["string", "null"], - "format": "date-time" - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "updatedAt": { - "type": "string", - "format": "date-time" + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "automation.enable" + }, + "data": { + "type": "object", + "required": ["automation"], + "properties": { + "automation": { + "$ref": "#/components/schemas/AutomationRead" + } + }, + "additionalProperties": false + } + } + } + ] } }, "additionalProperties": false }, - "DestinationRead": { + "DisableAutomationCommandSuccess": { "type": "object", - "required": [ - "id", - "key", - "name", - "description", - "provider", - "kind", - "enabled", - "maskedConfig", - "syncStatus", - "lastSyncedAt", - "providerErrorCode", - "providerErrorMessage", - "isDefault", - "schemaVersion", - "configHash", - "archivedAt", - "createdAt", - "updatedAt" - ], + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "id": { + "ok": { + "type": "boolean", + "const": true + }, + "commandId": { "type": "string", - "format": "uuid" + "const": "automation.disable" }, - "key": { - "type": "string" + "commandVersion": { + "type": "integer", + "const": 1 }, - "name": { + "correlationId": { "type": "string" }, - "description": { - "type": ["string", "null"] - }, - "provider": { - "$ref": "#/components/schemas/DestinationProvider" - }, - "kind": { - "$ref": "#/components/schemas/DestinationKind" - }, - "enabled": { - "type": "boolean" - }, - "maskedConfig": { - "anyOf": [ + "result": { + "allOf": [ { - "type": "object", - "additionalProperties": true + "$ref": "#/components/schemas/CommandResultBase" }, { - "type": "null" + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "automation.disable" + }, + "data": { + "type": "object", + "required": ["automation"], + "properties": { + "automation": { + "$ref": "#/components/schemas/AutomationRead" + } + }, + "additionalProperties": false + } + } } ] + } + }, + "additionalProperties": false + }, + "ArchiveAutomationCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true }, - "syncStatus": { - "$ref": "#/components/schemas/DestinationSyncStatus" - }, - "lastSyncedAt": { - "type": ["string", "null"], - "format": "date-time" - }, - "providerErrorCode": { - "type": ["string", "null"] - }, - "providerErrorMessage": { - "type": ["string", "null"] + "commandId": { + "type": "string", + "const": "automation.archive" }, - "isDefault": { - "type": "boolean" + "commandVersion": { + "type": "integer", + "const": 1 }, - "schemaVersion": { + "correlationId": { "type": "string" }, - "configHash": { - "type": ["string", "null"] - }, - "archivedAt": { - "type": ["string", "null"], - "format": "date-time" - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "updatedAt": { - "type": "string", - "format": "date-time" + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "automation.archive" + }, + "data": { + "type": "object", + "required": ["automation"], + "properties": { + "automation": { + "$ref": "#/components/schemas/ArchivedResource" + } + }, + "additionalProperties": false + } + } + } + ] } }, "additionalProperties": false }, - "AutomationRead": { + "GetSignalCommandSuccess": { "type": "object", - "required": [ - "id", - "key", - "managedBy", - "name", - "description", - "enabled", - "triggerType", - "triggerJson", - "audienceFilterJson", - "outcomeType", - "processorJson", - "processorPolicyJson", - "deliveryPolicyJson", - "matchMode", - "schemaVersion", - "configHash", - "archivedAt", - "lastRunAt", - "lastRunStatus", - "nextRunAt", - "createdAt", - "updatedAt", - "signals", - "destinations", - "activeSignalCount", - "activeDestinationCount" - ], + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { - "id": { - "type": "string", - "format": "uuid" + "ok": { + "type": "boolean", + "const": true }, - "key": { - "type": "string" + "commandId": { + "type": "string", + "const": "signal.get" }, - "managedBy": { - "$ref": "#/components/schemas/PlatformActionManagedBy" + "commandVersion": { + "type": "integer", + "const": 1 }, - "name": { + "correlationId": { "type": "string" }, - "description": { - "type": ["string", "null"] - }, - "enabled": { - "type": "boolean" - }, - "triggerType": { - "$ref": "#/components/schemas/AutomationTriggerType" - }, - "triggerJson": {}, - "audienceFilterJson": {}, - "outcomeType": { - "$ref": "#/components/schemas/AutomationOutcomeType" - }, - "processorJson": {}, - "processorPolicyJson": {}, - "deliveryPolicyJson": {}, - "matchMode": { - "$ref": "#/components/schemas/AutomationMatchMode" - }, - "schemaVersion": { - "type": "string" + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "signal.get" + }, + "data": { + "type": "object", + "required": ["signal"], + "properties": { + "signal": { + "$ref": "#/components/schemas/SignalRead" + } + }, + "additionalProperties": false + } + } + } + ] + } + }, + "additionalProperties": false + }, + "ArchiveSignalCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true }, - "configHash": { - "type": ["string", "null"] + "commandId": { + "type": "string", + "const": "signal.archive" }, - "archivedAt": { - "type": ["string", "null"], - "format": "date-time" + "commandVersion": { + "type": "integer", + "const": 1 }, - "lastRunAt": { - "type": ["string", "null"], - "format": "date-time" + "correlationId": { + "type": "string" }, - "lastRunStatus": { - "anyOf": [ + "result": { + "allOf": [ { - "$ref": "#/components/schemas/AutomationRunStatus" + "$ref": "#/components/schemas/CommandResultBase" }, { - "type": "null" + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "signal.archive" + }, + "data": { + "type": "object", + "required": ["signal"], + "properties": { + "signal": { + "$ref": "#/components/schemas/ArchivedResource" + } + }, + "additionalProperties": false + } + } } ] + } + }, + "additionalProperties": false + }, + "GetDestinationCommandSuccess": { + "type": "object", + "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "properties": { + "ok": { + "type": "boolean", + "const": true }, - "nextRunAt": { - "type": ["string", "null"], - "format": "date-time" - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "updatedAt": { + "commandId": { "type": "string", - "format": "date-time" - }, - "signals": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SignalRead" - } - }, - "destinations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DestinationRead" - } + "const": "destination.get" }, - "activeSignalCount": { + "commandVersion": { "type": "integer", - "minimum": 0 + "const": 1 }, - "activeDestinationCount": { - "type": "integer", - "minimum": 0 + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "destination.get" + }, + "data": { + "type": "object", + "required": ["destination"], + "properties": { + "destination": { + "$ref": "#/components/schemas/DestinationRead" + } + }, + "additionalProperties": false + } + } + } + ] } }, "additionalProperties": false }, - "ListAutomationsCommandSuccess": { + "EnableDestinationCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -3814,7 +5122,7 @@ }, "commandId": { "type": "string", - "const": "automation.list" + "const": "destination.enable" }, "commandVersion": { "type": "integer", @@ -3833,17 +5141,14 @@ "properties": { "operationId": { "type": "string", - "const": "automation.list" + "const": "destination.enable" }, "data": { "type": "object", - "required": ["automations"], + "required": ["destination"], "properties": { - "automations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AutomationRead" - } + "destination": { + "$ref": "#/components/schemas/DestinationRead" } }, "additionalProperties": false @@ -3855,7 +5160,7 @@ }, "additionalProperties": false }, - "GetAutomationCommandSuccess": { + "DisableDestinationCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -3865,7 +5170,7 @@ }, "commandId": { "type": "string", - "const": "automation.get" + "const": "destination.disable" }, "commandVersion": { "type": "integer", @@ -3884,14 +5189,14 @@ "properties": { "operationId": { "type": "string", - "const": "automation.get" + "const": "destination.disable" }, "data": { "type": "object", - "required": ["automation"], + "required": ["destination"], "properties": { - "automation": { - "$ref": "#/components/schemas/AutomationRead" + "destination": { + "$ref": "#/components/schemas/DestinationRead" } }, "additionalProperties": false @@ -3903,7 +5208,7 @@ }, "additionalProperties": false }, - "ListSignalsCommandSuccess": { + "ArchiveDestinationCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -3913,126 +5218,633 @@ }, "commandId": { "type": "string", - "const": "signal.list" + "const": "destination.archive" }, "commandVersion": { "type": "integer", "const": 1 }, - "correlationId": { - "type": "string" + "correlationId": { + "type": "string" + }, + "result": { + "allOf": [ + { + "$ref": "#/components/schemas/CommandResultBase" + }, + { + "type": "object", + "properties": { + "operationId": { + "type": "string", + "const": "destination.archive" + }, + "data": { + "type": "object", + "required": ["destination"], + "properties": { + "destination": { + "$ref": "#/components/schemas/ArchivedResource" + } + }, + "additionalProperties": false + } + } + } + ] + } + }, + "additionalProperties": false + }, + "CreateAgentCustomRequest": { + "type": "object", + "required": ["type", "displayName", "instructions", "surfaceCriteria"], + "properties": { + "type": { + "type": "string", + "const": "custom" + }, + "displayName": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "instructions": { + "type": "string", + "minLength": 1, + "maxLength": 10000 + }, + "surfaceCriteria": { + "type": "string", + "minLength": 1, + "maxLength": 10000 + }, + "skipCriteria": { + "type": "string", + "minLength": 1, + "maxLength": 10000 + }, + "maxItemsToSurface": { + "type": "integer", + "minimum": 1, + "maximum": 50, + "default": 10 + }, + "actionKeys": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "default": [] + } + }, + "additionalProperties": false + }, + "UpdateAgentRequest": { + "type": "object", + "minProperties": 1, + "properties": { + "displayName": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "instructions": { + "type": "string", + "minLength": 1, + "maxLength": 10000 + }, + "actionKeys": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + } + }, + "additionalProperties": false + }, + "CreateAutomationRequest": { + "type": "object", + "required": ["agentId", "name", "triggerType"], + "properties": { + "agentId": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "description": { + "type": ["string", "null"], + "maxLength": 1000, + "default": null + }, + "enabled": { + "type": "boolean", + "default": true + }, + "triggerType": { + "$ref": "#/components/schemas/AutomationTriggerType" + }, + "signalIds": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "maxItems": 50, + "default": [] + }, + "matchMode": { + "$ref": "#/components/schemas/AutomationMatchMode" + }, + "triggerWindow": { + "type": "object", + "properties": { + "value": { + "type": "integer", + "minimum": 1 + }, + "unit": { + "type": "string", + "enum": ["hour", "day"] + } + }, + "required": ["value", "unit"], + "additionalProperties": false + }, + "triggerThresholdCount": { + "type": "integer", + "minimum": 2, + "maximum": 5 }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" + "schedule": { + "type": "object", + "properties": { + "cadence": { + "type": "string", + "enum": ["hourly", "daily", "weekly"] }, - { + "localTime": { "type": "object", "properties": { - "operationId": { - "type": "string", - "const": "signal.list" + "hour": { + "type": "integer", + "minimum": 0, + "maximum": 23 }, - "data": { - "type": "object", - "required": ["signals"], - "properties": { - "signals": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SignalRead" - } - } - }, - "additionalProperties": false + "minute": { + "type": "integer", + "minimum": 0, + "maximum": 59 + }, + "second": { + "type": "integer", + "minimum": 0, + "maximum": 59, + "default": 0 + }, + "millisecond": { + "type": "integer", + "minimum": 0, + "maximum": 999, + "default": 0 } - } + }, + "required": ["hour", "minute"], + "additionalProperties": false + }, + "timezone": { + "type": "string", + "default": "America/Los_Angeles" + }, + "weekday": { + "type": "string", + "enum": [ + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday", + "sunday" + ] } - ] + }, + "required": ["cadence"], + "additionalProperties": false + }, + "audienceFilter": { + "$ref": "#/components/schemas/AutomationAudienceFilter" + }, + "processorPolicy": { + "type": "object", + "properties": { + "subjectHandling": { + "type": "string", + "enum": ["event_customer", "scheduled_customer_pool"], + "default": "event_customer" + }, + "maxCustomersPerRun": { + "type": "integer", + "minimum": 1, + "maximum": 500 + }, + "maxConcurrentRuns": { + "type": "integer", + "const": 1 + }, + "cooldownHours": { + "type": "integer", + "minimum": 0, + "maximum": 2160 + } + }, + "additionalProperties": false + }, + "deliveryPolicy": { + "type": "object", + "properties": { + "requireAllDestinations": { + "type": "boolean", + "default": false + } + }, + "additionalProperties": false, + "default": { + "requireAllDestinations": false + } + }, + "destinationIds": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "maxItems": 25, + "default": [] } }, "additionalProperties": false }, - "ListDestinationsCommandSuccess": { + "UpdateAutomationRequest": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "required": ["agentId", "name", "enabled", "triggerType"], "properties": { - "ok": { - "type": "boolean", - "const": true + "agentId": { + "type": "string", + "format": "uuid" }, - "commandId": { + "name": { "type": "string", - "const": "destination.list" + "minLength": 1, + "maxLength": 120 }, - "commandVersion": { - "type": "integer", - "const": 1 + "description": { + "type": ["string", "null"], + "maxLength": 1000, + "default": null }, - "correlationId": { - "type": "string" + "enabled": { + "type": "boolean" }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" + "triggerType": { + "$ref": "#/components/schemas/AutomationTriggerType" + }, + "signalIds": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "maxItems": 50, + "default": [] + }, + "matchMode": { + "$ref": "#/components/schemas/AutomationMatchMode" + }, + "triggerWindow": { + "type": "object", + "properties": { + "value": { + "type": "integer", + "minimum": 1 }, - { + "unit": { + "type": "string", + "enum": ["hour", "day"] + } + }, + "required": ["value", "unit"], + "additionalProperties": false + }, + "triggerThresholdCount": { + "type": "integer", + "minimum": 2, + "maximum": 5 + }, + "schedule": { + "type": "object", + "properties": { + "cadence": { + "type": "string", + "enum": ["hourly", "daily", "weekly"] + }, + "localTime": { "type": "object", "properties": { - "operationId": { - "type": "string", - "const": "destination.list" + "hour": { + "type": "integer", + "minimum": 0, + "maximum": 23 }, - "data": { - "type": "object", - "required": ["destinations"], - "properties": { - "destinations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DestinationRead" - } - } - }, - "additionalProperties": false + "minute": { + "type": "integer", + "minimum": 0, + "maximum": 59 + }, + "second": { + "type": "integer", + "minimum": 0, + "maximum": 59, + "default": 0 + }, + "millisecond": { + "type": "integer", + "minimum": 0, + "maximum": 999, + "default": 0 } - } + }, + "required": ["hour", "minute"], + "additionalProperties": false + }, + "timezone": { + "type": "string", + "default": "America/Los_Angeles" + }, + "weekday": { + "type": "string", + "enum": [ + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday", + "sunday" + ] } - ] + }, + "required": ["cadence"], + "additionalProperties": false + }, + "audienceFilter": { + "$ref": "#/components/schemas/AutomationAudienceFilter" + }, + "processorPolicy": { + "type": "object", + "properties": { + "subjectHandling": { + "type": "string", + "enum": ["event_customer", "scheduled_customer_pool"], + "default": "event_customer" + }, + "maxCustomersPerRun": { + "type": "integer", + "minimum": 1, + "maximum": 500 + }, + "maxConcurrentRuns": { + "type": "integer", + "const": 1 + }, + "cooldownHours": { + "type": "integer", + "minimum": 0, + "maximum": 2160 + } + }, + "additionalProperties": false + }, + "deliveryPolicy": { + "type": "object", + "properties": { + "requireAllDestinations": { + "type": "boolean", + "default": false + } + }, + "additionalProperties": false, + "default": { + "requireAllDestinations": false + } + }, + "destinationIds": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + }, + "maxItems": 25, + "default": [] } }, "additionalProperties": false }, - "ArchivedResource": { + "CreateSignalRequest": { + "oneOf": [ + { + "type": "object", + "required": ["kind", "name", "definition"], + "properties": { + "kind": { + "type": "string", + "const": "EVENT_MATCH" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "description": { + "type": ["string", "null"], + "maxLength": 1000, + "default": null + }, + "definition": { + "$ref": "#/components/schemas/EventMatchSignalDefinition" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": ["kind", "name", "definition"], + "properties": { + "kind": { + "type": "string", + "const": "EVENT_PATTERN" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "description": { + "type": ["string", "null"], + "maxLength": 1000, + "default": null + }, + "definition": { + "$ref": "#/components/schemas/AuthoredSignalDefinition" + } + }, + "additionalProperties": false + } + ] + }, + "UpdateSignalRequest": { + "oneOf": [ + { + "type": "object", + "required": ["kind", "name", "definition"], + "properties": { + "kind": { + "type": "string", + "const": "EVENT_MATCH" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "description": { + "type": ["string", "null"], + "maxLength": 1000, + "default": null + }, + "definition": { + "$ref": "#/components/schemas/EventMatchSignalDefinition" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": ["kind", "name", "definition"], + "properties": { + "kind": { + "type": "string", + "const": "EVENT_PATTERN" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "description": { + "type": ["string", "null"], + "maxLength": 1000, + "default": null + }, + "definition": { + "$ref": "#/components/schemas/AuthoredSignalDefinition" + } + }, + "additionalProperties": false + } + ] + }, + "CreateDestinationRequest": { "type": "object", - "required": ["id", "archivedAt"], + "required": ["name", "url"], "properties": { - "id": { + "type": { "type": "string", - "minLength": 1 + "const": "WEBHOOK_ENDPOINT", + "default": "WEBHOOK_ENDPOINT" }, - "archivedAt": { + "name": { "type": "string", - "format": "date-time" + "minLength": 1, + "maxLength": 120 + }, + "description": { + "type": ["string", "null"], + "maxLength": 1000, + "default": null + }, + "enabled": { + "type": "boolean", + "default": true + }, + "url": { + "type": "string", + "format": "uri", + "pattern": "^(https://|http://(localhost|127\\.0\\.0\\.1|\\[::1\\]|::1)([:/]|$))" } }, "additionalProperties": false }, - "RenameAgentRequest": { - "type": "object", - "required": ["displayName"], - "properties": { - "displayName": { - "type": "string", - "minLength": 1, - "maxLength": 120 + "UpdateDestinationRequest": { + "oneOf": [ + { + "type": "object", + "required": ["type"], + "minProperties": 2, + "properties": { + "type": { + "type": "string", + "const": "WEBHOOK_ENDPOINT" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "description": { + "type": ["string", "null"], + "maxLength": 1000 + }, + "enabled": { + "type": "boolean" + }, + "url": { + "type": "string", + "format": "uri", + "pattern": "^(https://|http://(localhost|127\\.0\\.0\\.1|\\[::1\\]|::1)([:/]|$))" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": ["type"], + "minProperties": 2, + "properties": { + "type": { + "type": "string", + "const": "SLACK_CHANNEL" + }, + "label": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "enabled": { + "type": "boolean" + } + }, + "additionalProperties": false } - }, - "additionalProperties": false + ] }, - "EnableAgentCommandSuccess": { + "UpdateAgentCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -4042,7 +5854,7 @@ }, "commandId": { "type": "string", - "const": "agent.enable" + "const": "agent.update" }, "commandVersion": { "type": "integer", @@ -4061,7 +5873,7 @@ "properties": { "operationId": { "type": "string", - "const": "agent.enable" + "const": "agent.update" }, "data": { "type": "object", @@ -4080,7 +5892,7 @@ }, "additionalProperties": false }, - "DisableAgentCommandSuccess": { + "CreateAutomationCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -4090,7 +5902,7 @@ }, "commandId": { "type": "string", - "const": "agent.disable" + "const": "automation.create" }, "commandVersion": { "type": "integer", @@ -4109,14 +5921,14 @@ "properties": { "operationId": { "type": "string", - "const": "agent.disable" + "const": "automation.create" }, "data": { "type": "object", - "required": ["agent"], + "required": ["automation"], "properties": { - "agent": { - "$ref": "#/components/schemas/AgentSummary" + "automation": { + "$ref": "#/components/schemas/AutomationRead" } }, "additionalProperties": false @@ -4128,7 +5940,7 @@ }, "additionalProperties": false }, - "RenameAgentCommandSuccess": { + "UpdateAutomationCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -4138,7 +5950,7 @@ }, "commandId": { "type": "string", - "const": "agent.rename" + "const": "automation.update" }, "commandVersion": { "type": "integer", @@ -4157,14 +5969,14 @@ "properties": { "operationId": { "type": "string", - "const": "agent.rename" + "const": "automation.update" }, "data": { "type": "object", - "required": ["agent"], + "required": ["automation"], "properties": { - "agent": { - "$ref": "#/components/schemas/AgentSummary" + "automation": { + "$ref": "#/components/schemas/AutomationRead" } }, "additionalProperties": false @@ -4176,7 +5988,7 @@ }, "additionalProperties": false }, - "EnableAutomationCommandSuccess": { + "CreateSignalCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -4186,7 +5998,7 @@ }, "commandId": { "type": "string", - "const": "automation.enable" + "const": "signal.create" }, "commandVersion": { "type": "integer", @@ -4205,14 +6017,14 @@ "properties": { "operationId": { "type": "string", - "const": "automation.enable" + "const": "signal.create" }, "data": { "type": "object", - "required": ["automation"], + "required": ["signal"], "properties": { - "automation": { - "$ref": "#/components/schemas/AutomationRead" + "signal": { + "$ref": "#/components/schemas/SignalRead" } }, "additionalProperties": false @@ -4224,7 +6036,7 @@ }, "additionalProperties": false }, - "DisableAutomationCommandSuccess": { + "UpdateSignalCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -4234,7 +6046,7 @@ }, "commandId": { "type": "string", - "const": "automation.disable" + "const": "signal.update" }, "commandVersion": { "type": "integer", @@ -4253,14 +6065,14 @@ "properties": { "operationId": { "type": "string", - "const": "automation.disable" + "const": "signal.update" }, "data": { "type": "object", - "required": ["automation"], + "required": ["signal"], "properties": { - "automation": { - "$ref": "#/components/schemas/AutomationRead" + "signal": { + "$ref": "#/components/schemas/SignalRead" } }, "additionalProperties": false @@ -4272,7 +6084,7 @@ }, "additionalProperties": false }, - "ArchiveAutomationCommandSuccess": { + "CreateDestinationCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -4282,7 +6094,7 @@ }, "commandId": { "type": "string", - "const": "automation.archive" + "const": "destination.create" }, "commandVersion": { "type": "integer", @@ -4301,14 +6113,14 @@ "properties": { "operationId": { "type": "string", - "const": "automation.archive" + "const": "destination.create" }, "data": { "type": "object", - "required": ["automation"], + "required": ["destination"], "properties": { - "automation": { - "$ref": "#/components/schemas/ArchivedResource" + "destination": { + "$ref": "#/components/schemas/DestinationRead" } }, "additionalProperties": false @@ -4320,7 +6132,7 @@ }, "additionalProperties": false }, - "GetSignalCommandSuccess": { + "UpdateDestinationCommandSuccess": { "type": "object", "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], "properties": { @@ -4330,7 +6142,7 @@ }, "commandId": { "type": "string", - "const": "signal.get" + "const": "destination.update" }, "commandVersion": { "type": "integer", @@ -4349,14 +6161,14 @@ "properties": { "operationId": { "type": "string", - "const": "signal.get" + "const": "destination.update" }, "data": { "type": "object", - "required": ["signal"], + "required": ["destination"], "properties": { - "signal": { - "$ref": "#/components/schemas/SignalRead" + "destination": { + "$ref": "#/components/schemas/DestinationRead" } }, "additionalProperties": false @@ -4368,242 +6180,543 @@ }, "additionalProperties": false }, - "ArchiveSignalCommandSuccess": { + "SignalPropertyCondition": { + "oneOf": [ + { + "type": "object", + "required": ["key", "operator"], + "properties": { + "key": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "operator": { + "type": "string", + "const": "exists" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": ["key", "operator", "value"], + "properties": { + "key": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "operator": { + "type": "string", + "enum": ["equals", "not_equals"] + }, + "value": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ] + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": ["key", "operator", "value"], + "properties": { + "key": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "operator": { + "type": "string", + "const": "starts_with" + }, + "value": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "EventChannel": { + "type": "string", + "enum": [ + "PRODUCT", + "COMMUNICATION", + "MEETING", + "CRM", + "BILLING", + "SUPPORT", + "IDENTITY", + "DOCUMENT", + "SYSTEM" + ] + }, + "EventMatchSignalDefinition": { + "type": "object", + "required": ["grain", "subjectResolver", "eventNames"], + "properties": { + "grain": { + "type": "string", + "enum": ["organization", "customer", "segment"] + }, + "subjectResolver": { + "type": "string", + "enum": ["organization", "event_customer", "segment"] + }, + "eventNames": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 50, + "minItems": 1 + }, + "eventChannels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventChannel" + }, + "maxItems": 9 + }, + "propertyConditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SignalPropertyCondition" + }, + "maxItems": 5, + "default": [] + }, + "conditionMode": { + "type": "string", + "const": "ALL", + "default": "ALL" + } + }, + "additionalProperties": false + }, + "SignalWindow": { + "type": "object", + "required": ["value", "unit"], + "properties": { + "value": { + "type": "integer", + "minimum": 1, + "maximum": 365 + }, + "unit": { + "type": "string", + "enum": ["hour", "day"] + } + }, + "additionalProperties": false + }, + "EventOccurredDetection": { + "type": "object", + "required": ["type", "eventNames"], + "properties": { + "type": { + "type": "string", + "const": "event_occurred" + }, + "eventNames": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 50, + "minItems": 1 + }, + "eventChannels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventChannel" + }, + "maxItems": 9 + }, + "propertyConditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SignalPropertyCondition" + }, + "maxItems": 5, + "default": [] + } + }, + "additionalProperties": false + }, + "EventCountThresholdDetection": { + "type": "object", + "required": ["type", "eventNames", "threshold", "window"], + "properties": { + "type": { + "type": "string", + "const": "event_count_threshold" + }, + "eventNames": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 50, + "minItems": 1 + }, + "eventChannels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventChannel" + }, + "maxItems": 9 + }, + "propertyConditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SignalPropertyCondition" + }, + "maxItems": 5, + "default": [] + }, + "threshold": { + "type": "object", + "required": ["operator", "count"], + "properties": { + "operator": { + "type": "string", + "enum": [">=", ">"] + }, + "count": { + "type": "integer", + "minimum": 1, + "maximum": 10000 + } + }, + "additionalProperties": false + }, + "window": { + "$ref": "#/components/schemas/SignalWindow" + } + }, + "additionalProperties": false + }, + "EventAbsenceDetection": { + "type": "object", + "required": ["type", "window"], + "properties": { + "type": { + "type": "string", + "const": "event_absence" + }, + "eventNameMode": { + "type": "string", + "enum": ["exact", "all_except"] + }, + "eventNames": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 50, + "default": [] + }, + "excludeEventNames": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 50 + }, + "eventChannels": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventChannel" + }, + "maxItems": 9 + }, + "propertyConditions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SignalPropertyCondition" + }, + "maxItems": 5, + "default": [] + }, + "window": { + "type": "object", + "required": ["value", "unit"], + "properties": { + "value": { + "type": "integer", + "minimum": 1, + "maximum": 30 + }, + "unit": { + "type": "string", + "const": "day" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "ActivityWindow": { + "type": "object", + "required": ["value", "unit"], + "properties": { + "value": { + "type": "integer", + "minimum": 1, + "maximum": 365 + }, + "unit": { + "type": "string", + "const": "day" + } + }, + "additionalProperties": false + }, + "CustomerActivityThresholdDetection": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "required": ["type", "metric", "window", "operator", "count"], "properties": { - "ok": { - "type": "boolean", - "const": true + "type": { + "type": "string", + "const": "customer_activity_threshold" }, - "commandId": { + "metric": { "type": "string", - "const": "signal.archive" + "const": "active_days" }, - "commandVersion": { - "type": "integer", - "const": 1 + "window": { + "$ref": "#/components/schemas/ActivityWindow" }, - "correlationId": { - "type": "string" + "operator": { + "type": "string", + "enum": ["<=", "<", ">=", ">"] }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" - }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "signal.archive" - }, - "data": { - "type": "object", - "required": ["signal"], - "properties": { - "signal": { - "$ref": "#/components/schemas/ArchivedResource" - } - }, - "additionalProperties": false - } - } - } - ] + "count": { + "type": "integer", + "minimum": 0, + "maximum": 365 + }, + "minimumObservedAgeDays": { + "type": "integer", + "minimum": 1, + "maximum": 365 } }, "additionalProperties": false }, - "GetDestinationCommandSuccess": { + "CustomerActivityDropDetection": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "required": [ + "type", + "metric", + "window", + "baselineWindow", + "dropPercent", + "minimumBaselineActiveDays", + "minimumBaselineEventCount" + ], "properties": { - "ok": { - "type": "boolean", - "const": true + "type": { + "type": "string", + "const": "customer_activity_drop" }, - "commandId": { + "metric": { "type": "string", - "const": "destination.get" + "const": "active_days" }, - "commandVersion": { - "type": "integer", - "const": 1 + "window": { + "$ref": "#/components/schemas/ActivityWindow" }, - "correlationId": { - "type": "string" + "baselineWindow": { + "$ref": "#/components/schemas/ActivityWindow" }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" - }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "destination.get" - }, - "data": { - "type": "object", - "required": ["destination"], - "properties": { - "destination": { - "$ref": "#/components/schemas/DestinationRead" - } - }, - "additionalProperties": false - } - } - } - ] + "dropPercent": { + "type": "number", + "minimum": 1, + "maximum": 100 + }, + "minimumBaselineActiveDays": { + "type": "integer", + "minimum": 1, + "maximum": 365 + }, + "minimumBaselineEventCount": { + "type": "integer", + "minimum": 1, + "maximum": 100000 } }, "additionalProperties": false }, - "EnableDestinationCommandSuccess": { + "RelatedUserInactivityDetection": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "required": [ + "type", + "priorWindow", + "inactiveWindow", + "minimumPriorActiveDays", + "minimumPreviouslyActiveUsers" + ], "properties": { - "ok": { - "type": "boolean", - "const": true - }, - "commandId": { + "type": { "type": "string", - "const": "destination.enable" + "const": "related_user_inactivity" }, - "commandVersion": { - "type": "integer", - "const": 1 + "priorWindow": { + "$ref": "#/components/schemas/ActivityWindow" }, - "correlationId": { - "type": "string" + "inactiveWindow": { + "$ref": "#/components/schemas/ActivityWindow" }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" - }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "destination.enable" - }, - "data": { - "type": "object", - "required": ["destination"], - "properties": { - "destination": { - "$ref": "#/components/schemas/DestinationRead" - } - }, - "additionalProperties": false - } - } - } - ] + "minimumPriorActiveDays": { + "type": "integer", + "minimum": 1, + "maximum": 365 + }, + "minimumPreviouslyActiveUsers": { + "type": "integer", + "minimum": 1, + "maximum": 10000 } }, "additionalProperties": false }, - "DisableDestinationCommandSuccess": { + "SignalDetection": { + "oneOf": [ + { + "$ref": "#/components/schemas/EventOccurredDetection" + }, + { + "$ref": "#/components/schemas/EventCountThresholdDetection" + }, + { + "$ref": "#/components/schemas/EventAbsenceDetection" + }, + { + "$ref": "#/components/schemas/CustomerActivityThresholdDetection" + }, + { + "$ref": "#/components/schemas/CustomerActivityDropDetection" + }, + { + "$ref": "#/components/schemas/RelatedUserInactivityDetection" + } + ] + }, + "AuthoredSignalDefinition": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "required": ["schemaVersion", "subjectType", "detection"], "properties": { - "ok": { - "type": "boolean", - "const": true - }, - "commandId": { + "schemaVersion": { "type": "string", - "const": "destination.disable" - }, - "commandVersion": { - "type": "integer", - "const": 1 + "const": "2026-06-17" }, - "correlationId": { - "type": "string" + "subjectType": { + "type": "string", + "const": "customer" }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" + "catalogSource": { + "type": "object", + "required": ["provider", "key", "version"], + "properties": { + "provider": { + "type": "string", + "const": "outlit" }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "destination.disable" - }, - "data": { - "type": "object", - "required": ["destination"], - "properties": { - "destination": { - "$ref": "#/components/schemas/DestinationRead" - } - }, - "additionalProperties": false - } - } + "key": { + "type": "string", + "minLength": 1, + "maxLength": 191 + }, + "version": { + "type": "string", + "minLength": 1, + "maxLength": 40 } - ] + }, + "additionalProperties": false + }, + "detection": { + "$ref": "#/components/schemas/SignalDetection" } }, "additionalProperties": false }, - "ArchiveDestinationCommandSuccess": { + "AutomationAudienceRevenueFilter": { "type": "object", - "required": ["ok", "commandId", "commandVersion", "correlationId", "result"], + "required": ["metric", "operator", "value"], "properties": { - "ok": { - "type": "boolean", - "const": true - }, - "commandId": { + "metric": { "type": "string", - "const": "destination.archive" + "enum": ["ARR", "MRR"] }, - "commandVersion": { - "type": "integer", - "const": 1 + "operator": { + "type": "string", + "enum": [">=", ">", "<=", "<"] }, - "correlationId": { - "type": "string" + "value": { + "type": "number", + "minimum": 0, + "maximum": 1000000000 }, - "result": { - "allOf": [ - { - "$ref": "#/components/schemas/CommandResultBase" + "currency": { + "type": "string", + "const": "USD" + } + }, + "additionalProperties": false + }, + "AutomationAudienceFilter": { + "type": "object", + "properties": { + "customer": { + "type": "object", + "properties": { + "billingStatuses": { + "type": "array", + "items": { + "type": "string", + "enum": ["NONE", "TRIALING", "PAYING", "PAST_DUE", "CHURNED"] + } }, - { - "type": "object", - "properties": { - "operationId": { - "type": "string", - "const": "destination.archive" - }, - "data": { - "type": "object", - "required": ["destination"], - "properties": { - "destination": { - "$ref": "#/components/schemas/ArchivedResource" - } - }, - "additionalProperties": false - } + "customerIds": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "revenue": { + "$ref": "#/components/schemas/AutomationAudienceRevenueFilter" + }, + "ownerUserIds": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 191 } } - ] + }, + "additionalProperties": false } }, "additionalProperties": false diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index fd2de8d..723ad83 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -26,7 +26,7 @@ async function startCli() { name: "outlit", version: CLI_VERSION, description: - "Outlit CLI -- customer intelligence from the terminal.\n\nUsage examples:\n outlit onboard --agent codex --json\n outlit customers list --billing-status PAYING --no-activity-in 30d\n outlit customers get acme.com --include users,revenue\n outlit customers timeline acme.com --timeframe 90d\n outlit users list --journey-stage CHAMPION\n outlit ws-users list --role CSM --has-owned-customers\n outlit facts list acme.com --fact-types CHURN_RISK,EXPANSION\n outlit facts get --fact-id fact_123 --include evidence\n outlit sources get --source-type OPPORTUNITY --source-id opp_123\n outlit search 'pricing objections last quarter' --source-types CALL,OPPORTUNITY\n outlit sql 'SELECT * FROM activity LIMIT 10'\n outlit notify --title 'Risk found' '{\"customer\":\"acme.com\"}'\n outlit schema activity\n outlit agents list --json\n outlit agents create-from-template churn --json\n outlit agents enable agent_123 --json\n outlit automations enable 10000000-0000-4000-8000-000000000001 --json\n outlit signals archive 10000000-0000-4000-8000-000000000002 --json\n outlit destinations disable 10000000-0000-4000-8000-000000000003 --json\n outlit doctor --json\n\nFor AI agents: commands auto-output JSON when stdout is piped. No --json flag needed.", + "Outlit CLI -- customer intelligence from the terminal.\n\nUsage examples:\n outlit onboard --agent codex --json\n outlit customers list --billing-status PAYING --no-activity-in 30d\n outlit customers get acme.com --include users,revenue\n outlit customers timeline acme.com --timeframe 90d\n outlit users list --journey-stage CHAMPION\n outlit ws-users list --role CSM --has-owned-customers\n outlit facts list acme.com --fact-types CHURN_RISK,EXPANSION\n outlit facts get --fact-id fact_123 --include evidence\n outlit sources get --source-type OPPORTUNITY --source-id opp_123\n outlit search 'pricing objections last quarter' --source-types CALL,OPPORTUNITY\n outlit sql 'SELECT * FROM activity LIMIT 10'\n outlit notify --title 'Risk found' '{\"customer\":\"acme.com\"}'\n outlit schema activity\n outlit agents list --json\n outlit agents create --template churn --json\n outlit agents enable agent_123 --json\n outlit automations enable 10000000-0000-4000-8000-000000000001 --json\n outlit signals archive 10000000-0000-4000-8000-000000000002 --json\n outlit destinations disable 10000000-0000-4000-8000-000000000003 --json\n outlit doctor --json\n\nFor AI agents: commands auto-output JSON when stdout is piped. No --json flag needed.", }, subCommands: { auth: () => import("./commands/auth/index").then((m) => m.default), diff --git a/packages/cli/src/commands/agents/create-from-template.ts b/packages/cli/src/commands/agents/create-from-template.ts deleted file mode 100644 index 88cf20d..0000000 --- a/packages/cli/src/commands/agents/create-from-template.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { defineCommand } from "citty" -import { authArgs } from "../../args/auth" -import { AGENT_JSON_HINT, outputArgs } from "../../args/output" -import { getClientOrExit, runTool } from "../../lib/api" - -export default defineCommand({ - meta: { - name: "create-from-template", - description: [ - "Create a draft agent from a platform template.", - "", - "Outputs the full platform command envelope, including safety details.", - "", - "Examples:", - " outlit agents create-from-template churn --json", - "", - AGENT_JSON_HINT, - ].join("\n"), - }, - args: { - ...authArgs, - ...outputArgs, - template: { - type: "positional", - description: "Agent template key to create, such as churn", - required: true, - }, - }, - async run({ args }) { - const json = !!args.json - const client = await getClientOrExit(args["api-key"], json) - - return runTool( - client, - "outlit_agent_create_from_template", - { - source: { type: "template", templateKey: args.template }, - mode: "draft", - }, - json, - { - spinnerMessage: "Creating agent template draft...", - }, - ) - }, -}) diff --git a/packages/cli/src/commands/agents/create.ts b/packages/cli/src/commands/agents/create.ts new file mode 100644 index 0000000..e4aa66e --- /dev/null +++ b/packages/cli/src/commands/agents/create.ts @@ -0,0 +1,126 @@ +import { defineCommand } from "citty" +import { authArgs } from "../../args/auth" +import { AGENT_JSON_HINT, outputArgs } from "../../args/output" +import { getClientOrExit, runTool } from "../../lib/api" +import { outputError } from "../../lib/output" +import { + optionalTrimmedString, + parseCsvList, + parseIntegerFlag, + requiredTrimmedString, +} from "../../lib/platform-input" + +function hasCustomAgentFlags(args: Record): boolean { + return [ + "display-name", + "instructions", + "surface-criteria", + "skip-criteria", + "max-items-to-surface", + "action-keys", + ].some((key) => args[key] !== undefined) +} + +export default defineCommand({ + meta: { + name: "create", + description: [ + "Create an Outlit agent.", + "", + "Use --template to create from a supported template, or --type custom for a custom hosted agent.", + "", + "Examples:", + " outlit agents create --template churn --json", + " outlit agents create --type custom --display-name 'Renewal risk' --instructions 'Find risk' --surface-criteria 'Surface risky customers' --json", + "", + AGENT_JSON_HINT, + ].join("\n"), + }, + args: { + ...authArgs, + ...outputArgs, + template: { + type: "string", + description: "Agent template key to create, such as churn", + }, + type: { + type: "string", + description: "Agent type to create. Currently supports: custom", + }, + "display-name": { type: "string", description: "Custom agent display name" }, + instructions: { type: "string", description: "Custom agent instructions" }, + "surface-criteria": { type: "string", description: "Criteria for surfacing items" }, + "skip-criteria": { type: "string", description: "Optional criteria for skipping items" }, + "max-items-to-surface": { + type: "string", + description: "Maximum items the custom agent should surface per run", + }, + "action-keys": { type: "string", description: "Comma-separated custom agent action keys" }, + }, + async run({ args }) { + const json = !!args.json + const client = await getClientOrExit(args["api-key"], json) + const template = optionalTrimmedString(args.template) + const type = optionalTrimmedString(args.type) + + if (template && type) { + return outputError( + { message: "Use either --template or --type custom, not both", code: "invalid_input" }, + json, + ) + } + + if (template) { + if (hasCustomAgentFlags(args)) { + return outputError( + { + message: "Custom agent flags cannot be used with --template", + code: "invalid_input", + }, + json, + ) + } + + return runTool( + client, + "outlit_agent_create", + { type: "template", templateKey: template, mode: "draft" }, + json, + { + spinnerMessage: "Creating agent...", + }, + ) + } + + if (type !== "custom") { + return outputError( + { + message: "Provide --template or --type custom", + code: type ? "invalid_input" : "missing_input", + }, + json, + ) + } + + const input = { + type: "custom", + displayName: requiredTrimmedString(args["display-name"], "--display-name", json), + instructions: requiredTrimmedString(args.instructions, "--instructions", json), + surfaceCriteria: requiredTrimmedString(args["surface-criteria"], "--surface-criteria", json), + ...(optionalTrimmedString(args["skip-criteria"]) + ? { skipCriteria: optionalTrimmedString(args["skip-criteria"]) } + : {}), + maxItemsToSurface: parseIntegerFlag( + args["max-items-to-surface"], + 10, + "--max-items-to-surface", + json, + ), + actionKeys: parseCsvList(args["action-keys"]), + } + + return runTool(client, "outlit_agent_create", input, json, { + spinnerMessage: "Creating agent...", + }) + }, +}) diff --git a/packages/cli/src/commands/agents/disable.ts b/packages/cli/src/commands/agents/disable.ts index 5e79e2a..3187f11 100644 --- a/packages/cli/src/commands/agents/disable.ts +++ b/packages/cli/src/commands/agents/disable.ts @@ -10,7 +10,7 @@ export default defineCommand({ "Disable a configured Outlit agent by id.", "", "Examples:", - " outlit agents disable agent_123 --json", + " outlit agents disable 10000000-0000-4000-8000-000000000004 --json", "", AGENT_JSON_HINT, ].join("\n"), diff --git a/packages/cli/src/commands/agents/enable.ts b/packages/cli/src/commands/agents/enable.ts index 83416a6..48d8e6a 100644 --- a/packages/cli/src/commands/agents/enable.ts +++ b/packages/cli/src/commands/agents/enable.ts @@ -10,7 +10,7 @@ export default defineCommand({ "Enable a configured Outlit agent by id.", "", "Examples:", - " outlit agents enable agent_123 --json", + " outlit agents enable 10000000-0000-4000-8000-000000000004 --json", "", AGENT_JSON_HINT, ].join("\n"), diff --git a/packages/cli/src/commands/agents/get.ts b/packages/cli/src/commands/agents/get.ts index a6e91d5..ee3b4b0 100644 --- a/packages/cli/src/commands/agents/get.ts +++ b/packages/cli/src/commands/agents/get.ts @@ -10,7 +10,7 @@ export default defineCommand({ "Get one configured Outlit agent by id.", "", "Examples:", - " outlit agents get agent_123 --json", + " outlit agents get 10000000-0000-4000-8000-000000000004 --json", "", AGENT_JSON_HINT, ].join("\n"), diff --git a/packages/cli/src/commands/agents/index.ts b/packages/cli/src/commands/agents/index.ts index 45664e6..0e55d74 100644 --- a/packages/cli/src/commands/agents/index.ts +++ b/packages/cli/src/commands/agents/index.ts @@ -5,28 +5,33 @@ export default defineCommand({ meta: { name: "agents", description: [ - "Configure Outlit agents from platform templates.", + "Configure Outlit agents.", "", "Commands:", " list List configured agents", " get Get one configured agent", " templates List available agent templates", " actions List available agent configuration actions", - " create-from-template