diff --git a/docs/cli/commands/access-token.md b/docs/cli/commands/access-token.md index a48020ed..b1d59b3d 100644 --- a/docs/cli/commands/access-token.md +++ b/docs/cli/commands/access-token.md @@ -49,7 +49,11 @@ epilot access-token listAccessTokens - [`getAccessTokenJwks`](#getaccesstokenjwks) — Get jwks public key set to verify access tokens generated by this API - [`getAccessTokenOIDC`](#getaccesstokenoidc) — OpenID Connect configuration for Access Token API as identity provider - [`getPublicTokenJwks`](#getpublictokenjwks) — Get jwks public key set to verify public tokens generated by this API +- [`getPortalPreviewTokenJwks`](#getportalpreviewtokenjwks) — Get jwks public key set to verify portal preview tokens generated by this API - [`getPublicTokenOIDC`](#getpublictokenoidc) — OpenID Connect configuration for Access Token API a a public identity provider +- [`getPortalPreviewTokenOIDC`](#getportalpreviewtokenoidc) — OpenID Connect configuration for Access Token API a a portal preview identity provider +- [`getContactIdentificationTokenJwks`](#getcontactidentificationtokenjwks) — Get jwks public key set to verify contact identification tokens generated by this API +- [`getContactIdentificationTokenOIDC`](#getcontactidentificationtokenoidc) — OpenID Connect configuration for Access Token API as a contact identification identity provider ### `listAccessTokens` @@ -61,7 +65,7 @@ Lists all Access Tokens for current user (by default excludes system generated t | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `token_type` | query | "api" \| "journey" \| "portal" \| "assume" \| "app"[] | No | Filter by token types | +| `token_type` | query | "api" \| "journey" \| "portal" \| "assume" \| "app" \| "portal_preview" \| "contact_identification"[] | No | Filter by token types | **Sample Call** @@ -87,8 +91,14 @@ epilot access-token listAccessTokens --jsonata '$' "token_type": "api", "journey_id": "string", "portal_id": "string", + "portal_user_id": "string", + "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_operations": ["getContact", "getContracts"], "assignments": ["123:owner"], - "last_used": "2026-02-24" + "read_only": true, + "anonymize": true, + "last_used": "2026-02-24", + "expires_at": "2026-03-01T12:00:00.000Z" } ] ``` @@ -107,9 +117,22 @@ epilot access-token listAccessTokens --jsonata '$' **Sample Call** +```bash +epilot access-token createAccessToken +``` + +With request body: + ```bash epilot access-token createAccessToken \ - -d '{"name":"Postman Access Token","token_type":"api","assignments":["123:owner"],"expires_in":3600}' + -d '{ + "name": "Postman Access Token", + "token_type": "api", + "assignments": ["123:owner"], + "expires_in": 3600, + "read_only": true, + "anonymize": true +}' ``` Using stdin pipe: @@ -136,8 +159,14 @@ epilot access-token createAccessToken --jsonata '$' "token_type": "api", "journey_id": "string", "portal_id": "string", + "portal_user_id": "string", + "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_operations": ["getContact", "getContracts"], "assignments": ["123:owner"], - "last_used": "2026-02-24" + "read_only": true, + "anonymize": true, + "last_used": "2026-02-24", + "expires_at": "2026-03-01T12:00:00.000Z" } ``` @@ -187,8 +216,14 @@ epilot access-token revokeAccessToken -p id=api_5ZugdRXasLfWBypHi93Fk --jsonata "token_type": "api", "journey_id": "string", "portal_id": "string", + "portal_user_id": "string", + "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_operations": ["getContact", "getContracts"], "assignments": ["123:owner"], - "last_used": "2026-02-24" + "read_only": true, + "anonymize": true, + "last_used": "2026-02-24", + "expires_at": "2026-03-01T12:00:00.000Z" } ``` @@ -308,6 +343,46 @@ epilot access-token getPublicTokenJwks --jsonata 'keys' --- +### `getPortalPreviewTokenJwks` + +Get jwks public key set to verify portal preview tokens generated by this API + +`GET /v1/access-tokens/portal-preview/.well-known/jwks.json` + +**Sample Call** + +```bash +epilot access-token getPortalPreviewTokenJwks +``` + +With JSONata filter: + +```bash +epilot access-token getPortalPreviewTokenJwks --jsonata 'keys' +``` + +
+Sample Response + +```json +{ + "keys": [ + { + "alg": "RS256", + "e": "AQAB", + "kid": "tXWU5mPMbRPczpbQwi6vbhLF4GgF3wlMDSyqo7pfeiw=", + "kty": "RSA", + "n": "h_QDoCjZ8W_trtYXaP7_S22wf5r5Wd9XBLED78oT44bJjQXn8ddcFV8Hik65_4IYXVX_hTTU4zpxe3H8vx2j7-Zz3O59mYMp5S0MzODNEdf5Y_2o19eis0brmAJniixsNlQ9LlYkdrVamrgaxHu3ZpP_99zkfFybYeuYoQNzb3PyrT8xVnz_USs_nlFMHpGUxvvz7gfKPqxcLvgLJr4cwI9yzaSY9CD4qW181QVcnL_WzpQ8xx6AuhhHZQ1l_3GG4InTk8ahE7U2ZHVu8RrX6d01pMgc3piEcet9RgFLnhbTg3YIiKGoAbN42wJn_x3lgIAC42T9mbmTsHyUdS6nUQ", + "use": "sig" + } + ] +} +``` + +
+ +--- + ### `getPublicTokenOIDC` OpenID Connect configuration for Access Token API a a public identity provider @@ -339,3 +414,107 @@ epilot access-token getPublicTokenOIDC --jsonata 'issuer' --- + +### `getPortalPreviewTokenOIDC` + +OpenID Connect configuration for Access Token API a a portal preview identity provider + +`GET /v1/access-tokens/portal-preview/.well-known/openid-configuration` + +**Sample Call** + +```bash +epilot access-token getPortalPreviewTokenOIDC +``` + +With JSONata filter: + +```bash +epilot access-token getPortalPreviewTokenOIDC --jsonata 'issuer' +``` + +
+Sample Response + +```json +{ + "issuer": "https://access-token.sls.epilot.io/v1/access-tokens/portal-preview", + "jwks_uri": "https://access-token.sls.epilot.io/v1/access-tokens/portal-preview/.well-known/jwks.json" +} +``` + +
+ +--- + +### `getContactIdentificationTokenJwks` + +Get jwks public key set to verify contact identification tokens generated by this API + +`GET /v1/access-tokens/contact-identification/.well-known/jwks.json` + +**Sample Call** + +```bash +epilot access-token getContactIdentificationTokenJwks +``` + +With JSONata filter: + +```bash +epilot access-token getContactIdentificationTokenJwks --jsonata 'keys' +``` + +
+Sample Response + +```json +{ + "keys": [ + { + "alg": "RS256", + "e": "AQAB", + "kid": "tXWU5mPMbRPczpbQwi6vbhLF4GgF3wlMDSyqo7pfeiw=", + "kty": "RSA", + "n": "h_QDoCjZ8W_trtYXaP7_S22wf5r5Wd9XBLED78oT44bJjQXn8ddcFV8Hik65_4IYXVX_hTTU4zpxe3H8vx2j7-Zz3O59mYMp5S0MzODNEdf5Y_2o19eis0brmAJniixsNlQ9LlYkdrVamrgaxHu3ZpP_99zkfFybYeuYoQNzb3PyrT8xVnz_USs_nlFMHpGUxvvz7gfKPqxcLvgLJr4cwI9yzaSY9CD4qW181QVcnL_WzpQ8xx6AuhhHZQ1l_3GG4InTk8ahE7U2ZHVu8RrX6d01pMgc3piEcet9RgFLnhbTg3YIiKGoAbN42wJn_x3lgIAC42T9mbmTsHyUdS6nUQ", + "use": "sig" + } + ] +} +``` + +
+ +--- + +### `getContactIdentificationTokenOIDC` + +OpenID Connect configuration for Access Token API as a contact identification identity provider + +`GET /v1/access-tokens/contact-identification/.well-known/openid-configuration` + +**Sample Call** + +```bash +epilot access-token getContactIdentificationTokenOIDC +``` + +With JSONata filter: + +```bash +epilot access-token getContactIdentificationTokenOIDC --jsonata 'issuer' +``` + +
+Sample Response + +```json +{ + "issuer": "https://access-token.sls.epilot.io/v1/access-tokens/contact-identification", + "jwks_uri": "https://access-token.sls.epilot.io/v1/access-tokens/contact-identification/.well-known/jwks.json" +} +``` + +
+ +--- diff --git a/docs/cli/commands/ai-agents.md b/docs/cli/commands/ai-agents.md index 3e96d72b..d91ad3cf 100644 --- a/docs/cli/commands/ai-agents.md +++ b/docs/cli/commands/ai-agents.md @@ -1,9 +1,9 @@ --- -title: "AI Agents API - OpenAPI 3.0" -description: "epilot CLI commands for the AI Agents API - OpenAPI 3.0: quick start, common flags and every operation, callable from the command line." +title: "AI Agents API" +description: "epilot CLI commands for the AI Agents API: quick start, common flags and every operation, callable from the command line." --- -# AI Agents API - OpenAPI 3.0 +# AI Agents API - **Base URL:** `https://ai-agents.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/ai-agents](https://docs.epilot.io/api/ai-agents) @@ -49,12 +49,25 @@ epilot ai-agents listAgents **Agent Execution** - [`executeAgent`](#executeagent) — Executes an agent (system skill or custom agent). -- [`listExecutions`](#listexecutions) — GET /v1/executions -- [`getExecution`](#getexecution) — GET /v1/executions/{execution_id} -- [`cancelExecution`](#cancelexecution) — DELETE /v1/executions/{execution_id} +- [`executeAgentStream`](#executeagentstream) — Executes an agent with real-time streaming of tokens and tool events. +- [`listExecutions`](#listexecutions) — List executions +- [`getExecution`](#getexecution) — Get execution by ID +- [`cancelExecution`](#cancelexecution) — Cancel execution - [`getExecutionTrace`](#getexecutiontrace) — Returns the step-by-step reasoning and tool calls for ReAct mode executions. Returns empty iterations array for direct m +- [`getExecutionFeedback`](#getexecutionfeedback) — Returns the authenticated user's feedback for an execution. +- [`putExecutionFeedback`](#putexecutionfeedback) — Upserts thumbs up/down feedback and mirrors it to the execution's Langfuse trace. - [`approveExecution`](#approveexecution) — Approves a pending tool action when execution is in waiting_approval status - [`rejectExecution`](#rejectexecution) — Rejects a pending tool action when execution is in waiting_approval status +- [`streamExecution`](#streamexecution) — Reconnects to an execution's event stream after approval. Replays missed events from event log and continues streaming i + +**Chat** +- [`chat`](#chat) — Initiates a streaming chat session with an AI agent. Supports server-side conversation memory via conversationId or clie + +**Conversations** +- [`listConversations`](#listconversations) — Lists conversations for the authenticated user, sorted by most recent. +- [`getConversation`](#getconversation) — Retrieves a conversation and its message history. +- [`deleteConversation`](#deleteconversation) — Deletes a conversation and all its messages. +- [`submitConversationFeedback`](#submitconversationfeedback) — Records a thumbs up/down (with optional comment) for the assistant turn identified by its Langfuse trace id. The rating ### `listAgents` @@ -67,7 +80,7 @@ Lists agents from both system skills and custom agents. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `source` | query | "system" \| "custom" | No | Filter by agent source (system = pre-built skills, custom = user-created) | -| `availability` | query | "flows" \| "copilot" \| "all" | No | Filter by availability context (flows, copilot) | +| `availability` | query | "flows" \| "copilot" \| "portals" \| "all" | No | Filter by availability context (flows, copilot) | | `entity_schema` | query | string | No | Filter by allowed entity schema (e.g., "message" for email-related skills) | **Sample Call** @@ -103,7 +116,9 @@ epilot ai-agents listAgents --jsonata 'agents' "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 0, "execution_pattern": "direct", @@ -171,7 +186,9 @@ epilot ai-agents createAgent \ "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 10, "execution_pattern": "direct", @@ -231,7 +248,9 @@ epilot ai-agents createAgent --jsonata 'agent_id' "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 0, "execution_pattern": "direct", @@ -318,7 +337,9 @@ epilot ai-agents getAgentById -p agent_id=skill:email-categorizer --jsonata 'age "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 0, "execution_pattern": "direct", @@ -391,7 +412,9 @@ epilot ai-agents updateAgentById \ "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 1, "execution_pattern": "direct", @@ -457,7 +480,9 @@ epilot ai-agents updateAgentById -p agent_id=skill:email-categorizer --jsonata ' "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 0, "execution_pattern": "direct", @@ -639,7 +664,15 @@ epilot ai-agents executeAgent -p agent_id=skill:email-categorizer --jsonata 'exe "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -647,8 +680,79 @@ epilot ai-agents executeAgent -p agent_id=skill:email-categorizer --jsonata 'exe --- +### `executeAgentStream` + +Executes an agent with real-time streaming of tokens and tool events. + +`POST /v1/agents/{agent_id}/execute/stream` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `agent_id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot ai-agents executeAgentStream \ + -p agent_id=skill:email-categorizer +``` + +With request body: + +```bash +epilot ai-agents executeAgentStream \ + -p agent_id=skill:email-categorizer \ + -d '{ + "input": { + "entity_id": "string", + "entity_schema": "string", + "workflow_id": "string", + "workflow_execution_id": "string", + "task_id": "string", + "custom_data": {}, + "flow_context": [ + { + "entity_id": "string", + "entity_schema": "string" + } + ] + }, + "parameters": {}, + "execution_mode_override": "automatic", + "execution_context": "flows", + "callback_url": "https://example.com/path", + "timeout_ms": 30000 +}' +``` + +Using positional args for path parameters: + +```bash +epilot ai-agents executeAgentStream skill:email-categorizer +``` + +Using stdin pipe: + +```bash +cat body.json | epilot ai-agents executeAgentStream -p agent_id=skill:email-categorizer +``` + +With JSONata filter: + +```bash +epilot ai-agents executeAgentStream -p agent_id=skill:email-categorizer --jsonata '$' +``` + +--- + ### `listExecutions` +List executions + `GET /v1/executions` **Parameters** @@ -692,7 +796,8 @@ epilot ai-agents listExecutions --jsonata 'executions' "pending_action": {}, "metrics": {}, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [] } ], "next_cursor": "string" @@ -705,6 +810,8 @@ epilot ai-agents listExecutions --jsonata 'executions' ### `getExecution` +Get execution by ID + `GET /v1/executions/{execution_id}` **Parameters** @@ -777,7 +884,15 @@ epilot ai-agents getExecution -p execution_id=123e4567-e89b-12d3-a456-4266141740 "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -787,6 +902,8 @@ epilot ai-agents getExecution -p execution_id=123e4567-e89b-12d3-a456-4266141740 ### `cancelExecution` +Cancel execution + `DELETE /v1/executions/{execution_id}` **Parameters** @@ -859,7 +976,15 @@ epilot ai-agents cancelExecution -p execution_id=123e4567-e89b-12d3-a456-4266141 "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -926,6 +1051,113 @@ epilot ai-agents getExecutionTrace -p execution_id=123e4567-e89b-12d3-a456-42661 --- +### `getExecutionFeedback` + +Returns the authenticated user's feedback for an execution. + +`GET /v1/executions/{execution_id}/feedback` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `execution_id` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot ai-agents getExecutionFeedback \ + -p execution_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot ai-agents getExecutionFeedback 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot ai-agents getExecutionFeedback -p execution_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'feedback' +``` + +
+Sample Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +### `putExecutionFeedback` + +Upserts thumbs up/down feedback and mirrors it to the execution's Langfuse trace. + +`PUT /v1/executions/{execution_id}/feedback` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `execution_id` | path | string (uuid) | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot ai-agents putExecutionFeedback \ + -p execution_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"rating":"up","comment":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot ai-agents putExecutionFeedback 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot ai-agents putExecutionFeedback -p execution_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot ai-agents putExecutionFeedback -p execution_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'feedback' +``` + +
+Sample Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + ### `approveExecution` Approves a pending tool action when execution is in waiting_approval status @@ -945,7 +1177,7 @@ Approves a pending tool action when execution is in waiting_approval status ```bash epilot ai-agents approveExecution \ -p execution_id=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"reason":"string"}' + -d '{"reason":"string","approved_action_ids":["string"],"rejected_action_ids":["string"]}' ``` Using positional args for path parameters: @@ -1011,7 +1243,15 @@ epilot ai-agents approveExecution -p execution_id=123e4567-e89b-12d3-a456-426614 "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -1104,7 +1344,341 @@ epilot ai-agents rejectExecution -p execution_id=123e4567-e89b-12d3-a456-4266141 "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + + + +--- + +### `streamExecution` + +Reconnects to an execution's event stream after approval. Replays missed events from event log and continues streaming i + +`GET /v1/executions/{execution_id}/stream` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `execution_id` | path | string (uuid) | Yes | | +| `from_sequence` | query | number | No | Resume from this event sequence number (for reconnection) | + +**Sample Call** + +```bash +epilot ai-agents streamExecution \ + -p execution_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot ai-agents streamExecution 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot ai-agents streamExecution -p execution_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `chat` + +Initiates a streaming chat session with an AI agent. Supports server-side conversation memory via conversationId or clie + +`POST /v1/chat` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot ai-agents chat +``` + +With request body: + +```bash +epilot ai-agents chat \ + -d '{ + "agentId": "string", + "message": "string", + "conversationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "clientHistory": [ + { + "role": "user", + "content": "string", + "tool_calls": [ + { + "id": "string", + "name": "string", + "input": {}, + "output": "string" + } + ] + } + ], + "context": { + "entityId": "string", + "customData": {} + }, + "streaming": { + "mode": "updates", + "streamTokens": false, + "includeMetadata": false + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot ai-agents chat +``` + +With JSONata filter: + +```bash +epilot ai-agents chat --jsonata '$' +``` + +--- + +### `listConversations` + +Lists conversations for the authenticated user, sorted by most recent. + +`GET /v1/conversations` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `agent_id` | query | string | No | Filter by agent ID | +| `limit` | query | number | No | Maximum number of conversations to return | +| `cursor` | query | string | No | Pagination cursor | + +**Sample Call** + +```bash +epilot ai-agents listConversations +``` + +With JSONata filter: + +```bash +epilot ai-agents listConversations --jsonata 'conversations' +``` + +
+Sample Response + +```json +{ + "conversations": [ + { + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "user_id": "string", + "agent_id": "string", + "title": "string", + "message_count": 0, + "last_message": "string", + "last_message_at": "1970-01-01T00:00:00.000Z", + "context": { + "entityId": "string", + "customData": {} + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `getConversation` + +Retrieves a conversation and its message history. + +`GET /v1/conversations/{conversation_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `conversation_id` | path | string (uuid) | Yes | | +| `message_limit` | query | number | No | Maximum number of messages to return | + +**Sample Call** + +```bash +epilot ai-agents getConversation \ + -p conversation_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot ai-agents getConversation 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot ai-agents getConversation -p conversation_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'conversation' +``` + +
+Sample Response + +```json +{ + "conversation": { + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "user_id": "string", + "agent_id": "string", + "title": "string", + "message_count": 0, + "last_message": "string", + "last_message_at": "1970-01-01T00:00:00.000Z", + "context": { + "entityId": "string", + "customData": {} + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + }, + "messages": [ + { + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "role": "user", + "content": "string", + "timestamp": "1970-01-01T00:00:00.000Z", + "tool_calls": [ + { + "id": "string", + "name": "string", + "input": {}, + "output": "string" + } + ], + "token_count": 0, + "trace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } + } + ] +} +``` + +
+ +--- + +### `deleteConversation` + +Deletes a conversation and all its messages. + +`DELETE /v1/conversations/{conversation_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `conversation_id` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot ai-agents deleteConversation \ + -p conversation_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot ai-agents deleteConversation 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot ai-agents deleteConversation -p conversation_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `submitConversationFeedback` + +Records a thumbs up/down (with optional comment) for the assistant turn identified by its Langfuse trace id. The rating + +`POST /v1/conversations/{conversation_id}/feedback` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `conversation_id` | path | string (uuid) | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot ai-agents submitConversationFeedback \ + -p conversation_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"trace_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","rating":"up","comment":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot ai-agents submitConversationFeedback 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot ai-agents submitConversationFeedback -p conversation_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot ai-agents submitConversationFeedback -p conversation_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'feedback' +``` + +
+Sample Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } } ``` diff --git a/docs/cli/commands/app.md b/docs/cli/commands/app.md index 0f54788b..154be66c 100644 --- a/docs/cli/commands/app.md +++ b/docs/cli/commands/app.md @@ -48,6 +48,7 @@ epilot app getPublicFacingComponent -p appId=123e4567-e89b-12d3-a456-42661417400 - [`patchInstallation`](#patchinstallation) — Patch an installed app by its ID. - [`uninstall`](#uninstall) — Uninstall an app by its ID. - [`promoteVersion`](#promoteversion) — Update an installed app to a new version +- [`resolveOptions`](#resolveoptions) — Resolve the effective app-level options of an installation, including decrypted sensitive values (secrets). This endpoin **App Configuration** - [`listConfigurations`](#listconfigurations) — List all app configuration metadata owned by an organization. To get full app configuration details, use the /v1/app-con @@ -76,6 +77,13 @@ epilot app getPublicFacingComponent -p appId=123e4567-e89b-12d3-a456-42661417400 - [`queryEvents`](#queryevents) — Query analytics events for a specific app with flexible filtering - [`ingestEvent`](#ingestevent) — Internal endpoint for services to submit app events for analytic purposes +**App Proxy** +- [`publicProxyGet`](#publicproxyget) — Forward a GET request to a registered proxy target from a public-facing component (e.g. journey blocks) +- [`publicProxyPost`](#publicproxypost) — Forward a POST request to a registered proxy target from a public-facing component (e.g. journey blocks) +- [`publicProxyPut`](#publicproxyput) — Forward a PUT request to a registered proxy target from a public-facing component +- [`publicProxyPatch`](#publicproxypatch) — Forward a PATCH request to a registered proxy target from a public-facing component +- [`publicProxyDelete`](#publicproxydelete) — Forward a DELETE request to a registered proxy target from a public-facing component + ### `getPublicFacingComponent` Retrieve public facing components for an installed app @@ -404,6 +412,35 @@ epilot app getPublicConfiguration -p appId=123e4567-e89b-12d3-a456-426614174000 "configuration": {} } ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ], "is_beta": true, "deprecated_at": "string", "version": "string", @@ -415,7 +452,8 @@ epilot app getPublicConfiguration -p appId=123e4567-e89b-12d3-a456-426614174000 }, "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "latest_version": "string", "public": true, @@ -424,6 +462,8 @@ epilot app getPublicConfiguration -p appId=123e4567-e89b-12d3-a456-426614174000 "app_id": "string", "owner_org_id": "string", "components": [], + "functions": [], + "options": [], "visibility": "private", "public": false, "pending": false, @@ -522,6 +562,35 @@ epilot app getConfiguration -p appId=123e4567-e89b-12d3-a456-426614174000 --json "configuration": {} } ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ], "visibility": "private", "public": false, "pending": false, @@ -538,7 +607,8 @@ epilot app getConfiguration -p appId=123e4567-e89b-12d3-a456-426614174000 --json }, "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "version_audit": { "created_at": "string", @@ -692,7 +762,8 @@ epilot app queryEvents \ "source": ["CUSTOM_JOURNEY_BLOCK"], "component_id": ["string"], "event_type": ["ERROR"], - "correlation_id": "string" + "correlation_id": "string", + "search": "string" }, "aggregation": { "group_by": ["source"], @@ -700,7 +771,8 @@ epilot app queryEvents \ }, "pagination": { "page": 1, - "page_size": 100 + "page_size": 100, + "before": "1970-01-01T00:00:00.000Z" }, "sort": { "field": "timestamp", @@ -742,7 +814,8 @@ epilot app queryEvents -p appId=123e4567-e89b-12d3-a456-426614174000 --jsonata ' "source": ["CUSTOM_JOURNEY_BLOCK"], "component_id": ["string"], "event_type": ["ERROR"], - "correlation_id": "string" + "correlation_id": "string", + "search": "string" }, "aggregation": { "group_by": ["source"], @@ -750,7 +823,8 @@ epilot app queryEvents -p appId=123e4567-e89b-12d3-a456-426614174000 --jsonata ' }, "pagination": { "page": 1, - "page_size": 100 + "page_size": 100, + "before": "1970-01-01T00:00:00.000Z" }, "sort": { "field": "timestamp", @@ -863,7 +937,7 @@ Generate a presigned URL to upload a zip file with artifacts that will be unpack | ---- | -- | ---- | -------- | ----------- | | `appId` | path | string | Yes | ID of the app configuration | -**Request Body** +**Request Body** (required) **Sample Call** @@ -1044,25 +1118,9 @@ epilot app listVersions -p appId=123e4567-e89b-12d3-a456-426614174000 --jsonata { "app_id": "string", "owner_org_id": "string", - "components": [ - { - "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } - } - ], + "components": [], + "functions": [], + "options": [], "visibility": "private", "public": false, "pending": false, @@ -1071,27 +1129,9 @@ epilot app listVersions -p appId=123e4567-e89b-12d3-a456-426614174000 --jsonata "deprecated_at": "string", "changelog": "string", "review_status": "approved", - "role": { - "id": "string", - "grants": [ - { - "action": "string", - "resource": "string" - } - ] - }, - "blueprint_ref": { - "manifest_id": "string", - "job_id": "string" - }, - "version_audit": { - "created_at": "string", - "created_by": "string", - "updated_at": "string", - "updated_by": "string", - "versioned_at": "string", - "versioned_by": "string" - } + "role": {}, + "blueprint_ref": {}, + "version_audit": {} } ], "pagination": { @@ -1185,6 +1225,35 @@ epilot app getVersion -p appId=123e4567-e89b-12d3-a456-426614174000 -p version=e "configuration": {} } ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ], "visibility": "private", "public": false, "pending": false, @@ -1201,7 +1270,8 @@ epilot app getVersion -p appId=123e4567-e89b-12d3-a456-426614174000 -p version=e }, "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "version_audit": { "created_at": "string", @@ -1235,11 +1305,72 @@ Patch an existing app version **Sample Call** +```bash +epilot app patchVersion \ + -p appId=123e4567-e89b-12d3-a456-426614174000 \ + -p version=example +``` + +With request body: + ```bash epilot app patchVersion \ -p appId=123e4567-e89b-12d3-a456-426614174000 \ -p version=example \ - -d '{"manifest_id":"string","role_id":"string","grants":[{"action":"string","resource":"string"}]}' + -d '{ + "manifest_id": "string", + "role_id": "string", + "grants": [ + { + "action": "string", + "resource": "string" + } + ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": { + "en": "string", + "de": "string" + }, + "description": { + "en": "string", + "de": "string" + }, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [ + { + "key": "string", + "label": "string", + "description": "string", + "required": true, + "type": "text" + } + ], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ], + "changelog": "string" +}' ``` Using positional args for path parameters: @@ -1631,13 +1762,16 @@ Clone an existing app version to create a new version | `sourceVersion` | path | string | Yes | Source version to clone from | | `targetVersion` | path | string | Yes | Target version to create | +**Request Body** + **Sample Call** ```bash epilot app cloneVersion \ -p appId=123e4567-e89b-12d3-a456-426614174000 \ -p sourceVersion=example \ - -p targetVersion=example + -p targetVersion=example \ + -d '{"changelog":"string"}' ``` Using positional args for path parameters: @@ -1646,6 +1780,12 @@ Using positional args for path parameters: epilot app cloneVersion 123e4567-e89b-12d3-a456-426614174000 example example ``` +Using stdin pipe: + +```bash +cat body.json | epilot app cloneVersion -p appId=123e4567-e89b-12d3-a456-426614174000 -p sourceVersion=example -p targetVersion=example +``` + With JSONata filter: ```bash @@ -1677,7 +1817,7 @@ Retrieve a list of installed apps for the organization. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `componentType` | query | "CUSTOM_JOURNEY_BLOCK" \| "CUSTOM_PORTAL_BLOCK" \| "PORTAL_EXTENSION" \| "CUSTOM_FLOW_ACTION" \| "ERP_INFORM_TOOLKIT" \| "CUSTOM_CAPABILITY" \| "EXTERNAL_PRODUCT_CATALOG" \| "CUSTOM_PAGE" | No | Filter apps by specific component type | +| `componentType` | query | "CUSTOM_JOURNEY_BLOCK" \| "CUSTOM_PORTAL_BLOCK" \| "PORTAL_EXTENSION" \| "CUSTOM_FLOW_ACTION" \| "ERP_INFORM_TOOLKIT" \| "CUSTOM_CAPABILITY" \| "EXTERNAL_PRODUCT_CATALOG" \| "CUSTOM_PAGE" \| "API_PROXY" \| "EXTERNAL_VALUES" \| "APP_FUNCTION" | No | Filter apps by specific component type | | `enabled` | query | boolean | No | Filter apps by enabled status | | `page` | query | number | No | Page number for pagination | | `pageSize` | query | number | No | Number of items per page | @@ -1706,48 +1846,15 @@ epilot app listInstallations --jsonata 'apps' "owner_org_id": "string", "enabled": true, "name": "string", - "option_values": [ - { - "component_id": "string", - "options": [ - { - "key": "string", - "value": {} - } - ] - } - ], - "components": [ - { - "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } - } - ], + "icon_url": "string", + "option_values": [], + "components": [], + "functions": [], + "options": [], "installed_version": "string", "role": "string", - "blueprint_ref": { - "manifest_id": "string", - "job_id": "string" - }, - "installation_audit": { - "created_at": "string", - "created_by": "string", - "updated_at": "string", - "updated_by": "string" - }, + "blueprint_ref": {}, + "installation_audit": {}, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } ], @@ -1804,41 +1911,54 @@ epilot app getInstallation -p appId=123e4567-e89b-12d3-a456-426614174000 --jsona "owner_org_id": "string", "enabled": true, "name": "string", + "icon_url": "string", "option_values": [ { "component_id": "string", - "options": [ - { - "key": "string", - "value": {} - } - ] + "options": [] } ], "components": [ { "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } + "configuration": {} + } + ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" } ], "installed_version": "string", "role": "string", "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "installation_audit": { "created_at": "string", @@ -1866,7 +1986,7 @@ Upsert app installation by its ID. | ---- | -- | ---- | -------- | ----------- | | `appId` | path | string | Yes | | -**Request Body** +**Request Body** (required) **Sample Call** @@ -1925,41 +2045,54 @@ epilot app install -p appId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'app_ "owner_org_id": "string", "enabled": true, "name": "string", + "icon_url": "string", "option_values": [ { "component_id": "string", - "options": [ - { - "key": "string", - "value": {} - } - ] + "options": [] } ], "components": [ { "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } + "configuration": {} + } + ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" } ], "installed_version": "string", "role": "string", "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "installation_audit": { "created_at": "string", @@ -1987,7 +2120,7 @@ Patch an installed app by its ID. | ---- | -- | ---- | -------- | ----------- | | `appId` | path | string | Yes | | -**Request Body** +**Request Body** (required) **Sample Call** @@ -2114,41 +2247,54 @@ epilot app promoteVersion -p appId=123e4567-e89b-12d3-a456-426614174000 -p versi "owner_org_id": "string", "enabled": true, "name": "string", + "icon_url": "string", "option_values": [ { "component_id": "string", - "options": [ - { - "key": "string", - "value": {} - } - ] + "options": [] } ], "components": [ { "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } + "configuration": {} + } + ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" } ], "installed_version": "string", "role": "string", "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "installation_audit": { "created_at": "string", @@ -2164,6 +2310,82 @@ epilot app promoteVersion -p appId=123e4567-e89b-12d3-a456-426614174000 -p versi --- +### `resolveOptions` + +Resolve the effective app-level options of an installation, including decrypted sensitive values (secrets). This endpoin + +`POST /v1/app/{appId}/options/resolve` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `appId` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot app resolveOptions \ + -p appId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"keys":["string"]}' +``` + +Using positional args for path parameters: + +```bash +epilot app resolveOptions 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot app resolveOptions -p appId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot app resolveOptions -p appId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'options' +``` + +
+Sample Response + +```json +{ + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [ + { + "key": "string", + "label": "string", + "description": "string", + "required": true, + "type": "text" + } + ], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ] +} +``` + +
+ +--- + ### `ingestEvent` Internal endpoint for services to submit app events for analytic purposes @@ -2213,3 +2435,220 @@ epilot app ingestEvent --jsonata '$' ``` --- + +### `publicProxyGet` + +Forward a GET request to a registered proxy target from a public-facing component (e.g. journey blocks) + +`GET /v1/public/app/{appId}/proxy/{proxyName}/{path}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `appId` | path | string | Yes | ID of the installed app | +| `proxyName` | path | string | Yes | Name of the proxy target as defined in the app manifest | +| `path` | path | string | Yes | Path to forward to the proxy target | +| `query` | query | object | No | Free-form query parameters, forwarded unchanged to the proxy target | + +**Sample Call** + +```bash +epilot app publicProxyGet \ + -p appId=123e4567-e89b-12d3-a456-426614174000 \ + -p proxyName=example \ + -p path=example +``` + +Using positional args for path parameters: + +```bash +epilot app publicProxyGet 123e4567-e89b-12d3-a456-426614174000 example example +``` + +With JSONata filter: + +```bash +epilot app publicProxyGet -p appId=123e4567-e89b-12d3-a456-426614174000 -p proxyName=example -p path=example --jsonata '$' +``` + +--- + +### `publicProxyPost` + +Forward a POST request to a registered proxy target from a public-facing component (e.g. journey blocks) + +`POST /v1/public/app/{appId}/proxy/{proxyName}/{path}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `appId` | path | string | Yes | ID of the installed app | +| `proxyName` | path | string | Yes | Name of the proxy target as defined in the app manifest | +| `path` | path | string | Yes | Path to forward to the proxy target | +| `query` | query | object | No | Free-form query parameters, forwarded unchanged to the proxy target | + +**Request Body** + +**Sample Call** + +```bash +epilot app publicProxyPost \ + -p appId=123e4567-e89b-12d3-a456-426614174000 \ + -p proxyName=example \ + -p path=example \ + -d '{}' +``` + +Using positional args for path parameters: + +```bash +epilot app publicProxyPost 123e4567-e89b-12d3-a456-426614174000 example example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot app publicProxyPost -p appId=123e4567-e89b-12d3-a456-426614174000 -p proxyName=example -p path=example +``` + +With JSONata filter: + +```bash +epilot app publicProxyPost -p appId=123e4567-e89b-12d3-a456-426614174000 -p proxyName=example -p path=example --jsonata '$' +``` + +--- + +### `publicProxyPut` + +Forward a PUT request to a registered proxy target from a public-facing component + +`PUT /v1/public/app/{appId}/proxy/{proxyName}/{path}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `appId` | path | string | Yes | ID of the installed app | +| `proxyName` | path | string | Yes | Name of the proxy target as defined in the app manifest | +| `path` | path | string | Yes | Path to forward to the proxy target | +| `query` | query | object | No | Free-form query parameters, forwarded unchanged to the proxy target | + +**Request Body** + +**Sample Call** + +```bash +epilot app publicProxyPut \ + -p appId=123e4567-e89b-12d3-a456-426614174000 \ + -p proxyName=example \ + -p path=example \ + -d '{}' +``` + +Using positional args for path parameters: + +```bash +epilot app publicProxyPut 123e4567-e89b-12d3-a456-426614174000 example example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot app publicProxyPut -p appId=123e4567-e89b-12d3-a456-426614174000 -p proxyName=example -p path=example +``` + +With JSONata filter: + +```bash +epilot app publicProxyPut -p appId=123e4567-e89b-12d3-a456-426614174000 -p proxyName=example -p path=example --jsonata '$' +``` + +--- + +### `publicProxyPatch` + +Forward a PATCH request to a registered proxy target from a public-facing component + +`PATCH /v1/public/app/{appId}/proxy/{proxyName}/{path}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `appId` | path | string | Yes | ID of the installed app | +| `proxyName` | path | string | Yes | Name of the proxy target as defined in the app manifest | +| `path` | path | string | Yes | Path to forward to the proxy target | +| `query` | query | object | No | Free-form query parameters, forwarded unchanged to the proxy target | + +**Request Body** + +**Sample Call** + +```bash +epilot app publicProxyPatch \ + -p appId=123e4567-e89b-12d3-a456-426614174000 \ + -p proxyName=example \ + -p path=example \ + -d '{}' +``` + +Using positional args for path parameters: + +```bash +epilot app publicProxyPatch 123e4567-e89b-12d3-a456-426614174000 example example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot app publicProxyPatch -p appId=123e4567-e89b-12d3-a456-426614174000 -p proxyName=example -p path=example +``` + +With JSONata filter: + +```bash +epilot app publicProxyPatch -p appId=123e4567-e89b-12d3-a456-426614174000 -p proxyName=example -p path=example --jsonata '$' +``` + +--- + +### `publicProxyDelete` + +Forward a DELETE request to a registered proxy target from a public-facing component + +`DELETE /v1/public/app/{appId}/proxy/{proxyName}/{path}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `appId` | path | string | Yes | ID of the installed app | +| `proxyName` | path | string | Yes | Name of the proxy target as defined in the app manifest | +| `path` | path | string | Yes | Path to forward to the proxy target | +| `query` | query | object | No | Free-form query parameters, forwarded unchanged to the proxy target | + +**Sample Call** + +```bash +epilot app publicProxyDelete \ + -p appId=123e4567-e89b-12d3-a456-426614174000 \ + -p proxyName=example \ + -p path=example +``` + +Using positional args for path parameters: + +```bash +epilot app publicProxyDelete 123e4567-e89b-12d3-a456-426614174000 example example +``` + +With JSONata filter: + +```bash +epilot app publicProxyDelete -p appId=123e4567-e89b-12d3-a456-426614174000 -p proxyName=example -p path=example --jsonata '$' +``` + +--- diff --git a/docs/cli/commands/automation.md b/docs/cli/commands/automation.md index ea57af45..cae7b73b 100644 --- a/docs/cli/commands/automation.md +++ b/docs/cli/commands/automation.md @@ -51,6 +51,7 @@ epilot automation searchFlows **executions** - [`getExecutions`](#getexecutions) — List automation executions - [`startExecution`](#startexecution) — Start new automation execution +- [`searchExecutions`](#searchexecutions) — Search automation executions of an entity with cursor-based pagination. - [`getExecution`](#getexecution) — Get automation execution - [`cancelExecution`](#cancelexecution) — Cancel automation execution - [`retriggerAction`](#retriggeraction) — Retry a specific automation execution action which failed / is stuck. @@ -76,6 +77,8 @@ Search available automation flows | `size` | query | number | No | Pagination: max number of results to return | | `from` | query | number | No | Pagination: starting for results | | `trigger_source_id` | query | string | No | Trigger source identifier | +| `target_workflow` | query | string | No | Filter by target workflow ID. Returns only automations that have a trigger-workflow action targeting this workflow. | +| `trigger_event_name` | query | string | No | Filter by Event Catalog event name. Returns only automations that have an event_catalog trigger for this event. | | `include_flows` | query | boolean | No | Include flow automations in the response | **Sample Call** @@ -309,7 +312,11 @@ epilot automation getExecutions --jsonata 'results[0]' "trigger_context": {}, "version": 2, "trigger_event": {}, - "workflow_context": {} + "workflow_context": {}, + "workflow_wait_context": {}, + "loops": [], + "loop_state": {}, + "chain": ["string"] } ] } @@ -348,7 +355,16 @@ epilot automation startExecution \ "parent_execution_id": "string", "parent_task_id": "string", "depth": 0 - } + }, + "_automation_chain": ["string"], + "entity_contexts": [ + { + "entity_id": "string", + "entity_schema": "string", + "is_primary": true + } + ], + "trigger_user_id": "10006129" }, "flow_execution_id": "string", "flow_automation_task_id": "string" @@ -395,7 +411,10 @@ epilot automation startExecution --jsonata 'id' { "id": "string", "schedule_id": "string", + "evaluation_order": "AFTER_SCHEDULE", "evaluationResult": true, + "error_output": {}, + "allow_failure": true, "statements": [] } ], @@ -422,12 +441,14 @@ epilot automation startExecution --jsonata 'id' "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] }, { "id": "9ec3711b-db63-449c-b894-54d5bb622a8f", @@ -441,12 +462,14 @@ epilot automation startExecution --jsonata 'id' "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] } ], "resume_token": "eyJraWQiOiJrZXkifQ==", @@ -470,8 +493,97 @@ epilot automation startExecution --jsonata 'id' "parent_execution_id": "string", "parent_task_id": "string", "depth": 0 + }, + "_automation_chain": ["string"], + "entity_contexts": [ + {} + ], + "trigger_user_id": "10006129" + }, + "workflow_wait_context": { + "workflow_execution_id": "string", + "workflow_task_id": "string", + "source": "journey_submission" + }, + "loops": [ + { + "id": "loop_contracts", + "source_path": "submission.steps[0]['Contracts']", + "source_type": "journey-multi-select", + "filter_tags": ["_hidden_ 2a4b1c3d-0000-4000-8000-000000000000 - Dokumente"], + "length": 0 } - } + ], + "loop_state": {}, + "chain": ["string"] +} +``` + +
+ +--- + +### `searchExecutions` + +Search automation executions of an entity with cursor-based pagination. + +`POST /v1/automation/executions:search` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot automation searchExecutions \ + -d '{"entity_id":"e3d3ebac-baab-4395-abf4-50b5bf1f8b74","include_flows":false,"size":25,"cursor":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot automation searchExecutions +``` + +With JSONata filter: + +```bash +epilot automation searchExecutions --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "total": 0, + "results": [ + { + "id": "9baf184f-bc81-4128-bca3-d974c90a12c4", + "execution_status": "pending", + "entity_id": "e3d3ebac-baab-4395-abf4-50b5bf1f8b74", + "activity_id": "e3d3ebac-baab-4395-abf4-50b5bf1f8b74", + "entity_snapshot": {}, + "org_id": "e3d3ebac-baab-4395-abf4-50b5bf1f8b74", + "flow_id": "7791b04a-16d2-44a2-9af9-2d59c25c512f", + "flow_name": "Handle contact form", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "current_action_id": "9ec3711b-db63-449c-b894-54d5bb622a8f", + "conditions": [], + "schedules": [], + "actions": [], + "resume_token": "eyJraWQiOiJrZXkifQ==", + "trigger_context": {}, + "version": 2, + "trigger_event": {}, + "workflow_context": {}, + "workflow_wait_context": {}, + "loops": [], + "loop_state": {}, + "chain": ["string"] + } + ], + "next_cursor": "string" } ``` @@ -759,7 +871,10 @@ epilot automation getExecution -p execution_id=9baf184f-bc81-4128-bca3-d974c90a1 { "id": "string", "schedule_id": "string", + "evaluation_order": "AFTER_SCHEDULE", "evaluationResult": true, + "error_output": {}, + "allow_failure": true, "statements": [] } ], @@ -786,12 +901,14 @@ epilot automation getExecution -p execution_id=9baf184f-bc81-4128-bca3-d974c90a1 "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] }, { "id": "9ec3711b-db63-449c-b894-54d5bb622a8f", @@ -805,12 +922,14 @@ epilot automation getExecution -p execution_id=9baf184f-bc81-4128-bca3-d974c90a1 "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] } ], "resume_token": "eyJraWQiOiJrZXkifQ==", @@ -834,8 +953,29 @@ epilot automation getExecution -p execution_id=9baf184f-bc81-4128-bca3-d974c90a1 "parent_execution_id": "string", "parent_task_id": "string", "depth": 0 + }, + "_automation_chain": ["string"], + "entity_contexts": [ + {} + ], + "trigger_user_id": "10006129" + }, + "workflow_wait_context": { + "workflow_execution_id": "string", + "workflow_task_id": "string", + "source": "journey_submission" + }, + "loops": [ + { + "id": "loop_contracts", + "source_path": "submission.steps[0]['Contracts']", + "source_type": "journey-multi-select", + "filter_tags": ["_hidden_ 2a4b1c3d-0000-4000-8000-000000000000 - Dokumente"], + "length": 0 } - } + ], + "loop_state": {}, + "chain": ["string"] } ``` @@ -902,7 +1042,10 @@ epilot automation cancelExecution -p execution_id=9baf184f-bc81-4128-bca3-d974c9 { "id": "string", "schedule_id": "string", + "evaluation_order": "AFTER_SCHEDULE", "evaluationResult": true, + "error_output": {}, + "allow_failure": true, "statements": [] } ], @@ -929,12 +1072,14 @@ epilot automation cancelExecution -p execution_id=9baf184f-bc81-4128-bca3-d974c9 "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] }, { "id": "9ec3711b-db63-449c-b894-54d5bb622a8f", @@ -948,12 +1093,14 @@ epilot automation cancelExecution -p execution_id=9baf184f-bc81-4128-bca3-d974c9 "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] } ], "resume_token": "eyJraWQiOiJrZXkifQ==", @@ -977,8 +1124,29 @@ epilot automation cancelExecution -p execution_id=9baf184f-bc81-4128-bca3-d974c9 "parent_execution_id": "string", "parent_task_id": "string", "depth": 0 + }, + "_automation_chain": ["string"], + "entity_contexts": [ + {} + ], + "trigger_user_id": "10006129" + }, + "workflow_wait_context": { + "workflow_execution_id": "string", + "workflow_task_id": "string", + "source": "journey_submission" + }, + "loops": [ + { + "id": "loop_contracts", + "source_path": "submission.steps[0]['Contracts']", + "source_type": "journey-multi-select", + "filter_tags": ["_hidden_ 2a4b1c3d-0000-4000-8000-000000000000 - Dokumente"], + "length": 0 } - } + ], + "loop_state": {}, + "chain": ["string"] } ``` @@ -1107,8 +1275,21 @@ epilot automation resumeExecutionWithToken --jsonata 'execution' "workflow_exec_id": "string", "workflow_exec_task_id": "string", "workflow_role": "trigger_workflow", - "_execution_chain": {} - } + "_execution_chain": {}, + "_automation_chain": ["string"], + "entity_contexts": [], + "trigger_user_id": "10006129" + }, + "workflow_wait_context": { + "workflow_execution_id": "string", + "workflow_task_id": "string", + "source": "journey_submission" + }, + "loops": [ + {} + ], + "loop_state": {}, + "chain": ["string"] }, "resumedAction": { "id": "9ec3711b-db63-449c-b894-54d5bb622a8f", @@ -1118,11 +1299,13 @@ epilot automation resumeExecutionWithToken --jsonata 'execution' "config": { "mapping_config": {}, "target_schema": "string", + "use_uniqueness_criteria": true, "target_unique": ["string"], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] }, "allow_failure": true, "created_automatically": true, @@ -1133,6 +1316,7 @@ epilot automation resumeExecutionWithToken --jsonata 'execution' }, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", @@ -1142,7 +1326,10 @@ epilot automation resumeExecutionWithToken --jsonata 'execution' "error_reason": "string", "error_info": {} }, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [ + {} + ] } } ``` diff --git a/docs/cli/commands/billing.md b/docs/cli/commands/billing.md index c3311321..2484e929 100644 --- a/docs/cli/commands/billing.md +++ b/docs/cli/commands/billing.md @@ -8,7 +8,7 @@ description: "epilot CLI commands for the Billing API: quick start, common flags - **Base URL:** `https://billing.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/billing](https://docs.epilot.io/api/billing) -API to manage billing data for epilot contracts and orders +API to manage billing data for epilot contracts and orders. ## Quick Start @@ -41,24 +41,32 @@ epilot billing getBillingEvents ## Operations **Billing Events** -- [`getBillingEvents`](#getbillingevents) — Get and filter billing events such as installments and reimbursements. -- [`createBillingEvent`](#createbillingevent) — Create a new billing event. -- [`getBillingEvent`](#getbillingevent) — Get a single billing event by ID. -- [`updateBillingEvent`](#updatebillingevent) — Update an existing billing event. -- [`deleteBillingEvent`](#deletebillingevent) — Delete an existing billing event. -- [`getBillingEventByExternalId`](#getbillingeventbyexternalid) — Get a single billing event by External ID. +- [`getBillingEvents`](#getbillingevents) — Retrieve and filter billing events (Buchungssätze) such as installments (Abschlagszahlungen), +- [`createBillingEvent`](#createbillingevent) — Create a new billing event (Buchungssatz) such as an installment (Abschlagszahlung), +- [`getBillingEvent`](#getbillingevent) — Retrieve a single billing event (Buchungssatz) by its unique ID. +- [`updateBillingEvent`](#updatebillingevent) — Update an existing billing event (Buchungssatz). +- [`deleteBillingEvent`](#deletebillingevent) — Delete an existing billing event (Buchungssatz). +- [`getBillingEventByExternalId`](#getbillingeventbyexternalid) — Retrieve a billing event (Buchungssatz) by its external system identifier. **Contracts** -- [`createContractEntity`](#createcontractentity) — Create a new contract entity. -- [`updateContractEntity`](#updatecontractentity) — Update an existing contract entity. -- [`deleteContractEntity`](#deletecontractentity) — Delete an existing contract entity. +- [`createContractEntity`](#createcontractentity) — Create a new contract entity (Vertrag) for billing purposes. +- [`updateContractEntity`](#updatecontractentity) — Update an existing contract entity (Vertrag). +- [`deleteContractEntity`](#deletecontractentity) — Delete an existing contract entity (Vertrag). + +**Pricing Information** +- [`getContractPricingInformation`](#getcontractpricinginformation) — Get current pricing information and recent configuration history for a Contract. +- [`getBillingAccountPricingInformation`](#getbillingaccountpricinginformation) — Get current pricing information for the active Contracts linked to a Billing Account. + +**Configuration History** +- [`getContractConfigurationHistory`](#getcontractconfigurationhistory) — Get billing configuration history for a Contract. +- [`getBillingAccountConfigurationHistory`](#getbillingaccountconfigurationhistory) — Get merged billing configuration history for active Contracts linked to a Billing Account. **Balance** -- [`getCustomerBalance`](#getcustomerbalance) — Get total balance across all contracts and orders of a customer entity. +- [`getCustomerBalance`](#getcustomerbalance) — Retrieve the total balance (Kontostand) across all contracts and orders for a customer. ### `getBillingEvents` -Get and filter billing events such as installments and reimbursements. +Retrieve and filter billing events (Buchungssätze) such as installments (Abschlagszahlungen), `GET /v1/billing/events` @@ -66,12 +74,16 @@ Get and filter billing events such as installments and reimbursements. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `from` | query | number | No | | -| `size` | query | number | No | | -| `entity_id` | query | string[] | No | Entity ID to filter billing events by | -| `event_type` | query | "installment" \| "reimbursement" | No | | -| `date_after` | query | string (date-time) | No | | -| `date_before` | query | string (date-time) | No | | +| `from` | query | number | No | Pagination offset - number of results to skip | +| `size` | query | number | No | Maximum number of results to return per page | +| `entity_id` | query | string[] | No | Filter billing events by one or more entity IDs (e.g., contract or order IDs) | +| `contact_id` | query | string | No | Filter billing events by customer contact ID (Kundennummer) | +| `event_type` | query | "installment" \| "reimbursement" | No | Filter by billing event type (Buchungsart): +- `installment`: Abschlagszahlung (scheduled payment due) +- `reimbursement`: Rückerstattung (refund to customer) + | +| `date_after` | query | string (date-time) | No | Filter billing events with booking date (Buchungsdatum) after this timestamp | +| `date_before` | query | string (date-time) | No | Filter billing events with booking date (Buchungsdatum) before this timestamp | **Sample Call** @@ -90,30 +102,18 @@ epilot billing getBillingEvents --jsonata 'results[0]' ```json { - "hits": 0, + "hits": 42, "results": [ { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ] } @@ -125,7 +125,7 @@ epilot billing getBillingEvents --jsonata 'results[0]' ### `createBillingEvent` -Create a new billing event. +Create a new billing event (Buchungssatz) such as an installment (Abschlagszahlung), `POST /v1/billing/events` @@ -142,27 +142,15 @@ With request body: ```bash epilot billing createBillingEvent \ -d '{ - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" }' ``` @@ -183,27 +171,15 @@ epilot billing createBillingEvent --jsonata '$' ```json { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ``` @@ -213,7 +189,7 @@ epilot billing createBillingEvent --jsonata '$' ### `getBillingEvent` -Get a single billing event by ID. +Retrieve a single billing event (Buchungssatz) by its unique ID. `GET /v1/billing/events/{id}` @@ -221,25 +197,25 @@ Get a single billing event by ID. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | ID of the billing event to get | +| `id` | path | string | Yes | Unique identifier of the billing event (Buchungssatz-ID) | **Sample Call** ```bash epilot billing getBillingEvent \ - -p id=123e4567-e89b-12d3-a456-426614174000 + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using positional args for path parameters: ```bash -epilot billing getBillingEvent 123e4567-e89b-12d3-a456-426614174000 +epilot billing getBillingEvent 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot billing getBillingEvent -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot billing getBillingEvent -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' ```
@@ -247,27 +223,15 @@ epilot billing getBillingEvent -p id=123e4567-e89b-12d3-a456-426614174000 --json ```json { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ``` @@ -277,7 +241,7 @@ epilot billing getBillingEvent -p id=123e4567-e89b-12d3-a456-426614174000 --json ### `updateBillingEvent` -Update an existing billing event. +Update an existing billing event (Buchungssatz). `PATCH /v1/billing/events/{id}` @@ -285,7 +249,7 @@ Update an existing billing event. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | ID of the billing event to update | +| `id` | path | string | Yes | Unique identifier of the billing event to update | **Request Body** (required) @@ -293,19 +257,21 @@ Update an existing billing event. ```bash epilot billing updateBillingEvent \ - -p id=123e4567-e89b-12d3-a456-426614174000 + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` With request body: ```bash epilot billing updateBillingEvent \ - -p id=123e4567-e89b-12d3-a456-426614174000 \ + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 \ -d '{ - "billing_amount": 10050, - "billing_amount_decimal": "100.50", + "type": "installment", + "direction": "debit", + "billing_amount": 10000, + "billing_amount_decimal": "100.00", "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", + "external_id": "SAP-54321", "contract": { "$relation": [ { @@ -313,35 +279,43 @@ epilot billing updateBillingEvent \ } ] }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", - "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "booking_date": "2025-06-15", + "due_date": "2025-06-30", + "paid_date": "2025-06-15T10:00:00Z", + "status": "closed", + "related_event": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", + "external_link": { + "href": "https://billing.example.com/invoices/12345", + "title": "Invoice 12345" + }, + "attachments": { + "$relation": [ + { + "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + } + ] + }, + "note": "Teilzahlung für Abschlag Juni", + "internal_note": "Rückmeldung von SAP: Betrag aus Zahlungsavis 2025-06-14 übernommen" }' ``` Using positional args for path parameters: ```bash -epilot billing updateBillingEvent 123e4567-e89b-12d3-a456-426614174000 +epilot billing updateBillingEvent 5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using stdin pipe: ```bash -cat body.json | epilot billing updateBillingEvent -p id=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot billing updateBillingEvent -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot billing updateBillingEvent -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot billing updateBillingEvent -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' ```
@@ -349,27 +323,15 @@ epilot billing updateBillingEvent -p id=123e4567-e89b-12d3-a456-426614174000 --j ```json { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ``` @@ -379,7 +341,7 @@ epilot billing updateBillingEvent -p id=123e4567-e89b-12d3-a456-426614174000 --j ### `deleteBillingEvent` -Delete an existing billing event. +Delete an existing billing event (Buchungssatz). `DELETE /v1/billing/events/{id}` @@ -387,32 +349,32 @@ Delete an existing billing event. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | ID of the billing event to delete | +| `id` | path | string | Yes | Unique identifier of the billing event to delete | **Sample Call** ```bash epilot billing deleteBillingEvent \ - -p id=123e4567-e89b-12d3-a456-426614174000 + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using positional args for path parameters: ```bash -epilot billing deleteBillingEvent 123e4567-e89b-12d3-a456-426614174000 +epilot billing deleteBillingEvent 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot billing deleteBillingEvent -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot billing deleteBillingEvent -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' ``` --- ### `getBillingEventByExternalId` -Get a single billing event by External ID. +Retrieve a billing event (Buchungssatz) by its external system identifier. `GET /v1/billing/external/{external_id}` @@ -420,25 +382,27 @@ Get a single billing event by External ID. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `external_id` | path | string | Yes | ID of the billing event to get | +| `external_id` | path | string | Yes | External system identifier for the billing event. +For example, a SAP document number or payment processor reference ID. + | **Sample Call** ```bash epilot billing getBillingEventByExternalId \ - -p external_id=123e4567-e89b-12d3-a456-426614174000 + -p external_id=SAP-54321 ``` Using positional args for path parameters: ```bash -epilot billing getBillingEventByExternalId 123e4567-e89b-12d3-a456-426614174000 +epilot billing getBillingEventByExternalId SAP-54321 ``` With JSONata filter: ```bash -epilot billing getBillingEventByExternalId -p external_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot billing getBillingEventByExternalId -p external_id=SAP-54321 --jsonata '$' ```
@@ -446,27 +410,15 @@ epilot billing getBillingEventByExternalId -p external_id=123e4567-e89b-12d3-a45 ```json { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ``` @@ -476,7 +428,7 @@ epilot billing getBillingEventByExternalId -p external_id=123e4567-e89b-12d3-a45 ### `createContractEntity` -Create a new contract entity. +Create a new contract entity (Vertrag) for billing purposes. `POST /v1/billing/contracts` @@ -494,32 +446,32 @@ With request body: epilot billing createContractEntity \ -d '{ "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", + "_title": "Abschlagszahlung Juli 2025", + "_org": "123456", + "_schema": "billing_event", + "_tags": ["billing", "energy"], + "_created_at": "2025-06-15T10:30:00Z", + "_updated_at": "2025-06-15T14:45:00Z", + "contract_name": "Stromvertrag Haushalt", + "contract_number": "STR-2025-001234", + "status": "active", + "description": "Haushaltsstrom-Tarif mit 24 Monaten Preisgarantie", + "account_number": "KD-67890", "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", + "billing_address": "Musterstraße 123, 50667 Köln", + "delivery_address": "Musterstraße 123, 50667 Köln", + "additional_addresses": "Postfach 456, 50668 Köln", + "termination_date": "2025-12-31", + "termination_reason": "Kundenkündigung", "billing_period": "monthly", "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", + "renewal_duration_amount": 12, + "renewal_duration_unit": "months", "notice_time_amount": 30, "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, + "start_date": "2025-01-01", + "billing_due_day": 15, + "installment_amount": 8500, "balance": 8990, "balance_currency": "EUR" }' @@ -543,32 +495,32 @@ epilot billing createContractEntity --jsonata '$' ```json { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", + "_title": "Abschlagszahlung Juli 2025", + "_org": "123456", + "_schema": "billing_event", + "_tags": ["billing", "energy"], + "_created_at": "2025-06-15T10:30:00Z", + "_updated_at": "2025-06-15T14:45:00Z", + "contract_name": "Stromvertrag Haushalt", + "contract_number": "STR-2025-001234", + "status": "active", + "description": "Haushaltsstrom-Tarif mit 24 Monaten Preisgarantie", + "account_number": "KD-67890", "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", + "billing_address": "Musterstraße 123, 50667 Köln", + "delivery_address": "Musterstraße 123, 50667 Köln", + "additional_addresses": "Postfach 456, 50668 Köln", + "termination_date": "2025-12-31", + "termination_reason": "Kundenkündigung", "billing_period": "monthly", "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", + "renewal_duration_amount": 12, + "renewal_duration_unit": "months", "notice_time_amount": 30, "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, + "start_date": "2025-01-01", + "billing_due_day": 15, + "installment_amount": 8500, "balance": 8990, "balance_currency": "EUR" } @@ -580,7 +532,7 @@ epilot billing createContractEntity --jsonata '$' ### `updateContractEntity` -Update an existing contract entity. +Update an existing contract entity (Vertrag). `PATCH /v1/billing/contracts/{id}` @@ -588,7 +540,7 @@ Update an existing contract entity. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | ID of the contract entity to update | +| `id` | path | string | Yes | Unique identifier of the contract (Vertragsnummer) | **Request Body** (required) @@ -596,42 +548,42 @@ Update an existing contract entity. ```bash epilot billing updateContractEntity \ - -p id=123e4567-e89b-12d3-a456-426614174000 + -p id=f589786b-3024-43cd-9cb3-5a3c953f2896 ``` With request body: ```bash epilot billing updateContractEntity \ - -p id=123e4567-e89b-12d3-a456-426614174000 \ + -p id=f589786b-3024-43cd-9cb3-5a3c953f2896 \ -d '{ "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", + "_title": "Abschlagszahlung Juli 2025", + "_org": "123456", + "_schema": "billing_event", + "_tags": ["billing", "energy"], + "_created_at": "2025-06-15T10:30:00Z", + "_updated_at": "2025-06-15T14:45:00Z", + "contract_name": "Stromvertrag Haushalt", + "contract_number": "STR-2025-001234", + "status": "active", + "description": "Haushaltsstrom-Tarif mit 24 Monaten Preisgarantie", + "account_number": "KD-67890", "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", + "billing_address": "Musterstraße 123, 50667 Köln", + "delivery_address": "Musterstraße 123, 50667 Köln", + "additional_addresses": "Postfach 456, 50668 Köln", + "termination_date": "2025-12-31", + "termination_reason": "Kundenkündigung", "billing_period": "monthly", "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", + "renewal_duration_amount": 12, + "renewal_duration_unit": "months", "notice_time_amount": 30, "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, + "start_date": "2025-01-01", + "billing_due_day": 15, + "installment_amount": 8500, "balance": 8990, "balance_currency": "EUR" }' @@ -640,19 +592,19 @@ epilot billing updateContractEntity \ Using positional args for path parameters: ```bash -epilot billing updateContractEntity 123e4567-e89b-12d3-a456-426614174000 +epilot billing updateContractEntity f589786b-3024-43cd-9cb3-5a3c953f2896 ``` Using stdin pipe: ```bash -cat body.json | epilot billing updateContractEntity -p id=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot billing updateContractEntity -p id=f589786b-3024-43cd-9cb3-5a3c953f2896 ``` With JSONata filter: ```bash -epilot billing updateContractEntity -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot billing updateContractEntity -p id=f589786b-3024-43cd-9cb3-5a3c953f2896 --jsonata '$' ```
@@ -661,32 +613,32 @@ epilot billing updateContractEntity -p id=123e4567-e89b-12d3-a456-426614174000 - ```json { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", + "_title": "Abschlagszahlung Juli 2025", + "_org": "123456", + "_schema": "billing_event", + "_tags": ["billing", "energy"], + "_created_at": "2025-06-15T10:30:00Z", + "_updated_at": "2025-06-15T14:45:00Z", + "contract_name": "Stromvertrag Haushalt", + "contract_number": "STR-2025-001234", + "status": "active", + "description": "Haushaltsstrom-Tarif mit 24 Monaten Preisgarantie", + "account_number": "KD-67890", "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", + "billing_address": "Musterstraße 123, 50667 Köln", + "delivery_address": "Musterstraße 123, 50667 Köln", + "additional_addresses": "Postfach 456, 50668 Köln", + "termination_date": "2025-12-31", + "termination_reason": "Kundenkündigung", "billing_period": "monthly", "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", + "renewal_duration_amount": 12, + "renewal_duration_unit": "months", "notice_time_amount": 30, "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, + "start_date": "2025-01-01", + "billing_due_day": 15, + "installment_amount": 8500, "balance": 8990, "balance_currency": "EUR" } @@ -698,7 +650,7 @@ epilot billing updateContractEntity -p id=123e4567-e89b-12d3-a456-426614174000 - ### `deleteContractEntity` -Delete an existing contract entity. +Delete an existing contract entity (Vertrag). `DELETE /v1/billing/contracts/{id}` @@ -706,32 +658,363 @@ Delete an existing contract entity. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | ID of the contract entity to delete | +| `id` | path | string | Yes | Unique identifier of the contract to delete | **Sample Call** ```bash epilot billing deleteContractEntity \ + -p id=f589786b-3024-43cd-9cb3-5a3c953f2896 +``` + +Using positional args for path parameters: + +```bash +epilot billing deleteContractEntity f589786b-3024-43cd-9cb3-5a3c953f2896 +``` + +With JSONata filter: + +```bash +epilot billing deleteContractEntity -p id=f589786b-3024-43cd-9cb3-5a3c953f2896 --jsonata '$' +``` + +--- + +### `getContractPricingInformation` + +Get current pricing information and recent configuration history for a Contract. + +`GET /v1/billing/contracts/{id}/pricing_information` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | ID of the Contract entity | +| `history_change_types` | query | string | No | Comma-separated billing configuration change types to return. When omitted, installment history is returned by default. | +| `include_history` | query | boolean | No | Include recent configuration history in the pricing information response. Set to false when using the dedicated configuration history endpoint. | + +**Sample Call** + +```bash +epilot billing getContractPricingInformation \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot billing getContractPricingInformation 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot billing getContractPricingInformation -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'entity_type' +``` + +
+Sample Response + +```json +{ + "entity_type": "contract", + "entity_id": "string", + "title": "string", + "current_installment_amount": { + "amount": 10050, + "amount_decimal": "100.50", + "currency": "EUR" + }, + "context": { + "base_price": { + "price_id": "string", + "price_title": "string", + "tariff_type": "string", + "pricing_model": "string", + "unit_amount_gross_decimal": "string", + "unit_amount_net_decimal": "string", + "before_discount_unit_amount_gross_decimal": "string", + "before_discount_unit_amount_net_decimal": "string", + "unit_discount_amount_decimal": "string", + "unit_discount_amount_net_decimal": "string", + "currency": "EUR", + "billing_period": "string", + "unit": "string", + "has_discount": true, + "is_dynamic_tariff": true, + "dynamic_tariff": {} + }, + "base_prices": [ + {} + ], + "working_price": { + "price_id": "string", + "price_title": "string", + "tariff_type": "string", + "pricing_model": "string", + "unit_amount_gross_decimal": "string", + "unit_amount_net_decimal": "string", + "before_discount_unit_amount_gross_decimal": "string", + "before_discount_unit_amount_net_decimal": "string", + "unit_discount_amount_decimal": "string", + "unit_discount_amount_net_decimal": "string", + "currency": "EUR", + "billing_period": "string", + "unit": "string", + "has_discount": true, + "is_dynamic_tariff": true, + "dynamic_tariff": {} + }, + "working_prices": [ + {} + ] + }, + "balance": { + "amount": 8990, + "amount_decimal": "89.90", + "currency": "EUR" + }, + "schedule": { + "billing_due_day": 0, + "billing_period": "weekly", + "installments_per_year": 0, + "inferred": true + }, + "pending_installment_change": true, + "history": [ + { + "event_id": "string", + "org_id": "string", + "entity_type": "contract", + "entity_id": "string", + "schema_version": 1, + "effective_at": "1970-01-01T00:00:00.000Z", + "changed_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "source": "portal", + "source_label": "string", + "source_system": "string", + "source_reference": "string", + "change_type": "installment_amount_changed", + "previous_value": {}, + "new_value": {}, + "context": {} + } + ] +} +``` + +
+ +--- + +### `getBillingAccountPricingInformation` + +Get current pricing information for the active Contracts linked to a Billing Account. + +`GET /v1/billing/billing_accounts/{id}/pricing_information` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | ID of the Billing Account entity | +| `history_change_types` | query | string | No | Comma-separated billing configuration change types to return. When omitted, installment history is returned by default. | +| `include_history` | query | boolean | No | Include recent configuration history in the pricing information response. Set to false when using the dedicated configuration history endpoint. | + +**Sample Call** + +```bash +epilot billing getBillingAccountPricingInformation \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot billing getBillingAccountPricingInformation 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot billing getBillingAccountPricingInformation -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'entity_type' +``` + +
+Sample Response + +```json +{ + "entity_type": "billing_account", + "entity_id": "string", + "title": "string", + "balance": { + "amount": 8990, + "amount_decimal": "89.90", + "currency": "EUR" + }, + "contracts": [ + { + "entity_type": "contract", + "entity_id": "string", + "title": "string", + "current_installment_amount": {}, + "context": {}, + "balance": {}, + "schedule": {}, + "pending_installment_change": true, + "history": [] + } + ] +} +``` + +
+ +--- + +### `getContractConfigurationHistory` + +Get billing configuration history for a Contract. + +`GET /v1/billing/contracts/{id}/configuration_history` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | ID of the Contract entity | +| `change_type` | query | "installment_amount_changed" \| "contract_pricing_changed" | No | Billing configuration change type to return. | +| `history_change_types` | query | string | No | Comma-separated billing configuration change types to return. When omitted, installment history is returned by default. | +| `from` | query | number | No | Initial offset for paginated results. | +| `size` | query | number | No | Maximum number of results to return. | + +**Sample Call** + +```bash +epilot billing getContractConfigurationHistory \ -p id=123e4567-e89b-12d3-a456-426614174000 ``` Using positional args for path parameters: ```bash -epilot billing deleteContractEntity 123e4567-e89b-12d3-a456-426614174000 +epilot billing getContractConfigurationHistory 123e4567-e89b-12d3-a456-426614174000 ``` With JSONata filter: ```bash -epilot billing deleteContractEntity -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot billing getContractConfigurationHistory -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'history' +``` + +
+Sample Response + +```json +{ + "history": [ + { + "event_id": "string", + "org_id": "string", + "entity_type": "contract", + "entity_id": "string", + "schema_version": 1, + "effective_at": "1970-01-01T00:00:00.000Z", + "changed_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "source": "portal", + "source_label": "string", + "source_system": "string", + "source_reference": "string", + "change_type": "installment_amount_changed", + "previous_value": {}, + "new_value": {}, + "context": {} + } + ], + "total": 0 +} ``` +
+ +--- + +### `getBillingAccountConfigurationHistory` + +Get merged billing configuration history for active Contracts linked to a Billing Account. + +`GET /v1/billing/billing_accounts/{id}/configuration_history` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | ID of the Billing Account entity | +| `change_type` | query | "installment_amount_changed" \| "contract_pricing_changed" | No | Billing configuration change type to return. | +| `history_change_types` | query | string | No | Comma-separated billing configuration change types to return. When omitted, installment history is returned by default. | +| `from` | query | number | No | Initial offset for paginated results. | +| `size` | query | number | No | Maximum number of results to return. | + +**Sample Call** + +```bash +epilot billing getBillingAccountConfigurationHistory \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot billing getBillingAccountConfigurationHistory 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot billing getBillingAccountConfigurationHistory -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'history' +``` + +
+Sample Response + +```json +{ + "history": [ + { + "event_id": "string", + "org_id": "string", + "entity_type": "contract", + "entity_id": "string", + "schema_version": 1, + "effective_at": "1970-01-01T00:00:00.000Z", + "changed_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "source": "portal", + "source_label": "string", + "source_system": "string", + "source_reference": "string", + "change_type": "installment_amount_changed", + "previous_value": {}, + "new_value": {}, + "context": {} + } + ], + "total": 0 +} +``` + +
+ --- ### `getCustomerBalance` -Get total balance across all contracts and orders of a customer entity. +Retrieve the total balance (Kontostand) across all contracts and orders for a customer. `GET /v1/billing/customers/{id}/balance` @@ -739,7 +1022,9 @@ Get total balance across all contracts and orders of a customer entity. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | Customer entity ID (contact or account) | +| `id` | path | string | Yes | Customer entity ID. This can be either a contact ID (Kontakt-ID) or +an account ID (Kundenkonto-ID). + | **Sample Call** diff --git a/docs/cli/commands/blueprint-manifest.md b/docs/cli/commands/blueprint-manifest.md index 887ebea7..324b4b05 100644 --- a/docs/cli/commands/blueprint-manifest.md +++ b/docs/cli/commands/blueprint-manifest.md @@ -47,15 +47,19 @@ epilot blueprint-manifest getJob -p job_id=4854bb2a-94f9-424d-a968-3fb17fb0bf89 - [`listBlueprints`](#listblueprints) — List Custom and Installed Blueprints - [`createBlueprint`](#createblueprint) — Create a Blueprint - [`listInstalledMarketplaceBlueprints`](#listinstalledmarketplaceblueprints) — List installed Marketplace Blueprints for the organization. -- [`preInstallBlueprint`](#preinstallblueprint) — Pre-install a Blueprint based on a blueprint file +- [`preInstallBlueprint`](#preinstallblueprint) — Pre-install a Blueprint based on a blueprint file. Format-agnostic: the engine is detected from the uploaded archive, so - [`getBlueprintPreview`](#getblueprintpreview) — Get Blueprint Preview by ID -- [`installBlueprint`](#installblueprint) — Kick off a new blueprint installation job. Returns 202 Accepted with Location header pointing to the job resource - [`getBlueprint`](#getblueprint) — Get Blueprint by ID - [`updateBlueprint`](#updateblueprint) — Update a Blueprint - [`deleteBlueprint`](#deleteblueprint) — Delete a Blueprint -- [`validateBlueprint`](#validateblueprint) — Start a blueprint validation job. Validates Terraform for the blueprint (all types). -- [`exportBlueprint`](#exportblueprint) — Kick off a new blueprint export job. Returns 202 Accepted with Location header pointing to the job resource. +- [`addBlueprintNote`](#addblueprintnote) — Append an internal note to a blueprint. `id`, `created_at` and `created_by` +- [`updateBlueprintNote`](#updateblueprintnote) — Rewrite the text of an existing internal note. The note keeps its position in +- [`deleteBlueprintNote`](#deleteblueprintnote) — Remove a single internal note from a blueprint. +- [`verifyBlueprint`](#verifyblueprint) — Start a blueprint verification job. Compares resource configurations between a source org +- [`listMarketplaceSlugs`](#listmarketplaceslugs) — List all available marketplace blueprint slugs from Webflow CMS. +- [`publishBlueprint`](#publishblueprint) — Publish a blueprint to the marketplace. Exports the blueprint, uploads it to file-api with public access, and updates th - [`formatBlueprintDescription`](#formatblueprintdescription) — Format a blueprint description as markdown using AI. +- [`suggestBlueprintResources`](#suggestblueprintresources) — Suggest resources to add to a blueprint based on a natural-language prompt. - [`addBlueprintResource`](#addblueprintresource) — Add a resource to a Blueprint - [`syncDependencies`](#syncdependencies) — Sync dependencies of all root resources in a Blueprint - [`bulkAddBlueprintResources`](#bulkaddblueprintresources) — Bulk Add resources in a Blueprint @@ -63,13 +67,46 @@ epilot blueprint-manifest getJob -p job_id=4854bb2a-94f9-424d-a968-3fb17fb0bf89 - [`bulkDeleteBlueprintResources`](#bulkdeleteblueprintresources) — Bulk delete resources in a Blueprint - [`updateBlueprintResource`](#updateblueprintresource) — Update a resource in a Blueprint - [`deleteBlueprintResource`](#deleteblueprintresource) — Delete a resource from a Blueprint +- [`publishBlueprintV3`](#publishblueprintv3) — Starts an asynchronous V3 publication. The result is a signed, portable package; poll the existing blueprint job endpoin +- [`preInstallBlueprintV3`](#preinstallblueprintv3) — Validates a signed V3 package and returns the destination-specific resource plan used by the install UI. +- [`installBlueprintV3`](#installblueprintv3) — Install a blueprint into a single destination org using the V3 engine (direct API +- [`restoreBlueprintDeploymentV3`](#restoreblueprintdeploymentv3) — Roll a deployment back to its pre-install state. Two phases: +- [`getRestorePreview`](#getrestorepreview) — Computes what would happen if the user triggered a restore on this +- [`triggerDeploymentHealthCheckV3`](#triggerdeploymenthealthcheckv3) — Starts a read-only health scan of the resources this deployment's +- [`getDeploymentHealthReportV3`](#getdeploymenthealthreportv3) — Returns the most recent health report produced for this deployment +- [`getBlueprintLineageV3`](#getblueprintlineagev3) — Returns the lineage registry entries for a blueprint's resources in the current org. +- [`createBulkInstallV3`](#createbulkinstallv3) — Install one source blueprint into many destination organizations in a single +- [`getBulkInstallV3`](#getbulkinstallv3) — Returns the bulk install parent with aggregate status and counts. Scoped by the +- [`listBulkInstallTargetsV3`](#listbulkinstalltargetsv3) — Pages through the bulk install's target rows. Each row hydrates its latest child +- [`retryBulkInstallTargetV3`](#retrybulkinstalltargetv3) — Retries a single failed target. Allowed only for `FAILED` and `PARTIAL_SUCCESS` **Jobs** - [`listBlueprintJobs`](#listblueprintjobs) — List all blueprint jobs -- [`getBlueprintJob`](#getblueprintjob) — Poll current state of a job. -- [`continueInstallationJob`](#continueinstallationjob) — Continue an installation job if it is waiting for user action. +- [`getBlueprintJob`](#getblueprintjob) — Poll the current state of a job. Serves both Terraform (v2) and V3-engine jobs — +- [`continueInstallationJob`](#continueinstallationjob) — Resume an installation job that is paused at `status: "WAITING_USER_ACTION"` after +- [`retryInstallationJob`](#retryinstallationjob) — Retry a finished V3 installation job whose status is `FAILED` or - [`cancelBlueprintJob`](#cancelblueprintjob) — Cancel a blueprint job if it is still running. +**Marketplace Listings** +- [`getMarketplaceListing`](#getmarketplacelisting) — Get marketplace listing for a blueprint including all versions +- [`createMarketplaceListing`](#createmarketplacelisting) — Create a marketplace listing for a blueprint. Returns 409 if one already exists. +- [`listMarketplaceListings`](#listmarketplacelistings) — List all marketplace listings for the authenticated organization +- [`getMarketplaceListingById`](#getmarketplacelistingbyid) — Get marketplace listing by listing ID including all versions +- [`updateMarketplaceListing`](#updatemarketplacelisting) — Update listing-level fields +- [`deleteMarketplaceListing`](#deletemarketplacelisting) — Delete listing and all versions + +**Marketplace Listing Versions** +- [`listMarketplaceListingVersions`](#listmarketplacelistingversions) — List all versions for a listing, newest first +- [`createMarketplaceListingVersion`](#createmarketplacelistingversion) — Create a draft version; auto-snapshots resources, requiredFeatures, recommendedApps from current blueprint +- [`updateMarketplaceListingVersion`](#updatemarketplacelistingversion) — Update updateNote, requiredFeatures, or recommendedApps on a draft version +- [`publishMarketplaceListingVersion`](#publishmarketplacelistingversion) — Publish a draft version; archives the previous live version + +**Uniqueness Criteria** +- [`listUniquenessCriteria`](#listuniquenesscriteria) — List all custom uniqueness criteria configured for the caller's organization. +- [`getUniquenessCriteria`](#getuniquenesscriteria) — Get the configured uniqueness criteria for a specific resource type, if any. +- [`putUniquenessCriteria`](#putuniquenesscriteria) — Set or replace the uniqueness criteria for a resource type. The provided fields +- [`deleteUniquenessCriteria`](#deleteuniquenesscriteria) — Remove the custom criteria for a resource type, reverting to the default fields. + ### `uploadManifest` Create pre-signed S3 URL to upload a manifest file. @@ -149,64 +186,29 @@ epilot blueprint-manifest listBlueprints --jsonata 'results[0]' "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "title": "string", "slug": "string", - "description": { - "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", - "postinstall": "This is the content of the postinstall.md file\n" - }, + "description": {}, + "notes": [], "version": "string", - "deployments": [ - { - "source_org_id": "string", - "source_blueprint_id": "string", - "destination_org_id": "string", - "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" - } - ], + "deployments": [], "is_verified": true, + "latest_verification": {}, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", - "created_by": { - "name": "manifest@epilot.cloud", - "org_id": "911690", - "user_id": "11001045", - "token_id": "api_5ZugdRXasLfWBypHi93Fk" - }, - "updated_by": { - "name": "manifest@epilot.cloud", - "org_id": "911690", - "user_id": "11001045", - "token_id": "api_5ZugdRXasLfWBypHi93Fk" - }, + "created_by": {}, + "updated_by": {}, "installation_job_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "archived": false, "docs_url": "string", "recommended_apps": ["string"], - "required_features": { - "enabled": ["string"], - "disabled": ["string"] - }, + "required_features": {}, "zip_file_name": "string", - "resources": [ - { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] - } - ], - "source_type": "string" + "resources": [], + "source_type": "custom" } ] } @@ -242,6 +244,15 @@ epilot blueprint-manifest createBlueprint \ "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -249,11 +260,40 @@ epilot blueprint-manifest createBlueprint \ "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -295,7 +335,7 @@ epilot blueprint-manifest createBlueprint \ "impact_on_install_reason": ["string"] } ], - "source_type": "string" + "source_type": "custom" }' ``` @@ -323,6 +363,15 @@ epilot blueprint-manifest createBlueprint --jsonata '$' "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -330,11 +379,40 @@ epilot blueprint-manifest createBlueprint --jsonata '$' "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -376,7 +454,7 @@ epilot blueprint-manifest createBlueprint --jsonata '$' "impact_on_install_reason": ["string"] } ], - "source_type": "string" + "source_type": "custom" } ``` @@ -441,7 +519,7 @@ epilot blueprint-manifest listInstalledMarketplaceBlueprints --jsonata 'results[ ### `preInstallBlueprint` -Pre-install a Blueprint based on a blueprint file +Pre-install a Blueprint based on a blueprint file. Format-agnostic: the engine is detected from the uploaded archive, so `POST /v2/blueprint-manifest/blueprints:pre-install` @@ -480,10 +558,15 @@ epilot blueprint-manifest preInstallBlueprint --jsonata 'id' "version": "string", "slug": "string", "source_type": "marketplace", + "sync_engine": "terraform", "blueprint_file_s3_key": "string", "is_verified": true, "docs_url": "string", "recommended_apps": ["string"], + "required_features": { + "enabled": ["string"], + "disabled": ["string"] + }, "created_at": "1970-01-01T00:00:00.000Z", "created_by": { "name": "manifest@epilot.cloud", @@ -561,10 +644,15 @@ epilot blueprint-manifest getBlueprintPreview -p preview_id=123e4567-e89b-12d3-a "version": "string", "slug": "string", "source_type": "marketplace", + "sync_engine": "terraform", "blueprint_file_s3_key": "string", "is_verified": true, "docs_url": "string", "recommended_apps": ["string"], + "required_features": { + "enabled": ["string"], + "disabled": ["string"] + }, "created_at": "1970-01-01T00:00:00.000Z", "created_by": { "name": "manifest@epilot.cloud", @@ -597,53 +685,6 @@ epilot blueprint-manifest getBlueprintPreview -p preview_id=123e4567-e89b-12d3-a --- -### `installBlueprint` - -Kick off a new blueprint installation job. Returns 202 Accepted with Location header pointing to the job resource - -`POST /v2/blueprint-manifest/blueprint:install` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot blueprint-manifest installBlueprint -``` - -With request body: - -```bash -epilot blueprint-manifest installBlueprint \ - -d '{ - "source_org_id": "string", - "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "source_blueprint_file": "string", - "destination_org_id": "string", - "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "options": { - "resources_to_ignore": ["string"] - }, - "mode": "simple", - "source_blueprint_type": "marketplace", - "slug": "string" -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot blueprint-manifest installBlueprint -``` - -With JSONata filter: - -```bash -epilot blueprint-manifest installBlueprint --jsonata '$' -``` - ---- - ### `getBlueprint` Get Blueprint by ID @@ -687,6 +728,15 @@ epilot blueprint-manifest getBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1 "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -694,11 +744,40 @@ epilot blueprint-manifest getBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1 "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -740,7 +819,7 @@ epilot blueprint-manifest getBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1 "impact_on_install_reason": ["string"] } ], - "source_type": "string" + "source_type": "custom" } ``` @@ -782,6 +861,15 @@ epilot blueprint-manifest updateBlueprint \ "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -789,11 +877,40 @@ epilot blueprint-manifest updateBlueprint \ "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -835,7 +952,7 @@ epilot blueprint-manifest updateBlueprint \ "impact_on_install_reason": ["string"] } ], - "source_type": "string" + "source_type": "custom" }' ``` @@ -869,6 +986,15 @@ epilot blueprint-manifest updateBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6 "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -876,11 +1002,40 @@ epilot blueprint-manifest updateBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6 "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -922,7 +1077,7 @@ epilot blueprint-manifest updateBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6 "impact_on_install_reason": ["string"] } ], - "source_type": "string" + "source_type": "custom" } ``` @@ -973,6 +1128,15 @@ epilot blueprint-manifest deleteBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6 "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -980,11 +1144,40 @@ epilot blueprint-manifest deleteBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6 "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -1026,7 +1219,7 @@ epilot blueprint-manifest deleteBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6 "impact_on_install_reason": ["string"] } ], - "source_type": "string" + "source_type": "custom" } ``` @@ -1034,11 +1227,11 @@ epilot blueprint-manifest deleteBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6 --- -### `validateBlueprint` +### `addBlueprintNote` -Start a blueprint validation job. Validates Terraform for the blueprint (all types). +Append an internal note to a blueprint. `id`, `created_at` and `created_by` -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/validate` +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/notes` **Parameters** @@ -1046,107 +1239,151 @@ Start a blueprint validation job. Validates Terraform for the blueprint (all typ | ---- | -- | ---- | -------- | ----------- | | `blueprint_id` | path | string | Yes | | +**Request Body** (required) + **Sample Call** ```bash -epilot blueprint-manifest validateBlueprint \ - -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +epilot blueprint-manifest addBlueprintNote \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -d '{"text":"string"}' ``` Using positional args for path parameters: ```bash -epilot blueprint-manifest validateBlueprint c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +epilot blueprint-manifest addBlueprintNote c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest addBlueprintNote -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 ``` With JSONata filter: ```bash -epilot blueprint-manifest validateBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' +epilot blueprint-manifest addBlueprintNote -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + } +} ``` +
+ --- -### `exportBlueprint` +### `updateBlueprintNote` -Kick off a new blueprint export job. Returns 202 Accepted with Location header pointing to the job resource. +Rewrite the text of an existing internal note. The note keeps its position in -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}:export` +`PATCH /v2/blueprint-manifest/blueprints/{blueprint_id}/notes/{note_id}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `blueprint_id` | path | string | Yes | | +| `note_id` | path | string | Yes | | -**Request Body** +**Request Body** (required) **Sample Call** ```bash -epilot blueprint-manifest exportBlueprint \ +epilot blueprint-manifest updateBlueprintNote \ -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ - -d '{"destination_org_id":"string","destination_blueprint_id":"string","validate":true}' + -p note_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"text":"string"}' ``` Using positional args for path parameters: ```bash -epilot blueprint-manifest exportBlueprint c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +epilot blueprint-manifest updateBlueprintNote c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 123e4567-e89b-12d3-a456-426614174000 ``` Using stdin pipe: ```bash -cat body.json | epilot blueprint-manifest exportBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +cat body.json | epilot blueprint-manifest updateBlueprintNote -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -p note_id=123e4567-e89b-12d3-a456-426614174000 ``` With JSONata filter: ```bash -epilot blueprint-manifest exportBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' +epilot blueprint-manifest updateBlueprintNote -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -p note_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + } +} ``` +
+ --- -### `formatBlueprintDescription` +### `deleteBlueprintNote` -Format a blueprint description as markdown using AI. +Remove a single internal note from a blueprint. -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}:format-description` +`DELETE /v2/blueprint-manifest/blueprints/{blueprint_id}/notes/{note_id}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `blueprint_id` | path | string | Yes | | - -**Request Body** (required) +| `note_id` | path | string | Yes | | **Sample Call** ```bash -epilot blueprint-manifest formatBlueprintDescription \ +epilot blueprint-manifest deleteBlueprintNote \ -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ - -d '{"text":"string"}' + -p note_id=123e4567-e89b-12d3-a456-426614174000 ``` Using positional args for path parameters: ```bash -epilot blueprint-manifest formatBlueprintDescription c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot blueprint-manifest formatBlueprintDescription -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +epilot blueprint-manifest deleteBlueprintNote c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 123e4567-e89b-12d3-a456-426614174000 ``` With JSONata filter: ```bash -epilot blueprint-manifest formatBlueprintDescription -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata 'markdown' +epilot blueprint-manifest deleteBlueprintNote -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -p note_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'notes' ```
@@ -1154,7 +1391,20 @@ epilot blueprint-manifest formatBlueprintDescription -p blueprint_id=c2d6cac8-bd ```json { - "markdown": "string" + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + } + } + ] } ``` @@ -1162,66 +1412,80 @@ epilot blueprint-manifest formatBlueprintDescription -p blueprint_id=c2d6cac8-bd --- -### `addBlueprintResource` +### `verifyBlueprint` -Add a resource to a Blueprint +Start a blueprint verification job. Compares resource configurations between a source org -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/resources` +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}:verify` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `blueprint_id` | path | string | Yes | | -| `add_dependencies` | query | boolean | No | | -**Request Body** +**Request Body** (required) **Sample Call** ```bash -epilot blueprint-manifest addBlueprintResource \ +epilot blueprint-manifest verifyBlueprint \ -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 ``` With request body: ```bash -epilot blueprint-manifest addBlueprintResource \ +epilot blueprint-manifest verifyBlueprint \ -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ -d '{ - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "source_auth_token": "string", + "destination_auth_token": "string", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform" }' ``` Using positional args for path parameters: ```bash -epilot blueprint-manifest addBlueprintResource c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +epilot blueprint-manifest verifyBlueprint c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 ``` Using stdin pipe: ```bash -cat body.json | epilot blueprint-manifest addBlueprintResource -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +cat body.json | epilot blueprint-manifest verifyBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 ``` With JSONata filter: ```bash -epilot blueprint-manifest addBlueprintResource -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata 'resources' +epilot blueprint-manifest verifyBlueprint -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' +``` + +--- + +### `listMarketplaceSlugs` + +List all available marketplace blueprint slugs from Webflow CMS. + +`GET /v2/blueprint-manifest/marketplace/slugs` + +**Sample Call** + +```bash +epilot blueprint-manifest listMarketplaceSlugs +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest listMarketplaceSlugs --jsonata 'results[0]' ```
@@ -1229,21 +1493,13 @@ epilot blueprint-manifest addBlueprintResource -p blueprint_id=c2d6cac8-bdd5-4ea ```json { - "resources": [ + "results": [ { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "slug": "wallbox_b2c", + "marketplace_slug": "wallbox-b2c", + "version": "v1.0.0", + "name": "Wallbox B2C", + "installation_link": "https://portal.epilot.cloud/app/blueprints/install/marketplace/wallbox_b2c?s3Ref=https://example.com/blueprint.zip" } ] } @@ -1253,6 +1509,265 @@ epilot blueprint-manifest addBlueprintResource -p blueprint_id=c2d6cac8-bdd5-4ea --- +### `publishBlueprint` + +Publish a blueprint to the marketplace. Exports the blueprint, uploads it to file-api with public access, and updates th + +`POST /v2/blueprint-manifest/blueprints:publish` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest publishBlueprint \ + -d '{"blueprint_id":"c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341","slug":"string","version":"string","name":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest publishBlueprint +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest publishBlueprint --jsonata '$' +``` + +--- + +### `formatBlueprintDescription` + +Format a blueprint description as markdown using AI. + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}:format-description` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest formatBlueprintDescription \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -d '{"text":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest formatBlueprintDescription c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest formatBlueprintDescription -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest formatBlueprintDescription -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata 'markdown' +``` + +
+Sample Response + +```json +{ + "markdown": "string" +} +``` + +
+ +--- + +### `suggestBlueprintResources` + +Suggest resources to add to a blueprint based on a natural-language prompt. + +`POST /v2/blueprint-manifest/blueprints:suggest-resources` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest suggestBlueprintResources \ + -d '{"prompt":"everything for the hausanschluss use case","blueprint_id":"c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest suggestBlueprintResources +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest suggestBlueprintResources --jsonata 'resources' +``` + +
+Sample Response + +```json +{ + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"] + } + ], + "suggested_blueprint_name": "Hausanschluss", + "explanation": "string", + "add_dependencies_recommended": true +} +``` + +
+ +--- + +### `addBlueprintResource` + +Add a resource to a Blueprint + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/resources` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | +| `add_dependencies` | query | boolean | No | | + +**Request Body** + +**Sample Call** + +```bash +epilot blueprint-manifest addBlueprintResource \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With request body: + +```bash +epilot blueprint-manifest addBlueprintResource \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -d '{ + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"] +}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest addBlueprintResource c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest addBlueprintResource -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest addBlueprintResource -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata 'resources' +``` + +
+Sample Response + +```json +{ + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"] + } + ], + "skipped": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "type": "designbuilder", + "reason": "not_found" + } + ], + "errors": [ + { + "error": "string", + "code": "dependency_extraction", + "data": { + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string" + } + } + ], + "total_errors": 0, + "errors_truncated": true +} +``` + +
+ +--- + ### `syncDependencies` Sync dependencies of all root resources in a Blueprint @@ -1264,6 +1779,10 @@ Sync dependencies of all root resources in a Blueprint | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `blueprint_id` | path | string | Yes | | +| `trigger` | query | "manual" \| "pre_sync" \| "post_revert" | No | What initiated the sync. Automated triggers (`pre_sync`, +`post_revert`) are side effects of an operation the activity +feed already shows on its own row, so they are excluded from +the audit log — same | **Sample Call** @@ -1371,7 +1890,34 @@ epilot blueprint-manifest bulkAddBlueprintResources -p blueprint_id=c2d6cac8-bdd "impact_on_install": ["create"], "impact_on_install_reason": ["string"] } - ] + ], + "skipped": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "type": "designbuilder", + "reason": "not_found" + } + ], + "errors": [ + { + "error": "string", + "code": "dependency_extraction", + "data": { + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string" + } + } + ], + "total_errors": 0, + "errors_truncated": true } ``` @@ -1759,6 +2305,7 @@ epilot blueprint-manifest listBlueprintJobs --jsonata 'results[0]' "user_id": "11001045", "token_id": "api_5ZugdRXasLfWBypHi93Fk" }, + "job_type": "export", "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "status": "IN_PROGRESS", "download_file": { @@ -1776,7 +2323,7 @@ epilot blueprint-manifest listBlueprintJobs --jsonata 'results[0]' ### `getBlueprintJob` -Poll current state of a job. +Poll the current state of a job. Serves both Terraform (v2) and V3-engine jobs — `GET /v2/blueprint-manifest/jobs/{job_id}` @@ -1848,6 +2395,7 @@ epilot blueprint-manifest getBlueprintJob -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbd "user_id": "11001045", "token_id": "api_5ZugdRXasLfWBypHi93Fk" }, + "job_type": "export", "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "status": "IN_PROGRESS", "download_file": { @@ -1863,7 +2411,7 @@ epilot blueprint-manifest getBlueprintJob -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbd ### `continueInstallationJob` -Continue an installation job if it is waiting for user action. +Resume an installation job that is paused at `status: "WAITING_USER_ACTION"` after `POST /v2/blueprint-manifest/jobs/{job_id}:continue` @@ -1880,7 +2428,7 @@ Continue an installation job if it is waiting for user action. ```bash epilot blueprint-manifest continueInstallationJob \ -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ - -d '{"resources_to_ignore":["string"]}' + -d '{"resources_to_ignore":["string"],"sync_notes":false,"source_auth_token":"string"}' ``` Using positional args for path parameters: @@ -1944,6 +2492,7 @@ epilot blueprint-manifest continueInstallationJob -p job_id=c2d6cac8-bdd5-4ea2-8 "user_id": "11001045", "token_id": "api_5ZugdRXasLfWBypHi93Fk" }, + "job_type": "install", "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "source_blueprint_type": "custom", "source_org_id": "string", @@ -1951,6 +2500,24 @@ epilot blueprint-manifest continueInstallationJob -p job_id=c2d6cac8-bdd5-4ea2-8 "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "destination_org_id": "string", "slug": "string", + "sync_engine": "terraform", + "resource_progress": [ + { + "lineage_id": "string", + "type": "string", + "address": "string", + "name": "string", + "status": "pending", + "target_id": "string", + "error_message": "string", + "error_code": "string", + "error_data": {} + } + ], + "options": { + "resources_to_ignore": ["string"], + "sync_notes": false + }, "status": "IN_PROGRESS" } ``` @@ -1959,11 +2526,11 @@ epilot blueprint-manifest continueInstallationJob -p job_id=c2d6cac8-bdd5-4ea2-8 --- -### `cancelBlueprintJob` +### `retryInstallationJob` -Cancel a blueprint job if it is still running. +Retry a finished V3 installation job whose status is `FAILED` or -`POST /v2/blueprint-manifest/jobs/{job_id}:cancel` +`POST /v2/blueprint-manifest/jobs/{job_id}:retry` **Parameters** @@ -1974,26 +2541,59 @@ Cancel a blueprint job if it is still running. **Sample Call** ```bash -epilot blueprint-manifest cancelBlueprintJob \ +epilot blueprint-manifest retryInstallationJob \ -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 ``` Using positional args for path parameters: ```bash -epilot blueprint-manifest cancelBlueprintJob c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +epilot blueprint-manifest retryInstallationJob c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 ``` With JSONata filter: ```bash -epilot blueprint-manifest cancelBlueprintJob -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' +epilot blueprint-manifest retryInstallationJob -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' ``` -
-Sample Response +--- -```json +### `cancelBlueprintJob` + +Cancel a blueprint job if it is still running. + +`POST /v2/blueprint-manifest/jobs/{job_id}:cancel` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `job_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest cancelBlueprintJob \ + -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest cancelBlueprintJob c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest cancelBlueprintJob -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' +``` + +
+Sample Response + +```json { "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "events": [ @@ -2033,6 +2633,7 @@ epilot blueprint-manifest cancelBlueprintJob -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1 "user_id": "11001045", "token_id": "api_5ZugdRXasLfWBypHi93Fk" }, + "job_type": "export", "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "status": "IN_PROGRESS", "download_file": { @@ -2045,3 +2646,1733 @@ epilot blueprint-manifest cancelBlueprintJob -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1
--- + +### `getMarketplaceListing` + +Get marketplace listing for a blueprint including all versions + +`GET /v1/blueprints/{blueprint_id}/marketplace-listing` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest getMarketplaceListing \ + -p blueprint_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest getMarketplaceListing 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest getMarketplaceListing -p blueprint_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "versions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" + } + ], + "has_publishable_draft": true +} +``` + +
+ +--- + +### `createMarketplaceListing` + +Create a marketplace listing for a blueprint. Returns 409 if one already exists. + +`POST /v1/blueprints/{blueprint_id}/marketplace-listing` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest createMarketplaceListing \ + -p blueprint_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"name":"string","slug":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest createMarketplaceListing 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest createMarketplaceListing -p blueprint_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest createMarketplaceListing -p blueprint_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listMarketplaceListings` + +List all marketplace listings for the authenticated organization + +`GET /v1/marketplace-listings` + +**Sample Call** + +```bash +epilot blueprint-manifest listMarketplaceListings +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest listMarketplaceListings --jsonata 'listings' +``` + +
+Sample Response + +```json +{ + "listings": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `getMarketplaceListingById` + +Get marketplace listing by listing ID including all versions + +`GET /v1/marketplace-listings/{listing_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `listing_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest getMarketplaceListingById \ + -p listing_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest getMarketplaceListingById 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest getMarketplaceListingById -p listing_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "versions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" + } + ], + "has_publishable_draft": true +} +``` + +
+ +--- + +### `updateMarketplaceListing` + +Update listing-level fields + +`PATCH /v1/marketplace-listings/{listing_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `listing_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest updateMarketplaceListing \ + -p listing_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot blueprint-manifest updateMarketplaceListing \ + -p listing_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"] +}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest updateMarketplaceListing 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest updateMarketplaceListing -p listing_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest updateMarketplaceListing -p listing_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteMarketplaceListing` + +Delete listing and all versions + +`DELETE /v1/marketplace-listings/{listing_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `listing_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest deleteMarketplaceListing \ + -p listing_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest deleteMarketplaceListing 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest deleteMarketplaceListing -p listing_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `listMarketplaceListingVersions` + +List all versions for a listing, newest first + +`GET /v1/marketplace-listings/{listing_id}/versions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `listing_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest listMarketplaceListingVersions \ + -p listing_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest listMarketplaceListingVersions 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest listMarketplaceListingVersions -p listing_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'versions' +``` + +
+Sample Response + +```json +{ + "versions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `createMarketplaceListingVersion` + +Create a draft version; auto-snapshots resources, requiredFeatures, recommendedApps from current blueprint + +`POST /v1/marketplace-listings/{listing_id}/versions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `listing_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest createMarketplaceListingVersion \ + -p listing_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest createMarketplaceListingVersion 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest createMarketplaceListingVersion -p listing_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateMarketplaceListingVersion` + +Update updateNote, requiredFeatures, or recommendedApps on a draft version + +`PATCH /v1/marketplace-listings/{listing_id}/versions/{version_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `listing_id` | path | string | Yes | | +| `version_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest updateMarketplaceListingVersion \ + -p listing_id=123e4567-e89b-12d3-a456-426614174000 \ + -p version_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"update_note":"string","required_features":["string"],"recommended_apps":["string"]}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest updateMarketplaceListingVersion 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest updateMarketplaceListingVersion -p listing_id=123e4567-e89b-12d3-a456-426614174000 -p version_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest updateMarketplaceListingVersion -p listing_id=123e4567-e89b-12d3-a456-426614174000 -p version_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `publishMarketplaceListingVersion` + +Publish a draft version; archives the previous live version + +`POST /v1/marketplace-listings/{listing_id}/versions/{version_id}/publish` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `listing_id` | path | string | Yes | | +| `version_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest publishMarketplaceListingVersion \ + -p listing_id=123e4567-e89b-12d3-a456-426614174000 \ + -p version_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"version_name":"string","update_note":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest publishMarketplaceListingVersion 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest publishMarketplaceListingVersion -p listing_id=123e4567-e89b-12d3-a456-426614174000 -p version_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest publishMarketplaceListingVersion -p listing_id=123e4567-e89b-12d3-a456-426614174000 -p version_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `publishBlueprintV3` + +Starts an asynchronous V3 publication. The result is a signed, portable package; poll the existing blueprint job endpoin + +`POST /v3/blueprint-manifest/blueprints/{blueprint_id}:publish` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot blueprint-manifest publishBlueprintV3 \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -d '{"publish_to_marketplace":false}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest publishBlueprintV3 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest publishBlueprintV3 -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest publishBlueprintV3 -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' +``` + +--- + +### `preInstallBlueprintV3` + +Validates a signed V3 package and returns the destination-specific resource plan used by the install UI. + +`POST /v3/blueprint-manifest/blueprints:pre-install` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest preInstallBlueprintV3 \ + -d '{"blueprint_file":"string","source_blueprint_type":"marketplace","slug":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest preInstallBlueprintV3 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest preInstallBlueprintV3 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "org_id": "string", + "title": "string", + "description": { + "preinstall": "string" + }, + "version": "string", + "slug": "string", + "source_type": "marketplace", + "sync_engine": "terraform", + "blueprint_file_s3_key": "string", + "is_verified": true, + "docs_url": "string", + "recommended_apps": ["string"], + "required_features": { + "enabled": ["string"], + "disabled": ["string"] + }, + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "is_updating": true, + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"] + } + ] +} +``` + +
+ +--- + +### `installBlueprintV3` + +Install a blueprint into a single destination org using the V3 engine (direct API + +`POST /v3/blueprint-manifest/blueprint:install` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest installBlueprintV3 \ + -d '{}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest installBlueprintV3 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest installBlueprintV3 --jsonata '$' +``` + +--- + +### `restoreBlueprintDeploymentV3` + +Roll a deployment back to its pre-install state. Two phases: + +`POST /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}:restore` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | +| `job_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest restoreBlueprintDeploymentV3 \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest restoreBlueprintDeploymentV3 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest restoreBlueprintDeploymentV3 -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' +``` + +--- + +### `getRestorePreview` + +Computes what would happen if the user triggered a restore on this + +`GET /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}/restore-preview` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | +| `job_id` | path | string | Yes | The install job whose deployment is being previewed. | + +**Sample Call** + +```bash +epilot blueprint-manifest getRestorePreview \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest getRestorePreview c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest getRestorePreview -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata 'snapshot_id' +``` + +
+Sample Response + +```json +{ + "snapshot_id": "string", + "resources": [ + { + "lineage_id": "string", + "type": "string", + "name": "string", + "target_id": "string", + "action": "restore", + "reason": "modified", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "current_updated_at": "1970-01-01T00:00:00.000Z", + "error_message": "string", + "is_hidden": true, + "co_owned_by": [ + { + "blueprint_id": "string", + "title": "string" + } + ], + "protected_by": [ + { + "lineage_id": "string", + "type": "string", + "target_id": "string" + } + ] + } + ], + "has_effective_changes": true +} +``` + +
+ +--- + +### `triggerDeploymentHealthCheckV3` + +Starts a read-only health scan of the resources this deployment's + +`POST /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}:health-check` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | +| `job_id` | path | string | Yes | The install job whose deployment is being checked. | + +**Request Body** + +**Sample Call** + +```bash +epilot blueprint-manifest triggerDeploymentHealthCheckV3 \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -d '{"source_org_id":"string","source_auth_token":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest triggerDeploymentHealthCheckV3 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest triggerDeploymentHealthCheckV3 -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest triggerDeploymentHealthCheckV3 -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata '$' +``` + +--- + +### `getDeploymentHealthReportV3` + +Returns the most recent health report produced for this deployment + +`GET /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}/health-report` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | +| `job_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest getDeploymentHealthReportV3 \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 \ + -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest getDeploymentHealthReportV3 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest getDeploymentHealthReportV3 -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 -p job_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "running", + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "blueprint_instance_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "generated_at": "1970-01-01T00:00:00.000Z", + "html_url": "string", + "summary": { + "resources_scanned": 0, + "unchecked": 0, + "errors": 0, + "warnings": 0, + "infos": 0 + }, + "findings": [ + { + "check_id": "live_readability", + "code": "missing_in_destination", + "severity": "error", + "resource_type": "string", + "lineage_id": "string", + "target_id": "string", + "resource_name": "string", + "message": "string", + "verdict": "string", + "evidence": { + "path": "string", + "referenced_id": "string", + "referenced_type": "string", + "referenced_name": "string", + "referenced_lineage_id": "string", + "expected_target_id": "string", + "reference_kind": "string", + "operation": "string", + "rejection_reason": "string", + "error_message": "string", + "response_status": 0 + } + } + ], + "coverage": { + "checks": [ + { + "check_id": "live_readability", + "status": "completed", + "scope": "tracked_resources", + "resources_considered": 0, + "details": ["string"] + } + ], + "resource_types": [ + { + "resource_type": "string", + "tracked": 0, + "readable_by_lineage": 0, + "missing_by_lineage": 0, + "read_errors": 0, + "unchecked": 0, + "specialized_checks": ["live_readability"], + "known_blind_spots": ["string"] + } + ] + }, + "error": "string" +} +``` + +
+ +--- + +### `getBlueprintLineageV3` + +Returns the lineage registry entries for a blueprint's resources in the current org. + +`GET /v3/blueprint-manifest/blueprints/{blueprint_id}/lineage` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `blueprint_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest getBlueprintLineageV3 \ + -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest getBlueprintLineageV3 c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest getBlueprintLineageV3 -p blueprint_id=c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341 --jsonata 'total' +``` + +
+Sample Response + +```json +{ + "total": 0, + "entries": [ + { + "lineage_id": "string", + "target_id": "string", + "resource_type": "designbuilder", + "blueprint_instance_ids": ["string"], + "fidelity": "full", + "last_synced_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `createBulkInstallV3` + +Install one source blueprint into many destination organizations in a single + +`POST /v3/blueprint-manifest/bulk-installs` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest createBulkInstallV3 +``` + +With request body: + +```bash +epilot blueprint-manifest createBulkInstallV3 \ + -d '{ + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "max_concurrency": 2, + "slug": "string", + "options": { + "resources_to_ignore": ["string"], + "sync_notes": false + }, + "targets": [ + { + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_auth_token": "string" + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest createBulkInstallV3 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest createBulkInstallV3 --jsonata '$' +``` + +--- + +### `getBulkInstallV3` + +Returns the bulk install parent with aggregate status and counts. Scoped by the + +`GET /v3/blueprint-manifest/bulk-installs/{bulk_job_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `bulk_job_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest getBulkInstallV3 \ + -p bulk_job_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest getBulkInstallV3 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest getBulkInstallV3 -p bulk_job_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'bulk_job_id' +``` + +
+Sample Response + +```json +{ + "bulk_job_id": "string", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "QUEUED", + "target_count": 0, + "max_concurrency": 0, + "counts": { + "queued": 0, + "in_progress": 0, + "success": 0, + "partial_success": 0, + "failed": 0 + }, + "slug": "string", + "options": { + "resources_to_ignore": ["string"], + "sync_notes": false + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listBulkInstallTargetsV3` + +Pages through the bulk install's target rows. Each row hydrates its latest child + +`GET /v3/blueprint-manifest/bulk-installs/{bulk_job_id}/targets` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `bulk_job_id` | path | string | Yes | | +| `limit` | query | number | No | | +| `cursor` | query | string | No | | + +**Sample Call** + +```bash +epilot blueprint-manifest listBulkInstallTargetsV3 \ + -p bulk_job_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest listBulkInstallTargetsV3 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest listBulkInstallTargetsV3 -p bulk_job_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "bulk_job_id": "string", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "QUEUED", + "job_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "job": {} + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `retryBulkInstallTargetV3` + +Retries a single failed target. Allowed only for `FAILED` and `PARTIAL_SUCCESS` + +`POST /v3/blueprint-manifest/bulk-installs/{bulk_job_id}/targets/{destination_org_id}:retry` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `bulk_job_id` | path | string | Yes | | +| `destination_org_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest retryBulkInstallTargetV3 \ + -p bulk_job_id=123e4567-e89b-12d3-a456-426614174000 \ + -p destination_org_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"destination_auth_token":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest retryBulkInstallTargetV3 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest retryBulkInstallTargetV3 -p bulk_job_id=123e4567-e89b-12d3-a456-426614174000 -p destination_org_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest retryBulkInstallTargetV3 -p bulk_job_id=123e4567-e89b-12d3-a456-426614174000 -p destination_org_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'bulk_job_id' +``` + +
+Sample Response + +```json +{ + "bulk_job_id": "string", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "QUEUED", + "job_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "job": { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "events": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "message": "string", + "errors": [ + { + "error": "string", + "code": "dependency_extraction", + "data": { + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string" + } + } + ], + "level": "info", + "data": { + "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "resources": 0 + } + } + ], + "triggered_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "job_type": "install", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "source_blueprint_type": "custom", + "source_org_id": "string", + "source_blueprint_file": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "slug": "string", + "sync_engine": "terraform", + "resource_progress": [ + { + "lineage_id": "string", + "type": "string", + "address": "string", + "name": "string", + "status": "pending", + "target_id": "string", + "error_message": "string", + "error_code": "string", + "error_data": {} + } + ], + "options": { + "resources_to_ignore": ["string"], + "sync_notes": false + }, + "status": "IN_PROGRESS" + } +} +``` + +
+ +--- + +### `listUniquenessCriteria` + +List all custom uniqueness criteria configured for the caller's organization. + +`GET /v1/blueprint-manifest/uniqueness-criteria` + +**Sample Call** + +```bash +epilot blueprint-manifest listUniquenessCriteria +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest listUniquenessCriteria --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "org_id": "string", + "resource_type": "emailtemplate", + "fields": ["string"], + "propagated_to": ["string"], + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string" + } + ], + "defaults": {}, + "readonly_types": ["string"] +} +``` + +
+ +--- + +### `getUniquenessCriteria` + +Get the configured uniqueness criteria for a specific resource type, if any. + +`GET /v1/blueprint-manifest/uniqueness-criteria/{resource_type}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `resource_type` | path | "emailtemplate" \| "product" \| "price" \| "tax" \| "coupon" \| "product_recommendation" \| "file" \| "document_template" \| "notification_template" \| "journey" | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest getUniquenessCriteria \ + -p resource_type=example +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest getUniquenessCriteria example +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest getUniquenessCriteria -p resource_type=example --jsonata 'org_id' +``` + +
+Sample Response + +```json +{ + "org_id": "string", + "resource_type": "emailtemplate", + "fields": ["string"], + "propagated_to": ["string"], + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string" +} +``` + +
+ +--- + +### `putUniquenessCriteria` + +Set or replace the uniqueness criteria for a resource type. The provided fields + +`PUT /v1/blueprint-manifest/uniqueness-criteria/{resource_type}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `resource_type` | path | "emailtemplate" \| "product" \| "price" \| "tax" \| "coupon" \| "product_recommendation" \| "file" \| "document_template" \| "notification_template" \| "journey" | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot blueprint-manifest putUniquenessCriteria \ + -p resource_type=example \ + -d '{"fields":["string"],"propagated_to":["string"]}' +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest putUniquenessCriteria example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot blueprint-manifest putUniquenessCriteria -p resource_type=example +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest putUniquenessCriteria -p resource_type=example --jsonata 'org_id' +``` + +
+Sample Response + +```json +{ + "org_id": "string", + "resource_type": "emailtemplate", + "fields": ["string"], + "propagated_to": ["string"], + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string" +} +``` + +
+ +--- + +### `deleteUniquenessCriteria` + +Remove the custom criteria for a resource type, reverting to the default fields. + +`DELETE /v1/blueprint-manifest/uniqueness-criteria/{resource_type}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `resource_type` | path | "emailtemplate" \| "product" \| "price" \| "tax" \| "coupon" \| "product_recommendation" \| "file" \| "document_template" \| "notification_template" \| "journey" | Yes | | + +**Sample Call** + +```bash +epilot blueprint-manifest deleteUniquenessCriteria \ + -p resource_type=example +``` + +Using positional args for path parameters: + +```bash +epilot blueprint-manifest deleteUniquenessCriteria example +``` + +With JSONata filter: + +```bash +epilot blueprint-manifest deleteUniquenessCriteria -p resource_type=example --jsonata '$' +``` + +--- diff --git a/docs/cli/commands/calendar.md b/docs/cli/commands/calendar.md new file mode 100644 index 00000000..8fa375a7 --- /dev/null +++ b/docs/cli/commands/calendar.md @@ -0,0 +1,1848 @@ +--- +title: "Calendar API" +description: "epilot CLI commands for the Calendar API: quick start, common flags and every operation, callable from the command line." +--- + +# Calendar API + +- **Base URL:** `https://calendar.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/calendar](https://docs.epilot.io/api/calendar) + +epilot's calendar API. + +## Quick Start + +```bash +# List available operations +epilot calendar + +# Call an operation +epilot calendar listUsersAbsence -p from=example -p to=example +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Absence** +- [`listUsersAbsence`](#listusersabsence) — List organization users with known absence metadata in the requested time window. +- [`searchAbsence`](#searchabsence) — Search known absence for candidate users in the requested time window. +- [`searchNowAbsence`](#searchnowabsence) — Search known absence for candidate users at the current server time. +- [`listAbsenceAdjustments`](#listabsenceadjustments) — List absence adjustments for a user in a time window. +- [`createAbsenceAdjustment`](#createabsenceadjustment) — Create a time-bound absence adjustment for a user in the caller organization. +- [`getAbsenceAdjustment`](#getabsenceadjustment) — Get an absence adjustment by ID. +- [`patchAbsenceAdjustment`](#patchabsenceadjustment) — Update an absence adjustment in the caller organization. +- [`deleteAbsenceAdjustment`](#deleteabsenceadjustment) — Delete an absence adjustment. +- [`getUserAbsence`](#getuserabsence) — Get known absence for a user in a time window. absent=false means no known absence, not guaranteed availability. + +**Working Hours** +- [`getWorkingHours`](#getworkinghours) — Get the recurring weekly working hours of a user. 404 means no record exists and the user is treated as always available +- [`putWorkingHours`](#putworkinghours) — Create or fully replace the working hours of a user in the caller organization. This is a full replace, not a merge. +- [`deleteWorkingHours`](#deleteworkinghours) — Delete the working hours of a user. The user is then treated as always available again. + +**Calendars** +- [`listCalendars`](#listcalendars) — List calendars visible to the caller. +- [`createCalendar`](#createcalendar) — Create a native epilot calendar. +- [`addOutlookCalendar`](#addoutlookcalendar) — Registers one of the caller's Outlook calendars as an epilot calendar. +- [`listOutlookCalendars`](#listoutlookcalendars) — Lists the calling user's Outlook calendars available to import as epilot calendars. +- [`deleteOutlookCalendar`](#deleteoutlookcalendar) — Disconnects a previously registered Outlook calendar. +- [`outlookWebhook`](#outlookwebhook) — Public Microsoft Graph webhook receiver for per-user Outlook calendar +- [`getCalendar`](#getcalendar) — Get a single calendar by its epilot ID. +- [`updateCalendar`](#updatecalendar) — Update local calendar details. Changes to synced calendars do not modify the provider calendar. +- [`deleteCalendar`](#deletecalendar) — Delete a native epilot calendar or disconnect a synced calendar, including its locally stored events. + +**Calendar Events** +- [`listEvents`](#listevents) — List events in a time window. Recurring events are returned as expanded occurrences – each instance appears as its own e +- [`createEvent`](#createevent) — Create a native epilot calendar event. Omit `calendar_id` to use the caller’s epilot default calendar. +- [`getEvent`](#getevent) — Get a single event by its epilot ID. +- [`updateEvent`](#updateevent) — Update a native epilot calendar event. +- [`deleteEvent`](#deleteevent) — Delete a native epilot calendar event. +- [`shareEvent`](#shareevent) — Share a calendar event with another user of the same organization, view-only. Owner-only: recipients of a share cannot r +- [`unshareEvent`](#unshareevent) — Revoke a per-event share. The recipient loses access immediately. Owner-only. + +### `listUsersAbsence` + +List organization users with known absence metadata in the requested time window. + +`GET /v1/calendar/absence/users` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `from` | query | string (date-time) | Yes | Start of the time window (inclusive). Maximum window: 31 days. | +| `to` | query | string (date-time) | Yes | End of the time window (exclusive). Must be after from. | +| `include_busy` | query | boolean | No | Include busy inputs in addition to out-of-office absence. Defaults to false. | +| `working_hours_granularity` | query | "time" \| "day" | No | At what granularity working hours contribute to absence. "time" (default): all time outside a user's working windows counts as absent. "day": only full days with no working windows count as absent (wh | +| `query` | query | string | No | Optional user directory search query. | +| `limit` | query | number | No | Maximum users to return. | +| `offset` | query | number | No | User directory offset. | + +**Sample Call** + +```bash +epilot calendar listUsersAbsence \ + -p from=example \ + -p to=example +``` + +With JSONata filter: + +```bash +epilot calendar listUsersAbsence -p from=example -p to=example --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "hits": 0, + "results": [ + { + "absent": true, + "absence_intervals": [ + { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "original_from": "1970-01-01T00:00:00.000Z", + "original_to": "1970-01-01T00:00:00.000Z", + "absent": true, + "source": "calendar_event", + "calendar_event_id": "string", + "absence_adjustment_id": "string", + "reason": "string" + } + ], + "user_id": "string", + "display_name": "string", + "email": "user@example.com", + "status": "string" + } + ] +} +``` + +
+ +--- + +### `searchAbsence` + +Search known absence for candidate users in the requested time window. + +`POST /v1/calendar/absence:search` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar searchAbsence +``` + +With request body: + +```bash +epilot calendar searchAbsence \ + -d '{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "user_ids": ["string"], + "include_busy": false, + "working_hours_granularity": "time" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar searchAbsence +``` + +With JSONata filter: + +```bash +epilot calendar searchAbsence --jsonata 'from' +``` + +
+Sample Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "users": {} +} +``` + +
+ +--- + +### `searchNowAbsence` + +Search known absence for candidate users at the current server time. + +`POST /v1/calendar/absence:search-now` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar searchNowAbsence \ + -d '{"user_ids":["string"],"include_busy":false,"working_hours_granularity":"time"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar searchNowAbsence +``` + +With JSONata filter: + +```bash +epilot calendar searchNowAbsence --jsonata 'from' +``` + +
+Sample Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "users": {} +} +``` + +
+ +--- + +### `listAbsenceAdjustments` + +List absence adjustments for a user in a time window. + +`GET /v1/calendar/absence/users/{user_id}/adjustments` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | +| `from` | query | string (date-time) | Yes | Start of the time window (inclusive). Maximum window: 90 days. | +| `to` | query | string (date-time) | Yes | End of the time window (exclusive). Must be after from. | + +**Sample Call** + +```bash +epilot calendar listAbsenceAdjustments \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -p from=example \ + -p to=example +``` + +Using positional args for path parameters: + +```bash +epilot calendar listAbsenceAdjustments 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar listAbsenceAdjustments -p user_id=123e4567-e89b-12d3-a456-426614174000 -p from=example -p to=example --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "results": [ + { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string", + "adjustment_id": "string", + "user_id": "string", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `createAbsenceAdjustment` + +Create a time-bound absence adjustment for a user in the caller organization. + +`POST /v1/calendar/absence/users/{user_id}/adjustments` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar createAbsenceAdjustment \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot calendar createAbsenceAdjustment \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string" +}' +``` + +Using positional args for path parameters: + +```bash +epilot calendar createAbsenceAdjustment 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar createAbsenceAdjustment -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar createAbsenceAdjustment -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'from' +``` + +
+Sample Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string", + "adjustment_id": "string", + "user_id": "string", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getAbsenceAdjustment` + +Get an absence adjustment by ID. + +`GET /v1/calendar/absence/users/{user_id}/adjustments/{adjustment_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | +| `adjustment_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar getAbsenceAdjustment \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -p adjustment_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar getAbsenceAdjustment 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar getAbsenceAdjustment -p user_id=123e4567-e89b-12d3-a456-426614174000 -p adjustment_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'from' +``` + +
+Sample Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string", + "adjustment_id": "string", + "user_id": "string", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `patchAbsenceAdjustment` + +Update an absence adjustment in the caller organization. + +`PATCH /v1/calendar/absence/users/{user_id}/adjustments/{adjustment_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | +| `adjustment_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar patchAbsenceAdjustment \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -p adjustment_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot calendar patchAbsenceAdjustment \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -p adjustment_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string" +}' +``` + +Using positional args for path parameters: + +```bash +epilot calendar patchAbsenceAdjustment 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar patchAbsenceAdjustment -p user_id=123e4567-e89b-12d3-a456-426614174000 -p adjustment_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar patchAbsenceAdjustment -p user_id=123e4567-e89b-12d3-a456-426614174000 -p adjustment_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'from' +``` + +
+Sample Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string", + "adjustment_id": "string", + "user_id": "string", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteAbsenceAdjustment` + +Delete an absence adjustment. + +`DELETE /v1/calendar/absence/users/{user_id}/adjustments/{adjustment_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | +| `adjustment_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar deleteAbsenceAdjustment \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -p adjustment_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar deleteAbsenceAdjustment 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar deleteAbsenceAdjustment -p user_id=123e4567-e89b-12d3-a456-426614174000 -p adjustment_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `getUserAbsence` + +Get known absence for a user in a time window. absent=false means no known absence, not guaranteed availability. + +`GET /v1/calendar/absence/users/{user_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | +| `from` | query | string (date-time) | Yes | Start of the time window (inclusive). Maximum window: 31 days. | +| `to` | query | string (date-time) | Yes | End of the time window (exclusive). Must be after from. | +| `include_busy` | query | boolean | No | Include busy inputs in addition to out-of-office absence. Defaults to false. | +| `working_hours_granularity` | query | "time" \| "day" | No | At what granularity working hours contribute to absence. "time" (default): all time outside a user's working windows counts as absent. "day": only full days with no working windows count as absent (wh | + +**Sample Call** + +```bash +epilot calendar getUserAbsence \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -p from=example \ + -p to=example +``` + +Using positional args for path parameters: + +```bash +epilot calendar getUserAbsence 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar getUserAbsence -p user_id=123e4567-e89b-12d3-a456-426614174000 -p from=example -p to=example --jsonata 'absent' +``` + +
+Sample Response + +```json +{ + "absent": true, + "absence_intervals": [ + { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "original_from": "1970-01-01T00:00:00.000Z", + "original_to": "1970-01-01T00:00:00.000Z", + "absent": true, + "source": "calendar_event", + "calendar_event_id": "string", + "absence_adjustment_id": "string", + "reason": "string" + } + ], + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "user_id": "string", + "external_calendars": [ + { + "provider": "outlook", + "last_synced_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `getWorkingHours` + +Get the recurring weekly working hours of a user. 404 means no record exists and the user is treated as always available + +`GET /v1/calendar/working-hours/users/{user_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar getWorkingHours \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar getWorkingHours 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar getWorkingHours -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'monday' +``` + +
+Sample Response + +```json +{ + "monday": [ + { + "start": "string", + "end": "string" + } + ], + "tuesday": [ + { + "start": "string", + "end": "string" + } + ], + "wednesday": [ + { + "start": "string", + "end": "string" + } + ], + "thursday": [ + { + "start": "string", + "end": "string" + } + ], + "friday": [ + { + "start": "string", + "end": "string" + } + ], + "saturday": [ + { + "start": "string", + "end": "string" + } + ], + "sunday": [ + { + "start": "string", + "end": "string" + } + ], + "timezone": "string", + "user_id": "string", + "updated_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `putWorkingHours` + +Create or fully replace the working hours of a user in the caller organization. This is a full replace, not a merge. + +`PUT /v1/calendar/working-hours/users/{user_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar putWorkingHours \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot calendar putWorkingHours \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "monday": [ + { + "start": "string", + "end": "string" + } + ], + "tuesday": [ + { + "start": "string", + "end": "string" + } + ], + "wednesday": [ + { + "start": "string", + "end": "string" + } + ], + "thursday": [ + { + "start": "string", + "end": "string" + } + ], + "friday": [ + { + "start": "string", + "end": "string" + } + ], + "saturday": [ + { + "start": "string", + "end": "string" + } + ], + "sunday": [ + { + "start": "string", + "end": "string" + } + ], + "timezone": "Europe/Berlin" +}' +``` + +Using positional args for path parameters: + +```bash +epilot calendar putWorkingHours 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar putWorkingHours -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar putWorkingHours -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'monday' +``` + +
+Sample Response + +```json +{ + "monday": [ + { + "start": "string", + "end": "string" + } + ], + "tuesday": [ + { + "start": "string", + "end": "string" + } + ], + "wednesday": [ + { + "start": "string", + "end": "string" + } + ], + "thursday": [ + { + "start": "string", + "end": "string" + } + ], + "friday": [ + { + "start": "string", + "end": "string" + } + ], + "saturday": [ + { + "start": "string", + "end": "string" + } + ], + "sunday": [ + { + "start": "string", + "end": "string" + } + ], + "timezone": "string", + "user_id": "string", + "updated_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteWorkingHours` + +Delete the working hours of a user. The user is then treated as always available again. + +`DELETE /v1/calendar/working-hours/users/{user_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar deleteWorkingHours \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar deleteWorkingHours 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar deleteWorkingHours -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `listCalendars` + +List calendars visible to the caller. + +`GET /v1/calendar` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `size` | query | number | No | | +| `cursor` | query | string | No | Opaque cursor from a previous response | + +**Sample Call** + +```bash +epilot calendar listCalendars +``` + +With JSONata filter: + +```bash +epilot calendar listCalendars --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createCalendar` + +Create a native epilot calendar. + +`POST /v1/calendar` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar createCalendar \ + -d '{"name":"string","description":"string","color":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar createCalendar +``` + +With JSONata filter: + +```bash +epilot calendar createCalendar --jsonata '_id' +``` + +
+Sample Response + +```json +{ + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `addOutlookCalendar` + +Registers one of the caller's Outlook calendars as an epilot calendar. + +`POST /v1/calendar/sources/outlook` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar addOutlookCalendar \ + -d '{"provider_calendar_id":"string","name":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar addOutlookCalendar +``` + +With JSONata filter: + +```bash +epilot calendar addOutlookCalendar --jsonata '_id' +``` + +
+Sample Response + +```json +{ + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listOutlookCalendars` + +Lists the calling user's Outlook calendars available to import as epilot calendars. + +`GET /v1/calendar/sources/outlook/available` + +**Sample Call** + +```bash +epilot calendar listOutlookCalendars +``` + +With JSONata filter: + +```bash +epilot calendar listOutlookCalendars --jsonata 'calendars' +``` + +
+Sample Response + +```json +{ + "calendars": [ + { + "provider_calendar_id": "string", + "name": "string", + "color": "string", + "is_default": true, + "can_edit": true, + "owner": "string" + } + ] +} +``` + +
+ +--- + +### `deleteOutlookCalendar` + +Disconnects a previously registered Outlook calendar. + +`DELETE /v1/calendar/sources/outlook/{calendar_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `calendar_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar deleteOutlookCalendar \ + -p calendar_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar deleteOutlookCalendar 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar deleteOutlookCalendar -p calendar_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `outlookWebhook` + +Public Microsoft Graph webhook receiver for per-user Outlook calendar + +`POST /v1/calendar/outlook/webhook` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `validationToken` | query | string | No | Set by Graph on the subscription-validation handshake; echoed back verbatim. | + +**Sample Call** + +```bash +epilot calendar outlookWebhook +``` + +With JSONata filter: + +```bash +epilot calendar outlookWebhook --jsonata '$' +``` + +--- + +### `getCalendar` + +Get a single calendar by its epilot ID. + +`GET /v1/calendar/{calendar_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `calendar_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar getCalendar \ + -p calendar_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar getCalendar 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar getCalendar -p calendar_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '_id' +``` + +
+Sample Response + +```json +{ + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateCalendar` + +Update local calendar details. Changes to synced calendars do not modify the provider calendar. + +`PATCH /v1/calendar/{calendar_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `calendar_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar updateCalendar \ + -p calendar_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"name":"string","description":"string","color":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot calendar updateCalendar 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar updateCalendar -p calendar_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar updateCalendar -p calendar_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '_id' +``` + +
+Sample Response + +```json +{ + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteCalendar` + +Delete a native epilot calendar or disconnect a synced calendar, including its locally stored events. + +`DELETE /v1/calendar/{calendar_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `calendar_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar deleteCalendar \ + -p calendar_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar deleteCalendar 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar deleteCalendar -p calendar_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `listEvents` + +List events in a time window. Recurring events are returned as expanded occurrences – each instance appears as its own e + +`GET /v1/calendar/events` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `from` | query | string (date-time) | Yes | Start of the time window (inclusive) | +| `to` | query | string (date-time) | Yes | End of the time window (exclusive) | +| `calendar_id` | query | string | No | Filter to a single calendar. Omit to query across all accessible calendars. | +| `size` | query | number | No | | +| `cursor` | query | string | No | | + +**Sample Call** + +```bash +epilot calendar listEvents \ + -p from=example \ + -p to=example +``` + +With JSONata filter: + +```bash +epilot calendar listEvents -p from=example -p to=example --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "_id": "string", + "_schema": "calendar_event", + "_org": "string", + "_title": "string", + "_tags": ["string"], + "calendar_id": "string", + "event_type": "singleInstance", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "busy": true, + "is_cancelled": true, + "is_draft": true, + "sensitivity": "normal", + "importance": "low", + "is_online_meeting": true, + "online_meeting_url": "https://example.com/path", + "web_link": "https://example.com/path", + "response_status": "none", + "organizer_email": "user@example.com", + "attendees": [ + { + "email": "user@example.com", + "name": "string", + "response": "none", + "type": "required" + } + ], + "metadata": {}, + "is_recurring": true, + "series_master_id": "string", + "source": { + "type": "native", + "provider": "outlook", + "provider_event_id": "string", + "provider_event_url": "https://example.com/path", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "etag": "string" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createEvent` + +Create a native epilot calendar event. Omit `calendar_id` to use the caller’s epilot default calendar. + +`POST /v1/calendar/events` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar createEvent +``` + +With request body: + +```bash +epilot calendar createEvent \ + -d '{ + "calendar_id": "string", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "sensitivity": "normal", + "metadata": {}, + "_title": "string" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar createEvent +``` + +With JSONata filter: + +```bash +epilot calendar createEvent --jsonata '_id' +``` + +
+Sample Response + +```json +{ + "_id": "string", + "_schema": "calendar_event", + "_org": "string", + "_title": "string", + "_tags": ["string"], + "calendar_id": "string", + "event_type": "singleInstance", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "busy": true, + "is_cancelled": true, + "is_draft": true, + "sensitivity": "normal", + "importance": "low", + "is_online_meeting": true, + "online_meeting_url": "https://example.com/path", + "web_link": "https://example.com/path", + "response_status": "none", + "organizer_email": "user@example.com", + "attendees": [ + { + "email": "user@example.com", + "name": "string", + "response": "none", + "type": "required" + } + ], + "metadata": {}, + "is_recurring": true, + "series_master_id": "string", + "source": { + "type": "native", + "provider": "outlook", + "provider_event_id": "string", + "provider_event_url": "https://example.com/path", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "etag": "string" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getEvent` + +Get a single event by its epilot ID. + +`GET /v1/calendar/events/{event_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar getEvent \ + -p event_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar getEvent 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar getEvent -p event_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '_id' +``` + +
+Sample Response + +```json +{ + "_id": "string", + "_schema": "calendar_event", + "_org": "string", + "_title": "string", + "_tags": ["string"], + "calendar_id": "string", + "event_type": "singleInstance", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "busy": true, + "is_cancelled": true, + "is_draft": true, + "sensitivity": "normal", + "importance": "low", + "is_online_meeting": true, + "online_meeting_url": "https://example.com/path", + "web_link": "https://example.com/path", + "response_status": "none", + "organizer_email": "user@example.com", + "attendees": [ + { + "email": "user@example.com", + "name": "string", + "response": "none", + "type": "required" + } + ], + "metadata": {}, + "is_recurring": true, + "series_master_id": "string", + "source": { + "type": "native", + "provider": "outlook", + "provider_event_id": "string", + "provider_event_url": "https://example.com/path", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "etag": "string" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateEvent` + +Update a native epilot calendar event. + +`PATCH /v1/calendar/events/{event_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar updateEvent \ + -p event_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot calendar updateEvent \ + -p event_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "is_cancelled": true, + "sensitivity": "normal", + "_title": "string" +}' +``` + +Using positional args for path parameters: + +```bash +epilot calendar updateEvent 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar updateEvent -p event_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar updateEvent -p event_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '_id' +``` + +
+Sample Response + +```json +{ + "_id": "string", + "_schema": "calendar_event", + "_org": "string", + "_title": "string", + "_tags": ["string"], + "calendar_id": "string", + "event_type": "singleInstance", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "busy": true, + "is_cancelled": true, + "is_draft": true, + "sensitivity": "normal", + "importance": "low", + "is_online_meeting": true, + "online_meeting_url": "https://example.com/path", + "web_link": "https://example.com/path", + "response_status": "none", + "organizer_email": "user@example.com", + "attendees": [ + { + "email": "user@example.com", + "name": "string", + "response": "none", + "type": "required" + } + ], + "metadata": {}, + "is_recurring": true, + "series_master_id": "string", + "source": { + "type": "native", + "provider": "outlook", + "provider_event_id": "string", + "provider_event_url": "https://example.com/path", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "etag": "string" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteEvent` + +Delete a native epilot calendar event. + +`DELETE /v1/calendar/events/{event_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar deleteEvent \ + -p event_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar deleteEvent 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar deleteEvent -p event_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `shareEvent` + +Share a calendar event with another user of the same organization, view-only. Owner-only: recipients of a share cannot r + +`POST /v1/calendar/events/{event_id}/share` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot calendar shareEvent \ + -p event_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"user_id":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot calendar shareEvent 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot calendar shareEvent -p event_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar shareEvent -p event_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `unshareEvent` + +Revoke a per-event share. The recipient loses access immediately. Owner-only. + +`DELETE /v1/calendar/events/{event_id}/share/{user_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_id` | path | string | Yes | | +| `user_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot calendar unshareEvent \ + -p event_id=123e4567-e89b-12d3-a456-426614174000 \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot calendar unshareEvent 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot calendar unshareEvent -p event_id=123e4567-e89b-12d3-a456-426614174000 -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- diff --git a/docs/cli/commands/chat.md b/docs/cli/commands/chat.md new file mode 100644 index 00000000..016f00b1 --- /dev/null +++ b/docs/cli/commands/chat.md @@ -0,0 +1,632 @@ +--- +title: "epilot Chat API" +description: "epilot CLI commands for the epilot Chat API: quick start, common flags and every operation, callable from the command line." +--- + +# epilot Chat API + +- **Base URL:** `https://chat.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/chat](https://docs.epilot.io/api/chat) + +Widget management and anonymous browser chat. + +## Quick Start + +```bash +# List available operations +epilot chat + +# Call an operation +epilot chat listChatWidgets +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Chat widgets** +- [`listChatWidgets`](#listchatwidgets) — GET /v1/widgets +- [`createChatWidget`](#createchatwidget) — POST /v1/widgets +- [`getChatWidget`](#getchatwidget) — GET /v1/widgets/{widget_id} +- [`updateChatWidget`](#updatechatwidget) — PUT /v1/widgets/{widget_id} +- [`deleteChatWidget`](#deletechatwidget) — DELETE /v1/widgets/{widget_id} + +**Other** +- [`getPublicChatWidget`](#getpublicchatwidget) — Resolve visitor-facing configuration for an independent widget and its current agent assignment. The widget ID is not an +- [`createPublicChatGrant`](#createpublicchatgrant) — Called by the host website with its widget_key. Checks the saved website origin allowlist and issues a single-use grant +- [`createAnonymousChatSession`](#createanonymouschatsession) — Exchanges an unexpired grant once for an independent 30-minute session. Expired or previously used grants return 401 INV +- [`sendAnonymousChatMessage`](#sendanonymouschatmessage) — Creates a turn or replays its persisted result. Reuse request_id and the exact + +### `listChatWidgets` + +`GET /v1/widgets` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `cursor` | query | string | No | | + +**Sample Call** + +```bash +epilot chat listChatWidgets +``` + +With JSONata filter: + +```bash +epilot chat listChatWidgets --jsonata 'widgets' +``` + +
+Sample Response + +```json +{ + "widgets": [ + { + "name": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "website_chat": { + "allowed_origins": ["string"], + "organisation_name": "string", + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + } + }, + "widget_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "binding_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "version": 1, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "website_chat_embed": { + "script_url": "https://example.com/path", + "chat_api_origin": "https://example.com/path", + "demo_url": "https://example.com/path" + } + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createChatWidget` + +`POST /v1/widgets` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot chat createChatWidget +``` + +With request body: + +```bash +epilot chat createChatWidget \ + -d '{ + "name": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "website_chat": { + "allowed_origins": ["string"], + "organisation_name": "string", + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + } + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot chat createChatWidget +``` + +With JSONata filter: + +```bash +epilot chat createChatWidget --jsonata 'name' +``` + +
+Sample Response + +```json +{ + "name": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "website_chat": { + "allowed_origins": ["string"], + "organisation_name": "string", + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + } + }, + "widget_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "binding_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "version": 1, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "website_chat_embed": { + "script_url": "https://example.com/path", + "chat_api_origin": "https://example.com/path", + "demo_url": "https://example.com/path" + } +} +``` + +
+ +--- + +### `getChatWidget` + +`GET /v1/widgets/{widget_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `widget_id` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot chat getChatWidget \ + -p widget_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot chat getChatWidget 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot chat getChatWidget -p widget_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'name' +``` + +
+Sample Response + +```json +{ + "name": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "website_chat": { + "allowed_origins": ["string"], + "organisation_name": "string", + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + } + }, + "widget_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "binding_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "version": 1, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "website_chat_embed": { + "script_url": "https://example.com/path", + "chat_api_origin": "https://example.com/path", + "demo_url": "https://example.com/path" + } +} +``` + +
+ +--- + +### `updateChatWidget` + +`PUT /v1/widgets/{widget_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `widget_id` | path | string (uuid) | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot chat updateChatWidget \ + -p widget_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot chat updateChatWidget \ + -p widget_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "name": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "website_chat": { + "allowed_origins": ["string"], + "organisation_name": "string", + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + } + }, + "version": 1 +}' +``` + +Using positional args for path parameters: + +```bash +epilot chat updateChatWidget 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot chat updateChatWidget -p widget_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot chat updateChatWidget -p widget_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'name' +``` + +
+Sample Response + +```json +{ + "name": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "website_chat": { + "allowed_origins": ["string"], + "organisation_name": "string", + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + } + }, + "widget_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "binding_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "version": 1, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "website_chat_embed": { + "script_url": "https://example.com/path", + "chat_api_origin": "https://example.com/path", + "demo_url": "https://example.com/path" + } +} +``` + +
+ +--- + +### `deleteChatWidget` + +`DELETE /v1/widgets/{widget_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `widget_id` | path | string (uuid) | Yes | | +| `version` | query | number | Yes | | + +**Sample Call** + +```bash +epilot chat deleteChatWidget \ + -p widget_id=123e4567-e89b-12d3-a456-426614174000 \ + -p version=1 +``` + +Using positional args for path parameters: + +```bash +epilot chat deleteChatWidget 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot chat deleteChatWidget -p widget_id=123e4567-e89b-12d3-a456-426614174000 -p version=1 --jsonata '$' +``` + +--- + +### `getPublicChatWidget` + +Resolve visitor-facing configuration for an independent widget and its current agent assignment. The widget ID is not an + +`GET /v1/widgets/{widget_id}/configuration` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `widget_id` | path | string | Yes | Public widget ID, also used as widget_key in bootstrap and data-epilot-chat in the embed. | + +**Sample Call** + +```bash +epilot chat getPublicChatWidget \ + -p widget_id=550e8400-e29b-41d4-a716-446655440000 +``` + +Using positional args for path parameters: + +```bash +epilot chat getPublicChatWidget 550e8400-e29b-41d4-a716-446655440000 +``` + +With JSONata filter: + +```bash +epilot chat getPublicChatWidget -p widget_id=550e8400-e29b-41d4-a716-446655440000 --jsonata 'key' +``` + +
+Sample Response + +```json +{ + "key": "string", + "organisationName": "string", + "assistantName": "string", + "defaultLocale": "en", + "design": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "last_modified_at": "string", + "style": { + "palette": { + "primary": "string", + "background": "string" + }, + "typography": { + "font": { + "font_family": "string" + } + }, + "shape": { + "border_radius": 0 + } + }, + "spark_theme": { + "accentColor": "string", + "backgroundColor": "string", + "fontBody": "string", + "fontHeading": "string", + "radius": "string", + "scaling": "string", + "spacing": "string", + "appearance": "string", + "neutralColor": "string", + "styleVariant": "string", + "labelPosition": "string", + "inputStyle": "string", + "inputColor": "string", + "cardVariant": "string", + "cardColor": "string", + "highContrast": true + } + }, + "locales": ["en"] +} +``` + +
+ +--- + +### `createPublicChatGrant` + +Called by the host website with its widget_key. Checks the saved website origin allowlist and issues a single-use grant + +`POST /v1/bootstrap` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot chat createPublicChatGrant \ + -d '{"widget_key":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot chat createPublicChatGrant +``` + +With JSONata filter: + +```bash +epilot chat createPublicChatGrant --jsonata 'grant' +``` + +
+Sample Response + +```json +{ + "grant": "string", + "expires_in": 60, + "widget_origin": "https://example.com/path" +} +``` + +
+ +--- + +### `createAnonymousChatSession` + +Exchanges an unexpired grant once for an independent 30-minute session. Expired or previously used grants return 401 INV + +`POST /v1/sessions` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot chat createAnonymousChatSession \ + -d '{"grant":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot chat createAnonymousChatSession +``` + +With JSONata filter: + +```bash +epilot chat createAnonymousChatSession --jsonata 'token' +``` + +
+Sample Response + +```json +{ + "token": "string", + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "expires_at": 0, + "widget": { + "key": "string", + "organisationName": "string", + "assistantName": "string", + "defaultLocale": "en", + "design": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "last_modified_at": "string", + "style": { + "palette": { + "primary": "string", + "background": "string" + }, + "typography": { + "font": { + "font_family": "string" + } + }, + "shape": { + "border_radius": 0 + } + }, + "spark_theme": { + "accentColor": "string", + "backgroundColor": "string", + "fontBody": "string", + "fontHeading": "string", + "radius": "string", + "scaling": "string", + "spacing": "string", + "appearance": "string", + "neutralColor": "string", + "styleVariant": "string", + "labelPosition": "string", + "inputStyle": "string", + "inputColor": "string", + "cardVariant": "string", + "cardColor": "string", + "highContrast": true + } + }, + "locales": ["en"] + } +} +``` + +
+ +--- + +### `sendAnonymousChatMessage` + +Creates a turn or replays its persisted result. Reuse request_id and the exact + +`POST /v1/messages` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot chat sendAnonymousChatMessage \ + -d '{"request_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","message":"string","locale":"en","simple_language":true}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot chat sendAnonymousChatMessage +``` + +With JSONata filter: + +```bash +epilot chat sendAnonymousChatMessage --jsonata '$' +``` + +--- diff --git a/docs/cli/commands/configuration-hub.md b/docs/cli/commands/configuration-hub.md new file mode 100644 index 00000000..066eda70 --- /dev/null +++ b/docs/cli/commands/configuration-hub.md @@ -0,0 +1,2686 @@ +--- +title: "Configuration Hub API" +description: "epilot CLI commands for the Configuration Hub API: quick start, common flags and every operation, callable from the command line." +--- + +# Configuration Hub API + +- **Base URL:** `https://configuration-hub.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/configuration-hub](https://docs.epilot.io/api/configuration-hub) + +Lightweight index API for exploring epilot organization configurations. + +## Quick Start + +```bash +# List available operations +epilot configuration-hub + +# Call an operation +epilot configuration-hub listConfigTypes +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Configs** +- [`listConfigTypes`](#listconfigtypes) — Returns the static list of available configuration types with display metadata. +- [`listConfigs`](#listconfigs) — List configs of a given type with pagination. Returns summary metadata only +- [`getConfigDependencies`](#getconfigdependencies) — Get configs that are referenced by the given config. +- [`getConfigUsedBy`](#getconfigusedby) — Get configs that reference the given config (reverse dependencies). +- [`getIndex`](#getindex) — Return the current index build state for the caller's organization. +- [`rebuildIndex`](#rebuildindex) — Rebuild the configuration index for the caller's organization. +- [`getConfigInventory`](#getconfiginventory) — Returns a fresh inventory of an org's configuration resources — `{ type, id }` identities only, + +**Health** +- [`startHealthScan`](#starthealthscan) — Start an asynchronous org health scan — fire-and-forget, mirrors +- [`getHealthReport`](#gethealthreport) — Return the caller org's current health report: scan status, summary +- [`requestHealthCoverage`](#requesthealthcoverage) — Send a request for configuration the health check does not cover yet. +- [`startHealthCleanup`](#starthealthcleanup) — Remove references that are already inert: dangling `$relation` entries +- [`setHealthFindingsIgnored`](#sethealthfindingsignored) — Acknowledge findings as intentional (or undo that). An ignored + +**Compare** +- [`compareConfigs`](#compareconfigs) — Compare the caller org's configs of a single type against another +- [`suggestMatches`](#suggestmatches) — Run the sync-grade heuristic match (`lookupByHeuristic` — name / slug / +- [`confirmLineage`](#confirmlineage) — Persist a lineage entry pairing a source-org config with a config in +- [`breakLineage`](#breaklineage) — Delete a lineage entry from the caller org's partition (caller as sync + +**Sync** +- [`listSyncJobs`](#listsyncjobs) — List sync jobs scoped to the caller's organization, paginated with an opaque +- [`createSyncJob`](#createsyncjob) — Create a new cross-org sync job. The job is enqueued for asynchronous execution +- [`getSyncJob`](#getsyncjob) — Fetch a single sync job by ID. Returns the job header, counts summary, +- [`getSyncJobHealth`](#getsyncjobhealth) — Targeted health check of an applied (non-dry-run) sync job. When the job +- [`runSyncJobHealth`](#runsyncjobhealth) — Start the targeted health check of a finished, applied sync job again: +- [`retrySyncJob`](#retrysyncjob) — Retry the unresolved resources from a prior sync job: `failed` rows, plus +- [`planSyncJobRetry`](#plansyncjobretry) — Preview what `retrySyncJob` would re-run for the same `resources`, +- [`cancelSyncJob`](#cancelsyncjob) — Cancel a running sync job. Marks the job `cancelled` with a `finished_at` +- [`listSyncJobEvents`](#listsyncjobevents) — Full activity log of a sync job, latest first: one event per resource +- [`listSyncJobResources`](#listsyncjobresources) — List the per-resource rows for a sync job. Supports filtering by status +- [`getSyncPlan`](#getsyncplan) — Summary of a plan: a dry-run sync job (`createSyncJob` with +- [`listSyncPlanDiffs`](#listsyncplandiffs) — Field-level diffs of a plan, one per planned resource: what the target +- [`getSyncPlanDiff`](#getsyncplandiff) — Field-level diff of one planned resource. See `listSyncPlanDiffs`. +- [`applySyncPlan`](#applysyncplan) — Run a finished plan for real. Creates a new sync job (it carries +- [`replanSyncPlan`](#replansyncplan) — Plan some rows of a plan again, in place, e.g. after fixing a + +**Delete** +- [`listDeleteJobs`](#listdeletejobs) — List bulk-delete jobs scoped to the caller's organization, paginated +- [`createDeleteJob`](#createdeletejob) — Create a bulk-delete job for the caller's organization. The selected +- [`getDeleteJob`](#getdeletejob) — Fetch a single bulk-delete job by ID. Returns the job header and counts +- [`listDeleteJobResources`](#listdeletejobresources) — List the per-resource rows for a delete job, cursor-paginated. Used by + +**Previews** +- [`listPreviews`](#listpreviews) — Lists the previews requested from the caller's current org, newest first (max 50). +- [`createPreview`](#createpreview) — Starts a preview of the caller's current org (internal callers: the org in `x-ivy-org-id`, +- [`getPreview`](#getpreview) — Returns a preview requested from the caller's current org, with its progress. + +### `listConfigTypes` + +Returns the static list of available configuration types with display metadata. + +`GET /v1/configs/types` + +**Sample Call** + +```bash +epilot configuration-hub listConfigTypes +``` + +With JSONata filter: + +```bash +epilot configuration-hub listConfigTypes --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "type": "journey", + "label": "Journeys", + "icon": "Route", + "source_api": "https://journey.sls.epilot.io", + "sdk_client": "@epilot/sdk/journey", + "deletable": true + } + ] +} +``` + +
+ +--- + +### `listConfigs` + +List configs of a given type with pagination. Returns summary metadata only + +`GET /v1/configs/{type}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `type` | path | "journey" \| "datasource" \| "automation_flow" \| "workflow_definition" \| "closing_reason" \| "flow_template" \| "schema" \| "emailtemplate" \| "product" \| "price" \| "tax" \| "coupon" \| "file" \| "document_template" \| "webhook" \| "saved_view" \| "dashboard" \| "kanban" \| "role" \| "usergroup" \| "validation_rule" \| "integration" \| "app" \| "designbuilder" \| "notification_template" \| "custom_variable" \| "environment_variable" \| "taxonomy" \| "taxonomy_classification" \| "entity_mapping" \| "portal_config" \| "target" \| "product_recommendation" \| "access_token" \| "email_signature" \| "shared_inbox" \| "org_setting" | Yes | Configuration resource type | +| `cursor` | query | string | No | Opaque cursor for fetching the next page. Omit for the first page. | +| `size` | query | number | No | Number of items per page | +| `q` | query | string | No | Search query to filter configs by name/title | +| `updated_after` | query | string (date-time) | No | Filter configs updated after this date (ISO 8601) | +| `updated_before` | query | string (date-time) | No | Filter configs updated before this date (ISO 8601) | +| `purposes` | query | string | No | Filter by purpose classification IDs (comma-separated) | +| `blueprint_ids` | query | string | No | Filter by installed-blueprint IDs (comma-separated). Only configs installed by one of the listed blueprints are returned. | +| `sort` | query | "updated_at" \| "usage" \| "name" | No | Sort order. `updated_at` (default) sorts by most recently modified. +`usage` sorts by the type-specific usage metric descending +(submissions for journeys, executions for automations, entities for schem | +| `active_only` | query | boolean | No | If true, filter out configs that are explicitly inactive (active=false). +Configs with no `active` field are always included. + | + +**Sample Call** + +```bash +epilot configuration-hub listConfigs \ + -p type=example +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub listConfigs example +``` + +With JSONata filter: + +```bash +epilot configuration-hub listConfigs -p type=example --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "type": "journey", + "label": "string", + "icon": "string", + "total": 0, + "next_cursor": "string", + "results": [ + { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + } + ] +} +``` + +
+ +--- + +### `getConfigDependencies` + +Get configs that are referenced by the given config. + +`GET /v1/configs/{type}/{id}/dependencies` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `type` | path | "journey" \| "datasource" \| "automation_flow" \| "workflow_definition" \| "closing_reason" \| "flow_template" \| "schema" \| "emailtemplate" \| "product" \| "price" \| "tax" \| "coupon" \| "file" \| "document_template" \| "webhook" \| "saved_view" \| "dashboard" \| "kanban" \| "role" \| "usergroup" \| "validation_rule" \| "integration" \| "app" \| "designbuilder" \| "notification_template" \| "custom_variable" \| "environment_variable" \| "taxonomy" \| "taxonomy_classification" \| "entity_mapping" \| "portal_config" \| "target" \| "product_recommendation" \| "access_token" \| "email_signature" \| "shared_inbox" \| "org_setting" | Yes | Configuration resource type | +| `id` | path | string | Yes | Configuration resource ID | +| `cursor` | query | string | No | Opaque cursor for fetching the next page. Omit for the first page. | +| `size` | query | number | No | Number of items per page | + +**Sample Call** + +```bash +epilot configuration-hub getConfigDependencies \ + -p type=example \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub getConfigDependencies example 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub getConfigDependencies -p type=example -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "total": 0, + "next_cursor": "string", + "results": [ + { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + } + ] +} +``` + +
+ +--- + +### `getConfigUsedBy` + +Get configs that reference the given config (reverse dependencies). + +`GET /v1/configs/{type}/{id}/used_by` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `type` | path | "journey" \| "datasource" \| "automation_flow" \| "workflow_definition" \| "closing_reason" \| "flow_template" \| "schema" \| "emailtemplate" \| "product" \| "price" \| "tax" \| "coupon" \| "file" \| "document_template" \| "webhook" \| "saved_view" \| "dashboard" \| "kanban" \| "role" \| "usergroup" \| "validation_rule" \| "integration" \| "app" \| "designbuilder" \| "notification_template" \| "custom_variable" \| "environment_variable" \| "taxonomy" \| "taxonomy_classification" \| "entity_mapping" \| "portal_config" \| "target" \| "product_recommendation" \| "access_token" \| "email_signature" \| "shared_inbox" \| "org_setting" | Yes | Configuration resource type | +| `id` | path | string | Yes | Configuration resource ID | + +**Sample Call** + +```bash +epilot configuration-hub getConfigUsedBy \ + -p type=example \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub getConfigUsedBy example 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub getConfigUsedBy -p type=example -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "total": 0, + "next_cursor": "string", + "results": [ + { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + } + ] +} +``` + +
+ +--- + +### `getIndex` + +Return the current index build state for the caller's organization. + +`GET /v1/configs/index` + +**Sample Call** + +```bash +epilot configuration-hub getIndex +``` + +With JSONata filter: + +```bash +epilot configuration-hub getIndex --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "missing", + "org_id": "string", + "last_built_at": "1970-01-01T00:00:00.000Z", + "total_items": 0, + "build_duration_ms": 0 +} +``` + +
+ +--- + +### `startHealthScan` + +Start an asynchronous org health scan — fire-and-forget, mirrors + +`POST /v1/configs/health:scan` + +**Sample Call** + +```bash +epilot configuration-hub startHealthScan +``` + +With JSONata filter: + +```bash +epilot configuration-hub startHealthScan --jsonata '$' +``` + +--- + +### `getHealthReport` + +Return the caller org's current health report: scan status, summary + +`GET /v1/configs/health` + +**Sample Call** + +```bash +epilot configuration-hub getHealthReport +``` + +With JSONata filter: + +```bash +epilot configuration-hub getHealthReport --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "missing", + "last_scanned_at": "1970-01-01T00:00:00.000Z", + "scan_duration_ms": 0, + "scanned_configs": 0, + "scanned_by_type": {}, + "counts": { + "error": 0, + "warning": 0, + "info": 0 + }, + "new_since_previous": 0, + "resolved_since_previous": 0, + "last_cleanup_at": "1970-01-01T00:00:00.000Z", + "cleaned_count": 0, + "history": [ + { + "scanned_at": "1970-01-01T00:00:00.000Z", + "clean": 0, + "total": 0 + } + ], + "error": "string", + "findings": [ + { + "id": "string", + "code": "broken_reference", + "severity": "error", + "source_type": "string", + "source_id": "string", + "source_title": "string", + "message": "string", + "message_key": "string", + "message_params": {}, + "ref_type": "string", + "ref_id": "string", + "ref_title": "string", + "source_link": "string", + "ref_link": "string", + "owner_type": "string", + "owner_id": "string", + "owner_title": "string", + "owner_link": "string", + "path": "string", + "cleanable": true, + "ignored": true, + "ignored_at": "1970-01-01T00:00:00.000Z", + "ignored_by": "string", + "ignored_reason": "string", + "first_seen": "1970-01-01T00:00:00.000Z", + "last_seen": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `requestHealthCoverage` + +Send a request for configuration the health check does not cover yet. + +`POST /v1/configs/health:coverage-request` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub requestHealthCoverage \ + -d '{"message":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub requestHealthCoverage +``` + +With JSONata filter: + +```bash +epilot configuration-hub requestHealthCoverage --jsonata '$' +``` + +--- + +### `startHealthCleanup` + +Remove references that are already inert: dangling `$relation` entries + +`POST /v1/configs/health:cleanup` + +**Request Body** + +**Sample Call** + +```bash +epilot configuration-hub startHealthCleanup \ + -d '{"finding_ids":["string"]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub startHealthCleanup +``` + +With JSONata filter: + +```bash +epilot configuration-hub startHealthCleanup --jsonata '$' +``` + +--- + +### `setHealthFindingsIgnored` + +Acknowledge findings as intentional (or undo that). An ignored + +`POST /v1/configs/health:ignore` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub setHealthFindingsIgnored \ + -d '{"finding_ids":["string"],"ignored":true,"reason":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub setHealthFindingsIgnored +``` + +With JSONata filter: + +```bash +epilot configuration-hub setHealthFindingsIgnored --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "ok", + "count": 0 +} +``` + +
+ +--- + +### `compareConfigs` + +Compare the caller org's configs of a single type against another + +`POST /v1/configs/compare` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub compareConfigs \ + -d '{"source_org_id":"string","source_auth_token":"string","type":"journey"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub compareConfigs +``` + +With JSONata filter: + +```bash +epilot configuration-hub compareConfigs --jsonata 'type' +``` + +
+Sample Response + +```json +{ + "type": "journey", + "label": "string", + "icon": "string", + "rows": [ + { + "match_status": "matched", + "current": { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + }, + "source": { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + }, + "lineage": { + "direction": "pull", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "last_sync_job_id": "string", + "origin": "string" + } + } + ], + "counts": { + "matched": 0, + "only_current": 0, + "only_source": 0 + } +} +``` + +
+ +--- + +### `suggestMatches` + +Run the sync-grade heuristic match (`lookupByHeuristic` — name / slug / + +`POST /v1/configs/compare/suggestions` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub suggestMatches \ + -d '{"source_org_id":"string","source_auth_token":"string","type":"journey","source_ids":["string"]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub suggestMatches +``` + +With JSONata filter: + +```bash +epilot configuration-hub suggestMatches --jsonata 'type' +``` + +
+Sample Response + +```json +{ + "type": "journey", + "suggestions": [ + { + "source_id": "string", + "candidate": { + "id": "string", + "title": "string" + } + } + ] +} +``` + +
+ +--- + +### `confirmLineage` + +Persist a lineage entry pairing a source-org config with a config in + +`POST /v1/configs/lineage` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub confirmLineage \ + -d '{"type":"journey","source_org_id":"string","source_id":"string","target_id":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub confirmLineage +``` + +With JSONata filter: + +```bash +epilot configuration-hub confirmLineage --jsonata 'type' +``` + +
+Sample Response + +```json +{ + "type": "journey", + "target_org_id": "string", + "source_org_id": "string", + "source_id": "string", + "target_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "origin": "string" +} +``` + +
+ +--- + +### `breakLineage` + +Delete a lineage entry from the caller org's partition (caller as sync + +`DELETE /v1/configs/lineage` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `type` | query | "journey" \| "datasource" \| "automation_flow" \| "workflow_definition" \| "closing_reason" \| "flow_template" \| "schema" \| "emailtemplate" \| "product" \| "price" \| "tax" \| "coupon" \| "file" \| "document_template" \| "webhook" \| "saved_view" \| "dashboard" \| "kanban" \| "role" \| "usergroup" \| "validation_rule" \| "integration" \| "app" \| "designbuilder" \| "notification_template" \| "custom_variable" \| "environment_variable" \| "taxonomy" \| "taxonomy_classification" \| "entity_mapping" \| "portal_config" \| "target" \| "product_recommendation" \| "access_token" \| "email_signature" \| "shared_inbox" \| "org_setting" | Yes | Configuration resource type of the lineage entry | +| `source_id` | query | string | Yes | Source-org config id the lineage entry is keyed by | + +**Sample Call** + +```bash +epilot configuration-hub breakLineage \ + -p type=example \ + -p source_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub breakLineage -p type=example -p source_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'deleted' +``` + +
+Sample Response + +```json +{ + "deleted": true +} +``` + +
+ +--- + +### `listSyncJobs` + +List sync jobs scoped to the caller's organization, paginated with an opaque + +`GET /v1/configs/sync-jobs` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `cursor` | query | string | No | Opaque cursor for fetching the next page. Omit for the first page. | +| `size` | query | number | No | Number of items per page | +| `status` | query | "pending" \| "in_progress" \| "succeeded" \| "partial" \| "failed" \| "cancelled" | No | Filter jobs by status | + +**Sample Call** + +```bash +epilot configuration-hub listSyncJobs +``` + +With JSONata filter: + +```bash +epilot configuration-hub listSyncJobs --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": {}, + "current_phase": "phase_0", + "current_batch": {}, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": {}, + "events": [], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": {}, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [], + "errors_sample": [] + } + ] +} +``` + +
+ +--- + +### `createSyncJob` + +Create a new cross-org sync job. The job is enqueued for asynchronous execution + +`POST /v1/configs/sync-jobs` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub createSyncJob +``` + +With request body: + +```bash +epilot configuration-hub createSyncJob \ + -d '{ + "source_org_id": "string", + "target_org_id": "string", + "target_auth_token": "string", + "name": "string", + "dry_run": false, + "include_dependencies": true, + "sync_portal_widgets": true, + "resources": [ + { + "type": "string", + "id": "string" + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub createSyncJob +``` + +With JSONata filter: + +```bash +epilot configuration-hub createSyncJob --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": {} + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `getSyncJob` + +Fetch a single sync job by ID. Returns the job header, counts summary, + +`GET /v1/configs/sync-jobs/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Sample Call** + +```bash +epilot configuration-hub getSyncJob \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub getSyncJob 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub getSyncJob -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": {} + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `getSyncJobHealth` + +Targeted health check of an applied (non-dry-run) sync job. When the job + +`GET /v1/configs/sync-jobs/{id}/health` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Sample Call** + +```bash +epilot configuration-hub getSyncJobHealth \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub getSyncJobHealth 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub getSyncJobHealth -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "pending", + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "scanned": 0, + "counts": { + "error": 0, + "warning": 0, + "info": 0 + }, + "error": "string", + "findings": [ + { + "id": "string", + "code": "broken_reference", + "severity": "error", + "source_type": "string", + "source_id": "string", + "source_title": "string", + "message": "string", + "message_key": "string", + "message_params": {}, + "ref_type": "string", + "ref_id": "string", + "ref_title": "string", + "source_link": "string", + "ref_link": "string", + "owner_type": "string", + "owner_id": "string", + "owner_title": "string", + "owner_link": "string", + "path": "string", + "cleanable": true, + "ignored": true, + "ignored_at": "1970-01-01T00:00:00.000Z", + "ignored_by": "string", + "ignored_reason": "string", + "first_seen": "1970-01-01T00:00:00.000Z", + "last_seen": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `runSyncJobHealth` + +Start the targeted health check of a finished, applied sync job again: + +`POST /v1/configs/sync-jobs/{id}/health:run` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Sample Call** + +```bash +epilot configuration-hub runSyncJobHealth \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub runSyncJobHealth 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub runSyncJobHealth -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `retrySyncJob` + +Retry the unresolved resources from a prior sync job: `failed` rows, plus + +`POST /v1/configs/sync-jobs/{id}/retry` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Request Body** + +**Sample Call** + +```bash +epilot configuration-hub retrySyncJob \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"target_auth_token":"string","resources":[{"type":"string","source_id":"string"}],"payload_overrides":{}}' +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub retrySyncJob 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub retrySyncJob -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub retrySyncJob -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": {} + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `planSyncJobRetry` + +Preview what `retrySyncJob` would re-run for the same `resources`, + +`POST /v1/configs/sync-jobs/{id}/retry-plan` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Request Body** + +**Sample Call** + +```bash +epilot configuration-hub planSyncJobRetry \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"resources":[{"type":"string","source_id":"string"}]}' +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub planSyncJobRetry 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub planSyncJobRetry -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub planSyncJobRetry -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'selected' +``` + +
+Sample Response + +```json +{ + "selected": [ + { + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string", + "reason": "typed_reference" + }, + "status": "pending", + "phase": "phase_0", + "attempt": 0, + "error": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "source_link": "string", + "target_link": "string", + "plan": { + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changed_paths": ["string"], + "note": "string", + "depends_on": [ + { + "type": "string", + "source_id": "string" + } + ] + }, + "excluded_from_apply": "unchanged" + } + ], + "added_dependencies": [ + { + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string", + "reason": "typed_reference" + }, + "status": "pending", + "phase": "phase_0", + "attempt": 0, + "error": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "source_link": "string", + "target_link": "string", + "plan": { + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changed_paths": ["string"], + "note": "string", + "depends_on": [ + { + "type": "string", + "source_id": "string" + } + ] + }, + "excluded_from_apply": "unchanged" + } + ], + "dependency_resolution": "exact" +} +``` + +
+ +--- + +### `cancelSyncJob` + +Cancel a running sync job. Marks the job `cancelled` with a `finished_at` + +`POST /v1/configs/sync-jobs/{id}/cancel` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Sample Call** + +```bash +epilot configuration-hub cancelSyncJob \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub cancelSyncJob 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub cancelSyncJob -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": {} + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `listSyncJobEvents` + +Full activity log of a sync job, latest first: one event per resource + +`GET /v1/configs/sync-jobs/{id}/events` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | +| `cursor` | query | string | No | Opaque cursor for fetching the next page. Omit for the first page. | +| `size` | query | number | No | Number of events per page | +| `after` | query | string | No | Only return events strictly newer than this event id (max 500, +latest first). `truncated: true` means more new events existed than +were returned — reload from the first page. + | +| `kind` | query | string | No | Comma-separated event kinds to return (`resource`, `dependency`, +`step`), e.g. `dependency,step`. Omit for every kind. Applies to +pages, `after` polling and `total`. + | + +**Sample Call** + +```bash +epilot configuration-hub listSyncJobEvents \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub listSyncJobEvents 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub listSyncJobEvents -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": { + "outcome": "added", + "reason": "typed_reference", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string" + }, + "depth": 0 + } + } + ], + "next_cursor": "string", + "total": 0, + "truncated": true, + "source": "events" +} +``` + +
+ +--- + +### `listSyncJobResources` + +List the per-resource rows for a sync job. Supports filtering by status + +`GET /v1/configs/sync-jobs/{id}/resources` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | +| `cursor` | query | string | No | Opaque cursor for fetching the next page. Omit for the first page. | +| `size` | query | number | No | Number of items per page | +| `status` | query | "pending" \| "in_progress" \| "created" \| "patched" \| "skipped" \| "would_create" \| "would_patch" \| "would_skip_unchanged" \| "would_match_heuristic" \| "failed" | No | Filter resources by status | +| `type` | query | string | No | Filter resources by resource type | +| `plan_action` | query | "create" \| "update" \| "no_change" \| "skip" | No | Filter resources by plan action (`plan.action`). Only rows of plan +jobs and of jobs applying a plan carry one. + | + +**Sample Call** + +```bash +epilot configuration-hub listSyncJobResources \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub listSyncJobResources 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub listSyncJobResources -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string", + "reason": "typed_reference" + }, + "status": "pending", + "phase": "phase_0", + "attempt": 0, + "error": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "source_link": "string", + "target_link": "string", + "plan": { + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changed_paths": ["string"], + "note": "string", + "depends_on": [ + { + "type": "string", + "source_id": "string" + } + ] + }, + "excluded_from_apply": "unchanged" + } + ] +} +``` + +
+ +--- + +### `getSyncPlan` + +Summary of a plan: a dry-run sync job (`createSyncJob` with + +`GET /v1/configs/sync-jobs/{id}/plan` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Sample Call** + +```bash +epilot configuration-hub getSyncPlan \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub getSyncPlan 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub getSyncPlan -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'job_id' +``` + +
+Sample Response + +```json +{ + "job_id": "string", + "status": "pending", + "ready": true, + "applicable": true, + "expires_at": "1970-01-01T00:00:00.000Z", + "planned_at": "1970-01-01T00:00:00.000Z", + "replanned_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "target_org_id": "string", + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "by_type": [ + { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0, + "type": "string" + } + ], + "applied_by": ["string"] +} +``` + +
+ +--- + +### `listSyncPlanDiffs` + +Field-level diffs of a plan, one per planned resource: what the target + +`GET /v1/configs/sync-jobs/{id}/plan/diffs` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | +| `cursor` | query | string | No | Opaque cursor for fetching the next page. Omit for the first page. | +| `size` | query | number | No | Number of diffs per page | +| `type` | query | string | No | Only diffs of this resource type | +| `action` | query | "create" \| "update" \| "no_change" \| "skip" | No | Only diffs with this plan action | + +**Sample Call** + +```bash +epilot configuration-hub listSyncPlanDiffs \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub listSyncPlanDiffs 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub listSyncPlanDiffs -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changes": [ + { + "path": "string", + "kind": "added", + "before": {}, + "after": {} + } + ], + "truncated": true, + "note": "string", + "planned_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `getSyncPlanDiff` + +Field-level diff of one planned resource. See `listSyncPlanDiffs`. + +`GET /v1/configs/sync-jobs/{id}/plan/diffs/{type}/{source_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | +| `type` | path | string | Yes | Resource type | +| `source_id` | path | string | Yes | Source-org resource id | + +**Sample Call** + +```bash +epilot configuration-hub getSyncPlanDiff \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -p type=example \ + -p source_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub getSyncPlanDiff 123e4567-e89b-12d3-a456-426614174000 example 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub getSyncPlanDiff -p id=123e4567-e89b-12d3-a456-426614174000 -p type=example -p source_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'type' +``` + +
+Sample Response + +```json +{ + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changes": [ + { + "path": "string", + "kind": "added", + "before": {}, + "after": {} + } + ], + "truncated": true, + "note": "string", + "planned_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `applySyncPlan` + +Run a finished plan for real. Creates a new sync job (it carries + +`POST /v1/configs/sync-jobs/{id}/plan/apply` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub applySyncPlan \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot configuration-hub applySyncPlan \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "target_auth_token": "string", + "name": "string", + "resources": [ + { + "type": "string", + "source_id": "string" + } + ], + "exclude": [ + { + "type": "string", + "source_id": "string" + } + ], + "allow_missing_dependencies": false +}' +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub applySyncPlan 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub applySyncPlan -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub applySyncPlan -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": {} + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `replanSyncPlan` + +Plan some rows of a plan again, in place, e.g. after fixing a + +`POST /v1/configs/sync-jobs/{id}/plan/replan` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Sync job ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub replanSyncPlan \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"target_auth_token":"string","resources":[{"type":"string","source_id":"string"}]}' +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub replanSyncPlan 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub replanSyncPlan -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub replanSyncPlan -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `listDeleteJobs` + +List bulk-delete jobs scoped to the caller's organization, paginated + +`GET /v1/configs/delete-jobs` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `cursor` | query | string | No | Opaque cursor for fetching the next page. Omit for the first page. | +| `size` | query | number | No | Number of items per page | + +**Sample Call** + +```bash +epilot configuration-hub listDeleteJobs +``` + +With JSONata filter: + +```bash +epilot configuration-hub listDeleteJobs --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "id": "string", + "name": "string", + "status": "pending", + "org_id": "string", + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "deleted": 0, + "skipped": 0, + "failed": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "rebuild_triggered": true + } + ] +} +``` + +
+ +--- + +### `createDeleteJob` + +Create a bulk-delete job for the caller's organization. The selected + +`POST /v1/configs/delete-jobs` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot configuration-hub createDeleteJob \ + -d '{"name":"string","resources":[{"type":"string","id":"string","title":"string"}]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub createDeleteJob +``` + +With JSONata filter: + +```bash +epilot configuration-hub createDeleteJob --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "org_id": "string", + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "deleted": 0, + "skipped": 0, + "failed": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "rebuild_triggered": true +} +``` + +
+ +--- + +### `getDeleteJob` + +Fetch a single bulk-delete job by ID. Returns the job header and counts + +`GET /v1/configs/delete-jobs/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Delete job ID | + +**Sample Call** + +```bash +epilot configuration-hub getDeleteJob \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub getDeleteJob 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub getDeleteJob -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "org_id": "string", + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "deleted": 0, + "skipped": 0, + "failed": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "rebuild_triggered": true +} +``` + +
+ +--- + +### `listDeleteJobResources` + +List the per-resource rows for a delete job, cursor-paginated. Used by + +`GET /v1/configs/delete-jobs/{id}/resources` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Delete job ID | +| `cursor` | query | string | No | Opaque cursor for fetching the next page. Omit for the first page. | +| `size` | query | number | No | Number of items per page | + +**Sample Call** + +```bash +epilot configuration-hub listDeleteJobResources \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub listDeleteJobResources 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub listDeleteJobResources -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "type": "string", + "id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "error": "string", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `rebuildIndex` + +Rebuild the configuration index for the caller's organization. + +`POST /v1/configs/index:rebuild` + +**Sample Call** + +```bash +epilot configuration-hub rebuildIndex +``` + +With JSONata filter: + +```bash +epilot configuration-hub rebuildIndex --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "ready", + "last_built_at": "1970-01-01T00:00:00.000Z", + "total_items": 0, + "build_duration_ms": 0, + "failed_types": ["string"] +} +``` + +
+ +--- + +### `getConfigInventory` + +Returns a fresh inventory of an org's configuration resources — `{ type, id }` identities only, + +`GET /v1/configs/inventory` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `include_dependency_only` | query | boolean | No | When true (default), include dependency-only types (e.g. `entity_mapping`) +in the inventory in addition to the top-level registered types. + | + +**Sample Call** + +```bash +epilot configuration-hub getConfigInventory +``` + +With JSONata filter: + +```bash +epilot configuration-hub getConfigInventory --jsonata 'inventory_id' +``` + +
+Sample Response + +```json +{ + "inventory_id": "string", + "org_id": "string", + "indexed_at": "1970-01-01T00:00:00.000Z", + "resources_count": 0, + "resources": [ + { + "type": "journey", + "id": "string" + } + ], + "skipped_types": [ + { + "type": "string", + "reason": "string" + } + ] +} +``` + +
+ +--- + +### `listPreviews` + +Lists the previews requested from the caller's current org, newest first (max 50). + +`GET /v1/previews` + +**Sample Call** + +```bash +epilot configuration-hub listPreviews +``` + +With JSONata filter: + +```bash +epilot configuration-hub listPreviews --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "id": "string", + "name": "string", + "status": "creating_org", + "source_org_id": "string", + "preview_org_id": "string", + "sync_job_id": "string", + "sync_status": "string", + "requested_by": { + "user_id": "string", + "email": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `createPreview` + +Starts a preview of the caller's current org (internal callers: the org in `x-ivy-org-id`, + +`POST /v1/previews` + +**Request Body** + +**Sample Call** + +```bash +epilot configuration-hub createPreview \ + -d '{"name":"string","requester":{"user_id":"string","email":"user@example.com","display_name":"string","language":"de"}}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot configuration-hub createPreview +``` + +With JSONata filter: + +```bash +epilot configuration-hub createPreview --jsonata '$' +``` + +--- + +### `getPreview` + +Returns a preview requested from the caller's current org, with its progress. + +`GET /v1/previews/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot configuration-hub getPreview \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot configuration-hub getPreview 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot configuration-hub getPreview -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "name": "string", + "status": "creating_org", + "source_org_id": "string", + "preview_org_id": "string", + "sync_job_id": "string", + "sync_status": "string", + "requested_by": { + "user_id": "string", + "email": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" +} +``` + +
+ +--- diff --git a/docs/cli/commands/customer-portal.md b/docs/cli/commands/customer-portal.md index 2c79b2f8..5595d0eb 100644 --- a/docs/cli/commands/customer-portal.md +++ b/docs/cli/commands/customer-portal.md @@ -53,10 +53,13 @@ epilot customer-portal upsertPortal -p origin=example - [`getAllPortalConfigs`](#getallportalconfigs) — Retrieves all portal configurations. - [`getEmailTemplates`](#getemailtemplates) — Retrieves the email templates of a portal - [`upsertEmailTemplates`](#upsertemailtemplates) — Upserts the email templates of a portal +- [`migrateEmailTemplateReferences`](#migrateemailtemplatereferences) — Walk every email-template config row in the caller's org and re-point any +- [`listEmailTemplateReferences`](#listemailtemplatereferences) — Read-only sibling of migrateEmailTemplateReferences. Lists every portal in - [`getEmailTemplatesByPortalId`](#getemailtemplatesbyportalid) — Retrieves the email templates of a portal by portal ID - [`upsertEmailTemplatesByPortalId`](#upsertemailtemplatesbyportalid) — Upserts the email templates of a portal by portal ID -- [`getPortalWidgets`](#getportalwidgets) — Retrieves the widgets of a portal -- [`upsertPortalWidget`](#upsertportalwidget) — Upsert widget for a portal of an organization. +- [`getPortalWidgetsV3`](#getportalwidgetsv3) — Retrieves the widgets of a portal by portal_id. +- [`upsertPortalWidgetV3`](#upsertportalwidgetv3) — Upsert widget for a portal by portal_id. +- [`savePortalFilesV3`](#saveportalfilesv3) — Add files to portal by portal_id - [`replaceECPTemplateVariables`](#replaceecptemplatevariables) — Replaces the template variables of a portal - [`extraPermissionAttributes`](#extrapermissionattributes) — Retrieves the extra permission attributes. - [`validateCaaRecords`](#validatecaarecords) — Validates the CAA records of a portal @@ -76,6 +79,7 @@ epilot customer-portal upsertPortal -p origin=example - [`updatePortalPage`](#updateportalpage) — Update a portal page by id - [`deletePortalPage`](#deleteportalpage) — Delete a portal page by id - [`createPortalPage`](#createportalpage) — Create a new portal page +- [`interpolatePortalPages`](#interpolateportalpages) — Interpolate template variables in portal pages without reading from the database. Accepts pages in the request body and - [`getDefaultPages`](#getdefaultpages) — Fetch all default portal pages - [`createPortalPageBlock`](#createportalpageblock) — Create a new portal page block - [`updatePortalPageBlock`](#updateportalpageblock) — Update a portal page block by id @@ -84,26 +88,38 @@ epilot customer-portal upsertPortal -p origin=example - [`getPortalConfigV3`](#getportalconfigv3) — Retrieves a specific portal configuration by ID. - [`putPortalConfig`](#putportalconfig) — Updates a specific portal configuration by ID. - [`deletePortalConfig`](#deleteportalconfig) — Deletes a specific portal configuration by ID. +- [`listPortalRevisions`](#listportalrevisions) — Lists a portal's revision history, newest first. Metadata only — no config blob, no page bodies. `is_published` says whe +- [`createPortalRevision`](#createportalrevision) — Creates a new revision — a complete, immutable snapshot of the portal's configuration, pages and email templates. Nothin +- [`getPortalRevision`](#getportalrevision) — Returns the full content of one revision: the snapshotted config, its pages (in the live `Page` shape), email templates +- [`publishPortalRevision`](#publishportalrevision) — Makes one revision the portal's live configuration, atomically: either everything below takes effect or nothing does. Pu - [`listAllPortalConfigs`](#listallportalconfigs) — Retrieves all portal configurations. - [`swapPortalConfig`](#swapportalconfig) — Swaps the portal configuration of two portals. +- [`clonePortalConfig`](#cloneportalconfig) — Creates a new portal by cloning configuration and pages from an existing portal. The new portal gets its own domain, use +- [`verifyDns`](#verifydns) — Manually triggers DNS verification for a portal's domain setup. Runs the same verification logic as the scheduled proces +- [`getMobileConfig`](#getmobileconfig) — Returns the portal's mobile app configuration. By default the response is build-ready (resolved): base info (display_nam +- [`putMobileConfig`](#putmobileconfig) — Merges the provided fields into the portal's mobile app configuration **Public** -- [`createUser`](#createuser) — Registers a portal user -- [`createUserV3`](#createuserv3) — Registers a portal user with portal id +- [`createUserV3`](#createuserv3) — Registers a portal user. - [`getPortalConfigByDomain`](#getportalconfigbydomain) — Retrieves the portal configuration by domain. - [`getPublicPortalExtensionDetails`](#getpublicportalextensiondetails) — Get public extension details shown to end customers and configuring users. - [`getPublicPortalExtensionDetailsV3`](#getpublicportalextensiondetailsv3) — Get public extension details shown to end customers and configuring users. - [`getPublicPortalConfig`](#getpublicportalconfig) — Retrieves the public portal configuration. - [`getPublicPortalConfigV3`](#getpublicportalconfigv3) — Retrieves the public portal configuration. -- [`getPublicPortalWidgets`](#getpublicportalwidgets) — Retrieves the public widgets of a portal +- [`getPublicPortalWidgetsV3`](#getpublicportalwidgetsv3) — Retrieves the public widgets of a portal. - [`getSchemasByDomain`](#getschemasbydomain) — Retrieves schemas by domain. Only schemas and attributes used on public pages are returned. +- [`getPublicSchemasV3`](#getpublicschemasv3) — Retrieves schemas by portal. Only schemas and attributes used on public pages are returned. - [`getOrganizationSettingsByDomain`](#getorganizationsettingsbydomain) — Retrieves organization settings by domain. Only public organization settings are returned. - [`checkContactExists`](#checkcontactexists) — True if contact with given identifiers exists. - [`checkContactExistsV3`](#checkcontactexistsv3) — True if contact with given identifiers exists. +- [`identifyContact`](#identifycontact) — Identify a contact by the portal's configured registration identifiers and, on a match, +- [`checkAccountExists`](#checkaccountexists) — True if account with given identifiers exists. - [`confirmUser`](#confirmuser) — Confirm a portal user - [`confirmUserWithUserId`](#confirmuserwithuserid) — Confirm a portal user - [`userExists`](#userexists) — Checks whether a user exists in the portal -- [`userExistsV3`](#userexistsv3) — Checks whether a user exists in the portal +- [`userExistsV3`](#userexistsv3) — Checks whether a user exists in the portal. +- [`getSSOProvider`](#getssoprovider) — Returns the public configuration of a single SSO identity provider with env var +- [`getPublicSSOProviderV3`](#getpublicssoproviderv3) — Returns the public configuration of a single SSO identity provider with env var - [`ssoRedirect`](#ssoredirect) — Handles the redirect from the external SSO provider. Validates the authorization `code` and `state` received from the pr - [`ssoCallback`](#ssocallback) — Handles the callback from the external SSO provider, validates the authorization `code` - [`getPublicPages`](#getpublicpages) — Fetch all public portal pages @@ -114,54 +130,56 @@ epilot customer-portal upsertPortal -p origin=example **ECP** - [`validateToken`](#validatetoken) — Validates Portal Token is valid. Pass the token via Authorization Header. - [`revokeToken`](#revoketoken) — Revokes all of the access tokens for the given Refresh Token. +- [`createExport`](#createexport) — Request an asynchronous CSV export of the portal user's entities for one schema. Columns come from the request Returns a +- [`getExport`](#getexport) — Get the status of an export job, including the download URL once ready. - [`getConsumption`](#getconsumption) — Get energy consumption data between a given time period. +- [`prepareVisualizationExport`](#preparevisualizationexport) — Asks an installed App to prepare a downloadable export of a visualization (consumption chart, dynamic tariff chart, etc. +- [`getVisualizationMetadata`](#getvisualizationmetadata) — Returns runtime metadata describing how a visualization (consumption / price / cost chart) should be rendered for a give - [`getCosts`](#getcosts) — Get energy cost data between a given time period. - [`getPrices`](#getprices) — Get energy prices data between a given time period. - [`getResolvedSeamlessLink`](#getresolvedseamlesslink) — Retrieves a resolved seamless portal link. - [`getSchemas`](#getschemas) — Retrieves the schemas. Only schemas usable in the private part of the portal are returned. - [`getContact`](#getcontact) — Retrieves the contact of the logged in user. -- [`updateContact`](#updatecontact) — Updates the contact details. - [`getPortalUser`](#getportaluser) — Get the portal user details - [`updatePortalUser`](#updateportaluser) — Update the portal user details - [`deletePortalUser`](#deleteportaluser) — Delete the portal user - [`updatePortalUserEmail`](#updateportaluseremail) — Update portal user email -- [`getAllOrders`](#getallorders) — Get all orders for the portal user +- [`changePortalUserPassword`](#changeportaluserpassword) — Hand over a password change to the third-party system configured via the `changePassword` portal extension hook. - [`postOrderAcceptance`](#postorderacceptance) — Accept/decline an offer by id -- [`getOrder`](#getorder) — Get an order by id -- [`updateOrder`](#updateorder) — Update an order by id -- [`getAllOpportunities`](#getallopportunities) — Get all opportunities of a portal user -- [`getSearchableAttributesForOpportunities`](#getsearchableattributesforopportunities) — Get all opportunity searchable attributes for a portal user -- [`getSearchResultsForOpportunities`](#getsearchresultsforopportunities) — Get all opportunity with the given serached attributes -- [`getOpportunity`](#getopportunity) — Get an opportunity by id -- [`updateOpportunity`](#updateopportunity) — Update an opportunity by id -- [`getAllRequests`](#getallrequests) — Get all opportunities & orders of a portal user -- [`getAllContracts`](#getallcontracts) — Get all contracts for a portal user -- [`getContract`](#getcontract) — Get a contract by id -- [`updateContract`](#updatecontract) — Update a contract by id +- [`getContractWithTemplates`](#getcontractwithtemplates) — Resolve Handlebars templates against a contract's related meters and return the contract with templates_output populated - [`addContractByIdentifiers`](#addcontractbyidentifiers) — Self-assign contract(s) by pre-configured identifiers. - [`validateCadenceEntityEditRules`](#validatecadenceentityeditrules) — Validate if cadence rule is valid for an entity - [`searchPaymentRelationsInEntities`](#searchpaymentrelationsinentities) — Search for entities that have the payment relation with the given payment id - [`createCustomEntityActivity`](#createcustomentityactivity) — Create a custom activity that can be displayed in activity feed of an entity. - [`saveEntityFile`](#saveentityfile) — Add files to an entity - [`deleteEntityFile`](#deleteentityfile) — Delete files from an entity -- [`getFileById`](#getfilebyid) — Fetch a document with ID +- [`getFilePreview`](#getfilepreview) — resolves an in-portal preview for a file. Returns a Content-Disposition: inline URL for directly-previewable files (PDF, - [`trackFileDownloaded`](#trackfiledownloaded) — Track that user has downloaded a file - [`getBillingEvents`](#getbillingevents) — Fetch billing events for a portal user - [`triggerEntityAccessEvent`](#triggerentityaccessevent) — Trigger entity access event for a portal user -- [`triggerEntityAccessEventV3`](#triggerentityaccesseventv3) — Trigger entity access event for a portal user +- [`triggerEntityAccessEventV3`](#triggerentityaccesseventv3) — Trigger entity access event for a portal user. - [`getPortalUserEntity`](#getportaluserentity) — Get a single entity for a portal user - [`searchPortalUserEntities`](#searchportaluserentities) — Search all entities of a portal user - [`getAutomationContext`](#getautomationcontext) — Retrieves the automation context. - [`updateWorkflowStepAsDone`](#updateworkflowstepasdone) — Update a workflow step as done - [`getEntityWorkflows`](#getentityworkflows) — Get all workflows associated with an entity (requires access to the entity) +- [`getOutstandingTasks`](#getoutstandingtasks) — Returns all outstanding workflow journey tasks for the authenticated portal user, across their opportunity, order and co +- [`getEntityPortalWorkflows`](#getentityportalworkflows) — Get all portal-relevant workflows associated with an entity (requires access to the entity), +- [`getEntityPortalWorkflowsBatch`](#getentityportalworkflowsbatch) — Batch variant of `getEntityPortalWorkflows`: returns portal-relevant workflows for - [`uploadMeterReadingPhoto`](#uploadmeterreadingphoto) — Uploads a Meter Reading photo and - if enabled - gives back data extracted from the photo. - [`createMeterReading`](#createmeterreading) — Inserts a new meter reading. - [`getAllowedMeterReadingRange`](#getallowedmeterreadingrange) — Get allowed reading range for all counters of a meter from the configured +- [`getMeterReadings`](#getmeterreadings) — Fetches meter readings for a counter and optionally resolves Handlebars - [`getPortalPage`](#getportalpage) — Fetch a portal page by id - [`getPortalPages`](#getportalpages) — Fetch all portal pages +- [`getTriggeredJourney`](#gettriggeredjourney) — Returns the auto-triggered journey configured for the given trigger - [`getPortalPageBlocks`](#getportalpageblocks) — Fetch all portal page blocks - [`getPortalPageBlock`](#getportalpageblock) — Fetch a portal page block by id - [`updateCampaignPortalBlockStatus`](#updatecampaignportalblockstatus) — Updates the status of a campaign portal block for multiple recipients. +- [`listPortalNotifications`](#listportalnotifications) — Lists the 360 notifications addressed to the authenticated portal user, newest first. The organization and the portal us +- [`getPortalNotificationsUnreadCount`](#getportalnotificationsunreadcount) — Returns the number of unread notifications for the authenticated portal user. +- [`markAllPortalNotificationsRead`](#markallportalnotificationsread) — Marks all notifications of the authenticated portal user as read. +- [`markPortalNotificationRead`](#markportalnotificationread) — Marks a single notification of the authenticated portal user as read. - [`updateNotificationsStatus`](#updatenotificationsstatus) — Updates the statuses of multiple notifications at once. - [`invitePartner`](#invitepartner) — Invites a partner to a portal - [`listBusinessPartners`](#listbusinesspartners) — Lists all business partners linked to the businessaccount @@ -169,6 +187,7 @@ epilot customer-portal upsertPortal -p origin=example - [`revokePartner`](#revokepartner) — Revokes a partner from a portal - [`disablePartner`](#disablepartner) — Disables a partner from a portal - [`enablePartner`](#enablepartner) — Enables a partner from a portal +- [`portalProxyExecute`](#portalproxyexecute) — Execute an Integration Hub managed-call use case on behalf of a portal user. **Activity** - [`getEntityActivityFeed`](#getentityactivityfeed) — Get activity feed for an entity @@ -231,6 +250,55 @@ epilot customer-portal upsertPortal \ {} ] }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -242,13 +310,19 @@ epilot customer-portal upsertPortal \ "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -260,19 +334,31 @@ epilot customer-portal upsertPortal \ }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -333,10 +419,41 @@ epilot customer-portal upsertPortal \ "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -370,10 +487,21 @@ epilot customer-portal upsertPortal \ "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", - "pages": {} + "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_created", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + ], + "engagement_center_enabled": true }' ``` @@ -394,6 +522,43 @@ epilot customer-portal upsertPortal -p origin=example --jsonata '$' ```json { + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -405,13 +570,19 @@ epilot customer-portal upsertPortal -p origin=example --jsonata '$' "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -423,19 +594,31 @@ epilot customer-portal upsertPortal -p origin=example --jsonata '$' }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -496,10 +679,41 @@ epilot customer-portal upsertPortal -p origin=example --jsonata '$' "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -533,10 +747,21 @@ epilot customer-portal upsertPortal -p origin=example --jsonata '$' "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_created", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + ], + "engagement_center_enabled": true, "id": 12345, "organization_id": 12345, "org_settings": { @@ -570,80 +795,9 @@ epilot customer-portal upsertPortal -p origin=example --jsonata '$' --- -### `createUser` - -Registers a portal user - -`POST /v2/portal/public/user` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `origin` | query | string | Yes | Origin of the portal | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot customer-portal createUser \ - -p origin=example -``` - -With request body: - -```bash -epilot customer-portal createUser \ - -p origin=example \ - -d '{ - "email": "testemail921@yopmail.com", - "first_name": "John", - "last_name": "Doe", - "contactId": "5da0a718-c822-403d-9f5d-20d4584e0528", - "orgId": 728, - "password": "124n$aAJs*d41h4", - "contactIdentifiers": {}, - "registration_identifiers": { - "contact": { - "email": "john.doe@example.com" - }, - "contract": { - "contract_number": "123456" - } - }, - "account_id": "string" -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal createUser -p origin=example -``` - -With JSONata filter: - -```bash -epilot customer-portal createUser -p origin=example --jsonata 'message' -``` - -
-Sample Response - -```json -{ - "message": "User created successfully" -} -``` - -
- ---- - ### `createUserV3` -Registers a portal user with portal id +Registers a portal user. `POST /v3/portal/public/user` @@ -651,22 +805,21 @@ Registers a portal user with portal id | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `portal_id` | query | string | Yes | Origin of the portal | +| `portal_id` | query | string | No | Portal ID (required if domain is not provided) | +| `domain` | query | string | No | Portal domain for identification (alternative to portal_id) | **Request Body** (required) **Sample Call** ```bash -epilot customer-portal createUserV3 \ - -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c +epilot customer-portal createUserV3 ``` With request body: ```bash epilot customer-portal createUserV3 \ - -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c \ -d '{ "email": "testemail921@yopmail.com", "first_name": "John", @@ -683,6 +836,14 @@ epilot customer-portal createUserV3 \ "contract_number": "123456" } }, + "contact_identifiers_for_account": { + "first_name": "John", + "last_name": "Doe" + }, + "additional_contact_attributes": { + "first_name": "John", + "last_name": "Doe" + }, "account_id": "string" }' ``` @@ -690,13 +851,13 @@ epilot customer-portal createUserV3 \ Using stdin pipe: ```bash -cat body.json | epilot customer-portal createUserV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c +cat body.json | epilot customer-portal createUserV3 ``` With JSONata filter: ```bash -epilot customer-portal createUserV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c --jsonata 'message' +epilot customer-portal createUserV3 --jsonata 'message' ```
@@ -810,6 +971,43 @@ epilot customer-portal getPortalConfigByDomain -p domain=example.com --jsonata ' ```json { + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -821,13 +1019,19 @@ epilot customer-portal getPortalConfigByDomain -p domain=example.com --jsonata ' "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -839,19 +1043,31 @@ epilot customer-portal getPortalConfigByDomain -p domain=example.com --jsonata ' }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -912,10 +1128,41 @@ epilot customer-portal getPortalConfigByDomain -p domain=example.com --jsonata ' "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -949,10 +1196,21 @@ epilot customer-portal getPortalConfigByDomain -p domain=example.com --jsonata ' "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_created", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + ], + "engagement_center_enabled": true, "id": 12345, "organization_id": 12345, "org_settings": { @@ -1015,6 +1273,43 @@ epilot customer-portal getPortalConfig --jsonata '$' ```json { + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -1026,13 +1321,19 @@ epilot customer-portal getPortalConfig --jsonata '$' "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -1044,19 +1345,31 @@ epilot customer-portal getPortalConfig --jsonata '$' }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -1117,10 +1430,41 @@ epilot customer-portal getPortalConfig --jsonata '$' "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -1154,10 +1498,21 @@ epilot customer-portal getPortalConfig --jsonata '$' "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_created", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + ], + "engagement_center_enabled": true, "id": 12345, "organization_id": 12345, "org_settings": { @@ -1218,28 +1573,141 @@ epilot customer-portal deletePortal -p origin=example --jsonata '$' --- -### `getPortalExtensions` +### `createExport` -Retrieves the installed portal extensions. +Request an asynchronous CSV export of the portal user's entities for one schema. Columns come from the request Returns a -`GET /v2/portal/extensions` +`POST /v1/portal/exports` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal createExport +``` + +With request body: + +```bash +epilot customer-portal createExport \ + -d '{ + "schema": "string", + "search": { + "q": "string", + "q_fields": ["string"], + "filters": [ + {} + ], + "filters_context": [ + {} + ], + "sort": {} + }, + "columns": [ + { + "key": "vertragsnummer", + "header": { + "de": "Vertragsnummer", + "en": "Contract number" + }, + "source": { + "path": ["customer"], + "attribute": "customer_number", + "address_field": "full" + }, + "formatter": "text", + "enum_labels": {} + } + ], + "expand_over": "string", + "language": "de" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal createExport +``` + +With JSONata filter: + +```bash +epilot customer-portal createExport --jsonata '$' +``` + +--- + +### `getExport` + +Get the status of an export job, including the download URL once ready. + +`GET /v1/portal/exports/{jobId}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `origin` | query | string | No | Origin of the portal | +| `jobId` | path | string | Yes | The export job id returned by createExport. | **Sample Call** ```bash -epilot customer-portal getPortalExtensions +epilot customer-portal getExport \ + -p jobId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal getExport 123e4567-e89b-12d3-a456-426614174000 ``` With JSONata filter: ```bash -epilot customer-portal getPortalExtensions --jsonata '$' +epilot customer-portal getExport -p jobId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'jobId' +``` + +
+Sample Response + +```json +{ + "jobId": "string", + "status": "queued", + "downloadUrl": "string", + "error": "string" +} +``` + +
+ +--- + +### `getPortalExtensions` + +Retrieves the installed portal extensions. + +`GET /v2/portal/extensions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `origin` | query | string | No | Origin of the portal | + +**Sample Call** + +```bash +epilot customer-portal getPortalExtensions +``` + +With JSONata filter: + +```bash +epilot customer-portal getPortalExtensions --jsonata '$' ```
@@ -1309,78 +1777,98 @@ epilot customer-portal getPublicPortalExtensionDetails -p org_id=12324 -p origin { "consumptionDataRetrieval": [ { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } + "app": {}, + "extension": {}, + "hook": {} + } + ], + "dataExport": [ + { + "app": {}, + "extension": {}, + "hook": {} } ], "priceDataRetrieval": [ { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } + "app": {}, + "extension": {}, + "hook": {} } ], "costDataRetrieval": [ { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } + "app": {}, + "extension": {}, + "hook": {} } ], "contractIdentification": { + "app": { + "app_id": "string", + "name": {} + }, "extension": { "id": "string", - "name": { - "en": "string" - } + "name": {} }, "hook": { - "explanation": { - "en": "This process will give you access to all Contracts kept" - } + "explanation": {} } }, "meterReadingPlausibilityCheck": { "extension": { "id": "string", - "name": { - "en": "string" - } + "name": {} }, "hook": { "plausibility_mode": "check" } + }, + "changeEmail": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "change_mode": "asynchronous", + "require_password_confirmation": true, + "explanation": {} + } + }, + "changePassword": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "require_new_password": false, + "explanation": {} + } + }, + "deleteAccount": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "explanation": {} + } } } ``` @@ -1480,78 +1968,98 @@ epilot customer-portal getPublicPortalExtensionDetailsV3 --jsonata 'consumptionD { "consumptionDataRetrieval": [ { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } + "app": {}, + "extension": {}, + "hook": {} + } + ], + "dataExport": [ + { + "app": {}, + "extension": {}, + "hook": {} } ], "priceDataRetrieval": [ { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } + "app": {}, + "extension": {}, + "hook": {} } ], "costDataRetrieval": [ { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } + "app": {}, + "extension": {}, + "hook": {} } ], "contractIdentification": { + "app": { + "app_id": "string", + "name": {} + }, "extension": { "id": "string", - "name": { - "en": "string" - } + "name": {} }, "hook": { - "explanation": { - "en": "This process will give you access to all Contracts kept" - } + "explanation": {} } }, "meterReadingPlausibilityCheck": { "extension": { "id": "string", - "name": { - "en": "string" - } + "name": {} }, "hook": { "plausibility_mode": "check" } + }, + "changeEmail": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "change_mode": "asynchronous", + "require_password_confirmation": true, + "explanation": {} + } + }, + "changePassword": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "require_new_password": false, + "explanation": {} + } + }, + "deleteAccount": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "explanation": {} + } } } ``` @@ -1572,11 +2080,11 @@ Get energy consumption data between a given time period. | ---- | -- | ---- | -------- | ----------- | | `app_id` | query | string | No | App ID for consumption data. | | `extensionId` | query | string | Yes | Extension ID for consumption data. | -| `hookId` | query | string | Yes | Hook ID for consumption data. | +| `hookId` | query | string | No | Optional Hook ID. If omitted, the only matching hook on the extension is used; if the extension has multiple hooks of the relevant type, this becomes required. | | `meter_id` | query | string | No | Meter ID for consumption data. Deprecated - use context_entities instead. | | `from` | query | string (date-time) | Yes | Start date for consumption data (ISO 8601 format). | | `to` | query | string (date-time) | Yes | End date for consumption data (ISO 8601 format). | -| `interval` | query | "PT15M" \| "PT1H" \| "P1D" \| "P1M" | Yes | Interval between consumption data points (e.g., PT15M for 15 minutes, PT1H for hourly). Not all intervals have to be supported. | +| `interval` | query | "PT15M" \| "PT1H" \| "P1D" \| "P1M" \| "P1Y" \| "custom" | Yes | Interval between consumption data points (e.g., PT15M for 15 minutes, PT1H for hourly). Not all intervals have to be supported. `custom` is period-based retrieval for sources that advertise it in thei | | `context_entities` | query | object[] | No | Additional entities to include in the context for variable interpolation in the hook. | **Sample Call** @@ -1584,7 +2092,6 @@ Get energy consumption data between a given time period. ```bash epilot customer-portal getConsumption \ -p extensionId=123e4567-e89b-12d3-a456-426614174000 \ - -p hookId=123e4567-e89b-12d3-a456-426614174000 \ -p from=example \ -p to=example \ -p interval=example @@ -1593,7 +2100,7 @@ epilot customer-portal getConsumption \ With JSONata filter: ```bash -epilot customer-portal getConsumption -p extensionId=123e4567-e89b-12d3-a456-426614174000 -p hookId=123e4567-e89b-12d3-a456-426614174000 -p from=example -p to=example -p interval=example --jsonata 'consumptions' +epilot customer-portal getConsumption -p extensionId=123e4567-e89b-12d3-a456-426614174000 -p from=example -p to=example -p interval=example --jsonata 'consumptions' ```
@@ -1605,9 +2112,135 @@ epilot customer-portal getConsumption -p extensionId=123e4567-e89b-12d3-a456-426 { "timestamp": "1970-01-01T00:00:00.000Z", "value": 0, - "type": "string" + "type": "nt", + "unit": "kWh", + "label": { + "en": "Billing period 1", + "de": "Abrechnungszeitraum 1" + }, + "period": { + "from": "2024-01-03T00:00:00.000Z", + "to": "2025-01-05T00:00:00.000Z" + } + } + ] +} +``` + +
+ +--- + +### `prepareVisualizationExport` + +Asks an installed App to prepare a downloadable export of a visualization (consumption chart, dynamic tariff chart, etc. + +`POST /v2/portal/visualization:export` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal prepareVisualizationExport +``` + +With request body: + +```bash +epilot customer-portal prepareVisualizationExport \ + -d '{ + "app_id": "string", + "extension_id": "string", + "hook_id": "string", + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "context_entities": [ + { + "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "entity_schema": "contract" } ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal prepareVisualizationExport +``` + +With JSONata filter: + +```bash +epilot customer-portal prepareVisualizationExport --jsonata 'download_url' +``` + +
+Sample Response + +```json +{ + "download_url": "string", + "filename": "string", + "content_type": "text/csv", + "expires_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getVisualizationMetadata` + +Returns runtime metadata describing how a visualization (consumption / price / cost chart) should be rendered for a give + +`GET /v2/portal/visualization/metadata` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `app_id` | query | string | Yes | App ID providing the visualizationMetadata hook. | +| `extensionId` | query | string | Yes | Extension ID providing the visualizationMetadata hook. | +| `context_entities` | query | object[] | No | Entities to include in the context for variable interpolation in the hook (typically the meter and any other entities that scope the visualization). | + +**Sample Call** + +```bash +epilot customer-portal getVisualizationMetadata \ + -p app_id=123e4567-e89b-12d3-a456-426614174000 \ + -p extensionId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot customer-portal getVisualizationMetadata -p app_id=123e4567-e89b-12d3-a456-426614174000 -p extensionId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'type_options' +``` + +
+Sample Response + +```json +{ + "type_options": [ + { + "id": "string", + "label": {}, + "aggregation_group": "string", + "statistical_method": "sum", + "unit": "string", + "color": "primary", + "precision": 0 + } + ], + "intervals": ["PT15M"], + "data_range": { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z" + } } ``` @@ -1627,11 +2260,11 @@ Get energy cost data between a given time period. | ---- | -- | ---- | -------- | ----------- | | `app_id` | query | string | No | App ID for consumption data. | | `extensionId` | query | string | Yes | Extension ID for cost data. | -| `hookId` | query | string | Yes | Hook ID for cost data. | +| `hookId` | query | string | No | Optional Hook ID. If omitted, the only matching hook on the extension is used; if the extension has multiple hooks of the relevant type, this becomes required. | | `meter_id` | query | string | No | Meter ID for cost data. Deprecated - use context_entities instead. | | `from` | query | string (date-time) | Yes | Start date for cost data (ISO 8601 format). | | `to` | query | string (date-time) | Yes | End date for cost data (ISO 8601 format). | -| `interval` | query | "PT15M" \| "PT1H" \| "P1D" \| "P1M" | Yes | Interval between cost data points (e.g., PT15M for 15 minutes, PT1H for hourly). Not all intervals have to be supported. | +| `interval` | query | "PT15M" \| "PT1H" \| "P1D" \| "P1M" \| "P1Y" | Yes | Interval between cost data points (e.g., PT15M for 15 minutes, PT1H for hourly). Not all intervals have to be supported. | | `context_entities` | query | object[] | No | Additional entities to include in the context for variable interpolation in the hook. | **Sample Call** @@ -1639,7 +2272,6 @@ Get energy cost data between a given time period. ```bash epilot customer-portal getCosts \ -p extensionId=123e4567-e89b-12d3-a456-426614174000 \ - -p hookId=123e4567-e89b-12d3-a456-426614174000 \ -p from=example \ -p to=example \ -p interval=example @@ -1648,7 +2280,7 @@ epilot customer-portal getCosts \ With JSONata filter: ```bash -epilot customer-portal getCosts -p extensionId=123e4567-e89b-12d3-a456-426614174000 -p hookId=123e4567-e89b-12d3-a456-426614174000 -p from=example -p to=example -p interval=example --jsonata 'costs' +epilot customer-portal getCosts -p extensionId=123e4567-e89b-12d3-a456-426614174000 -p from=example -p to=example -p interval=example --jsonata 'costs' ```
@@ -1685,11 +2317,11 @@ Get energy prices data between a given time period. | ---- | -- | ---- | -------- | ----------- | | `app_id` | query | string | No | App ID for consumption data. | | `extensionId` | query | string | Yes | Extension ID for price data. | -| `hookId` | query | string | Yes | Hook ID for price data. | +| `hookId` | query | string | No | Optional Hook ID. If omitted, the only matching hook on the extension is used; if the extension has multiple hooks of the relevant type, this becomes required. | | `meter_id` | query | string | No | Meter ID for price data. Deprecated - use context_entities instead. | | `from` | query | string (date-time) | Yes | Start date for price data (ISO 8601 format). | | `to` | query | string (date-time) | Yes | End date for price data (ISO 8601 format). | -| `interval` | query | "PT15M" \| "PT1H" \| "P1D" \| "P1M" | Yes | Interval between price data points (e.g., PT15M for 15 minutes, PT1H for hourly). Not all intervals have to be supported. | +| `interval` | query | "PT15M" \| "PT1H" \| "P1D" \| "P1M" \| "P1Y" | Yes | Interval between price data points (e.g., PT15M for 15 minutes, PT1H for hourly). Not all intervals have to be supported. | | `context_entities` | query | object[] | No | Additional entities to include in the context for variable interpolation in the hook. | **Sample Call** @@ -1697,7 +2329,6 @@ Get energy prices data between a given time period. ```bash epilot customer-portal getPrices \ -p extensionId=123e4567-e89b-12d3-a456-426614174000 \ - -p hookId=123e4567-e89b-12d3-a456-426614174000 \ -p from=example \ -p to=example \ -p interval=example @@ -1706,7 +2337,7 @@ epilot customer-portal getPrices \ With JSONata filter: ```bash -epilot customer-portal getPrices -p extensionId=123e4567-e89b-12d3-a456-426614174000 -p hookId=123e4567-e89b-12d3-a456-426614174000 -p from=example -p to=example -p interval=example --jsonata 'prices' +epilot customer-portal getPrices -p extensionId=123e4567-e89b-12d3-a456-426614174000 -p from=example -p to=example -p interval=example --jsonata 'prices' ```
@@ -1927,6 +2558,43 @@ epilot customer-portal getPublicPortalConfig -p org_id=12324 -p origin=example - ```json { + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -1938,13 +2606,19 @@ epilot customer-portal getPublicPortalConfig -p org_id=12324 -p origin=example - "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -1956,19 +2630,31 @@ epilot customer-portal getPublicPortalConfig -p org_id=12324 -p origin=example - }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -2029,10 +2715,41 @@ epilot customer-portal getPublicPortalConfig -p org_id=12324 -p origin=example - "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -2066,10 +2783,21 @@ epilot customer-portal getPublicPortalConfig -p org_id=12324 -p origin=example - "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_created", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + ], + "engagement_center_enabled": true, "id": 12345, "organization_id": 12345, "org_settings": { @@ -2133,6 +2861,43 @@ epilot customer-portal getOrgPortalConfig -p origin=example --jsonata '$' ```json { + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -2144,13 +2909,19 @@ epilot customer-portal getOrgPortalConfig -p origin=example --jsonata '$' "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -2162,19 +2933,31 @@ epilot customer-portal getOrgPortalConfig -p origin=example --jsonata '$' }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -2235,25 +3018,56 @@ epilot customer-portal getOrgPortalConfig -p origin=example --jsonata '$' "schema": "contract" } ], - "triggered_journeys": [ + "surfaces": [ { - "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} } ], - "entity_edit_rules": [ + "contact_identifiers_for_account": [ { - "slug": "contact", - "attribute": "first_name", - "rule_type": "cadence", - "cadence_period_type": "days", - "cadence_period": 1, - "changes_allowed": 1, - "grace_period": 1, - "allowed_increment": "10%", - "allowed_decrement": "10%", - "number_of_days_before_restriction": 10 - } + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], + "triggered_journeys": [ + { + "trigger_name": "FIRST_LOGIN", + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] + } + ], + "entity_edit_rules": [ + { + "slug": "contact", + "attribute": "first_name", + "rule_type": "cadence", + "cadence_period_type": "days", + "cadence_period": 1, + "changes_allowed": 1, + "grace_period": 1, + "allowed_increment": "10%", + "allowed_decrement": "10%", + "number_of_days_before_restriction": 10 + } ], "allowed_file_extensions": { "document": ["pdf"], @@ -2272,10 +3086,21 @@ epilot customer-portal getOrgPortalConfig -p origin=example --jsonata '$' "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_created", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + ], + "engagement_center_enabled": true, "id": 12345, "organization_id": 12345, "org_settings": { @@ -2299,7 +3124,11 @@ epilot customer-portal getOrgPortalConfig -p origin=example --jsonata '$' "slug": "office-365-login", "display_name": "Office 365 Login", "oidc_config": {}, - "mobile_oidc_config": {} + "mobile_oidc_config": {}, + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "expose_client_secret": false } ], "certificate_details": { @@ -2345,6 +3174,43 @@ epilot customer-portal getPublicPortalConfigV3 -p org_id=12324 -p portal_id=453a ```json { + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -2356,13 +3222,19 @@ epilot customer-portal getPublicPortalConfigV3 -p org_id=12324 -p portal_id=453a "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -2374,19 +3246,31 @@ epilot customer-portal getPublicPortalConfigV3 -p org_id=12324 -p portal_id=453a }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -2447,10 +3331,41 @@ epilot customer-portal getPublicPortalConfigV3 -p org_id=12324 -p portal_id=453a "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -2484,10 +3399,21 @@ epilot customer-portal getPublicPortalConfigV3 -p org_id=12324 -p portal_id=453a "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_created", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + ], + "engagement_center_enabled": true, "id": 12345, "organization_id": 12345, "org_settings": { @@ -2551,6 +3477,43 @@ epilot customer-portal getOrgPortalConfigV3 -p portal_id=453ad7bf-86d5-46c8-8252 ```json { + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -2562,13 +3525,19 @@ epilot customer-portal getOrgPortalConfigV3 -p portal_id=453ad7bf-86d5-46c8-8252 "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -2580,19 +3549,31 @@ epilot customer-portal getOrgPortalConfigV3 -p portal_id=453ad7bf-86d5-46c8-8252 }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -2653,10 +3634,41 @@ epilot customer-portal getOrgPortalConfigV3 -p portal_id=453ad7bf-86d5-46c8-8252 "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -2690,10 +3702,21 @@ epilot customer-portal getOrgPortalConfigV3 -p portal_id=453ad7bf-86d5-46c8-8252 "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_created", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + ], + "engagement_center_enabled": true, "id": 12345, "organization_id": 12345, "org_settings": { @@ -2717,7 +3740,11 @@ epilot customer-portal getOrgPortalConfigV3 -p portal_id=453ad7bf-86d5-46c8-8252 "slug": "office-365-login", "display_name": "Office 365 Login", "oidc_config": {}, - "mobile_oidc_config": {} + "mobile_oidc_config": {}, + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "expose_client_secret": false } ], "certificate_details": { @@ -2756,6 +3783,7 @@ epilot customer-portal getAllPortalConfigs --jsonata 'data' { "data": [ { + "mobile_config": {}, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -2763,7 +3791,11 @@ epilot customer-portal getAllPortalConfigs --jsonata 'data' "epilot_domain": "example-portal-12345.ecp.epilot.cloud", "domain_settings": {}, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": {}, "accessToken": "string", @@ -2779,6 +3811,9 @@ epilot customer-portal getAllPortalConfigs --jsonata 'data' "contract_identifiers": [], "contract_selector_config": {}, "registration_identifiers": [], + "surfaces": [], + "contact_identifiers_for_account": [], + "additional_contact_attributes": [], "triggered_journeys": [], "entity_edit_rules": [], "allowed_file_extensions": {}, @@ -2787,10 +3822,14 @@ epilot customer-portal getAllPortalConfigs --jsonata 'data' "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [], + "engagement_center_enabled": true, "id": 12345, "organization_id": 12345, "org_settings": {}, @@ -2945,6 +3984,93 @@ epilot customer-portal upsertEmailTemplates -p origin=example --jsonata 'message --- +### `migrateEmailTemplateReferences` + +Walk every email-template config row in the caller's org and re-point any + +`POST /v3/portal/email-templates:migrate-references` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal migrateEmailTemplateReferences \ + -d '{"source_template_id":"string","destination_template_id":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal migrateEmailTemplateReferences +``` + +With JSONata filter: + +```bash +epilot customer-portal migrateEmailTemplateReferences --jsonata 'migrated_portal_count' +``` + +
+Sample Response + +```json +{ + "migrated_portal_count": 2, + "migrated_portal_ids": ["string"], + "failed_portal_ids": ["string"] +} +``` + +
+ +--- + +### `listEmailTemplateReferences` + +Read-only sibling of migrateEmailTemplateReferences. Lists every portal in + +`POST /v3/portal/email-templates:list-references` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal listEmailTemplateReferences \ + -d '{"template_id":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal listEmailTemplateReferences +``` + +With JSONata filter: + +```bash +epilot customer-portal listEmailTemplateReferences --jsonata 'portals' +``` + +
+Sample Response + +```json +{ + "portals": [ + { + "id": "string", + "name": "string" + } + ] +} +``` + +
+ +--- + ### `getEmailTemplatesByPortalId` Retrieves the email templates of a portal by portal ID @@ -3096,31 +4222,30 @@ epilot customer-portal upsertEmailTemplatesByPortalId -p portal_id=123e4567-e89b --- -### `getPublicPortalWidgets` +### `getPublicPortalWidgetsV3` -Retrieves the public widgets of a portal +Retrieves the public widgets of a portal. -`GET /v2/portal/public-widgets` +`GET /v3/portal/public/widgets` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `org_id` | query | string | Yes | | -| `origin` | query | string | Yes | Origin of the portal | +| `org_id` | query | string | No | Organization ID (required if domain is not provided) | +| `portal_id` | query | string | No | Portal ID (required if domain is not provided) | +| `domain` | query | string | No | Portal domain for identification (alternative to org_id + portal_id) | **Sample Call** ```bash -epilot customer-portal getPublicPortalWidgets \ - -p org_id=123 \ - -p origin=example +epilot customer-portal getPublicPortalWidgetsV3 ``` With JSONata filter: ```bash -epilot customer-portal getPublicPortalWidgets -p org_id=123 -p origin=example --jsonata 'widgets' +epilot customer-portal getPublicPortalWidgetsV3 --jsonata 'portal_sk_v3' ```
@@ -3128,6 +4253,8 @@ epilot customer-portal getPublicPortalWidgets -p org_id=123 -p origin=example -- ```json { + "portal_sk_v3": "string", + "is_v3_item": true, "widgets": [ { "id": "string", @@ -3165,29 +4292,30 @@ epilot customer-portal getPublicPortalWidgets -p org_id=123 -p origin=example -- --- -### `getPortalWidgets` +### `getPortalWidgetsV3` -Retrieves the widgets of a portal +Retrieves the widgets of a portal by portal_id. -`GET /v2/portal/widgets` +`GET /v3/portal/widgets` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `origin` | query | string | No | Origin of the portal | +| `portal_id` | query | string | Yes | PortalId of the portal | | `contract_id` | query | string (uuid) | No | Contract context for widgets | **Sample Call** ```bash -epilot customer-portal getPortalWidgets +epilot customer-portal getPortalWidgetsV3 \ + -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c ``` With JSONata filter: ```bash -epilot customer-portal getPortalWidgets --jsonata 'widgets' +epilot customer-portal getPortalWidgetsV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c --jsonata 'portal_sk_v3' ```
@@ -3195,6 +4323,8 @@ epilot customer-portal getPortalWidgets --jsonata 'widgets' ```json { + "portal_sk_v3": "string", + "is_v3_item": true, "widgets": [ { "id": "string", @@ -3232,33 +4362,35 @@ epilot customer-portal getPortalWidgets --jsonata 'widgets' --- -### `upsertPortalWidget` +### `upsertPortalWidgetV3` -Upsert widget for a portal of an organization. +Upsert widget for a portal by portal_id. -`POST /v2/portal/widgets` +`POST /v3/portal/widgets` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `origin` | query | string | Yes | Origin of the portal | +| `portal_id` | query | string | Yes | PortalId of the portal | **Request Body** (required) **Sample Call** ```bash -epilot customer-portal upsertPortalWidget \ - -p origin=example +epilot customer-portal upsertPortalWidgetV3 \ + -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c ``` With request body: ```bash -epilot customer-portal upsertPortalWidget \ - -p origin=example \ +epilot customer-portal upsertPortalWidgetV3 \ + -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c \ -d '{ + "portal_sk_v3": "string", + "is_v3_item": true, "widgets": [ { "id": "string", @@ -3295,13 +4427,13 @@ epilot customer-portal upsertPortalWidget \ Using stdin pipe: ```bash -cat body.json | epilot customer-portal upsertPortalWidget -p origin=example +cat body.json | epilot customer-portal upsertPortalWidgetV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c ``` With JSONata filter: ```bash -epilot customer-portal upsertPortalWidget -p origin=example --jsonata 'widgets' +epilot customer-portal upsertPortalWidgetV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c --jsonata 'portal_sk_v3' ```
@@ -3309,6 +4441,8 @@ epilot customer-portal upsertPortalWidget -p origin=example --jsonata 'widgets' ```json { + "portal_sk_v3": "string", + "is_v3_item": true, "widgets": [ { "id": "string", @@ -3346,31 +4480,58 @@ epilot customer-portal upsertPortalWidget -p origin=example --jsonata 'widgets' --- -### `replaceECPTemplateVariables` +### `savePortalFilesV3` -Replaces the template variables of a portal +Add files to portal by portal_id -`POST /v2/portal/replace-ecp-template-variables` +`POST /v3/portal/portal/files` -**Request Body** +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | query | string | Yes | PortalId of the portal | + +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal replaceECPTemplateVariables \ - -d '{"template_id":"5da0a718-c822-403d-9f5d-20d4584e0528","entity_context":{}}' +epilot customer-portal savePortalFilesV3 \ + -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c +``` + +With request body: + +```bash +epilot customer-portal savePortalFilesV3 \ + -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c \ + -d '{ + "origin": "string", + "files": [ + { + "filename": 12345, + "file_type": "orderRightTeaser", + "_tags": 12345, + "s3ref": { + "bucket": 12345, + "key": 12345 + } + } + ] +}' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal replaceECPTemplateVariables +cat body.json | epilot customer-portal savePortalFilesV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c ``` With JSONata filter: ```bash -epilot customer-portal replaceECPTemplateVariables --jsonata 'customerPortal' +epilot customer-portal savePortalFilesV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c --jsonata 'createdFiles' ```
@@ -3378,34 +4539,91 @@ epilot customer-portal replaceECPTemplateVariables --jsonata 'customerPortal' ```json { - "customerPortal": { - "invitationLink": "https://end-customer-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", - "newDocumentLink": "https://end-customer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", - "entityLink": "https://end-customer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", - "userEmailsOnEntity": ["john@doe.com", "mary@doe.com"] - }, - "installerPortal": { - "invitationLink": "https://installer-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", - "newDocumentLink": "https://installer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", - "entityLink": "https://installer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", - "userEmailsOnEntity": ["peter@doe.com", "jane@doe.com"] - }, - "portalUser": { - "invitationLink": "https://employee-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", - "newDocumentLink": "https://employee-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", - "entityLink": "https://employee-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", - "userEmailsOnEntity": ["peter@doe.com", "jane@doe.com"] - } -} -``` - -
- ---- - -### `getSchemas` - -Retrieves the schemas. Only schemas usable in the private part of the portal are returned. + "createdFiles": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "file" + } + ] +} +``` + +
+ +--- + +### `replaceECPTemplateVariables` + +Replaces the template variables of a portal + +`POST /v2/portal/replace-ecp-template-variables` + +**Request Body** + +**Sample Call** + +```bash +epilot customer-portal replaceECPTemplateVariables \ + -d '{"template_id":"5da0a718-c822-403d-9f5d-20d4584e0528","entity_context":{}}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal replaceECPTemplateVariables +``` + +With JSONata filter: + +```bash +epilot customer-portal replaceECPTemplateVariables --jsonata 'customerPortal' +``` + +
+Sample Response + +```json +{ + "customerPortal": { + "invitationLink": "https://end-customer-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", + "newDocumentLink": "https://end-customer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", + "entityLink": "https://end-customer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", + "userEmailsOnEntity": ["john@doe.com", "mary@doe.com"] + }, + "installerPortal": { + "invitationLink": "https://installer-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", + "newDocumentLink": "https://installer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", + "entityLink": "https://installer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", + "userEmailsOnEntity": ["peter@doe.com", "jane@doe.com"] + }, + "portalUser": { + "invitationLink": "https://employee-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", + "newDocumentLink": "https://employee-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", + "entityLink": "https://employee-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", + "userEmailsOnEntity": ["peter@doe.com", "jane@doe.com"] + } +} +``` + +
+ +--- + +### `getSchemas` + +Retrieves the schemas. Only schemas usable in the private part of the portal are returned. `GET /v2/portal/schemas` @@ -3480,6 +4698,49 @@ epilot customer-portal getSchemasByDomain -p domain=ecp.dev.epilot.io --jsonata --- +### `getPublicSchemasV3` + +Retrieves schemas by portal. Only schemas and attributes used on public pages are returned. + +`GET /v3/portal/public/schemas` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `org_id` | query | string | No | Organization ID (required if domain is not provided) | +| `portal_id` | query | string | No | Portal ID (required if domain is not provided) | +| `domain` | query | string | No | Portal domain for identification (alternative to org_id + portal_id) | + +**Sample Call** + +```bash +epilot customer-portal getPublicSchemasV3 +``` + +With JSONata filter: + +```bash +epilot customer-portal getPublicSchemasV3 --jsonata 'schemas' +``` + +
+Sample Response + +```json +{ + "schemas": [ + { + "slug": "contact" + } + ] +} +``` + +
+ +--- + ### `getOrganizationSettingsByDomain` Retrieves organization settings by domain. Only public organization settings are returned. @@ -3760,6 +5021,13 @@ epilot customer-portal getContact --jsonata 'entity._title' "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "contact" }, "files": [ @@ -3770,6 +5038,13 @@ epilot customer-portal getContact --jsonata 'entity._title' "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "file" } ], @@ -3781,6 +5056,13 @@ epilot customer-portal getContact --jsonata 'entity._title' "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "templates_output": { "content_top_name": "Customer #123456", "main_content_name": "Orange Flexible A2 (654321)", @@ -3817,54 +5099,6 @@ epilot customer-portal getContact --jsonata 'entity._title' --- -### `updateContact` - -Updates the contact details. - -`PATCH /v2/portal/contact` - -**Request Body** - -**Sample Call** - -```bash -epilot customer-portal updateContact \ - -d '{}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal updateContact -``` - -With JSONata filter: - -```bash -epilot customer-portal updateContact --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "contact" - } -} -``` - -
- ---- - ### `getECPContact` Get the Contact by id @@ -3902,6 +5136,13 @@ epilot customer-portal getECPContact -p id=5da0a718-c822-403d-9f5d-20d4584e0528 "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "contact" } } @@ -3946,7 +5187,8 @@ epilot customer-portal checkContactExists \ "contract": { "contract_number": "123456" } - } + }, + "trigger_identifiers_check": true }' ``` @@ -3968,7 +5210,8 @@ epilot customer-portal checkContactExists -p origin=example --jsonata 'exists' ```json { "exists": true, - "contactId": "5da0a718-c822-403d-9f5d-20d4584e0528" + "contactId": "5da0a718-c822-403d-9f5d-20d4584e0528", + "reason": "TIMEOUT" } ``` @@ -3986,22 +5229,21 @@ True if contact with given identifiers exists. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `portal_id` | query | string | Yes | PortalId of the portal | +| `portal_id` | query | string | No | PortalId of the portal (required if domain is not provided) | +| `domain` | query | string | No | Portal domain for identification (alternative to portal_id) | **Request Body** (required) **Sample Call** ```bash -epilot customer-portal checkContactExistsV3 \ - -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c +epilot customer-portal checkContactExistsV3 ``` With request body: ```bash epilot customer-portal checkContactExistsV3 \ - -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c \ -d '{ "org_id": 728, "registration_identifiers": { @@ -4011,20 +5253,21 @@ epilot customer-portal checkContactExistsV3 \ "contract": { "contract_number": "123456" } - } + }, + "trigger_identifiers_check": true }' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal checkContactExistsV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c +cat body.json | epilot customer-portal checkContactExistsV3 ``` With JSONata filter: ```bash -epilot customer-portal checkContactExistsV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c --jsonata 'exists' +epilot customer-portal checkContactExistsV3 --jsonata 'exists' ```
@@ -4033,7 +5276,9 @@ epilot customer-portal checkContactExistsV3 -p portal_id=453ad7bf-86d5-46c8-8252 ```json { "exists": true, - "contactId": "5da0a718-c822-403d-9f5d-20d4584e0528" + "contactId": "5da0a718-c822-403d-9f5d-20d4584e0528", + "accountId": "5da0a718-c822-403d-9f5d-20d4584e0528", + "reason": "TIMEOUT" } ``` @@ -4041,58 +5286,56 @@ epilot customer-portal checkContactExistsV3 -p portal_id=453ad7bf-86d5-46c8-8252 --- -### `getValidSecondaryAttributes` +### `identifyContact` -Get valid secondary attributes that are used while mapping a contact on registration +Identify a contact by the portal's configured registration identifiers and, on a match, -`GET /v2/portal/contact/valid/secondary/attributes` +`POST /v3/portal/public/contact/identify` -**Sample Call** +**Parameters** -```bash -epilot customer-portal getValidSecondaryAttributes -``` +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | query | string | No | PortalId of the portal (required if domain is not provided) | +| `domain` | query | string | No | Portal domain for identification (alternative to portal_id) | -With JSONata filter: +**Request Body** (required) + +**Sample Call** ```bash -epilot customer-portal getValidSecondaryAttributes --jsonata 'data' +epilot customer-portal identifyContact ``` -
-Sample Response +With request body: -```json -{ - "data": [ - { - "name": "first_name", - "type": "string" +```bash +epilot customer-portal identifyContact \ + -d '{ + "org_id": 728, + "registration_identifiers": { + "contact": { + "email": "john.doe@example.com" + }, + "contract": { + "contract_number": "123456" } - ] -} + }, + "trigger_identifiers_check": true, + "surface_id": "website-journeys" +}' ``` -
- ---- - -### `getPortalUser` - -Get the portal user details - -`GET /v2/portal/user` - -**Sample Call** +Using stdin pipe: ```bash -epilot customer-portal getPortalUser +cat body.json | epilot customer-portal identifyContact ``` With JSONata filter: ```bash -epilot customer-portal getPortalUser --jsonata 'data' +epilot customer-portal identifyContact --jsonata 'contact_id' ```
@@ -4100,15 +5343,14 @@ epilot customer-portal getPortalUser --jsonata 'data' ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "portal_user" - } + "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "account_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", + "token_type": "contact_identification", + "surface_id": "website-journeys", + "expires_at": "2026-08-11T10:35:00.000Z", + "allowed_operations": [], + "reason": "TIMEOUT" } ``` @@ -4116,28 +5358,174 @@ epilot customer-portal getPortalUser --jsonata 'data' --- -### `updatePortalUser` +### `checkAccountExists` -Update the portal user details +True if account with given identifiers exists. -`PATCH /v2/portal/user` +`POST /v3/portal/public/account/exists` -**Request Body** +**Parameters** -**Sample Call** +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | query | string | No | PortalId of the portal (required if domain is not provided) | +| `domain` | query | string | No | Portal domain for identification (alternative to portal_id) | -```bash -epilot customer-portal updatePortalUser \ - -d '{}' -``` +**Request Body** (required) -Using stdin pipe: +**Sample Call** ```bash -cat body.json | epilot customer-portal updatePortalUser +epilot customer-portal checkAccountExists ``` -With JSONata filter: +With request body: + +```bash +epilot customer-portal checkAccountExists \ + -d '{ + "org_id": 728, + "registration_identifiers": { + "account": { + "customer_number": "ACC-123456" + }, + "contract": { + "contract_number": "123456" + } + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal checkAccountExists +``` + +With JSONata filter: + +```bash +epilot customer-portal checkAccountExists --jsonata 'exists' +``` + +
+Sample Response + +```json +{ + "exists": true, + "accountId": "5da0a718-c822-403d-9f5d-20d4584e0528" +} +``` + +
+ +--- + +### `getValidSecondaryAttributes` + +Get valid secondary attributes that are used while mapping a contact on registration + +`GET /v2/portal/contact/valid/secondary/attributes` + +**Sample Call** + +```bash +epilot customer-portal getValidSecondaryAttributes +``` + +With JSONata filter: + +```bash +epilot customer-portal getValidSecondaryAttributes --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": [ + { + "name": "first_name", + "type": "string" + } + ] +} +``` + +
+ +--- + +### `getPortalUser` + +Get the portal user details + +`GET /v2/portal/user` + +**Sample Call** + +```bash +epilot customer-portal getPortalUser +``` + +With JSONata filter: + +```bash +epilot customer-portal getPortalUser --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "portal_user" + } +} +``` + +
+ +--- + +### `updatePortalUser` + +Update the portal user details + +`PATCH /v2/portal/user` + +**Request Body** + +**Sample Call** + +```bash +epilot customer-portal updatePortalUser \ + -d '{"templates_output_highlighted":{},"search_snippets":[{"field":"string","fragment":"string"}]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal updatePortalUser +``` + +With JSONata filter: ```bash epilot customer-portal updatePortalUser --jsonata 'data' @@ -4155,6 +5543,13 @@ epilot customer-portal updatePortalUser --jsonata 'data' "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "portal_user" } } @@ -4236,6 +5631,46 @@ epilot customer-portal updatePortalUserEmail --jsonata 'message' --- +### `changePortalUserPassword` + +Hand over a password change to the third-party system configured via the `changePassword` portal extension hook. + +`PUT /v2/portal/user/change/password` + +**Request Body** + +**Sample Call** + +```bash +epilot customer-portal changePortalUserPassword \ + -d '{"new_password":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal changePortalUserPassword +``` + +With JSONata filter: + +```bash +epilot customer-portal changePortalUserPassword --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + ### `resendConfirmationEmail` Resend confirmation email @@ -4320,6 +5755,13 @@ epilot customer-portal fetchPortalUsersByRelatedEntity -p entity_id=5da0a718-c82 "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "portal_user" } ] @@ -4450,7 +5892,7 @@ epilot customer-portal userExists -p email=user@example.com -p org_id=123 --json ### `userExistsV3` -Checks whether a user exists in the portal +Checks whether a user exists in the portal. `GET /v3/portal/public/user/exists` @@ -4459,21 +5901,21 @@ Checks whether a user exists in the portal | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `email` | query | string | Yes | | -| `org_id` | query | string | Yes | | -| `portal_id` | query | string | No | Checkes if user exists in the given portal ID. If not provided, checks in all portals. | +| `org_id` | query | string | No | | +| `portal_id` | query | string | No | Checks if user exists in the given portal ID. If not provided, checks in all portals. | +| `domain` | query | string | No | Portal domain for identification (alternative to org_id + portal_id) | **Sample Call** ```bash epilot customer-portal userExistsV3 \ - -p email=user@example.com \ - -p org_id=123 + -p email=user@example.com ``` With JSONata filter: ```bash -epilot customer-portal userExistsV3 -p email=user@example.com -p org_id=123 --jsonata 'exists' +epilot customer-portal userExistsV3 -p email=user@example.com --jsonata 'exists' ```
@@ -4621,69 +6063,6 @@ epilot customer-portal configureDistributionV3 -p portal_id=453ad7bf-86d5-46c8-8 --- -### `getAllOrders` - -Get all orders for the portal user - -`GET /v2/portal/order` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `from` | query | number | No | | -| `size` | query | number | No | | - -**Sample Call** - -```bash -epilot customer-portal getAllOrders -``` - -With JSONata filter: - -```bash -epilot customer-portal getAllOrders --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order", - "journey_actions": { - "journey_id": "string", - "action_label": { - "en": "string", - "de": "string" - }, - "slug": "string", - "rules": [ - { - "entity": "string", - "attribute": "string", - "attribute_value": "string" - } - ] - } - } - ] -} -``` - -
- ---- - ### `postOrderAcceptance` Accept/decline an offer by id @@ -4736,6 +6115,13 @@ epilot customer-portal postOrderAcceptance -p id=5da0a718-c822-403d-9f5d-20d4584 "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "order" } } @@ -4745,35 +6131,59 @@ epilot customer-portal postOrderAcceptance -p id=5da0a718-c822-403d-9f5d-20d4584 --- -### `getOrder` +### `getContractWithTemplates` -Get an order by id +Resolve Handlebars templates against a contract's related meters and return the contract with templates_output populated -`GET /v2/portal/order/{id}` +`POST /v2/portal/contract/{id}/resolve-templates` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | The ID of order | +| `id` | path | string (uuid) | Yes | The ID of the contract | + +**Request Body** **Sample Call** ```bash -epilot customer-portal getOrder \ +epilot customer-portal getContractWithTemplates \ -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` +With request body: + +```bash +epilot customer-portal getContractWithTemplates \ + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 \ + -d '{ + "templates": {}, + "templates_ref": { + "page_id": "string", + "block_id": "string", + "config_id": "string", + "global_search_config_id": "string" + } +}' +``` + Using positional args for path parameters: ```bash -epilot customer-portal getOrder 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal getContractWithTemplates 5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal getContractWithTemplates -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal getOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'entity._title' +epilot customer-portal getContractWithTemplates -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'entity._title' ```
@@ -4788,20 +6198,47 @@ epilot customer-portal getOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jso "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order" - }, - "files": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" + "templates_output_highlighted": {}, + "search_snippets": [ + {} + ], + "contract_name": "Grid Contract", + "contract_number": "12345", + "status": "approved", + "description": "This contract is for the supply of widgets.", + "account_number": "67890", + "branch": "power", + "billing_address": "123 Main St, Anytown", + "delivery_address": "456 Elm St, Anytown", + "additional_addresses": "789 Oak St, Anytown", + "termination_date": "2022-01-01", + "termination_reason": "Non-payment", + "billing_period": "monthly", + "billing_duration_amount": 30, + "renewal_duration_amount": 365, + "renewal_duration_unit": "years", + "notice_time_amount": 30, + "notice_time_unit": "months", + "start_date": "2021-01-01", + "billing_due_day": 2, + "installment_amount": 10050, + "balance": 8990, + "balance_currency": "EUR" + }, + "orders": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [], + "_schema": "order" } ], - "relations": [ + "meters": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -4809,11 +6246,13 @@ epilot customer-portal getOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jso "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": {}, - "_schema": "contact" + "templates_output_highlighted": {}, + "search_snippets": [], + "_schema": "meter", + "templates_output": {} } ], - "products": [ + "files": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -4821,10 +6260,12 @@ epilot customer-portal getOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jso "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "product" + "templates_output_highlighted": {}, + "search_snippets": [], + "_schema": "file" } ], - "crossSellableProducts": [ + "relations": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -4832,7 +6273,10 @@ epilot customer-portal getOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jso "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "product" + "templates_output_highlighted": {}, + "search_snippets": [], + "templates_output": {}, + "_schema": "contact" } ], "workflow": [ @@ -4863,44 +6307,31 @@ epilot customer-portal getOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jso --- -### `updateOrder` - -Update an order by id - -`PATCH /v2/portal/order/{id}` +### `addContractByIdentifiers` -**Parameters** +Self-assign contract(s) by pre-configured identifiers. -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | The ID of order | +`POST /v2/portal/contract/by-identifiers` -**Request Body** +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal updateOrder \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 \ - -d '{}' -``` - -Using positional args for path parameters: - -```bash -epilot customer-portal updateOrder 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal addContractByIdentifiers \ + -d '{"contract":{"contract_number":"123456"},"meter":{"meter_number":"123456"}}' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal updateOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +cat body.json | epilot customer-portal addContractByIdentifiers ``` With JSONata filter: ```bash -epilot customer-portal updateOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'data' +epilot customer-portal addContractByIdentifiers --jsonata 'data' ```
@@ -4908,15 +6339,34 @@ epilot customer-portal updateOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 -- ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order" - } + "data": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" + } + ], + "hits": 0 } ``` @@ -4924,29 +6374,35 @@ epilot customer-portal updateOrder -p id=5da0a718-c822-403d-9f5d-20d4584e0528 -- --- -### `getAllOpportunities` +### `getEntityIdentifiers` -Get all opportunities of a portal user +Retrieve a list of entity identifiers used for entity search by portal users. -`GET /v2/portal/opportunity` +`GET /v2/portal/entity/identifiers/{slug}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `from` | query | number | No | | -| `size` | query | number | No | | +| `slug` | path | string | Yes | The slug of an entity | **Sample Call** ```bash -epilot customer-portal getAllOpportunities +epilot customer-portal getEntityIdentifiers \ + -p slug=contact +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal getEntityIdentifiers contact ``` With JSONata filter: ```bash -epilot customer-portal getAllOpportunities --jsonata 'data' +epilot customer-portal getEntityIdentifiers -p slug=contact --jsonata 'data' ```
@@ -4956,28 +6412,8 @@ epilot customer-portal getAllOpportunities --jsonata 'data' { "data": [ { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity", - "journey_actions": { - "journey_id": "string", - "action_label": { - "en": "string", - "de": "string" - }, - "slug": "string", - "rules": [ - { - "entity": "string", - "attribute": "string", - "attribute_value": "string" - } - ] - } + "name": "contract_number", + "type": "string" } ] } @@ -4987,29 +6423,43 @@ epilot customer-portal getAllOpportunities --jsonata 'data' --- -### `getSearchableAttributesForOpportunities` +### `getEntityActivityFeed` -Get all opportunity searchable attributes for a portal user +Get activity feed for an entity -`GET /v2/portal/opportunities/searchable-attributes` +`GET /v2/portal/entity/{slug}/{id}/activity` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `from` | query | number | No | | -| `size` | query | number | No | | +| `slug` | path | string | Yes | Entity Type | +| `id` | path | string (uuid) | Yes | Entity id | +| `after` | query | string (date-time) | No | Get activities after this timestamp | +| `before` | query | string (date-time) | No | get activities before this timestamp | +| `from` | query | number | No | start from page | +| `size` | query | number | No | max number of results to return | +| `type` | query | string | No | Filter by activity type | +| `include_relations` | query | boolean | No | Include activities from related entities | **Sample Call** ```bash -epilot customer-portal getSearchableAttributesForOpportunities +epilot customer-portal getEntityActivityFeed \ + -p slug=contact \ + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal getEntityActivityFeed contact 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal getSearchableAttributesForOpportunities --jsonata 'data' +epilot customer-portal getEntityActivityFeed -p slug=contact -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'results[0]' ```
@@ -5017,15 +6467,20 @@ epilot customer-portal getSearchableAttributesForOpportunities --jsonata 'data' ```json { - "data": [ + "total": 1, + "results": [ { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" + "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", + "timestamp": "1970-01-01T00:00:00.000Z", + "type": "MyCustomActivity", + "title": "My custom activity", + "message": "{{caller}} did something with {{entity payload.entity.id}}.", + "payload": { + "entity": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "schema": "contact" + } + } } ] } @@ -5035,38 +6490,38 @@ epilot customer-portal getSearchableAttributesForOpportunities --jsonata 'data' --- -### `getSearchResultsForOpportunities` +### `validateCadenceEntityEditRules` -Get all opportunity with the given serached attributes +Validate if cadence rule is valid for an entity -`POST /v2/portal/opportunities/search` +`GET /v2/portal/{slug}/{id}:validateRule` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `from` | query | number | No | | -| `size` | query | number | No | | - -**Request Body** (required) +| `slug` | path | string | Yes | Entity Type | +| `id` | path | string (uuid) | Yes | Entity id | +| `attribute` | query | string | No | Get activities after this timestamp | **Sample Call** ```bash -epilot customer-portal getSearchResultsForOpportunities \ - -d '{"addresses":["string"],"customers":["string"],"purposes":["5da0a718-c822-403d-9f5d-20d4584e0528"],"workflows":[{}]}' +epilot customer-portal validateCadenceEntityEditRules \ + -p slug=contact \ + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` -Using stdin pipe: +Using positional args for path parameters: ```bash -cat body.json | epilot customer-portal getSearchResultsForOpportunities +epilot customer-portal validateCadenceEntityEditRules contact 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal getSearchResultsForOpportunities --jsonata 'data' +epilot customer-portal validateCadenceEntityEditRules -p slug=contact -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'isBlockedByRules' ```
@@ -5074,17 +6529,19 @@ epilot customer-portal getSearchResultsForOpportunities --jsonata 'data' ```json { - "data": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" - } - ] + "isBlockedByRules": false, + "failedRule": { + "slug": "contact", + "attribute": "string", + "rule_type": "string", + "cadence_period_type": "string", + "changes_allowed": 0, + "cadence_period": 0, + "allowed_decrement": "string", + "allowed_increment": "string", + "number_of_days_before_restriction": 0, + "grace_period": 0 + } } ``` @@ -5092,35 +6549,35 @@ epilot customer-portal getSearchResultsForOpportunities --jsonata 'data' --- -### `getOpportunity` +### `searchPaymentRelationsInEntities` -Get an opportunity by id +Search for entities that have the payment relation with the given payment id -`GET /v2/portal/opportunities/{id}` +`GET /v2/portal/entities-by-payment/{id}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | The ID of opportunity | +| `id` | path | string (uuid) | Yes | Entity id | **Sample Call** ```bash -epilot customer-portal getOpportunity \ +epilot customer-portal searchPaymentRelationsInEntities \ -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using positional args for path parameters: ```bash -epilot customer-portal getOpportunity 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal searchPaymentRelationsInEntities 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal getOpportunity -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'entity._title' +epilot customer-portal searchPaymentRelationsInEntities -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'results[0]' ```
@@ -5128,27 +6585,7 @@ epilot customer-portal getOpportunity -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ```json { - "entity": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" - }, - "orders": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order" - } - ], - "files": [ + "results": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -5156,42 +6593,26 @@ epilot customer-portal getOpportunity -p id=5da0a718-c822-403d-9f5d-20d4584e0528 "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" } ], - "relations": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": {}, - "_schema": "contact" - } - ], - "workflow": [ - { - "id": "8gja72h6kas6h", - "name": "Lead Qualification", - "trigger": "MANUAL", - "status": "STARTED", - "creationTime": "2021-04-27T12:01:13.000Z", - "lastUpdateTime": "2021-04-27T12:01:13.000Z", - "dueDate": "2021-04-27T12:01:13.000Z", - "assignedTo": ["252", "29052"], - "flow": [] - } - ], - "journey_actions": [ - { - "journey_id": "string", - "action_label": {}, - "slug": "string", - "rules": [] - } - ] + "hits": 50 } ``` @@ -5199,44 +6620,37 @@ epilot customer-portal getOpportunity -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --- -### `updateOpportunity` +### `createCustomEntityActivity` -Update an opportunity by id +Create a custom activity that can be displayed in activity feed of an entity. -`PATCH /v2/portal/opportunities/{id}` +`PUT /v2/portal/entity/activity` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | The ID of opportunity | +| `entities` | query | string (uuid)[] | No | Comma-separated list of entities which the activity primarily concerns. Deprecated - ignored as the list of entities is automatically determined now. | -**Request Body** (required) +**Request Body** **Sample Call** ```bash -epilot customer-portal updateOpportunity \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 \ - -d '{}' -``` - -Using positional args for path parameters: - -```bash -epilot customer-portal updateOpportunity 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal createCustomEntityActivity \ + -d '{"type":"PortalUserResetPassword"}' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal updateOpportunity -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +cat body.json | epilot customer-portal createCustomEntityActivity ``` With JSONata filter: ```bash -epilot customer-portal updateOpportunity -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'data' +epilot customer-portal createCustomEntityActivity --jsonata '$' ```
@@ -5244,14 +6658,16 @@ epilot customer-portal updateOpportunity -p id=5da0a718-c822-403d-9f5d-20d4584e0 ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" + "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", + "timestamp": "1970-01-01T00:00:00.000Z", + "type": "MyCustomActivity", + "title": "My custom activity", + "message": "{{caller}} did something with {{entity payload.entity.id}}.", + "payload": { + "entity": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "schema": "contact" + } } } ``` @@ -5260,29 +6676,50 @@ epilot customer-portal updateOpportunity -p id=5da0a718-c822-403d-9f5d-20d4584e0 --- -### `getAllRequests` - -Get all opportunities & orders of a portal user +### `saveEntityFile` -`GET /v2/portal/request` +Add files to an entity -**Parameters** +`POST /v2/portal/entity/file` -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `from` | query | number | No | | -| `size` | query | number | No | | +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal getAllRequests +epilot customer-portal saveEntityFile +``` + +With request body: + +```bash +epilot customer-portal saveEntityFile \ + -d '{ + "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "entity_type": "order", + "files": [ + { + "filename": "document.pdf", + "access_control": "private", + "s3ref": { + "bucket": 12345, + "key": 12345 + } + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal saveEntityFile ``` With JSONata filter: ```bash -epilot customer-portal getAllRequests --jsonata 'results[0]' +epilot customer-portal saveEntityFile --jsonata 'createdFiles' ```
@@ -5290,8 +6727,7 @@ epilot customer-portal getAllRequests --jsonata 'results[0]' ```json { - "hits": 1, - "results": [ + "createdFiles": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -5299,7 +6735,14 @@ epilot customer-portal getAllRequests --jsonata 'results[0]' "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "file" } ] } @@ -5309,29 +6752,89 @@ epilot customer-portal getAllRequests --jsonata 'results[0]' --- -### `getAllContracts` +### `deleteEntityFile` -Get all contracts for a portal user +Delete files from an entity -`GET /v2/portal/contract` +`DELETE /v2/portal/entity/file` -**Parameters** +**Request Body** (required) -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `from` | query | number | No | | -| `size` | query | number | No | | +**Sample Call** + +```bash +epilot customer-portal deleteEntityFile +``` + +With request body: + +```bash +epilot customer-portal deleteEntityFile \ + -d '{ + "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "entity_type": "order", + "file_entity_ids": ["5da0a718-c822-403d-9f5d-20d4584e0528"] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal deleteEntityFile +``` + +With JSONata filter: + +```bash +epilot customer-portal deleteEntityFile --jsonata '$' +``` + +--- + +### `savePortalFiles` + +Add files to portal + +`POST /v2/portal/portal/files` + +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal getAllContracts +epilot customer-portal savePortalFiles +``` + +With request body: + +```bash +epilot customer-portal savePortalFiles \ + -d '{ + "origin": "string", + "files": [ + { + "filename": 12345, + "file_type": "orderRightTeaser", + "_tags": 12345, + "s3ref": { + "bucket": 12345, + "key": 12345 + } + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal savePortalFiles ``` With JSONata filter: ```bash -epilot customer-portal getAllContracts --jsonata 'data' +epilot customer-portal savePortalFiles --jsonata 'createdFiles' ```
@@ -5339,7 +6842,7 @@ epilot customer-portal getAllContracts --jsonata 'data' ```json { - "data": [ + "createdFiles": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -5347,43 +6850,14 @@ epilot customer-portal getAllContracts --jsonata 'data' "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", - "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", - "billing_period": "monthly", - "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", - "notice_time_amount": 30, - "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, - "balance": 8990, - "balance_currency": "EUR", - "journey_actions": { - "journey_id": "string", - "action_label": { - "en": "string", - "de": "string" - }, - "slug": "string", - "rules": [ - { - "entity": "string", - "attribute": "string", - "attribute_value": "string" - } - ] - } + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "file" } ] } @@ -5393,35 +6867,81 @@ epilot customer-portal getAllContracts --jsonata 'data' --- -### `getContract` +### `getRegistrationIdentifiers` + +Get valid attributes from entities that can be used as identifier to map contact to user on registration + +`GET /v2/portal/registration/identifiers` + +**Sample Call** + +```bash +epilot customer-portal getRegistrationIdentifiers +``` + +With JSONata filter: + +```bash +epilot customer-portal getRegistrationIdentifiers --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": { + "contact": [ + { + "label": "First name", + "name": "first_name", + "type": "string" + } + ], + "contract": [ + { + "label": "Contract number", + "name": "contract_number", + "type": "string" + } + ] + } +} +``` + +
+ +--- + +### `getFilePreview` -Get a contract by id +resolves an in-portal preview for a file. Returns a Content-Disposition: inline URL for directly-previewable files (PDF, -`GET /v2/portal/contract/{id}` +`GET /v2/portal/user/file/{id}/preview` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | The ID of the contract | +| `id` | path | string (uuid) | Yes | The Id of a file | **Sample Call** ```bash -epilot customer-portal getContract \ +epilot customer-portal getFilePreview \ -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using positional args for path parameters: ```bash -epilot customer-portal getContract 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal getFilePreview 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal getContract -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'entity._title' +epilot customer-portal getFilePreview -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'kind' ```
@@ -5429,102 +6949,10 @@ epilot customer-portal getContract -p id=5da0a718-c822-403d-9f5d-20d4584e0528 -- ```json { - "entity": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", - "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", - "billing_period": "monthly", - "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", - "notice_time_amount": 30, - "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, - "balance": 8990, - "balance_currency": "EUR" - }, - "orders": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order" - } - ], - "meters": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "meter" - } - ], - "files": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" - } - ], - "relations": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": {}, - "_schema": "contact" - } - ], - "workflow": [ - { - "id": "8gja72h6kas6h", - "name": "Lead Qualification", - "trigger": "MANUAL", - "status": "STARTED", - "creationTime": "2021-04-27T12:01:13.000Z", - "lastUpdateTime": "2021-04-27T12:01:13.000Z", - "dueDate": "2021-04-27T12:01:13.000Z", - "assignedTo": ["252", "29052"], - "flow": [] - } - ], - "journey_actions": [ - { - "journey_id": "string", - "action_label": {}, - "slug": "string", - "rules": [] - } - ] + "kind": "pdf", + "url": "https://example.com/path", + "requires_auth": true, + "download_url": "https://example.com/path" } ``` @@ -5532,44 +6960,35 @@ epilot customer-portal getContract -p id=5da0a718-c822-403d-9f5d-20d4584e0528 -- --- -### `updateContract` +### `trackFileDownloaded` -Update a contract by id +Track that user has downloaded a file -`PATCH /v2/portal/contract/{id}` +`POST /v2/portal/user/file/{id}/downloaded` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | The ID of the contract | - -**Request Body** (required) +| `id` | path | string (uuid) | Yes | The Id of a file | **Sample Call** ```bash -epilot customer-portal updateContract \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 \ - -d '{}' +epilot customer-portal trackFileDownloaded \ + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using positional args for path parameters: ```bash -epilot customer-portal updateContract 5da0a718-c822-403d-9f5d-20d4584e0528 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal updateContract -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal trackFileDownloaded 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal updateContract -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'data' +epilot customer-portal trackFileDownloaded -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'file' ```
@@ -5577,35 +6996,36 @@ epilot customer-portal updateContract -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ```json { - "data": { + "file": { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", "_org": "123", "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", - "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", - "billing_period": "monthly", - "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", - "notice_time_amount": 30, - "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, - "balance": 8990, - "balance_currency": "EUR" + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "file", + "filename": "document.pdf", + "access_control": "private", + "file_date": "2021-02-09T12:41:43.662Z", + "public_url": "https://epilot-files-prod.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", + "type": "document", + "mime_type": "application/pdf", + "_relations": [ + { + "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_schema": "contact", + "_title": "Opportunity ABC" + } + ], + "is_new": true, + "custom_download_url_auth": "token" } } ``` @@ -5614,31 +7034,35 @@ epilot customer-portal updateContract -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --- -### `addContractByIdentifiers` - -Self-assign contract(s) by pre-configured identifiers. +### `getBillingEvents` -`POST /v2/portal/contract/by-identifiers` +Fetch billing events for a portal user -**Request Body** (required) +`GET /v2/portal/billing/events` -**Sample Call** +**Parameters** -```bash -epilot customer-portal addContractByIdentifiers \ - -d '{"contract":{"contract_number":"123456"},"meter":{"meter_number":"123456"}}' -``` +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `from` | query | number | No | | +| `size` | query | number | No | | +| `entity_id` | query | string (uuid)[] | No | Entity ID to filter billing events by | +| `event_type` | query | "installment" \| "reimbursement" | No | | +| `paid` | query | boolean | No | | +| `date_after` | query | string (date-time) | No | | +| `date_before` | query | string (date-time) | No | | +| `sort` | query | string | No | | -Using stdin pipe: +**Sample Call** ```bash -cat body.json | epilot customer-portal addContractByIdentifiers +epilot customer-portal getBillingEvents ``` With JSONata filter: ```bash -epilot customer-portal addContractByIdentifiers --jsonata 'data' +epilot customer-portal getBillingEvents --jsonata 'results[0]' ```
@@ -5646,27 +7070,38 @@ epilot customer-portal addContractByIdentifiers --jsonata 'data' ```json { - "data": [ + "results": [ { + "billing_amount_decimal": "100.50", + "billing_amount": 10050, + "billing_currency": "EUR", + "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", + "contract": { + "$relation": [ + { + "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + } + ] + }, "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", "_org": "123", "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" } - }, - "_schema": "contact" + ], + "type": "installment", + "due_date": "1970-01-01", + "paid_date": "1970-01-01" } ], - "hits": 0 + "hits": 50 } ``` @@ -5674,35 +7109,22 @@ epilot customer-portal addContractByIdentifiers --jsonata 'data' --- -### `getEntityIdentifiers` - -Retrieve a list of entity identifiers used for entity search by portal users. - -`GET /v2/portal/entity/identifiers/{slug}` +### `getCustomerBalance` -**Parameters** +Get total balance across all contracts and orders of a customer entity. -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `slug` | path | string | Yes | The slug of an entity | +`GET /v2/portal/billing/customers/balance` **Sample Call** ```bash -epilot customer-portal getEntityIdentifiers \ - -p slug=contact -``` - -Using positional args for path parameters: - -```bash -epilot customer-portal getEntityIdentifiers contact +epilot customer-portal getCustomerBalance ``` With JSONata filter: ```bash -epilot customer-portal getEntityIdentifiers -p slug=contact --jsonata 'data' +epilot customer-portal getCustomerBalance --jsonata 'balance' ```
@@ -5710,12 +7132,9 @@ epilot customer-portal getEntityIdentifiers -p slug=contact --jsonata 'data' ```json { - "data": [ - { - "name": "contract_number", - "type": "string" - } - ] + "balance": 8990, + "balance_decimal": "89.90", + "balance_currency": "EUR" } ``` @@ -5723,43 +7142,35 @@ epilot customer-portal getEntityIdentifiers -p slug=contact --jsonata 'data' --- -### `getEntityActivityFeed` +### `getBillingAccount` -Get activity feed for an entity +Get a billing account by id. -`GET /v2/portal/entity/{slug}/{id}/activity` +`GET /v2/portal/billing/accounts/{id}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `slug` | path | string | Yes | Entity Type | -| `id` | path | string (uuid) | Yes | Entity id | -| `after` | query | string (date-time) | No | Get activities after this timestamp | -| `before` | query | string (date-time) | No | get activities before this timestamp | -| `from` | query | number | No | start from page | -| `size` | query | number | No | max number of results to return | -| `type` | query | string | No | Filter by activity type | -| `include_relations` | query | boolean | No | Include activities from related entities | +| `id` | path | string (uuid) | Yes | | **Sample Call** ```bash -epilot customer-portal getEntityActivityFeed \ - -p slug=contact \ +epilot customer-portal getBillingAccount \ -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using positional args for path parameters: ```bash -epilot customer-portal getEntityActivityFeed contact 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal getBillingAccount 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal getEntityActivityFeed -p slug=contact -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'results[0]' +epilot customer-portal getBillingAccount -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'entity._title' ```
@@ -5767,20 +7178,66 @@ epilot customer-portal getEntityActivityFeed -p slug=contact -p id=5da0a718-c822 ```json { - "total": 1, - "results": [ - { - "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", - "timestamp": "1970-01-01T00:00:00.000Z", - "type": "MyCustomActivity", - "title": "My custom activity", - "message": "{{caller}} did something with {{entity payload.entity.id}}.", - "payload": { - "entity": { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "schema": "contact" + "entity": { + "billing_account_number": "string", + "balance": 0, + "balance_decimal": "string", + "balance_currency": "EUR", + "billing_contact": { + "$relation": [ + { + "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + } + ] + }, + "billing_address": { + "$relation_ref": [ + { + "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896", + "path": "address", + "_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" } + ] + }, + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" } + ] + }, + "relations": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" } ] } @@ -5790,38 +7247,31 @@ epilot customer-portal getEntityActivityFeed -p slug=contact -p id=5da0a718-c822 --- -### `validateCadenceEntityEditRules` - -Validate if cadence rule is valid for an entity +### `loginToPortalAsUser` -`GET /v2/portal/{slug}/{id}:validateRule` +Generate a token to log in to a portal impersonating a users. -**Parameters** +`POST /v2/portal/admin:login-as-user` -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `slug` | path | string | Yes | Entity Type | -| `id` | path | string (uuid) | Yes | Entity id | -| `attribute` | query | string | No | Get activities after this timestamp | +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal validateCadenceEntityEditRules \ - -p slug=contact \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal loginToPortalAsUser \ + -d '{"email":"portal-customer@email.com","origin":"string","portal_id":"string","domain":"string"}' ``` -Using positional args for path parameters: +Using stdin pipe: ```bash -epilot customer-portal validateCadenceEntityEditRules contact 5da0a718-c822-403d-9f5d-20d4584e0528 +cat body.json | epilot customer-portal loginToPortalAsUser ``` With JSONata filter: ```bash -epilot customer-portal validateCadenceEntityEditRules -p slug=contact -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'isBlockedByRules' +epilot customer-portal loginToPortalAsUser --jsonata 'login_as_token' ```
@@ -5829,19 +7279,7 @@ epilot customer-portal validateCadenceEntityEditRules -p slug=contact -p id=5da0 ```json { - "isBlockedByRules": false, - "failedRule": { - "slug": "contact", - "attribute": "string", - "rule_type": "string", - "cadence_period_type": "string", - "changes_allowed": 0, - "cadence_period": 0, - "allowed_decrement": "string", - "allowed_increment": "string", - "number_of_days_before_restriction": 0, - "grace_period": 0 - } + "login_as_token": "string" } ``` @@ -5849,35 +7287,38 @@ epilot customer-portal validateCadenceEntityEditRules -p slug=contact -p id=5da0 --- -### `searchPaymentRelationsInEntities` +### `triggerEntityAccessEvent` -Search for entities that have the payment relation with the given payment id +Trigger entity access event for a portal user -`GET /v2/portal/entities-by-payment/{id}` +`POST /v2/portal/entity/{schema}/access` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | Entity id | +| `schema` | path | string | Yes | Entity schema | +| `entity_id` | query | string (uuid) | No | Entity ID | +| `origin` | query | string | Yes | Portal origin | **Sample Call** ```bash -epilot customer-portal searchPaymentRelationsInEntities \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal triggerEntityAccessEvent \ + -p schema=contract \ + -p origin=example ``` Using positional args for path parameters: ```bash -epilot customer-portal searchPaymentRelationsInEntities 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal triggerEntityAccessEvent contract ``` With JSONata filter: ```bash -epilot customer-portal searchPaymentRelationsInEntities -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'results[0]' +epilot customer-portal triggerEntityAccessEvent -p schema=contract -p origin=example --jsonata 'eventId' ```
@@ -5885,27 +7326,7 @@ epilot customer-portal searchPaymentRelationsInEntities -p id=5da0a718-c822-403d ```json { - "results": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" - } - }, - "_schema": "contact" - } - ], - "hits": 50 + "eventId": "string" } ``` @@ -5913,37 +7334,38 @@ epilot customer-portal searchPaymentRelationsInEntities -p id=5da0a718-c822-403d --- -### `createCustomEntityActivity` +### `triggerEntityAccessEventV3` -Create a custom activity that can be displayed in activity feed of an entity. +Trigger entity access event for a portal user. -`PUT /v2/portal/entity/activity` +`POST /v3/portal/entity/{schema}/access` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `entities` | query | string (uuid)[] | No | Comma-separated list of entities which the activity primarily concerns. Deprecated - ignored as the list of entities is automatically determined now. | - -**Request Body** +| `schema` | path | string | Yes | Entity schema | +| `entity_id` | query | string (uuid) | No | Entity ID | +| `portal_id` | query | string | No | Portal ID (required if domain is not provided) | +| `domain` | query | string | No | Portal domain for identification (alternative to portal_id) | **Sample Call** ```bash -epilot customer-portal createCustomEntityActivity \ - -d '{"type":"PortalUserResetPassword"}' +epilot customer-portal triggerEntityAccessEventV3 \ + -p schema=contract ``` -Using stdin pipe: +Using positional args for path parameters: ```bash -cat body.json | epilot customer-portal createCustomEntityActivity +epilot customer-portal triggerEntityAccessEventV3 contract ``` With JSONata filter: ```bash -epilot customer-portal createCustomEntityActivity --jsonata '$' +epilot customer-portal triggerEntityAccessEventV3 -p schema=contract --jsonata 'eventId' ```
@@ -5951,17 +7373,7 @@ epilot customer-portal createCustomEntityActivity --jsonata '$' ```json { - "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", - "timestamp": "1970-01-01T00:00:00.000Z", - "type": "MyCustomActivity", - "title": "My custom activity", - "message": "{{caller}} did something with {{entity payload.entity.id}}.", - "payload": { - "entity": { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "schema": "contact" - } - } + "eventId": "string" } ``` @@ -5969,50 +7381,80 @@ epilot customer-portal createCustomEntityActivity --jsonata '$' --- -### `saveEntityFile` +### `getPortalUserEntity` -Add files to an entity +Get a single entity for a portal user -`POST /v2/portal/entity/file` +`POST /v2/portal/entity:get` -**Request Body** (required) +**Request Body** **Sample Call** ```bash -epilot customer-portal saveEntityFile +epilot customer-portal getPortalUserEntity ``` With request body: ```bash -epilot customer-portal saveEntityFile \ +epilot customer-portal getPortalUserEntity \ -d '{ - "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "entity_type": "order", - "files": [ + "slug": "contact", + "entity_id": "3ec28ab5-8598-41ef-9486-b57fca1d5e2a", + "hydrate": false, + "fields": ["_id", "_title"], + "templates": { + "content_top_name": "Customer #{{contract.customer_number}}", + "main_content_name": "{{contract.contract_name}} ({{contract.contract_number}})", + "content_bottom_name": "{{custom_contract_delivery_address}}", + "nested_content": { + "title": "{{contract.contract_name}}", + "subtitle": "{{contract.contract_number}}" + } + }, + "templates_ref": { + "page_id": "string", + "block_id": "string", + "config_id": "string", + "global_search_config_id": "string" + }, + "filters": [ { - "filename": "document.pdf", - "access_control": "private", - "s3ref": { - "bucket": 12345, - "key": 12345 + "term": { + "status.keyword": "active" + } + }, + { + "range": { + "_created_at": { + "gte": "2023-01-01" + } } } - ] + ], + "filters_context": [ + { + "portal_user": true + }, + { + "contact": true + } + ], + "targets": ["3ec28ab5-8598-41ef-9486-b57fca1d5e2a"] }' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal saveEntityFile +cat body.json | epilot customer-portal getPortalUserEntity ``` With JSONata filter: ```bash -epilot customer-portal saveEntityFile --jsonata 'createdFiles' +epilot customer-portal getPortalUserEntity --jsonata 'result' ```
@@ -6020,17 +7462,31 @@ epilot customer-portal saveEntityFile --jsonata 'createdFiles' ```json { - "createdFiles": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" - } - ] + "result": { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" + } } ``` @@ -6038,89 +7494,186 @@ epilot customer-portal saveEntityFile --jsonata 'createdFiles' --- -### `deleteEntityFile` +### `searchPortalUserEntities` -Delete files from an entity +Search all entities of a portal user -`DELETE /v2/portal/entity/file` +`POST /v2/portal/entity:search` -**Request Body** (required) +**Request Body** **Sample Call** ```bash -epilot customer-portal deleteEntityFile +epilot customer-portal searchPortalUserEntities ``` With request body: ```bash -epilot customer-portal deleteEntityFile \ +epilot customer-portal searchPortalUserEntities \ -d '{ - "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "entity_type": "order", - "file_entity_ids": ["5da0a718-c822-403d-9f5d-20d4584e0528"] + "slug": "contact", + "q": "contract", + "q_fields": ["_title", "customer._title", "customer.first_name", "customer.last_name"], + "group": "customer._title", + "group_title": "{{customer[Primary].first_name}} {{customer[Primary].last_name}}", + "group_size": 100, + "group_sort": "desc", + "group_after_key": {}, + "sort": "_created_at:desc", + "from": 0, + "size": 100, + "hydrate": false, + "fields": ["_id", "_title"], + "templates": { + "content_top_name": "Customer #{{contract.customer_number}}", + "main_content_name": "{{contract.contract_name}} ({{contract.contract_number}})", + "content_bottom_name": "{{custom_contract_delivery_address}}" + }, + "templates_ref": { + "page_id": "string", + "block_id": "string", + "config_id": "string", + "global_search_config_id": "string" + }, + "filters": [ + { + "term": { + "status.keyword": "active" + } + }, + { + "range": { + "_created_at": { + "gte": "2023-01-01" + } + } + } + ], + "filters_context": [ + { + "portal_user": true + }, + { + "contact": true + } + ], + "targets": ["3ec28ab5-8598-41ef-9486-b57fca1d5e2a"], + "include": ["active_workflow"], + "highlight": {} }' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal deleteEntityFile +cat body.json | epilot customer-portal searchPortalUserEntities ``` With JSONata filter: ```bash -epilot customer-portal deleteEntityFile --jsonata '$' +epilot customer-portal searchPortalUserEntities --jsonata '$' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" + } + ], + "pagination": { + "from": 0, + "size": 10, + "total": 50, + "has_more": true + }, + "hits": 10, + "includes": { + "active_workflow": {} + } +} ``` +
+ --- -### `savePortalFiles` +### `canTriggerPortalFlow` -Add files to portal +Returns whether the user can trigger a portal flow -`POST /v2/portal/portal/files` +`POST /v2/portal/can-trigger-portal-flow` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `origin` | query | string | No | Origin of the portal | +| `portal_id` | query | string | Yes | | **Request Body** (required) **Sample Call** ```bash -epilot customer-portal savePortalFiles +epilot customer-portal canTriggerPortalFlow \ + -p portal_id=123 ``` With request body: ```bash -epilot customer-portal savePortalFiles \ +epilot customer-portal canTriggerPortalFlow \ + -p portal_id=123 \ -d '{ - "origin": "string", - "files": [ - { - "filename": 12345, - "file_type": "orderRightTeaser", - "_tags": 12345, - "s3ref": { - "bucket": 12345, - "key": 12345 - } + "activity_id": "01F130Q52Q6MWSNS8N2AVXV4JN", + "ecp_config": { + "file_config": { + "shared_with_end_customer": true, + "_tags": ["example", "mock"] } - ] + } }' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal savePortalFiles +cat body.json | epilot customer-portal canTriggerPortalFlow -p portal_id=123 ``` With JSONata filter: ```bash -epilot customer-portal savePortalFiles --jsonata 'createdFiles' +epilot customer-portal canTriggerPortalFlow -p portal_id=123 --jsonata 'can_trigger' ```
@@ -6128,17 +7681,7 @@ epilot customer-portal savePortalFiles --jsonata 'createdFiles' ```json { - "createdFiles": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" - } - ] + "can_trigger": true } ``` @@ -6146,81 +7689,75 @@ epilot customer-portal savePortalFiles --jsonata 'createdFiles' --- -### `getRegistrationIdentifiers` +### `getAutomationContext` -Get valid attributes from entities that can be used as identifier to map contact to user on registration +Retrieves the automation context. -`GET /v2/portal/registration/identifiers` +`GET /v2/portal/automation-context` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `activity_id` | query | string (ulid) | Yes | Activity ID | +| `type` | query | "file" | Yes | Type of the context to retrieve | **Sample Call** ```bash -epilot customer-portal getRegistrationIdentifiers +epilot customer-portal getAutomationContext \ + -p activity_id=01F130Q52Q6MWSNS8N2AVXV4JN \ + -p type=example ``` With JSONata filter: ```bash -epilot customer-portal getRegistrationIdentifiers --jsonata 'data' +epilot customer-portal getAutomationContext -p activity_id=01F130Q52Q6MWSNS8N2AVXV4JN -p type=example --jsonata '$' ```
Sample Response ```json -{ - "data": { - "contact": [ - { - "label": "First name", - "name": "first_name", - "type": "string" - } - ], - "contract": [ - { - "label": "Contract number", - "name": "contract_number", - "type": "string" - } - ] - } -} +{} ```
--- -### `getFileById` +### `updateWorkflowStepAsDone` -Fetch a document with ID +Update a workflow step as done -`GET /v2/portal/user/file/{id}` +`PUT /v2/portal/workflow/{workflow_id}/{step_id}:markDone` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | The Id of a file | +| `workflow_id` | path | string | Yes | | +| `step_id` | path | string | Yes | | **Sample Call** ```bash -epilot customer-portal getFileById \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal updateWorkflowStepAsDone \ + -p workflow_id=0bjwcxc827t \ + -p step_id=q1d6vcbsqvn ``` Using positional args for path parameters: ```bash -epilot customer-portal getFileById 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal updateWorkflowStepAsDone 0bjwcxc827t q1d6vcbsqvn ``` With JSONata filter: ```bash -epilot customer-portal getFileById -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'file' +epilot customer-portal updateWorkflowStepAsDone -p workflow_id=0bjwcxc827t -p step_id=q1d6vcbsqvn --jsonata '$' ```
@@ -6228,29 +7765,25 @@ epilot customer-portal getFileById -p id=5da0a718-c822-403d-9f5d-20d4584e0528 -- ```json { - "file": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file", - "filename": "document.pdf", - "access_control": "private", - "file_date": "2021-02-09T12:41:43.662Z", - "public_url": "https://epilot-files-prod.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", - "type": "document", - "mime_type": "application/pdf", - "_relations": [ - { - "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_schema": "contact", - "_title": "Opportunity ABC" - } - ], - "is_new": true - } + "startedTime": "2024-01-12T13:29:55.942Z", + "requirements": [], + "created": "2023-10-20T17:41:10.256Z", + "executionType": "MANUAL", + "assignedToInProgress": "-", + "sectionId": "lzxsw2sblj7", + "type": "STEP", + "entityRefId": "q1d6vcbsqvn", + "assignedTo": ["10014532"], + "lastUpdated": "2024-01-13T05:18:43.838Z", + "ecp": {}, + "userIds": [], + "name": "Hinterlege den vereinbarten LIC Termin", + "id": "q1d6vcbsqvn", + "definitionId": "9UjHKq", + "status": "COMPLETED", + "manuallyCreated": false, + "enabled": true, + "completedTime": "2024-01-13T05:18:43.827Z" } ``` @@ -6258,35 +7791,37 @@ epilot customer-portal getFileById -p id=5da0a718-c822-403d-9f5d-20d4584e0528 -- --- -### `trackFileDownloaded` +### `getEntityWorkflows` -Track that user has downloaded a file +Get all workflows associated with an entity (requires access to the entity) -`POST /v2/portal/user/file/{id}/downloaded` +`GET /v2/portal/entity/{slug}/{id}/workflows` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | The Id of a file | +| `slug` | path | string | Yes | | +| `id` | path | string | Yes | | **Sample Call** ```bash -epilot customer-portal trackFileDownloaded \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal getEntityWorkflows \ + -p slug=contact \ + -p id=abc123 ``` Using positional args for path parameters: ```bash -epilot customer-portal trackFileDownloaded 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal getEntityWorkflows contact abc123 ``` With JSONata filter: ```bash -epilot customer-portal trackFileDownloaded -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'file' +epilot customer-portal getEntityWorkflows -p slug=contact -p id=abc123 --jsonata 'workflow_executions' ```
@@ -6294,97 +7829,43 @@ epilot customer-portal trackFileDownloaded -p id=5da0a718-c822-403d-9f5d-20d4584 ```json { - "file": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file", - "filename": "document.pdf", - "access_control": "private", - "file_date": "2021-02-09T12:41:43.662Z", - "public_url": "https://epilot-files-prod.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", - "type": "document", - "mime_type": "application/pdf", - "_relations": [ - { - "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_schema": "contact", - "_title": "Opportunity ABC" - } - ], - "is_new": true - } -} -``` - -
- ---- - -### `getBillingEvents` - -Fetch billing events for a portal user - -`GET /v2/portal/billing/events` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `from` | query | number | No | | -| `size` | query | number | No | | -| `entity_id` | query | string (uuid)[] | No | Entity ID to filter billing events by | -| `event_type` | query | "installment" \| "reimbursement" | No | | -| `paid` | query | boolean | No | | -| `date_after` | query | string (date-time) | No | | -| `date_before` | query | string (date-time) | No | | -| `sort` | query | string | No | | - -**Sample Call** - -```bash -epilot customer-portal getBillingEvents -``` - -With JSONata filter: - -```bash -epilot customer-portal getBillingEvents --jsonata 'results[0]' -``` - -
-Sample Response - -```json -{ - "results": [ + "workflow_executions": [ { - "billing_amount_decimal": "100.50", - "billing_amount": 10050, - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "type": "installment", - "due_date": "1970-01-01", - "paid_date": "1970-01-01" + "id": "8gja72h6kas6h", + "name": "Lead Qualification", + "trigger": "MANUAL", + "status": "STARTED", + "creationTime": "2021-04-27T12:01:13.000Z", + "lastUpdateTime": "2021-04-27T12:01:13.000Z", + "dueDate": "2021-04-27T12:01:13.000Z", + "assignedTo": ["252", "29052"], + "flow": [ + { + "id": "sectionId1", + "name": "Initial Information Gathering", + "steps": [ + { + "id": "sada5641f3a21", + "name": "Call client and confirm address and product", + "status": "ASSIGNED", + "assignedTo": ["11"] + }, + { + "id": "sada5641f3a22", + "name": "Check product availability", + "status": "UNASSIGNED" + } + ] + }, + { + "id": "firstLevelStepId1", + "name": "Print and send catalog", + "status": "SKIPPED", + "dueDate": "2023-01-15T20:00:00" + } + ] } - ], - "hits": 50 + ] } ``` @@ -6392,22 +7873,22 @@ epilot customer-portal getBillingEvents --jsonata 'results[0]' --- -### `getCustomerBalance` +### `getOutstandingTasks` -Get total balance across all contracts and orders of a customer entity. +Returns all outstanding workflow journey tasks for the authenticated portal user, across their opportunity, order and co -`GET /v2/portal/billing/customers/balance` +`GET /v2/portal/engagement/tasks` **Sample Call** ```bash -epilot customer-portal getCustomerBalance +epilot customer-portal getOutstandingTasks ``` With JSONata filter: ```bash -epilot customer-portal getCustomerBalance --jsonata 'balance' +epilot customer-portal getOutstandingTasks --jsonata 'tasks' ```
@@ -6415,9 +7896,20 @@ epilot customer-portal getCustomerBalance --jsonata 'balance' ```json { - "balance": 8990, - "balance_decimal": "89.90", - "balance_currency": "EUR" + "tasks": [ + { + "entity_id": "string", + "entity_schema": "string", + "entity_title": "string", + "workflow_id": "string", + "workflow_name": "string", + "step_id": "string", + "step_name": "string", + "journey_id": "string", + "complete_task_automatically": true + } + ], + "total": 0 } ``` @@ -6425,35 +7917,37 @@ epilot customer-portal getCustomerBalance --jsonata 'balance' --- -### `getBillingAccount` +### `getEntityPortalWorkflows` -Get a billing account by id. +Get all portal-relevant workflows associated with an entity (requires access to the entity), -`GET /v2/portal/billing/accounts/{id}` +`GET /v2/portal/entity/{slug}/{id}/workflows/linearized` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | | +| `slug` | path | string | Yes | | +| `id` | path | string | Yes | | **Sample Call** ```bash -epilot customer-portal getBillingAccount \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal getEntityPortalWorkflows \ + -p slug=opportunity \ + -p id=abc123 ``` Using positional args for path parameters: ```bash -epilot customer-portal getBillingAccount 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal getEntityPortalWorkflows opportunity abc123 ``` With JSONata filter: ```bash -epilot customer-portal getBillingAccount -p id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'entity._title' +epilot customer-portal getEntityPortalWorkflows -p slug=opportunity -p id=abc123 --jsonata 'portal_workflows' ```
@@ -6461,52 +7955,78 @@ epilot customer-portal getBillingAccount -p id=5da0a718-c822-403d-9f5d-20d4584e0 ```json { - "entity": { - "billing_account_number": "string", - "balance": 0, - "balance_decimal": "string", - "balance_currency": "EUR", - "billing_contact": { - "$relation": [ + "portal_workflows": [ + { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "version": 2, + "created_at": "string", + "updated_at": "string", + "completed_at": "string", + "due_date": "string", + "assigned_to": ["string"], + "contexts": [ { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + "entity_id": "string", + "entity_schema": "string", + "is_primary": true } - ] - }, - "billing_address": { - "$relation_ref": [ + ], + "is_path_complete": true, + "tasks": [ { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896", - "path": "address", - "_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + "id": "string", + "name": "string", + "order": 0, + "status": "COMPLETED", + "is_active": true, + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "complete_task_automatically": true + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "complete_task_automatically": true + } + }, + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "complete_task_automatically": true + }, + "assigned_to": ["string"], + "phase_id": "string", + "phase_name": "string", + "stage_id": "string", + "completed_at": "string", + "updated_at": "string" } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z" - }, - "relations": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" + ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "status": "COMPLETED", + "completed_at": "string" } - }, - "_schema": "contact" + ] } ] } @@ -6516,31 +8036,31 @@ epilot customer-portal getBillingAccount -p id=5da0a718-c822-403d-9f5d-20d4584e0 --- -### `loginToPortalAsUser` +### `getEntityPortalWorkflowsBatch` -Generate a token to log in to a portal impersonating a users. +Batch variant of `getEntityPortalWorkflows`: returns portal-relevant workflows for -`POST /v2/portal/admin:login-as-user` +`POST /v2/portal/entities/workflows/linearized/batch` **Request Body** (required) **Sample Call** ```bash -epilot customer-portal loginToPortalAsUser \ - -d '{"email":"portal-customer@email.com","origin":"string"}' +epilot customer-portal getEntityPortalWorkflowsBatch \ + -d '{"entities":[{"id":"string","slug":"order"}]}' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal loginToPortalAsUser +cat body.json | epilot customer-portal getEntityPortalWorkflowsBatch ``` With JSONata filter: ```bash -epilot customer-portal loginToPortalAsUser --jsonata 'login_as_token' +epilot customer-portal getEntityPortalWorkflowsBatch --jsonata 'results[0]' ```
@@ -6548,7 +8068,12 @@ epilot customer-portal loginToPortalAsUser --jsonata 'login_as_token' ```json { - "login_as_token": "string" + "results": [ + { + "entity_id": "string", + "portal_workflows": [] + } + ] } ``` @@ -6556,38 +8081,42 @@ epilot customer-portal loginToPortalAsUser --jsonata 'login_as_token' --- -### `triggerEntityAccessEvent` - -Trigger entity access event for a portal user +### `uploadMeterReadingPhoto` -`POST /v2/portal/entity/{schema}/access` +Uploads a Meter Reading photo and - if enabled - gives back data extracted from the photo. -**Parameters** +`POST /v2/portal/metering/reading/photo` -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `schema` | path | string | Yes | Entity schema | -| `entity_id` | query | string (uuid) | No | Entity ID | -| `origin` | query | string | Yes | Portal origin | +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal triggerEntityAccessEvent \ - -p schema=contract \ - -p origin=example +epilot customer-portal uploadMeterReadingPhoto ``` -Using positional args for path parameters: +With request body: ```bash -epilot customer-portal triggerEntityAccessEvent contract +epilot customer-portal uploadMeterReadingPhoto \ + -d '{ + "filename": "Reading 10.01.2025.jpg", + "mime_type": "image/jpeg", + "contents": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxMTEhUTExMWFhUXGBgYGBgYGBgYGBgYGBgYFxgYFxgYHSggGBolHRgXITEhJSkrLi4uFx8zODMtNygtLisBCgoKDg0OGhAQGy0lHyUt", + "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal uploadMeterReadingPhoto ``` With JSONata filter: ```bash -epilot customer-portal triggerEntityAccessEvent -p schema=contract -p origin=example --jsonata 'eventId' +epilot customer-portal uploadMeterReadingPhoto --jsonata 'data' ```
@@ -6595,7 +8124,17 @@ epilot customer-portal triggerEntityAccessEvent -p schema=contract -p origin=exa ```json { - "eventId": "string" + "data": { + "filename": "Reading 10.01.2025.jpg", + "s3ref": { + "bucket": "meter-readings", + "key": "uuid/reading-10.01.2025.jpg" + }, + "reading": "000123.45", + "sector": "water", + "meter_numbers": ["00123456"], + "file_id": "abc123def456" + } } ``` @@ -6603,38 +8142,59 @@ epilot customer-portal triggerEntityAccessEvent -p schema=contract -p origin=exa --- -### `triggerEntityAccessEventV3` +### `createMeterReading` -Trigger entity access event for a portal user +Inserts a new meter reading. -`POST /v3/portal/entity/{schema}/access` +`POST /v2/portal/metering/reading` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `schema` | path | string | Yes | Entity schema | -| `entity_id` | query | string (uuid) | No | Entity ID | -| `portal_id` | query | string | Yes | Portal ID | +| `override_plausibility` | query | boolean | No | Override plausibility check | + +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal triggerEntityAccessEventV3 \ - -p schema=contract \ - -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c +epilot customer-portal createMeterReading ``` -Using positional args for path parameters: +With request body: ```bash -epilot customer-portal triggerEntityAccessEventV3 contract +epilot customer-portal createMeterReading \ + -d '{ + "value": 240, + "read_by": "John Doe", + "reason": "Storing the feed-in record", + "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "counter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "direction": "feed-in", + "timestamp": "2022-10-10", + "source": "ECP", + "status": "valid", + "external_id": "string", + "remark": "Customer reported unusual consumption", + "metadata": { + "registration_id": "1234567890", + "business_unit": "ABC" + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal createMeterReading ``` With JSONata filter: ```bash -epilot customer-portal triggerEntityAccessEventV3 -p schema=contract -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c --jsonata 'eventId' +epilot customer-portal createMeterReading --jsonata 'data' ```
@@ -6642,7 +8202,23 @@ epilot customer-portal triggerEntityAccessEventV3 -p schema=contract -p portal_i ```json { - "eventId": "string" + "data": { + "value": 240, + "read_by": "John Doe", + "reason": "Storing the feed-in record", + "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "counter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "direction": "feed-in", + "timestamp": "2022-10-10", + "source": "ECP", + "status": "valid", + "external_id": "string", + "remark": "Customer reported unusual consumption", + "metadata": { + "registration_id": "1234567890", + "business_unit": "ABC" + } + } } ``` @@ -6650,74 +8226,38 @@ epilot customer-portal triggerEntityAccessEventV3 -p schema=contract -p portal_i --- -### `getPortalUserEntity` - -Get a single entity for a portal user +### `getAllowedMeterReadingRange` -`POST /v2/portal/entity:get` +Get allowed reading range for all counters of a meter from the configured -**Request Body** +`GET /v2/portal/metering/reading/allowed-range/{meter_id}` -**Sample Call** +**Parameters** -```bash -epilot customer-portal getPortalUserEntity -``` +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `meter_id` | path | string | Yes | The ID of the meter. | +| `origin` | query | string | No | Origin of the portal | +| `timestamp` | query | string | No | If not provided, the system will default to now. | +| `context_entities` | query | object[] | No | Additional entities to include in the context for variable interpolation in the hook. | -With request body: +**Sample Call** ```bash -epilot customer-portal getPortalUserEntity \ - -d '{ - "slug": "contact", - "entity_id": "3ec28ab5-8598-41ef-9486-b57fca1d5e2a", - "hydrate": false, - "fields": ["_id", "_title"], - "templates": { - "content_top_name": "Customer #{{contract.customer_number}}", - "main_content_name": "{{contract.contract_name}} ({{contract.contract_number}})", - "content_bottom_name": "{{custom_contract_delivery_address}}", - "nested_content": { - "title": "{{contract.contract_name}}", - "subtitle": "{{contract.contract_number}}" - } - }, - "filters": [ - { - "term": { - "status.keyword": "active" - } - }, - { - "range": { - "_created_at": { - "gte": "2023-01-01" - } - } - } - ], - "filters_context": [ - { - "portal_user": true - }, - { - "contact": true - } - ], - "targets": ["3ec28ab5-8598-41ef-9486-b57fca1d5e2a"] -}' +epilot customer-portal getAllowedMeterReadingRange \ + -p meter_id=123e4567-e89b-12d3-a456-426614174000 ``` -Using stdin pipe: +Using positional args for path parameters: ```bash -cat body.json | epilot customer-portal getPortalUserEntity +epilot customer-portal getAllowedMeterReadingRange 123e4567-e89b-12d3-a456-426614174000 ``` With JSONata filter: ```bash -epilot customer-portal getPortalUserEntity --jsonata 'result' +epilot customer-portal getAllowedMeterReadingRange -p meter_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' ```
@@ -6725,24 +8265,13 @@ epilot customer-portal getPortalUserEntity --jsonata 'result' ```json { - "result": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" - } - }, - "_schema": "contact" - } + "data": [ + { + "meter_counter_id": "string", + "min_value": 0, + "max_value": 0 + } + ] } ``` @@ -6750,79 +8279,51 @@ epilot customer-portal getPortalUserEntity --jsonata 'result' --- -### `searchPortalUserEntities` +### `getMeterReadings` -Search all entities of a portal user +Fetches meter readings for a counter and optionally resolves Handlebars -`POST /v2/portal/entity:search` +`POST /v2/portal/metering/readings` -**Request Body** +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal searchPortalUserEntities +epilot customer-portal getMeterReadings ``` With request body: ```bash -epilot customer-portal searchPortalUserEntities \ +epilot customer-portal getMeterReadings \ -d '{ - "slug": "contact", - "q": "contract", - "q_fields": ["_title", "customer._title", "customer.first_name", "customer.last_name"], - "group": "customer._title", - "group_title": "{{customer[Primary].first_name}} {{customer[Primary].last_name}}", - "group_size": 100, - "group_sort": "desc", - "group_after_key": {}, - "sort": "_created_at:desc", + "meter_id": "string", + "counter_id": "string", + "sort": "desc", "from": 0, - "size": 100, - "hydrate": false, - "fields": ["_id", "_title"], - "templates": { - "content_top_name": "Customer #{{contract.customer_number}}", - "main_content_name": "{{contract.contract_name}} ({{contract.contract_number}})", - "content_bottom_name": "{{custom_contract_delivery_address}}" - }, - "filters": [ - { - "term": { - "status.keyword": "active" - } - }, - { - "range": { - "_created_at": { - "gte": "2023-01-01" - } - } - } - ], - "filters_context": [ - { - "portal_user": true - }, - { - "contact": true - } - ], - "targets": ["3ec28ab5-8598-41ef-9486-b57fca1d5e2a"] + "size": 10, + "templates": {}, + "counter_templates": {}, + "templates_ref": { + "page_id": "string", + "block_id": "string", + "config_id": "string", + "global_search_config_id": "string" + } }' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal searchPortalUserEntities +cat body.json | epilot customer-portal getMeterReadings ``` With JSONata filter: ```bash -epilot customer-portal searchPortalUserEntities --jsonata '$' +epilot customer-portal getMeterReadings --jsonata 'results[0]' ```
@@ -6832,31 +8333,11 @@ epilot customer-portal searchPortalUserEntities --jsonata '$' { "results": [ { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" - } - }, - "_schema": "contact" + "templates_output": {} } ], - "pagination": { - "from": 0, - "size": 10, - "total": 50, - "has_more": true - }, - "hits": 10 + "hits": 0, + "counter_templates_output": {} } ``` @@ -6864,54 +8345,39 @@ epilot customer-portal searchPortalUserEntities --jsonata '$' --- -### `canTriggerPortalFlow` +### `getSSOProvider` -Returns whether the user can trigger a portal flow +Returns the public configuration of a single SSO identity provider with env var -`POST /v2/portal/can-trigger-portal-flow` +`GET /v2/portal/public/sso/providers/{provider_slug}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `origin` | query | string | No | Origin of the portal | -| `portal_id` | query | string | Yes | | - -**Request Body** (required) +| `provider_slug` | path | string | Yes | Provider slug (organization-unique) | +| `org_id` | query | string | No | epilot organization id (required with `origin` or `portal_id`) | +| `origin` | query | "END_CUSTOMER_PORTAL" \| "INSTALLER_PORTAL" | No | Origin of the Portal | +| `portal_id` | query | string | No | ID of the Portal | +| `domain` | query | string | No | Portal domain for identification (alternative to org_id + origin/portal_id) | **Sample Call** ```bash -epilot customer-portal canTriggerPortalFlow \ - -p portal_id=123 -``` - -With request body: - -```bash -epilot customer-portal canTriggerPortalFlow \ - -p portal_id=123 \ - -d '{ - "activity_id": "01F130Q52Q6MWSNS8N2AVXV4JN", - "ecp_config": { - "file_config": { - "shared_with_end_customer": true, - "_tags": ["example", "mock"] - } - } -}' +epilot customer-portal getSSOProvider \ + -p provider_slug=office-365-login ``` -Using stdin pipe: +Using positional args for path parameters: ```bash -cat body.json | epilot customer-portal canTriggerPortalFlow -p portal_id=123 +epilot customer-portal getSSOProvider office-365-login ``` With JSONata filter: ```bash -epilot customer-portal canTriggerPortalFlow -p portal_id=123 --jsonata 'can_trigger' +epilot customer-portal getSSOProvider -p provider_slug=office-365-login --jsonata 'slug' ```
@@ -6919,7 +8385,34 @@ epilot customer-portal canTriggerPortalFlow -p portal_id=123 --jsonata 'can_trig ```json { - "can_trigger": true + "slug": "office-365-login", + "display_name": "Office 365 Login", + "oidc_config": { + "type": "implicit", + "oidc_issuer": "https://login.microsoftonline.com/33d4f3e5-3df2-421e-b92e-a63cfa680a88/v2.0", + "redirect_uri": "https://customer-portal.com/login", + "client_id": "ab81daf8-8b1f-42d6-94ca-c51621054c75", + "client_secret": "7BIUnn~6shh.7fNtXb..3k1Mp3s6k6WK3B", + "has_client_secret": true, + "scope": "openid email", + "metadata": { + "response_modes_supported": ["form_post"], + "authorization_endpoint": "https://www.facebook.com/v12.0/dialog/oauth", + "token_endpoint": "https://graph.facebook.com/v12.0/oauth/access_token", + "userinfo_endpoint": "https://graph.facebook.com/me", + "logout_uri": "https://login.microsoftonline.com/common/oauth2/v2.0/logout", + "logout_redirect_uri": "https://customer-portal.com/login", + "skip_login_as_logout": false, + "mobile_redirect_uri": "msauth.io.epilot.ecp://auth", + "test_auth_username": "test@epilot.io", + "test_auth_password": "string" + }, + "prompt": "login" + }, + "mobile_oidc_config": { + "client_id": 123456, + "client_secret": 123456 + } } ``` @@ -6927,75 +8420,112 @@ epilot customer-portal canTriggerPortalFlow -p portal_id=123 --jsonata 'can_trig --- -### `getAutomationContext` +### `getPublicSSOProviderV3` -Retrieves the automation context. +Returns the public configuration of a single SSO identity provider with env var -`GET /v2/portal/automation-context` +`GET /v3/portal/public/sso/providers/{provider_slug}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `activity_id` | query | string (ulid) | Yes | Activity ID | -| `type` | query | "file" | Yes | Type of the context to retrieve | +| `provider_slug` | path | string | Yes | Provider slug (organization-unique) | +| `org_id` | query | string | Yes | epilot organization id | +| `portal_id` | query | string | Yes | ID of the Portal | **Sample Call** ```bash -epilot customer-portal getAutomationContext \ - -p activity_id=01F130Q52Q6MWSNS8N2AVXV4JN \ - -p type=example +epilot customer-portal getPublicSSOProviderV3 \ + -p provider_slug=office-365-login \ + -p org_id=123 \ + -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal getPublicSSOProviderV3 office-365-login ``` With JSONata filter: ```bash -epilot customer-portal getAutomationContext -p activity_id=01F130Q52Q6MWSNS8N2AVXV4JN -p type=example --jsonata '$' +epilot customer-portal getPublicSSOProviderV3 -p provider_slug=office-365-login -p org_id=123 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c --jsonata 'slug' ```
Sample Response ```json -{} +{ + "slug": "office-365-login", + "display_name": "Office 365 Login", + "oidc_config": { + "type": "implicit", + "oidc_issuer": "https://login.microsoftonline.com/33d4f3e5-3df2-421e-b92e-a63cfa680a88/v2.0", + "redirect_uri": "https://customer-portal.com/login", + "client_id": "ab81daf8-8b1f-42d6-94ca-c51621054c75", + "client_secret": "7BIUnn~6shh.7fNtXb..3k1Mp3s6k6WK3B", + "has_client_secret": true, + "scope": "openid email", + "metadata": { + "response_modes_supported": ["form_post"], + "authorization_endpoint": "https://www.facebook.com/v12.0/dialog/oauth", + "token_endpoint": "https://graph.facebook.com/v12.0/oauth/access_token", + "userinfo_endpoint": "https://graph.facebook.com/me", + "logout_uri": "https://login.microsoftonline.com/common/oauth2/v2.0/logout", + "logout_redirect_uri": "https://customer-portal.com/login", + "skip_login_as_logout": false, + "mobile_redirect_uri": "msauth.io.epilot.ecp://auth", + "test_auth_username": "test@epilot.io", + "test_auth_password": "string" + }, + "prompt": "login" + } +} ```
--- -### `updateWorkflowStepAsDone` +### `ssoLogin` -Update a workflow step as done +Initiate login using external SSO identity. -`PUT /v2/portal/workflow/{workflow_id}/{step_id}:markDone` +`POST /v2/portal/public/sso/login` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `workflow_id` | path | string | Yes | | -| `step_id` | path | string | Yes | | +| `origin` | query | string | Yes | Origin of the Portal | +| `org_id` | query | string | Yes | epilot organization id | +| `contact_id` | query | string (uuid) | No | contact id in the epilot system | + +**Request Body** **Sample Call** ```bash -epilot customer-portal updateWorkflowStepAsDone \ - -p workflow_id=0bjwcxc827t \ - -p step_id=q1d6vcbsqvn +epilot customer-portal ssoLogin \ + -p origin=example \ + -p org_id=123 \ + -d '{"provider_slug":"office-365-login"}' ``` -Using positional args for path parameters: +Using stdin pipe: ```bash -epilot customer-portal updateWorkflowStepAsDone 0bjwcxc827t q1d6vcbsqvn +cat body.json | epilot customer-portal ssoLogin -p origin=example -p org_id=123 ``` With JSONata filter: ```bash -epilot customer-portal updateWorkflowStepAsDone -p workflow_id=0bjwcxc827t -p step_id=q1d6vcbsqvn --jsonata '$' +epilot customer-portal ssoLogin -p origin=example -p org_id=123 --jsonata 'email' ```
@@ -7003,25 +8533,8 @@ epilot customer-portal updateWorkflowStepAsDone -p workflow_id=0bjwcxc827t -p st ```json { - "startedTime": "2024-01-12T13:29:55.942Z", - "requirements": [], - "created": "2023-10-20T17:41:10.256Z", - "executionType": "MANUAL", - "assignedToInProgress": "-", - "sectionId": "lzxsw2sblj7", - "type": "STEP", - "entityRefId": "q1d6vcbsqvn", - "assignedTo": ["10014532"], - "lastUpdated": "2024-01-13T05:18:43.838Z", - "ecp": {}, - "userIds": [], - "name": "Hinterlege den vereinbarten LIC Termin", - "id": "q1d6vcbsqvn", - "definitionId": "9UjHKq", - "status": "COMPLETED", - "manuallyCreated": false, - "enabled": true, - "completedTime": "2024-01-13T05:18:43.827Z" + "token": "string", + "email": "portal-customer@email.com" } ``` @@ -7029,37 +8542,40 @@ epilot customer-portal updateWorkflowStepAsDone -p workflow_id=0bjwcxc827t -p st --- -### `getEntityWorkflows` +### `ssoLoginV3` -Get all workflows associated with an entity (requires access to the entity) +Initiate login using external SSO identity. -`GET /v2/portal/entity/{slug}/{id}/workflows` +`POST /v3/portal/public/sso/login` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `slug` | path | string | Yes | | -| `id` | path | string | Yes | | +| `portal_id` | query | string | No | ID of the Portal (required if domain is not provided) | +| `org_id` | query | string | No | epilot organization id (required if domain is not provided) | +| `domain` | query | string | No | Portal domain for identification (alternative to org_id + portal_id) | +| `contact_id` | query | string (uuid) | No | contact id in the epilot system | + +**Request Body** **Sample Call** ```bash -epilot customer-portal getEntityWorkflows \ - -p slug=contact \ - -p id=abc123 +epilot customer-portal ssoLoginV3 \ + -d '{"provider_slug":"office-365-login","login_only":false}' ``` -Using positional args for path parameters: +Using stdin pipe: ```bash -epilot customer-portal getEntityWorkflows contact abc123 +cat body.json | epilot customer-portal ssoLoginV3 ``` With JSONata filter: ```bash -epilot customer-portal getEntityWorkflows -p slug=contact -p id=abc123 --jsonata 'workflow_executions' +epilot customer-portal ssoLoginV3 --jsonata 'email' ```
@@ -7067,43 +8583,8 @@ epilot customer-portal getEntityWorkflows -p slug=contact -p id=abc123 --jsonata ```json { - "workflow_executions": [ - { - "id": "8gja72h6kas6h", - "name": "Lead Qualification", - "trigger": "MANUAL", - "status": "STARTED", - "creationTime": "2021-04-27T12:01:13.000Z", - "lastUpdateTime": "2021-04-27T12:01:13.000Z", - "dueDate": "2021-04-27T12:01:13.000Z", - "assignedTo": ["252", "29052"], - "flow": [ - { - "id": "sectionId1", - "name": "Initial Information Gathering", - "steps": [ - { - "id": "sada5641f3a21", - "name": "Call client and confirm address and product", - "status": "ASSIGNED", - "assignedTo": ["11"] - }, - { - "id": "sada5641f3a22", - "name": "Check product availability", - "status": "UNASSIGNED" - } - ] - }, - { - "id": "firstLevelStepId1", - "name": "Print and send catalog", - "status": "SKIPPED", - "dueDate": "2023-01-15T20:00:00" - } - ] - } - ] + "token": "string", + "email": "portal-customer@email.com" } ``` @@ -7111,119 +8592,78 @@ epilot customer-portal getEntityWorkflows -p slug=contact -p id=abc123 --jsonata --- -### `uploadMeterReadingPhoto` - -Uploads a Meter Reading photo and - if enabled - gives back data extracted from the photo. - -`POST /v2/portal/metering/reading/photo` - -**Request Body** (required) +### `ssoRedirect` -**Sample Call** +Handles the redirect from the external SSO provider. Validates the authorization `code` and `state` received from the pr -```bash -epilot customer-portal uploadMeterReadingPhoto -``` +`POST /v2/portal/public/sso/redirect` -With request body: +**Parameters** -```bash -epilot customer-portal uploadMeterReadingPhoto \ - -d '{ - "filename": "Reading 10.01.2025.jpg", - "mime_type": "image/jpeg", - "contents": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxMTEhUTExMWFhUXGBgYGBgYGBgYGBgYGBgYFxgYFxgYHSggGBolHRgXITEhJSkrLi4uFx8zODMtNygtLisBCgoKDg0OGhAQGy0lHyUt", - "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528" -}' -``` +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `web_uri` | query | string | Yes | The URI to redirect to after the SSO login | -Using stdin pipe: +**Sample Call** ```bash -cat body.json | epilot customer-portal uploadMeterReadingPhoto +epilot customer-portal ssoRedirect \ + -p web_uri=https://customer-portal.com ``` With JSONata filter: ```bash -epilot customer-portal uploadMeterReadingPhoto --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": { - "filename": "Reading 10.01.2025.jpg", - "s3ref": { - "bucket": "meter-readings", - "key": "uuid/reading-10.01.2025.jpg" - }, - "reading": "000123.45", - "sector": "water", - "meter_numbers": ["00123456"] - } -} +epilot customer-portal ssoRedirect -p web_uri=https://customer-portal.com --jsonata '$' ``` -
- --- -### `createMeterReading` +### `ssoCallback` -Inserts a new meter reading. +Handles the callback from the external SSO provider, validates the authorization `code` -`POST /v2/portal/metering/reading` +`POST /v2/portal/public/sso/callback` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `override_plausibility` | query | boolean | No | Override plausibility check | +| `domain` | query | string | No | | **Request Body** (required) **Sample Call** ```bash -epilot customer-portal createMeterReading +epilot customer-portal ssoCallback ``` With request body: ```bash -epilot customer-portal createMeterReading \ +epilot customer-portal ssoCallback \ -d '{ - "value": 240, - "read_by": "John Doe", - "reason": "Storing the feed-in record", - "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "counter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", - "source": "ECP", - "status": "valid", - "external_id": "string", - "remark": "Customer reported unusual consumption", - "metadata": { - "registration_id": "1234567890", - "business_unit": "ABC" - } + "provider_slug": "office-365-login", + "token_endpoint": "https://www.facebook.com/v12.0/dialog/oauth", + "grant_type": "authorization_code", + "code": "123456", + "redirect_uri": "https://customer-portal.com/sso", + "client_id": "123456", + "code_verifier": "123456" }' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal createMeterReading +cat body.json | epilot customer-portal ssoCallback ``` With JSONata filter: ```bash -epilot customer-portal createMeterReading --jsonata 'data' +epilot customer-portal ssoCallback --jsonata 'access_token' ```
@@ -7231,23 +8671,12 @@ epilot customer-portal createMeterReading --jsonata 'data' ```json { - "data": { - "value": 240, - "read_by": "John Doe", - "reason": "Storing the feed-in record", - "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "counter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", - "source": "ECP", - "status": "valid", - "external_id": "string", - "remark": "Customer reported unusual consumption", - "metadata": { - "registration_id": "1234567890", - "business_unit": "ABC" - } - } + "access_token": "123456", + "token_type": "Bearer", + "expires_in": 3600, + "refresh_token": "123456", + "id_token": "123456", + "scope": "openid email" } ``` @@ -7255,276 +8684,29 @@ epilot customer-portal createMeterReading --jsonata 'data' --- -### `getAllowedMeterReadingRange` +### `getPortalPage` -Get allowed reading range for all counters of a meter from the configured +Fetch a portal page by id -`GET /v2/portal/metering/reading/allowed-range/{meter_id}` +`GET /v2/portal/pages/{id}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `meter_id` | path | string | Yes | The ID of the meter. | -| `origin` | query | string | No | Origin of the portal | -| `timestamp` | query | string | No | If not provided, the system will default to now. | -| `context_entities` | query | object[] | No | Additional entities to include in the context for variable interpolation in the hook. | +| `id` | path | string (uuid) | Yes | | **Sample Call** ```bash -epilot customer-portal getAllowedMeterReadingRange \ - -p meter_id=123e4567-e89b-12d3-a456-426614174000 +epilot customer-portal getPortalPage \ + -p id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using positional args for path parameters: ```bash -epilot customer-portal getAllowedMeterReadingRange 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot customer-portal getAllowedMeterReadingRange -p meter_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": [ - { - "meter_counter_id": "string", - "min_value": 0, - "max_value": 0 - } - ] -} -``` - -
- ---- - -### `ssoLogin` - -Initiate login using external SSO identity. - -`POST /v2/portal/public/sso/login` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `origin` | query | string | Yes | Origin of the Portal | -| `org_id` | query | string | Yes | epilot organization id | -| `contact_id` | query | string (uuid) | No | contact id in the epilot system | - -**Request Body** - -**Sample Call** - -```bash -epilot customer-portal ssoLogin \ - -p origin=example \ - -p org_id=123 \ - -d '{"provider_slug":"office-365-login"}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal ssoLogin -p origin=example -p org_id=123 -``` - -With JSONata filter: - -```bash -epilot customer-portal ssoLogin -p origin=example -p org_id=123 --jsonata 'email' -``` - -
-Sample Response - -```json -{ - "token": "string", - "email": "portal-customer@email.com" -} -``` - -
- ---- - -### `ssoLoginV3` - -Initiate login using external SSO identity. - -`POST /v3/portal/public/sso/login` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `portal_id` | query | string | Yes | ID of the Portal | -| `org_id` | query | string | Yes | epilot organization id | -| `contact_id` | query | string (uuid) | No | contact id in the epilot system | - -**Request Body** - -**Sample Call** - -```bash -epilot customer-portal ssoLoginV3 \ - -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c \ - -p org_id=123 \ - -d '{"provider_slug":"office-365-login"}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal ssoLoginV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c -p org_id=123 -``` - -With JSONata filter: - -```bash -epilot customer-portal ssoLoginV3 -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c -p org_id=123 --jsonata 'email' -``` - -
-Sample Response - -```json -{ - "token": "string", - "email": "portal-customer@email.com" -} -``` - -
- ---- - -### `ssoRedirect` - -Handles the redirect from the external SSO provider. Validates the authorization `code` and `state` received from the pr - -`POST /v2/portal/public/sso/redirect` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `web_uri` | query | string | Yes | The URI to redirect to after the SSO login | - -**Sample Call** - -```bash -epilot customer-portal ssoRedirect \ - -p web_uri=https://customer-portal.com -``` - -With JSONata filter: - -```bash -epilot customer-portal ssoRedirect -p web_uri=https://customer-portal.com --jsonata '$' -``` - ---- - -### `ssoCallback` - -Handles the callback from the external SSO provider, validates the authorization `code` - -`POST /v2/portal/public/sso/callback` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `domain` | query | string | No | | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot customer-portal ssoCallback -``` - -With request body: - -```bash -epilot customer-portal ssoCallback \ - -d '{ - "provider_slug": "office-365-login", - "token_endpoint": "https://www.facebook.com/v12.0/dialog/oauth", - "grant_type": "authorization_code", - "code": "123456", - "redirect_uri": "https://customer-portal.com/login", - "client_id": "123456", - "code_verifier": "123456" -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal ssoCallback -``` - -With JSONata filter: - -```bash -epilot customer-portal ssoCallback --jsonata 'access_token' -``` - -
-Sample Response - -```json -{ - "access_token": "123456", - "token_type": "Bearer", - "expires_in": 3600, - "refresh_token": "123456", - "id_token": "123456", - "scope": "openid email" -} -``` - -
- ---- - -### `getPortalPage` - -Fetch a portal page by id - -`GET /v2/portal/pages/{id}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `id` | path | string (uuid) | Yes | | - -**Sample Call** - -```bash -epilot customer-portal getPortalPage \ - -p id=5da0a718-c822-403d-9f5d-20d4584e0528 -``` - -Using positional args for path parameters: - -```bash -epilot customer-portal getPortalPage 5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal getPortalPage 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: @@ -7541,7 +8723,16 @@ epilot customer-portal getPortalPage -p id=5da0a718-c822-403d-9f5d-20d4584e0528 "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -7549,12 +8740,15 @@ epilot customer-portal getPortalPage -p id=5da0a718-c822-403d-9f5d-20d4584e0528 "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ``` @@ -7592,7 +8786,16 @@ epilot customer-portal updatePortalPage \ "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -7600,6 +8803,7 @@ epilot customer-portal updatePortalPage \ "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, @@ -7633,7 +8837,16 @@ epilot customer-portal updatePortalPage -p id=5da0a718-c822-403d-9f5d-20d4584e05 "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -7641,12 +8854,15 @@ epilot customer-portal updatePortalPage -p id=5da0a718-c822-403d-9f5d-20d4584e05 "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ``` @@ -7725,7 +8941,16 @@ epilot customer-portal getPortalPages -p domain=customer-portal.epilot.io --json "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -7733,12 +8958,15 @@ epilot customer-portal getPortalPages -p domain=customer-portal.epilot.io --json "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ] ``` @@ -7777,7 +9005,16 @@ epilot customer-portal createPortalPage \ "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -7785,6 +9022,7 @@ epilot customer-portal createPortalPage \ "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, @@ -7812,7 +9050,16 @@ epilot customer-portal createPortalPage -p domain=customer-portal.epilot.io --js "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -7820,12 +9067,15 @@ epilot customer-portal createPortalPage -p domain=customer-portal.epilot.io --js "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ``` @@ -7869,7 +9119,16 @@ epilot customer-portal getPublicPages -p domain=customer-portal.epilot.io --json "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -7877,12 +9136,15 @@ epilot customer-portal getPublicPages -p domain=customer-portal.epilot.io --json "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ] ``` @@ -7891,16 +9153,185 @@ epilot customer-portal getPublicPages -p domain=customer-portal.epilot.io --json --- -### `getDefaultPages` +### `interpolatePortalPages` -Fetch all default portal pages +Interpolate template variables in portal pages without reading from the database. Accepts pages in the request body and -`GET /v2/portal/pages/default` +`POST /v2/portal/pages/interpolate` + +**Request Body** (required) **Sample Call** ```bash -epilot customer-portal getDefaultPages +epilot customer-portal interpolatePortalPages +``` + +With request body: + +```bash +epilot customer-portal interpolatePortalPages \ + -d '{ + "pages": [ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] + } + ], + "context_entities": [ + { + "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "entity_schema": "contract" + } + ], + "evaluate_targeting": true +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal interpolatePortalPages +``` + +With JSONata filter: + +```bash +epilot customer-portal interpolatePortalPages --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] + } +] +``` + +
+ +--- + +### `getTriggeredJourney` + +Returns the auto-triggered journey configured for the given trigger + +`GET /v2/portal/config/triggered-journeys/{trigger_name}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `trigger_name` | path | "FIRST_LOGIN" \| "ACCEPT_ORDER" \| "DECLINE_ORDER" | Yes | The trigger event for the auto-triggered journey | +| `context_entities` | query | object[] | No | Additional entities to include in the resolution context (e.g. the order being accepted at trigger time). Portal User and Contact entities are automatically part of the context. | + +**Sample Call** + +```bash +epilot customer-portal getTriggeredJourney \ + -p trigger_name=example +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal getTriggeredJourney example +``` + +With JSONata filter: + +```bash +epilot customer-portal getTriggeredJourney -p trigger_name=example --jsonata 'trigger_name' +``` + +
+Sample Response + +```json +{ + "trigger_name": "FIRST_LOGIN", + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [ + { + "key": "string", + "value": "string" + } + ] +} +``` + +
+ +--- + +### `getDefaultPages` + +Fetch all default portal pages + +`GET /v2/portal/pages/default` + +**Sample Call** + +```bash +epilot customer-portal getDefaultPages ``` With JSONata filter: @@ -7918,7 +9349,16 @@ epilot customer-portal getDefaultPages --jsonata '$' "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -7926,12 +9366,15 @@ epilot customer-portal getDefaultPages --jsonata '$' "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ] ``` @@ -7978,7 +9421,18 @@ epilot customer-portal getPortalPageBlocks -p id=5da0a718-c822-403d-9f5d-20d4584 [ { "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, @@ -8022,7 +9476,18 @@ epilot customer-portal createPortalPageBlock \ -p id=5da0a718-c822-403d-9f5d-20d4584e0528 \ -d '{ "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, @@ -8056,7 +9521,18 @@ epilot customer-portal createPortalPageBlock -p id=5da0a718-c822-403d-9f5d-20d45 ```json { "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, @@ -8110,7 +9586,18 @@ epilot customer-portal getPortalPageBlock -p id=5da0a718-c822-403d-9f5d-20d4584e ```json { "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, @@ -8156,7 +9643,18 @@ epilot customer-portal updatePortalPageBlock \ -p block_id=5da0a718-c822-403d-9f5d-20d4584e0528 \ -d '{ "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, @@ -8190,7 +9688,18 @@ epilot customer-portal updatePortalPageBlock -p id=5da0a718-c822-403d-9f5d-20d45 ```json { "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, @@ -8283,87 +9792,1001 @@ epilot customer-portal getUserEntryPoint -p email=user@example.com -p domain=cus --- -### `updateCampaignPortalBlockStatus` +### `updateCampaignPortalBlockStatus` + +Updates the status of a campaign portal block for multiple recipients. + +`PUT /v2/portal/campaign/{campaign_id}/entity:status` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `campaign_id` | path | string | Yes | ID of the campaign | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal updateCampaignPortalBlockStatus \ + -p campaign_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"status":"seen","entity_refs":[{"entity_id":"5da0a718-c822-403d-9f5d-20d4584e0528","entity_schema":"string"}]}' +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal updateCampaignPortalBlockStatus 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal updateCampaignPortalBlockStatus -p campaign_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot customer-portal updateCampaignPortalBlockStatus -p campaign_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'success' +``` + +
+Sample Response + +```json +{ + "success": true, + "updated": 2, + "failed": 0, + "total": 2 +} +``` + +
+ +--- + +### `listPortalNotifications` + +Lists the 360 notifications addressed to the authenticated portal user, newest first. The organization and the portal us + +`GET /v2/portal/notifications` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `cursor` | query | string | No | Base64 encoded cursor returned by a previous call, used for pagination. | +| `limit` | query | number | No | The maximum number of notifications to return. | + +**Sample Call** + +```bash +epilot customer-portal listPortalNotifications +``` + +With JSONata filter: + +```bash +epilot customer-portal listPortalNotifications --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "cursor": "string", + "total_unread": 0, + "results": [ + { + "id": "1234567890", + "notification_id": 1234567890, + "type": "workflow_step_overdue", + "title": { + "en": "string", + "de": "string" + }, + "message": { + "en": "string", + "de": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "read": false, + "redirect_url": "string" + } + ] +} +``` + +
+ +--- + +### `getPortalNotificationsUnreadCount` + +Returns the number of unread notifications for the authenticated portal user. + +`GET /v2/portal/notifications/unread-count` + +**Sample Call** + +```bash +epilot customer-portal getPortalNotificationsUnreadCount +``` + +With JSONata filter: + +```bash +epilot customer-portal getPortalNotificationsUnreadCount --jsonata 'count' +``` + +
+Sample Response + +```json +{ + "count": 3 +} +``` + +
+ +--- + +### `markAllPortalNotificationsRead` + +Marks all notifications of the authenticated portal user as read. + +`PUT /v2/portal/notifications/read-all` + +**Sample Call** + +```bash +epilot customer-portal markAllPortalNotificationsRead +``` + +With JSONata filter: + +```bash +epilot customer-portal markAllPortalNotificationsRead --jsonata '$' +``` + +--- + +### `markPortalNotificationRead` + +Marks a single notification of the authenticated portal user as read. + +`PUT /v2/portal/notifications/{id}/read` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | number | Yes | Numeric id of the notification to mark as read. | + +**Sample Call** + +```bash +epilot customer-portal markPortalNotificationRead \ + -p id=1 +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal markPortalNotificationRead 1 +``` + +With JSONata filter: + +```bash +epilot customer-portal markPortalNotificationRead -p id=1 --jsonata '$' +``` + +--- + +### `updateNotificationsStatus` + +Updates the statuses of multiple notifications at once. + +`PUT /v2/portal/notifications/entity:status` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal updateNotificationsStatus \ + -d '{"notifications":[{"id":"string","status":"read"}]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal updateNotificationsStatus +``` + +With JSONata filter: + +```bash +epilot customer-portal updateNotificationsStatus --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "Notifications status updated successfully." +} +``` + +
+ +--- + +### `deRegisterMLoginUser` + +Deregisters a user from the M Login client + +`DELETE /v2/portal/public/m-login/deregister/{client_id}/{user_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | Client ID | +| `user_id` | path | string | Yes | User ID | + +**Sample Call** + +```bash +epilot customer-portal deRegisterMLoginUser \ + -p client_id=123e4567-e89b-12d3-a456-426614174000 \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal deRegisterMLoginUser 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot customer-portal deRegisterMLoginUser -p client_id=123e4567-e89b-12d3-a456-426614174000 -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `notifyMLoginInterestChange` + +Notifies the interest change of a user in the M Login client + +`POST /v2/portal/public/m-login/notify-interest-change/{client_id}/{user_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | Client ID | +| `user_id` | path | string | Yes | User ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal notifyMLoginInterestChange \ + -p client_id=123e4567-e89b-12d3-a456-426614174000 \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot customer-portal notifyMLoginInterestChange \ + -p client_id=123e4567-e89b-12d3-a456-426614174000 \ + -p user_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "resource_id": "string", + "user_id": "string", + "interest_tag": "string", + "action": "string", + "resource": { + "resource_id": "string", + "description": "string", + "contact": "string", + "kind": "string" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal notifyMLoginInterestChange 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal notifyMLoginInterestChange -p client_id=123e4567-e89b-12d3-a456-426614174000 -p user_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot customer-portal notifyMLoginInterestChange -p client_id=123e4567-e89b-12d3-a456-426614174000 -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `createPortalConfig` + +Creates a new portal configuration. + +`POST /v3/portal/config` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal createPortalConfig +``` + +With request body: + +```bash +epilot customer-portal createPortalConfig \ + -d '{ + "entity_actions": [ + { + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "slug": "contact", + "action_Label": {} + } + ], + "extensions": [ + { + "id": "string", + "status": "installed", + "options": {} + } + ], + "extension_hooks": {}, + "default_user_to_notify": { + "onPendingUser": [ + {} + ] + }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", + "is_epilot_domain": true, + "epilot_domain": "example-portal-1.ecp.epilot.io", + "domain_settings": { + "is_custom_domain_enabled": true, + "is_epilot_domain_enabled": true, + "is_redirection_enabled": true + }, + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], + "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", + "user_account_self_management": false, + "feature_settings": { + "start_page": true, + "billing": true, + "change_due_date": true, + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 + }, + "accessToken": "string", + "advanced_mfa": { + "enabled": true + }, + "auth_settings": { + "passwordless_login": { + "enabled": true + }, + "entry_point": "PASSWORD", + "preferred_sso_providers": ["office-365-login"], + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true + }, + "cognito_details": { + "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", + "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, + "password_policy": { + "minimum_length": 8, + "maximum_length": 256, + "require_lowercase": true, + "require_uppercase": true, + "require_numbers": true, + "require_symbols": true, + "password_history_size": 3 + } + }, + "config": "string", + "contact_identifiers": ["email", "last_name"], + "approval_state_attributes": { + "contact": ["name", "address"], + "contract": ["installment_amount"] + }, + "email_templates": { + "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", + "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", + "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", + "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" + }, + "images": { + "orderLeftTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg", + "orderRightTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg", + "welcomeBanner": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg" + }, + "entity_identifiers": { + "type": { + "isEnabled": true, + "attributes": ["contract_number"] + } + }, + "contract_identifiers": [ + { + "name": "email", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "contract_selector_config": { + "show_inactive": true, + "title_path": "string" + }, + "registration_identifiers": [ + { + "name": "last_name", + "schema": "contact" + }, + { + "name": "contract_number", + "schema": "contract" + } + ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], + "triggered_journeys": [ + { + "trigger_name": "FIRST_LOGIN", + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] + } + ], + "entity_edit_rules": [ + { + "slug": "contact", + "attribute": "first_name", + "rule_type": "cadence", + "cadence_period_type": "days", + "cadence_period": 1, + "changes_allowed": 1, + "grace_period": 1, + "allowed_increment": "10%", + "allowed_decrement": "10%", + "number_of_days_before_restriction": 10 + } + ], + "allowed_file_extensions": { + "document": ["pdf"], + "image": ["jpg"], + "spreadsheet": ["xls"], + "presentation": ["ppt"], + "audioVideo": ["mp4"], + "email": ["eml"], + "archive": ["zip"], + "cad": ["cad"], + "calendar": ["ics"], + "other": ["txt"] + }, + "prevent_search_engine_indexing": true, + "meter_reading_grace_period": 0, + "inactive_contract_cutoff_years": 0, + "is_dummy": true, + "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "origin": "string", + "global_blocks": {}, + "pages": [ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": {}, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal createPortalConfig +``` + +With JSONata filter: + +```bash +epilot customer-portal createPortalConfig --jsonata '$' +``` + +
+Sample Response + +```json +{ + "entity_actions": [ + { + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "slug": "contact", + "action_Label": {} + } + ], + "extensions": [ + { + "id": "string", + "status": "installed", + "options": {} + } + ], + "extension_hooks": {}, + "default_user_to_notify": { + "onPendingUser": [ + {} + ] + }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", + "is_epilot_domain": true, + "epilot_domain": "example-portal-1.ecp.epilot.io", + "domain_settings": { + "is_custom_domain_enabled": true, + "is_epilot_domain_enabled": true, + "is_redirection_enabled": true + }, + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], + "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", + "user_account_self_management": false, + "feature_settings": { + "start_page": true, + "billing": true, + "change_due_date": true, + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 + }, + "accessToken": "string", + "advanced_mfa": { + "enabled": true + }, + "auth_settings": { + "passwordless_login": { + "enabled": true + }, + "entry_point": "PASSWORD", + "preferred_sso_providers": ["office-365-login"], + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true + }, + "cognito_details": { + "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", + "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, + "password_policy": { + "minimum_length": 8, + "maximum_length": 256, + "require_lowercase": true, + "require_uppercase": true, + "require_numbers": true, + "require_symbols": true, + "password_history_size": 3 + } + }, + "config": "string", + "contact_identifiers": ["email", "last_name"], + "approval_state_attributes": { + "contact": ["name", "address"], + "contract": ["installment_amount"] + }, + "email_templates": { + "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", + "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", + "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", + "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" + }, + "images": { + "orderLeftTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg", + "orderRightTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg", + "welcomeBanner": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg" + }, + "entity_identifiers": { + "type": { + "isEnabled": true, + "attributes": ["contract_number"] + } + }, + "contract_identifiers": [ + { + "name": "email", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "contract_selector_config": { + "show_inactive": true, + "title_path": "string" + }, + "registration_identifiers": [ + { + "name": "last_name", + "schema": "contact" + }, + { + "name": "contract_number", + "schema": "contract" + } + ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], + "triggered_journeys": [ + { + "trigger_name": "FIRST_LOGIN", + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] + } + ], + "entity_edit_rules": [ + { + "slug": "contact", + "attribute": "first_name", + "rule_type": "cadence", + "cadence_period_type": "days", + "cadence_period": 1, + "changes_allowed": 1, + "grace_period": 1, + "allowed_increment": "10%", + "allowed_decrement": "10%", + "number_of_days_before_restriction": 10 + } + ], + "allowed_file_extensions": { + "document": ["pdf"], + "image": ["jpg"], + "spreadsheet": ["xls"], + "presentation": ["ppt"], + "audioVideo": ["mp4"], + "email": ["eml"], + "archive": ["zip"], + "cad": ["cad"], + "calendar": ["ics"], + "other": ["txt"] + }, + "prevent_search_engine_indexing": true, + "meter_reading_grace_period": 0, + "inactive_contract_cutoff_years": 0, + "is_dummy": true, + "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "origin": "string", + "global_blocks": {}, + "organization_id": 12345, + "org_settings": { + "canary": { + "enabled": true + }, + "notracking": { + "enabled": true + } + }, + "feature_flags": {}, + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "effect": "allow" + } + ], + "pages": [ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": {}, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] + } + ] +} +``` + +
+ +--- + +### `getPortalConfigV3` -Updates the status of a campaign portal block for multiple recipients. +Retrieves a specific portal configuration by ID. -`PUT /v2/portal/campaign/{campaign_id}/entity:status` +`GET /v3/portal/config/{portal_id}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `campaign_id` | path | string | Yes | ID of the campaign | - -**Request Body** (required) +| `portal_id` | path | string (uuid) | Yes | Portal ID (readonly UUID generated on portal creation) | **Sample Call** ```bash -epilot customer-portal updateCampaignPortalBlockStatus \ - -p campaign_id=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"status":"seen","entity_refs":[{"entity_id":"5da0a718-c822-403d-9f5d-20d4584e0528","entity_schema":"string"}]}' +epilot customer-portal getPortalConfigV3 \ + -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` Using positional args for path parameters: ```bash -epilot customer-portal updateCampaignPortalBlockStatus 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal updateCampaignPortalBlockStatus -p campaign_id=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot customer-portal updateCampaignPortalBlockStatus -p campaign_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'success' -``` - -
-Sample Response - -```json -{ - "success": true, - "updated": 2, - "failed": 0, - "total": 2 -} -``` - -
- ---- - -### `updateNotificationsStatus` - -Updates the statuses of multiple notifications at once. - -`PUT /v2/portal/notifications/entity:status` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot customer-portal updateNotificationsStatus \ - -d '{"notifications":[{"id":"string","status":"read"}]}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal updateNotificationsStatus +epilot customer-portal getPortalConfigV3 5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal updateNotificationsStatus --jsonata 'message' +epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' ```
@@ -8371,131 +10794,6 @@ epilot customer-portal updateNotificationsStatus --jsonata 'message' ```json { - "message": "Notifications status updated successfully." -} -``` - -
- ---- - -### `deRegisterMLoginUser` - -Deregisters a user from the M Login client - -`DELETE /v2/portal/public/m-login/deregister/{client_id}/{user_id}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `client_id` | path | string | Yes | Client ID | -| `user_id` | path | string | Yes | User ID | - -**Sample Call** - -```bash -epilot customer-portal deRegisterMLoginUser \ - -p client_id=123e4567-e89b-12d3-a456-426614174000 \ - -p user_id=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot customer-portal deRegisterMLoginUser 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot customer-portal deRegisterMLoginUser -p client_id=123e4567-e89b-12d3-a456-426614174000 -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - ---- - -### `notifyMLoginInterestChange` - -Notifies the interest change of a user in the M Login client - -`POST /v2/portal/public/m-login/notify-interest-change/{client_id}/{user_id}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `client_id` | path | string | Yes | Client ID | -| `user_id` | path | string | Yes | User ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot customer-portal notifyMLoginInterestChange \ - -p client_id=123e4567-e89b-12d3-a456-426614174000 \ - -p user_id=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot customer-portal notifyMLoginInterestChange \ - -p client_id=123e4567-e89b-12d3-a456-426614174000 \ - -p user_id=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "resource_id": "string", - "user_id": "string", - "interest_tag": "string", - "action": "string", - "resource": { - "resource_id": "string", - "description": "string", - "contact": "string", - "kind": "string" - } -}' -``` - -Using positional args for path parameters: - -```bash -epilot customer-portal notifyMLoginInterestChange 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal notifyMLoginInterestChange -p client_id=123e4567-e89b-12d3-a456-426614174000 -p user_id=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot customer-portal notifyMLoginInterestChange -p client_id=123e4567-e89b-12d3-a456-426614174000 -p user_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - ---- - -### `createPortalConfig` - -Creates a new portal configuration. - -`POST /v3/portal/config` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot customer-portal createPortalConfig -``` - -With request body: - -```bash -epilot customer-portal createPortalConfig \ - -d '{ "entity_actions": [ { "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -8516,6 +10814,55 @@ epilot customer-portal createPortalConfig \ {} ] }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -8527,13 +10874,19 @@ epilot customer-portal createPortalConfig \ "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -8545,19 +10898,31 @@ epilot customer-portal createPortalConfig \ }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -8618,10 +10983,41 @@ epilot customer-portal createPortalConfig \ "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -8655,9 +11051,28 @@ epilot customer-portal createPortalConfig \ "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", + "global_blocks": {}, + "organization_id": 12345, + "org_settings": { + "canary": { + "enabled": true + }, + "notracking": { + "enabled": true + } + }, + "feature_flags": {}, + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "effect": "allow" + } + ], "pages": [ { "slug": "dashboard", @@ -8671,32 +11086,54 @@ epilot customer-portal createPortalConfig \ "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, - "is_deleted": false + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ] -}' +} ``` -Using stdin pipe: +
-```bash -cat body.json | epilot customer-portal createPortalConfig -``` +--- -With JSONata filter: +### `putPortalConfig` + +Updates a specific portal configuration by ID. + +`PUT /v3/portal/config/{portal_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | path | string (uuid) | Yes | Portal ID (readonly UUID generated on portal creation) | +| `page_upsert_mode` | query | "id" \| "slug" | No | Determines how pages are matched for upsert operations: +- `id` (default): Match pages by their ID. Use this when page IDs are stable and known upfront. +- `slug`: Match pages by their slug. When a requ | + +**Request Body** (required) + +**Sample Call** ```bash -epilot customer-portal createPortalConfig --jsonata '$' +epilot customer-portal putPortalConfig \ + -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` -
-Sample Response +With request body: -```json -{ +```bash +epilot customer-portal putPortalConfig \ + -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 \ + -d '{ "entity_actions": [ { "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -8717,6 +11154,55 @@ epilot customer-portal createPortalConfig --jsonata '$' {} ] }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -8728,13 +11214,19 @@ epilot customer-portal createPortalConfig --jsonata '$' "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -8746,19 +11238,31 @@ epilot customer-portal createPortalConfig --jsonata '$' }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -8819,10 +11323,41 @@ epilot customer-portal createPortalConfig --jsonata '$' "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -8856,9 +11391,11 @@ epilot customer-portal createPortalConfig --jsonata '$' "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", + "global_blocks": {}, "organization_id": 12345, "org_settings": { "canary": { @@ -8876,14 +11413,6 @@ epilot customer-portal createPortalConfig --jsonata '$' "effect": "allow" } ], - "identity_providers": [ - { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} - } - ], "pages": [ { "slug": "dashboard", @@ -8897,50 +11426,36 @@ epilot customer-portal createPortalConfig --jsonata '$' "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ] -} +}' ``` -
- ---- - -### `getPortalConfigV3` - -Retrieves a specific portal configuration by ID. - -`GET /v3/portal/config/{portal_id}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `portal_id` | path | string (uuid) | Yes | Portal ID (readonly UUID generated on portal creation) | - -**Sample Call** +Using positional args for path parameters: ```bash -epilot customer-portal getPortalConfigV3 \ - -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 +epilot customer-portal putPortalConfig 5da0a718-c822-403d-9f5d-20d4584e0528 ``` -Using positional args for path parameters: +Using stdin pipe: ```bash -epilot customer-portal getPortalConfigV3 5da0a718-c822-403d-9f5d-20d4584e0528 +cat body.json | epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` With JSONata filter: ```bash -epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' +epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' ```
@@ -8968,6 +11483,55 @@ epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20 {} ] }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -8979,13 +11543,19 @@ epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20 "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -8997,19 +11567,31 @@ epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20 }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -9070,10 +11652,41 @@ epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20 "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -9107,9 +11720,11 @@ epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20 "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", + "global_blocks": {}, "organization_id": 12345, "org_settings": { "canary": { @@ -9127,14 +11742,6 @@ epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20 "effect": "allow" } ], - "identity_providers": [ - { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} - } - ], "pages": [ { "slug": "dashboard", @@ -9148,12 +11755,15 @@ epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20 "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"] } ] } @@ -9163,11 +11773,103 @@ epilot customer-portal getPortalConfigV3 -p portal_id=5da0a718-c822-403d-9f5d-20 --- -### `putPortalConfig` +### `deletePortalConfig` -Updates a specific portal configuration by ID. +Deletes a specific portal configuration by ID. -`PUT /v3/portal/config/{portal_id}` +`DELETE /v3/portal/config/{portal_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | path | string (uuid) | Yes | Portal ID (readonly UUID generated on portal creation) | + +**Sample Call** + +```bash +epilot customer-portal deletePortalConfig \ + -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal deletePortalConfig 5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +With JSONata filter: + +```bash +epilot customer-portal deletePortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' +``` + +--- + +### `listPortalRevisions` + +Lists a portal's revision history, newest first. Metadata only — no config blob, no page bodies. `is_published` says whe + +`GET /v3/portal/config/{portal_id}/revisions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | path | string (uuid) | Yes | Portal ID (readonly UUID generated on portal creation) | +| `limit` | query | number | No | Maximum number of revisions to return | +| `cursor` | query | string | No | Opaque pagination cursor, taken from a previous response's `next_cursor` | + +**Sample Call** + +```bash +epilot customer-portal listPortalRevisions \ + -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal listPortalRevisions 5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +With JSONata filter: + +```bash +epilot customer-portal listPortalRevisions -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "FAQ page launch", + "description": "string", + "page_count": 0, + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "is_published": true + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createPortalRevision` + +Creates a new revision — a complete, immutable snapshot of the portal's configuration, pages and email templates. Nothin + +`POST /v3/portal/config/{portal_id}/revisions` **Parameters** @@ -9180,14 +11882,14 @@ Updates a specific portal configuration by ID. **Sample Call** ```bash -epilot customer-portal putPortalConfig \ +epilot customer-portal createPortalRevision \ -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 ``` With request body: ```bash -epilot customer-portal putPortalConfig \ +epilot customer-portal createPortalRevision \ -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 \ -d '{ "entity_actions": [ @@ -9210,6 +11912,55 @@ epilot customer-portal putPortalConfig \ {} ] }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -9221,13 +11972,19 @@ epilot customer-portal putPortalConfig \ "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -9239,19 +11996,31 @@ epilot customer-portal putPortalConfig \ }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -9312,10 +12081,41 @@ epilot customer-portal putPortalConfig \ "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -9349,34 +12149,122 @@ epilot customer-portal putPortalConfig \ "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", - "organization_id": 12345, - "org_settings": { - "canary": { - "enabled": true - }, - "notracking": { - "enabled": true - } - }, - "feature_flags": {}, - "grants": [ + "global_blocks": {}, + "based_on_revision_id": "string", + "pages": [ { - "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", - "effect": "allow" + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "slug": "dashboard", + "order": 0, + "blocks": {} } - ], + ] +}' +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal createPortalRevision 5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal createPortalRevision -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +With JSONata filter: + +```bash +epilot customer-portal createPortalRevision -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "FAQ page launch", + "description": "string", + "page_count": 0, + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "is_published": true, "identity_providers": [ { "slug": "office-365-login", "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, "oidc_config": {}, - "mobile_oidc_config": {} + "mobile_oidc_config": {}, + "expose_client_secret": false } - ], + ] +} +``` + +
+ +--- + +### `getPortalRevision` + +Returns the full content of one revision: the snapshotted config, its pages (in the live `Page` shape), email templates + +`GET /v3/portal/config/{portal_id}/revisions/{revision_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | path | string (uuid) | Yes | Portal ID (readonly UUID generated on portal creation) | +| `revision_id` | path | string | Yes | Revision ID. Contains `:` characters — percent-encode it. | + +**Sample Call** + +```bash +epilot customer-portal getPortalRevision \ + -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 \ + -p revision_id=2026-08-25T14:03:11.482Z-a7f3c1d9 +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal getPortalRevision 5da0a718-c822-403d-9f5d-20d4584e0528 2026-08-25T14:03:11.482Z-a7f3c1d9 +``` + +With JSONata filter: + +```bash +epilot customer-portal getPortalRevision -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 -p revision_id=2026-08-25T14:03:11.482Z-a7f3c1d9 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "FAQ page launch", + "description": "string", + "page_count": 0, + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "is_published": true, + "config": {}, "pages": [ { "slug": "dashboard", @@ -9390,33 +12278,275 @@ epilot customer-portal putPortalConfig \ "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "org_id": "string" + } + ], + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "email_templates": { + "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", + "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", + "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", + "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" + }, + "email_template_settings": {} +} +``` + +
+ +--- + +### `publishPortalRevision` + +Makes one revision the portal's live configuration, atomically: either everything below takes effect or nothing does. Pu + +`POST /v3/portal/config/{portal_id}/publish` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | path | string (uuid) | Yes | Portal ID (readonly UUID generated on portal creation) | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal publishPortalRevision \ + -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 \ + -d '{"revision_id":"2026-08-25T14:03:11.482Z-a7f3c1d9","name":"FAQ page launch","description":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot customer-portal publishPortalRevision 5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal publishPortalRevision -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 +``` + +With JSONata filter: + +```bash +epilot customer-portal publishPortalRevision -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata 'revision_id' +``` + +
+Sample Response + +```json +{ + "revision_id": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "name": "FAQ page launch", + "post_publish_warnings": ["allowed_entities_change"] +} +``` + +
+ +--- + +### `listAllPortalConfigs` + +Retrieves all portal configurations. + +`GET /v3/portal/configs` + +**Sample Call** + +```bash +epilot customer-portal listAllPortalConfigs +``` + +With JSONata filter: + +```bash +epilot customer-portal listAllPortalConfigs --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": [ + { + "entity_actions": [], + "extensions": [], + "extension_hooks": {}, + "default_user_to_notify": {}, + "identity_providers": [], + "mobile_config": {}, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", + "is_epilot_domain": true, + "epilot_domain": "example-portal-1.ecp.epilot.io", + "domain_settings": {}, + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], + "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", + "user_account_self_management": false, + "feature_settings": {}, + "accessToken": "string", + "advanced_mfa": {}, + "auth_settings": {}, + "cognito_details": {}, + "config": "string", + "contact_identifiers": ["email", "last_name"], + "approval_state_attributes": {}, + "email_templates": {}, + "images": {}, + "entity_identifiers": {}, + "contract_identifiers": [], + "contract_selector_config": {}, + "registration_identifiers": [], + "surfaces": [], + "contact_identifiers_for_account": [], + "additional_contact_attributes": [], + "triggered_journeys": [], + "entity_edit_rules": [], + "allowed_file_extensions": {}, + "prevent_search_engine_indexing": true, + "meter_reading_grace_period": 0, + "inactive_contract_cutoff_years": 0, + "is_dummy": true, + "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "origin": "string", + "global_blocks": {}, + "organization_id": 12345, + "org_settings": {}, + "feature_flags": {}, + "grants": [], + "pages": [] } ] +} +``` + +
+ +--- + +### `swapPortalConfig` + +Swaps the portal configuration of two portals. + +`POST /v3/portal/config/swap` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal swapPortalConfig +``` + +With request body: + +```bash +epilot customer-portal swapPortalConfig \ + -d '{ + "source_portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "target_portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "items_to_swap": ["email_templates"] }' ``` -Using positional args for path parameters: +Using stdin pipe: ```bash -epilot customer-portal putPortalConfig 5da0a718-c822-403d-9f5d-20d4584e0528 +cat body.json | epilot customer-portal swapPortalConfig +``` + +With JSONata filter: + +```bash +epilot customer-portal swapPortalConfig --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "Domain and users swapped successfully." +} +``` + +
+ +--- + +### `clonePortalConfig` + +Creates a new portal by cloning configuration and pages from an existing portal. The new portal gets its own domain, use + +`POST /v3/portal/config/clone` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal clonePortalConfig \ + -d '{"source_portal_id":"453ad7bf-86d5-46c8-8252-bcc868df5e3c","name":"string"}' ``` Using stdin pipe: ```bash -cat body.json | epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 +cat body.json | epilot customer-portal clonePortalConfig ``` With JSONata filter: ```bash -epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' +epilot customer-portal clonePortalConfig --jsonata '$' ```
@@ -9444,6 +12574,55 @@ epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4 {} ] }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -9455,13 +12634,19 @@ epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4 "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0 }, "accessToken": "string", "advanced_mfa": { @@ -9473,19 +12658,31 @@ epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4 }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -9546,10 +12743,41 @@ epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4 "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -9573,174 +12801,60 @@ epilot customer-portal putPortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4 "presentation": ["ppt"], "audioVideo": ["mp4"], "email": ["eml"], - "archive": ["zip"], - "cad": ["cad"], - "calendar": ["ics"], - "other": ["txt"] - }, - "prevent_search_engine_indexing": true, - "meter_reading_grace_period": 0, - "inactive_contract_cutoff_years": 0, - "is_dummy": true, - "is_v3_item": true, - "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "organization_id": 12345, - "org_settings": { - "canary": { - "enabled": true - }, - "notracking": { - "enabled": true - } - }, - "feature_flags": {}, - "grants": [ - { - "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", - "effect": "allow" - } - ], - "identity_providers": [ - { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} - } - ], - "pages": [ - { - "slug": "dashboard", - "path": "/dashboard", - "schema": ["string"], - "visibility": {}, - "content": {}, - "design": {}, - "blocks": {}, - "order": 1, - "is_system": false, - "is_detail": false, - "detail_schema": "contact", - "is_public": true, - "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", - "is_entry_route": false, - "is_deleted": false, - "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" - } - ] -} -``` - -
- ---- - -### `deletePortalConfig` - -Deletes a specific portal configuration by ID. - -`DELETE /v3/portal/config/{portal_id}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `portal_id` | path | string (uuid) | Yes | Portal ID (readonly UUID generated on portal creation) | - -**Sample Call** - -```bash -epilot customer-portal deletePortalConfig \ - -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 -``` - -Using positional args for path parameters: - -```bash -epilot customer-portal deletePortalConfig 5da0a718-c822-403d-9f5d-20d4584e0528 -``` - -With JSONata filter: - -```bash -epilot customer-portal deletePortalConfig -p portal_id=5da0a718-c822-403d-9f5d-20d4584e0528 --jsonata '$' -``` - ---- - -### `listAllPortalConfigs` - -Retrieves all portal configurations. - -`GET /v3/portal/configs` - -**Sample Call** - -```bash -epilot customer-portal listAllPortalConfigs -``` - -With JSONata filter: - -```bash -epilot customer-portal listAllPortalConfigs --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": [ - { - "entity_actions": [], - "extensions": [], - "extension_hooks": {}, - "default_user_to_notify": {}, - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-1.ecp.epilot.io", - "domain_settings": {}, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", - "user_account_self_management": false, - "feature_settings": {}, - "accessToken": "string", - "advanced_mfa": {}, - "auth_settings": {}, - "cognito_details": {}, - "config": "string", - "contact_identifiers": ["email", "last_name"], - "approval_state_attributes": {}, - "email_templates": {}, - "images": {}, - "entity_identifiers": {}, - "contract_identifiers": [], - "contract_selector_config": {}, - "registration_identifiers": [], - "triggered_journeys": [], - "entity_edit_rules": [], - "allowed_file_extensions": {}, - "prevent_search_engine_indexing": true, - "meter_reading_grace_period": 0, - "inactive_contract_cutoff_years": 0, - "is_dummy": true, - "is_v3_item": true, + "archive": ["zip"], + "cad": ["cad"], + "calendar": ["ics"], + "other": ["txt"] + }, + "prevent_search_engine_indexing": true, + "meter_reading_grace_period": 0, + "inactive_contract_cutoff_years": 0, + "is_dummy": true, + "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "origin": "string", + "global_blocks": {}, + "organization_id": 12345, + "org_settings": { + "canary": { + "enabled": true + }, + "notracking": { + "enabled": true + } + }, + "feature_flags": {}, + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "effect": "allow" + } + ], + "pages": [ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": {}, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "organization_id": 12345, - "org_settings": {}, - "feature_flags": {}, - "grants": [], - "identity_providers": [], - "pages": [] + "past_routes": ["old-dashboard", "home"] } ] } @@ -9750,56 +12864,6 @@ epilot customer-portal listAllPortalConfigs --jsonata 'data' --- -### `swapPortalConfig` - -Swaps the portal configuration of two portals. - -`POST /v3/portal/config/swap` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot customer-portal swapPortalConfig -``` - -With request body: - -```bash -epilot customer-portal swapPortalConfig \ - -d '{ - "source_portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "target_portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "items_to_swap": ["all"] -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot customer-portal swapPortalConfig -``` - -With JSONata filter: - -```bash -epilot customer-portal swapPortalConfig --jsonata 'message' -``` - -
-Sample Response - -```json -{ - "message": "Domain and users swapped successfully." -} -``` - -
- ---- - ### `invitePartner` Invites a partner to a portal @@ -9812,7 +12876,7 @@ Invites a partner to a portal ```bash epilot customer-portal invitePartner \ - -d '{"email":"string","represents_contact_list":["5da0a718-c822-403d-9f5d-20d4584e0528"]}' + -d '{"email":"string","contact_data":{},"portal_user_data":{}}' ``` Using stdin pipe: @@ -10057,3 +13121,299 @@ epilot customer-portal enablePartner -p partner_id=123e4567-e89b-12d3-a456-42661
--- + +### `verifyDns` + +Manually triggers DNS verification for a portal's domain setup. Runs the same verification logic as the scheduled proces + +`POST /v3/portal/verify-dns` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | query | string | Yes | PortalId of the portal | + +**Sample Call** + +```bash +epilot customer-portal verifyDns \ + -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c +``` + +With JSONata filter: + +```bash +epilot customer-portal verifyDns -p portal_id=453ad7bf-86d5-46c8-8252-bcc868df5e3c --jsonata 'domain_status' +``` + +
+Sample Response + +```json +{ + "domain_status": "PENDING", + "message": "string" +} +``` + +
+ +--- + +### `portalProxyExecute` + +Execute an Integration Hub managed-call use case on behalf of a portal user. + +`POST /v2/portal/proxy/execute` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal portalProxyExecute \ + -d '{"integration_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","use_case_slug":"string","payload":{}}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal portalProxyExecute +``` + +With JSONata filter: + +```bash +epilot customer-portal portalProxyExecute --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "success": true, + "data": {} +} +``` + +
+ +--- + +### `getMobileConfig` + +Returns the portal's mobile app configuration. By default the response is build-ready (resolved): base info (display_nam + +`GET /v1/portal/mobile-config` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | query | string | Yes | Portal ID | +| `raw` | query | boolean | No | Return only the stored mobile_config without resolving base info/branding. | + +**Sample Call** + +```bash +epilot customer-portal getMobileConfig \ + -p portal_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot customer-portal getMobileConfig -p portal_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'portal_id' +``` + +
+Sample Response + +```json +{ + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": { + "version": "string", + "build_number": 0, + "track": "string", + "status": "building", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": { + "version": "string", + "build_number": 0, + "track": "string", + "status": "building", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } +} +``` + +
+ +--- + +### `putMobileConfig` + +Merges the provided fields into the portal's mobile app configuration + +`PUT /v1/portal/mobile-config` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `portal_id` | query | string | Yes | Portal ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot customer-portal putMobileConfig \ + -p portal_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot customer-portal putMobileConfig \ + -p portal_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "enabled": true, + "ios": { + "bundle_id": "string", + "team_id": "string", + "store_url": "string", + "app_store_id": "string" + }, + "android": { + "package_name": "string", + "store_url": "string" + }, + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot customer-portal putMobileConfig -p portal_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot customer-portal putMobileConfig -p portal_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'portal_id' +``` + +
+Sample Response + +```json +{ + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": { + "version": "string", + "build_number": 0, + "track": "string", + "status": "building", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": { + "version": "string", + "build_number": 0, + "track": "string", + "status": "building", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } +} +``` + +
+ +--- diff --git a/docs/cli/commands/dashboard.md b/docs/cli/commands/dashboard.md index 5ce637bf..8b8184b4 100644 --- a/docs/cli/commands/dashboard.md +++ b/docs/cli/commands/dashboard.md @@ -43,10 +43,23 @@ epilot dashboard listDashboards **Dashboards** - [`listDashboards`](#listdashboards) — List dashboards available to the user - [`createDashboard`](#createdashboard) — Create new dashboard +- [`listFavoriteDashboardIds`](#listfavoritedashboardids) — Returns the current user's favorited dashboard ids, with no dashboard metadata. Lets a +- [`favoriteDashboard`](#favoritedashboard) — Marks the dashboard as favorited by the current user. Idempotent — favoriting an +- [`unfavoriteDashboard`](#unfavoritedashboard) — Removes the current user's favorite for the dashboard. Idempotent — unfavoriting a - [`getDashboard`](#getdashboard) — Get dashboard by ID - [`putDashboard`](#putdashboard) — Update a dashboard by ID +- [`patchDashboard`](#patchdashboard) — Partially update a dashboard by ID. Update content (title/tiles) and/or manage sharing - [`deleteDashboard`](#deletedashboard) — Delete a dashboard by ID +**Insights** +- [`listInsights`](#listinsights) — List insights (saved charts) available to the user +- [`createInsight`](#createinsight) — Create a new insight (saved chart). The caller becomes the owner. +- [`listInsightTags`](#listinsighttags) — List the distinct tags used by insights in the organization (for filter facets) +- [`getInsight`](#getinsight) — Get insight by ID +- [`putInsight`](#putinsight) — Replace an insight's content by ID. Sharing is managed via patchInsight. +- [`patchInsight`](#patchinsight) — Partially update an insight by ID. Update content (name/description/visualisation/tags) and/or +- [`deleteInsight`](#deleteinsight) — Delete an insight by ID. Only owners may delete. + **Visualisations** - [`listAvailableVisualisations`](#listavailablevisualisations) — Returns list of available Visualisations to configure new dashboard tiles @@ -59,6 +72,31 @@ List dashboards available to the user `GET /v1/dashboard/dashboards` +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `q` | query | string | No | Free-text search over name/title and description (case-insensitive substring). | +| `created_by` | query | string | No | Filter by the id of the creating user. | +| `created_after` | query | string (date-time) | No | | +| `created_before` | query | string (date-time) | No | | +| `updated_after` | query | string (date-time) | No | | +| `updated_before` | query | string (date-time) | No | | +| `shared_with` | query | string[] | No | Filter to resources shared with any of the given user ids. | +| `owner` | query | string[] | No | Filter to resources owned by any of the given user ids. | +| `accessible_to` | query | string | No | Filter to resources the given user id may view (owner, shared, org-wide or legacy). | +| `favorite` | query | boolean | No | Dashboards only. Filter to only (`true`) or exclude (`false`) the requesting user's +favorited dashboards. A user with zero favorites and `favorite=true` gets an empty page, +not the unfiltered list. + | +| `favorites_first` | query | boolean | No | Dashboards only. No filtering — sorts the requesting user's favorited dashboards first, +preserving the existing secondary ordering (`sort`/`order`) otherwise. + | +| `sort` | query | "created_at" \| "updated_at" \| "name" \| "title" | No | Field to sort by. `name` and `title` are aliases for the resource's display name and are normalised per resource: dashboards sort by `title` and insights by `name`, whichever of the two values is sent | +| `order` | query | "asc" \| "desc" | No | Sort direction. Defaults to ascending (preserving the pre-migration order). | +| `limit` | query | number | No | Maximum results to return (max 200). Omit to return all matching results (pagination is opt-in). | +| `offset` | query | number | No | Number of results to skip, for pagination. Use with limit (page N = offset N*limit). | + **Sample Call** ```bash @@ -78,42 +116,37 @@ epilot dashboard listDashboards --jsonata 'results[0]' { "results": [ { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false } - ] + ], + "pagination": { + "total": 0, + "limit": 0, + "offset": 0, + "has_more": true + } } ``` @@ -140,40 +173,29 @@ With request body: ```bash epilot dashboard createDashboard \ -d '{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false }' ``` @@ -186,7 +208,7 @@ cat body.json | epilot dashboard createDashboard With JSONata filter: ```bash -epilot dashboard createDashboard --jsonata 'id' +epilot dashboard createDashboard --jsonata '$' ```
@@ -194,40 +216,61 @@ epilot dashboard createDashboard --jsonata 'id' ```json { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false +} +``` + +
+ +--- + +### `listFavoriteDashboardIds` + +Returns the current user's favorited dashboard ids, with no dashboard metadata. Lets a + +`GET /v1/dashboard/dashboards/favorites` + +**Sample Call** + +```bash +epilot dashboard listFavoriteDashboardIds +``` + +With JSONata filter: + +```bash +epilot dashboard listFavoriteDashboardIds --jsonata 'dashboard_ids' +``` + +
+Sample Response + +```json +{ + "dashboard_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"], + "total": 0 } ``` @@ -235,6 +278,72 @@ epilot dashboard createDashboard --jsonata 'id' --- +### `favoriteDashboard` + +Marks the dashboard as favorited by the current user. Idempotent — favoriting an + +`PUT /v1/dashboard/dashboards/{id}/favorite` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot dashboard favoriteDashboard \ + -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 +``` + +Using positional args for path parameters: + +```bash +epilot dashboard favoriteDashboard 3fa85f64-5717-4562-b3fc-2c963f66afa6 +``` + +With JSONata filter: + +```bash +epilot dashboard favoriteDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata '$' +``` + +--- + +### `unfavoriteDashboard` + +Removes the current user's favorite for the dashboard. Idempotent — unfavoriting a + +`DELETE /v1/dashboard/dashboards/{id}/favorite` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot dashboard unfavoriteDashboard \ + -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 +``` + +Using positional args for path parameters: + +```bash +epilot dashboard unfavoriteDashboard 3fa85f64-5717-4562-b3fc-2c963f66afa6 +``` + +With JSONata filter: + +```bash +epilot dashboard unfavoriteDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata '$' +``` + +--- + ### `getDashboard` Get dashboard by ID @@ -263,7 +372,7 @@ epilot dashboard getDashboard 3fa85f64-5717-4562-b3fc-2c963f66afa6 With JSONata filter: ```bash -epilot dashboard getDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata 'id' +epilot dashboard getDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata '$' ```
@@ -271,40 +380,29 @@ epilot dashboard getDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsona ```json { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false } ``` @@ -339,40 +437,29 @@ With request body: epilot dashboard putDashboard \ -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 \ -d '{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false }' ``` @@ -391,7 +478,7 @@ cat body.json | epilot dashboard putDashboard -p id=3fa85f64-5717-4562-b3fc-2c96 With JSONata filter: ```bash -epilot dashboard putDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata 'id' +epilot dashboard putDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata '$' ```
@@ -399,40 +486,29 @@ epilot dashboard putDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsona ```json { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false } ``` @@ -440,11 +516,11 @@ epilot dashboard putDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsona --- -### `deleteDashboard` +### `patchDashboard` -Delete a dashboard by ID +Partially update a dashboard by ID. Update content (title/tiles) and/or manage sharing -`DELETE /v1/dashboard/dashboards/{id}` +`PATCH /v1/dashboard/dashboards/{id}` **Parameters** @@ -452,64 +528,844 @@ Delete a dashboard by ID | ---- | -- | ---- | -------- | ----------- | | `id` | path | string (uuid) | Yes | | +**Request Body** + **Sample Call** ```bash -epilot dashboard deleteDashboard \ +epilot dashboard patchDashboard \ -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 ``` -Using positional args for path parameters: - -```bash -epilot dashboard deleteDashboard 3fa85f64-5717-4562-b3fc-2c963f66afa6 -``` - -With JSONata filter: +With request body: ```bash -epilot dashboard deleteDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata 'id' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", +epilot dashboard patchDashboard \ + -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 \ + -d '{ + "owners": ["string"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", + "title": "Number of opportunities created by journeys every month", + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "visualisation_id": "timechart", "visualisation_config": { "query": { "dataset": "entity_operations", "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, + "dimensions": [ { - "entity_schema": ["opportunity"] + "time_with_granularity": "year-month" } ], - "dimensions": [ - { - "time_with_granularity": "month" - }, + "filters": [ { - "entity_attribute": "source.title" + "entity_schema": "opportunity" } ] }, "options": { - "type": "line" + "type": "bar" } } } ] +}' +``` + +Using positional args for path parameters: + +```bash +epilot dashboard patchDashboard 3fa85f64-5717-4562-b3fc-2c963f66afa6 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot dashboard patchDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 +``` + +With JSONata filter: + +```bash +epilot dashboard patchDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "Employee Dashboard", + "tiles": [ + { + "id": "e4af1297-1fd6-440f-9846-f475f580d40f", + "coordinates": {}, + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" + } + ], + "favorited": false +} +``` + +
+ +--- + +### `deleteDashboard` + +Delete a dashboard by ID + +`DELETE /v1/dashboard/dashboards/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot dashboard deleteDashboard \ + -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 +``` + +Using positional args for path parameters: + +```bash +epilot dashboard deleteDashboard 3fa85f64-5717-4562-b3fc-2c963f66afa6 +``` + +With JSONata filter: + +```bash +epilot dashboard deleteDashboard -p id=3fa85f64-5717-4562-b3fc-2c963f66afa6 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "Employee Dashboard", + "tiles": [ + { + "id": "e4af1297-1fd6-440f-9846-f475f580d40f", + "coordinates": {}, + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" + } + ], + "favorited": false +} +``` + +
+ +--- + +### `listInsights` + +List insights (saved charts) available to the user + +`GET /v1/dashboard/insights` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `q` | query | string | No | Free-text search over name/title and description (case-insensitive substring). | +| `visualisation_id` | query | "kpi" \| "funnel" \| "toplist" \| "timechart" \| "pie" \| "bar" \| "entity_list" \| "markdown" \| "news_feed" \| "workflow"[] | No | Filter insights by one or more visualisation ids. | +| `tags` | query | string[] | No | Filter by one or more tags (see tags_match for any/all semantics). | +| `tags_match` | query | "any" \| "all" | No | Whether a result must match any (default) or all of the given tags. | +| `created_by` | query | string | No | Filter by the id of the creating user. | +| `created_after` | query | string (date-time) | No | | +| `created_before` | query | string (date-time) | No | | +| `updated_after` | query | string (date-time) | No | | +| `updated_before` | query | string (date-time) | No | | +| `shared_with` | query | string[] | No | Filter to resources shared with any of the given user ids. | +| `owner` | query | string[] | No | Filter to resources owned by any of the given user ids. | +| `accessible_to` | query | string | No | Filter to resources the given user id may view (owner, shared, org-wide or legacy). | +| `sort` | query | "created_at" \| "updated_at" \| "name" \| "title" | No | Field to sort by. `name` and `title` are aliases for the resource's display name and are normalised per resource: dashboards sort by `title` and insights by `name`, whichever of the two values is sent | +| `order` | query | "asc" \| "desc" | No | Sort direction. Defaults to ascending (preserving the pre-migration order). | +| `limit` | query | number | No | Maximum results to return (max 200). Omit to return all matching results (pagination is opt-in). | +| `offset` | query | number | No | Number of results to skip, for pagination. Use with limit (page N = offset N*limit). | + +**Sample Call** + +```bash +epilot dashboard listInsights +``` + +With JSONata filter: + +```bash +epilot dashboard listInsights --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] + } + ], + "pagination": { + "total": 0, + "limit": 0, + "offset": 0, + "has_more": true + } +} +``` + +
+ +--- + +### `createInsight` + +Create a new insight (saved chart). The caller becomes the owner. + +`POST /v1/dashboard/insights` + +**Request Body** + +**Sample Call** + +```bash +epilot dashboard createInsight +``` + +With request body: + +```bash +epilot dashboard createInsight \ + -d '{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot dashboard createInsight +``` + +With JSONata filter: + +```bash +epilot dashboard createInsight --jsonata '$' +``` + +
+Sample Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +} +``` + +
+ +--- + +### `listInsightTags` + +List the distinct tags used by insights in the organization (for filter facets) + +`GET /v1/dashboard/insights/tags` + +**Sample Call** + +```bash +epilot dashboard listInsightTags +``` + +With JSONata filter: + +```bash +epilot dashboard listInsightTags --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": ["string"] +} +``` + +
+ +--- + +### `getInsight` + +Get insight by ID + +`GET /v1/dashboard/insights/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot dashboard getInsight \ + -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +Using positional args for path parameters: + +```bash +epilot dashboard getInsight 8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +With JSONata filter: + +```bash +epilot dashboard getInsight -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e --jsonata '$' +``` + +
+Sample Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +} +``` + +
+ +--- + +### `putInsight` + +Replace an insight's content by ID. Sharing is managed via patchInsight. + +`PUT /v1/dashboard/insights/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot dashboard putInsight \ + -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +With request body: + +```bash +epilot dashboard putInsight \ + -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e \ + -d '{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +}' +``` + +Using positional args for path parameters: + +```bash +epilot dashboard putInsight 8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +Using stdin pipe: + +```bash +cat body.json | epilot dashboard putInsight -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +With JSONata filter: + +```bash +epilot dashboard putInsight -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e --jsonata '$' +``` + +
+Sample Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +} +``` + +
+ +--- + +### `patchInsight` + +Partially update an insight by ID. Update content (name/description/visualisation/tags) and/or + +`PATCH /v1/dashboard/insights/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot dashboard patchInsight \ + -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +With request body: + +```bash +epilot dashboard patchInsight \ + -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e \ + -d '{ + "owners": ["string"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "name": "string", + "description": "string", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +}' +``` + +Using positional args for path parameters: + +```bash +epilot dashboard patchInsight 8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +Using stdin pipe: + +```bash +cat body.json | epilot dashboard patchInsight -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +With JSONata filter: + +```bash +epilot dashboard patchInsight -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e --jsonata '$' +``` + +
+Sample Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +} +``` + +
+ +--- + +### `deleteInsight` + +Delete an insight by ID. Only owners may delete. + +`DELETE /v1/dashboard/insights/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot dashboard deleteInsight \ + -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +Using positional args for path parameters: + +```bash +epilot dashboard deleteInsight 8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e +``` + +With JSONata filter: + +```bash +epilot dashboard deleteInsight -p id=8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e --jsonata '$' +``` + +
+Sample Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] } ``` diff --git a/docs/cli/commands/data-governance.md b/docs/cli/commands/data-governance.md index fd628c21..a32d062e 100644 --- a/docs/cli/commands/data-governance.md +++ b/docs/cli/commands/data-governance.md @@ -8,6 +8,11 @@ description: "epilot CLI commands for the Data Governance API: quick start, comm - **Base URL:** `https://data-governance.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/data-governance](https://docs.epilot.io/api/data-governance) +The **Data Governance API** provides a set of endpoints for managing the lifecycle of +entity data within the epilot platform. It enables organizations to define governance +policies — such as automated data deletion rules — and execute them against any entity +schema (currently limited to Contacts). + ## Quick Start ```bash @@ -15,7 +20,7 @@ description: "epilot CLI commands for the Data Governance API: quick start, comm epilot data-governance # Call an operation -epilot data-governance queryEntities -p entity_schema=example +epilot data-governance queryEntities -p entity_schema=contact ``` ## Common Flags @@ -38,21 +43,25 @@ epilot data-governance queryEntities -p entity_schema=example ## Operations -**Data Management** -- [`queryEntities`](#queryentities) — Executes a query against the specified entity schema using the saved view definition, optionally combined with additiona -- [`createJob`](#createjob) — POST /data-governance/v1/{entity_schema}/jobs -- [`updateJob`](#updatejob) — PATCH /data-governance/v1/{entity_schema}/jobs/{job_id} -- [`getJob`](#getjob) — Returns details of a single job run. -- [`getJobReportUrl`](#getjobreporturl) — Returns a short-lived, pre-signed URL to download the report file for the given job. -- [`getConfig`](#getconfig) — Returns a data management config by its id. -- [`createJobForConfig`](#createjobforconfig) — Creates a job run for the given config and triggers asynchronous execution. Returns a job id which can be used to poll j -- [`upsertConfig`](#upsertconfig) — Creates or updates a config for the given entity schema. The config is later used by a scheduled background process to p -- [`listConfigs`](#listconfigs) — Returns a paginated list of configs -- [`listJobs`](#listjobs) — Returns a paginated list of jobs +**Query** +- [`queryEntities`](#queryentities) — Executes a query against the specified entity schema using a saved view + +**Auditable Jobs** +- [`createJob`](#createjob) — Creates a new job run for the given entity schema. The job is associated +- [`updateJob`](#updatejob) — Partially updates an existing job run. Typically used to record +- [`getJob`](#getjob) — Returns full details of a single job run, including its current status, +- [`getJobReportUrl`](#getjobreporturl) — Returns a short-lived, pre-signed S3 URL to download the CSV report +- [`createJobForConfig`](#createjobforconfig) — Manually triggers a new job run for the specified config. The job is +- [`listJobs`](#listjobs) — Returns a cursor-paginated list of job runs. Results can be filtered + +**Data Lifecycle Configs** +- [`getConfig`](#getconfig) — Returns a single data data lifecycle config by its unique identifier, +- [`upsertConfig`](#upsertconfig) — Creates a new data lifecycle config or updates an existing one for the +- [`listConfigs`](#listconfigs) — Returns a cursor-paginated list of data lifecycle configs. Results can be ### `queryEntities` -Executes a query against the specified entity schema using the saved view definition, optionally combined with additiona +Executes a query against the specified entity schema using a saved view `POST /data-governance/v1/{entity_schema}/query` @@ -60,7 +69,8 @@ Executes a query against the specified entity schema using the saved view defini | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `entity_schema` | path | string | Yes | Target entity schema to query (for example: "contact", "opportunity", "order"). +| `entity_schema` | path | string | Yes | The target entity schema slug to query +(e.g. `contact`, `opportunity`, `order`). | **Request Body** (required) @@ -69,14 +79,14 @@ Executes a query against the specified entity schema using the saved view defini ```bash epilot data-governance queryEntities \ - -p entity_schema=example + -p entity_schema=contact ``` With request body: ```bash epilot data-governance queryEntities \ - -p entity_schema=example \ + -p entity_schema=contact \ -d '{ "saved_view_id": "string", "include_deleted": "true", @@ -84,7 +94,9 @@ epilot data-governance queryEntities \ { "type": "entity_workflows_only_in_closed_or_cancelled_status", "related_entity_schemas": ["string"], - "lookback_period_days": 0 + "lookback_period_days": 0, + "message_type": ["SENT"], + "workflow_status": ["CLOSED"] } ], "from": 0, @@ -97,19 +109,19 @@ epilot data-governance queryEntities \ Using positional args for path parameters: ```bash -epilot data-governance queryEntities example +epilot data-governance queryEntities contact ``` Using stdin pipe: ```bash -cat body.json | epilot data-governance queryEntities -p entity_schema=example +cat body.json | epilot data-governance queryEntities -p entity_schema=contact ``` With JSONata filter: ```bash -epilot data-governance queryEntities -p entity_schema=example --jsonata 'results[0]' +epilot data-governance queryEntities -p entity_schema=contact --jsonata 'results[0]' ```
@@ -130,13 +142,15 @@ epilot data-governance queryEntities -p entity_schema=example --jsonata 'results ### `createJob` +Creates a new job run for the given entity schema. The job is associated + `POST /data-governance/v1/{entity_schema}/jobs` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `entity_schema` | path | string | Yes | | +| `entity_schema` | path | string | Yes | The entity schema slug this job operates on (e.g. `contact`). | **Request Body** (required) @@ -144,14 +158,14 @@ epilot data-governance queryEntities -p entity_schema=example --jsonata 'results ```bash epilot data-governance createJob \ - -p entity_schema=example + -p entity_schema=contact ``` With request body: ```bash epilot data-governance createJob \ - -p entity_schema=example \ + -p entity_schema=contact \ -d '{ "type": "deletion", "config_id": "string", @@ -164,19 +178,19 @@ epilot data-governance createJob \ Using positional args for path parameters: ```bash -epilot data-governance createJob example +epilot data-governance createJob contact ``` Using stdin pipe: ```bash -cat body.json | epilot data-governance createJob -p entity_schema=example +cat body.json | epilot data-governance createJob -p entity_schema=contact ``` With JSONata filter: ```bash -epilot data-governance createJob -p entity_schema=example --jsonata 'id' +epilot data-governance createJob -p entity_schema=contact --jsonata 'id' ```
@@ -212,14 +226,16 @@ epilot data-governance createJob -p entity_schema=example --jsonata 'id' ### `updateJob` +Partially updates an existing job run. Typically used to record + `PATCH /data-governance/v1/{entity_schema}/jobs/{job_id}` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `entity_schema` | path | string | Yes | | -| `job_id` | path | string | Yes | | +| `entity_schema` | path | string | Yes | The entity schema slug this job belongs to. | +| `job_id` | path | string | Yes | Unique identifier of the job to update. | **Request Body** (required) @@ -227,16 +243,16 @@ epilot data-governance createJob -p entity_schema=example --jsonata 'id' ```bash epilot data-governance updateJob \ - -p entity_schema=example \ - -p job_id=123e4567-e89b-12d3-a456-426614174000 + -p entity_schema=contact \ + -p job_id=2d3b5e90-e4c0-4f1a-9c7b-abc123def456 ``` With request body: ```bash epilot data-governance updateJob \ - -p entity_schema=example \ - -p job_id=123e4567-e89b-12d3-a456-426614174000 \ + -p entity_schema=contact \ + -p job_id=2d3b5e90-e4c0-4f1a-9c7b-abc123def456 \ -d '{ "status": "in_progress", "details": {}, @@ -253,19 +269,19 @@ epilot data-governance updateJob \ Using positional args for path parameters: ```bash -epilot data-governance updateJob example 123e4567-e89b-12d3-a456-426614174000 +epilot data-governance updateJob contact 2d3b5e90-e4c0-4f1a-9c7b-abc123def456 ``` Using stdin pipe: ```bash -cat body.json | epilot data-governance updateJob -p entity_schema=example -p job_id=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot data-governance updateJob -p entity_schema=contact -p job_id=2d3b5e90-e4c0-4f1a-9c7b-abc123def456 ``` With JSONata filter: ```bash -epilot data-governance updateJob -p entity_schema=example -p job_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +epilot data-governance updateJob -p entity_schema=contact -p job_id=2d3b5e90-e4c0-4f1a-9c7b-abc123def456 --jsonata 'id' ```
@@ -301,7 +317,7 @@ epilot data-governance updateJob -p entity_schema=example -p job_id=123e4567-e89 ### `getJob` -Returns details of a single job run. +Returns full details of a single job run, including its current status, `GET /data-governance/v1/jobs/{job_id}` @@ -309,25 +325,25 @@ Returns details of a single job run. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `job_id` | path | string | Yes | | +| `job_id` | path | string | Yes | Unique identifier of the job. | **Sample Call** ```bash epilot data-governance getJob \ - -p job_id=123e4567-e89b-12d3-a456-426614174000 + -p job_id=2d3b5e90-e4c0-4f1a-9c7b-abc123def456 ``` Using positional args for path parameters: ```bash -epilot data-governance getJob 123e4567-e89b-12d3-a456-426614174000 +epilot data-governance getJob 2d3b5e90-e4c0-4f1a-9c7b-abc123def456 ``` With JSONata filter: ```bash -epilot data-governance getJob -p job_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +epilot data-governance getJob -p job_id=2d3b5e90-e4c0-4f1a-9c7b-abc123def456 --jsonata 'id' ```
@@ -363,7 +379,7 @@ epilot data-governance getJob -p job_id=123e4567-e89b-12d3-a456-426614174000 --j ### `getJobReportUrl` -Returns a short-lived, pre-signed URL to download the report file for the given job. +Returns a short-lived, pre-signed S3 URL to download the CSV report `GET /data-governance/v1/jobs/{job_id}/report-url` @@ -371,25 +387,25 @@ Returns a short-lived, pre-signed URL to download the report file for the given | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `job_id` | path | string | Yes | | +| `job_id` | path | string | Yes | Unique identifier of the job whose report to download. | **Sample Call** ```bash epilot data-governance getJobReportUrl \ - -p job_id=123e4567-e89b-12d3-a456-426614174000 + -p job_id=2d3b5e90-e4c0-4f1a-9c7b-abc123def456 ``` Using positional args for path parameters: ```bash -epilot data-governance getJobReportUrl 123e4567-e89b-12d3-a456-426614174000 +epilot data-governance getJobReportUrl 2d3b5e90-e4c0-4f1a-9c7b-abc123def456 ``` With JSONata filter: ```bash -epilot data-governance getJobReportUrl -p job_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'url' +epilot data-governance getJobReportUrl -p job_id=2d3b5e90-e4c0-4f1a-9c7b-abc123def456 --jsonata 'url' ```
@@ -408,7 +424,7 @@ epilot data-governance getJobReportUrl -p job_id=123e4567-e89b-12d3-a456-4266141 ### `getConfig` -Returns a data management config by its id. +Returns a single data data lifecycle config by its unique identifier, `GET /data-governance/v1/configs/{config_id}` @@ -416,25 +432,25 @@ Returns a data management config by its id. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `config_id` | path | string | Yes | | +| `config_id` | path | string | Yes | Unique identifier of the config. | **Sample Call** ```bash epilot data-governance getConfig \ - -p config_id=123e4567-e89b-12d3-a456-426614174000 + -p config_id=cfg-8a12f3b4-5678-9abc-def0-123456789abc ``` Using positional args for path parameters: ```bash -epilot data-governance getConfig 123e4567-e89b-12d3-a456-426614174000 +epilot data-governance getConfig cfg-8a12f3b4-5678-9abc-def0-123456789abc ``` With JSONata filter: ```bash -epilot data-governance getConfig -p config_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +epilot data-governance getConfig -p config_id=cfg-8a12f3b4-5678-9abc-def0-123456789abc --jsonata 'id' ```
@@ -452,7 +468,9 @@ epilot data-governance getConfig -p config_id=123e4567-e89b-12d3-a456-4266141740 { "type": "entity_workflows_only_in_closed_or_cancelled_status", "related_entity_schemas": ["string"], - "lookback_period_days": 0 + "lookback_period_days": 0, + "message_type": ["SENT"], + "workflow_status": ["CLOSED"] } ] }, @@ -477,7 +495,7 @@ epilot data-governance getConfig -p config_id=123e4567-e89b-12d3-a456-4266141740 ### `createJobForConfig` -Creates a job run for the given config and triggers asynchronous execution. Returns a job id which can be used to poll j +Manually triggers a new job run for the specified config. The job is `POST /data-governance/v1/configs/{config_id}/jobs` @@ -485,25 +503,25 @@ Creates a job run for the given config and triggers asynchronous execution. Retu | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `config_id` | path | string | Yes | | +| `config_id` | path | string | Yes | Unique identifier of the config to execute. | **Sample Call** ```bash epilot data-governance createJobForConfig \ - -p config_id=123e4567-e89b-12d3-a456-426614174000 + -p config_id=cfg-8a12f3b4-5678-9abc-def0-123456789abc ``` Using positional args for path parameters: ```bash -epilot data-governance createJobForConfig 123e4567-e89b-12d3-a456-426614174000 +epilot data-governance createJobForConfig cfg-8a12f3b4-5678-9abc-def0-123456789abc ``` With JSONata filter: ```bash -epilot data-governance createJobForConfig -p config_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +epilot data-governance createJobForConfig -p config_id=cfg-8a12f3b4-5678-9abc-def0-123456789abc --jsonata 'id' ```
@@ -539,7 +557,7 @@ epilot data-governance createJobForConfig -p config_id=123e4567-e89b-12d3-a456-4 ### `upsertConfig` -Creates or updates a config for the given entity schema. The config is later used by a scheduled background process to p +Creates a new data lifecycle config or updates an existing one for the `POST /data-governance/v1/{entity_schema}/configs` @@ -547,8 +565,7 @@ Creates or updates a config for the given entity schema. The config is later use | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `entity_schema` | path | string | Yes | Target entity schema for the config - | +| `entity_schema` | path | string | Yes | The entity schema slug this config targets (e.g. `contact`). | **Request Body** (required) @@ -556,14 +573,14 @@ Creates or updates a config for the given entity schema. The config is later use ```bash epilot data-governance upsertConfig \ - -p entity_schema=example + -p entity_schema=contact ``` With request body: ```bash epilot data-governance upsertConfig \ - -p entity_schema=example \ + -p entity_schema=contact \ -d '{ "type": "deletion", "query": { @@ -573,7 +590,9 @@ epilot data-governance upsertConfig \ { "type": "entity_workflows_only_in_closed_or_cancelled_status", "related_entity_schemas": ["string"], - "lookback_period_days": 0 + "lookback_period_days": 0, + "message_type": ["SENT"], + "workflow_status": ["CLOSED"] } ] }, @@ -591,19 +610,19 @@ epilot data-governance upsertConfig \ Using positional args for path parameters: ```bash -epilot data-governance upsertConfig example +epilot data-governance upsertConfig contact ``` Using stdin pipe: ```bash -cat body.json | epilot data-governance upsertConfig -p entity_schema=example +cat body.json | epilot data-governance upsertConfig -p entity_schema=contact ``` With JSONata filter: ```bash -epilot data-governance upsertConfig -p entity_schema=example --jsonata 'id' +epilot data-governance upsertConfig -p entity_schema=contact --jsonata 'id' ```
@@ -621,7 +640,9 @@ epilot data-governance upsertConfig -p entity_schema=example --jsonata 'id' { "type": "entity_workflows_only_in_closed_or_cancelled_status", "related_entity_schemas": ["string"], - "lookback_period_days": 0 + "lookback_period_days": 0, + "message_type": ["SENT"], + "workflow_status": ["CLOSED"] } ] }, @@ -646,7 +667,7 @@ epilot data-governance upsertConfig -p entity_schema=example --jsonata 'id' ### `listConfigs` -Returns a paginated list of configs +Returns a cursor-paginated list of data lifecycle configs. Results can be `GET /data-governance/v1/configs` @@ -654,12 +675,16 @@ Returns a paginated list of configs | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `limit` | query | number | No | | -| `cursor` | query | string | No | | -| `entity_schema` | query | string | No | Optional entity schema to filter configs. | -| `type` | query | "deletion" | No | Optional config type to filter configs. | -| `next_run_at` | query | string (date) | No | Optional next run date (YYYY-MM-DD) to filter configs. | -| `enabled` | query | boolean | No | Optional enabled status to filter configs. | +| `limit` | query | number | No | Maximum number of configs to return per page. | +| `cursor` | query | string | No | Opaque cursor returned from a previous response for fetching the +next page of results. + | +| `entity_schema` | query | string | No | Filter configs by entity schema slug (e.g. `contact`). | +| `type` | query | "deletion" | No | Filter configs by governance action type. | +| `next_run_at` | query | string (date) | No | Filter configs whose next scheduled run date matches this value +(format: `YYYY-MM-DD`). + | +| `enabled` | query | boolean | No | Filter by enabled (`true`) or disabled (`false`) status. | **Sample Call** @@ -690,7 +715,9 @@ epilot data-governance listConfigs --jsonata 'configs' { "type": "entity_workflows_only_in_closed_or_cancelled_status", "related_entity_schemas": ["string"], - "lookback_period_days": 0 + "lookback_period_days": 0, + "message_type": ["SENT"], + "workflow_status": ["CLOSED"] } ] }, @@ -718,7 +745,7 @@ epilot data-governance listConfigs --jsonata 'configs' ### `listJobs` -Returns a paginated list of jobs +Returns a cursor-paginated list of job runs. Results can be filtered `GET /data-governance/v1/jobs` @@ -726,12 +753,14 @@ Returns a paginated list of jobs | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `limit` | query | number | No | | -| `cursor` | query | string | No | | -| `entity_schema` | query | string | No | Optional entity schema to filter jobs. | -| `type` | query | "deletion" | No | Optional job type to filter jobs. | -| `status` | query | "in_progress" \| "success" \| "failed" | No | Optional job status to filter jobs. | -| `config_id` | query | string | No | Optional config id to filter jobs. | +| `limit` | query | number | No | Maximum number of jobs to return per page. | +| `cursor` | query | string | No | Opaque cursor returned from a previous response for fetching the +next page of results. + | +| `entity_schema` | query | string | No | Filter jobs by entity schema slug (e.g. `contact`). | +| `type` | query | "deletion" | No | Filter jobs by governance action type. | +| `status` | query | "in_progress" \| "success" \| "failed" | No | Filter jobs by execution status. | +| `config_id` | query | string | No | Filter jobs belonging to a specific config. | **Sample Call** diff --git a/docs/cli/commands/deduplication.md b/docs/cli/commands/deduplication.md index 9559578b..e4214a73 100644 --- a/docs/cli/commands/deduplication.md +++ b/docs/cli/commands/deduplication.md @@ -41,6 +41,15 @@ epilot deduplication deduplicate ## Operations - [`deduplicate`](#deduplicate) — Deduplicates Entities +- [`deduplicateAsync`](#deduplicateasync) — Submits an async deduplication job. Returns a job ID immediately. Poll GET /v1/deduplicate/jobs/{jobId} for status. +- [`getDeduplicationJob`](#getdeduplicationjob) — Returns the current status of an async deduplication job +- [`detectDuplicates`](#detectduplicates) — Detects potential duplicate entities for the given entity using the schema's prioritized uniqueness rules. Returns match +- [`dismissDuplicates`](#dismissduplicates) — Confirms entities as NOT duplicates: clears the internal duplicate-detection flags (_matching_entities) on each given en +- [`listUniquenessCriteria`](#listuniquenesscriteria) — Lists UniquenessCriteria for the requesting organization. Optionally filtered by schema. +- [`createUniquenessCriteria`](#createuniquenesscriteria) — Creates a new UniquenessCriteria record. +- [`getUniquenessCriteria`](#getuniquenesscriteria) — Fetch a single UniquenessCriteria record. +- [`updateUniquenessCriteria`](#updateuniquenesscriteria) — Replace the matchRules on an existing UniquenessCriteria record. +- [`deleteUniquenessCriteria`](#deleteuniquenesscriteria) — Delete a UniquenessCriteria record. ### `deduplicate` @@ -66,35 +75,508 @@ cat body.json | epilot deduplication deduplicate With JSONata filter: ```bash -epilot deduplication deduplicate --jsonata '$' +epilot deduplication deduplicate --jsonata 'deduplicatedEntities' ```
Sample Response ```json -[ - { - "_id": "string", - "_org": "string", - "_schema": "string", - "_created_at": "1970-01-01T00:00:00.000Z", - "_updated_at": "1970-01-01T00:00:00.000Z", - "_created_by": "string", - "created_by": "string", - "_tags": ["string"], - "_acl": {}, - "_owners": [ - { - "org_id": "string", - "user_id": "string" - } - ], - "type": "string" - } -] +{ + "deduplicatedEntities": [ + { + "_id": "string", + "_org": "string", + "_schema": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_created_by": "string", + "created_by": "string", + "_tags": ["string"], + "_acl": {}, + "_owners": [ + { + "org_id": "string", + "user_id": "string" + } + ], + "type": "string" + } + ] +} ```
--- + +### `deduplicateAsync` + +Submits an async deduplication job. Returns a job ID immediately. Poll GET /v1/deduplicate/jobs/{jobId} for status. + +`POST /v1/deduplicate/job` + +**Request Body** + +**Sample Call** + +```bash +epilot deduplication deduplicateAsync \ + -d '[{"toKeep":"string","toDelete":["string"]}]' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot deduplication deduplicateAsync +``` + +With JSONata filter: + +```bash +epilot deduplication deduplicateAsync --jsonata '$' +``` + +--- + +### `getDeduplicationJob` + +Returns the current status of an async deduplication job + +`GET /v1/deduplicate/jobs/{jobId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `jobId` | path | string | Yes | The job ID returned by POST /v1/deduplicate/job | + +**Sample Call** + +```bash +epilot deduplication getDeduplicationJob \ + -p jobId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot deduplication getDeduplicationJob 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot deduplication getDeduplicationJob -p jobId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'jobId' +``` + +
+Sample Response + +```json +{ + "jobId": "string", + "status": "pending", + "message": "string", + "result": [ + { + "_id": "string", + "_org": "string", + "_schema": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_created_by": "string", + "created_by": "string", + "_tags": ["string"], + "_acl": {}, + "_owners": [ + { + "org_id": "string", + "user_id": "string" + } + ], + "type": "string" + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `detectDuplicates` + +Detects potential duplicate entities for the given entity using the schema's prioritized uniqueness rules. Returns match + +`POST /v1/detect-duplicates` + +**Request Body** + +**Sample Call** + +```bash +epilot deduplication detectDuplicates \ + -d '{"schema":"string","entity":{}}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot deduplication detectDuplicates +``` + +With JSONata filter: + +```bash +epilot deduplication detectDuplicates --jsonata 'matches' +``` + +
+Sample Response + +```json +{ + "matches": [ + { + "entity": { + "_id": "string", + "_org": "string", + "_schema": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_created_by": "string", + "created_by": "string", + "_tags": ["string"], + "_acl": {}, + "_owners": [ + { + "org_id": "string", + "user_id": "string" + } + ], + "type": "string" + }, + "confidence": 0, + "matched_attributes": ["string"] + } + ] +} +``` + +
+ +--- + +### `dismissDuplicates` + +Confirms entities as NOT duplicates: clears the internal duplicate-detection flags (_matching_entities) on each given en + +`POST /v1/duplicates/dismiss` + +**Request Body** + +**Sample Call** + +```bash +epilot deduplication dismissDuplicates \ + -d '{"schema":"string","entityIds":["string"]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot deduplication dismissDuplicates +``` + +With JSONata filter: + +```bash +epilot deduplication dismissDuplicates --jsonata 'dismissed' +``` + +
+Sample Response + +```json +{ + "dismissed": ["string"] +} +``` + +
+ +--- + +### `listUniquenessCriteria` + +Lists UniquenessCriteria for the requesting organization. Optionally filtered by schema. + +`GET /v1/uniqueness-criteria` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `schema` | query | string | No | Filter results to a specific entity schema. | + +**Sample Call** + +```bash +epilot deduplication listUniquenessCriteria +``` + +With JSONata filter: + +```bash +epilot deduplication listUniquenessCriteria --jsonata 'items[0]' +``` + +
+Sample Response + +```json +{ + "items": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "schema": "string", + "matchRules": [ + { + "name": "string", + "attributes": [ + { + "attribute": "string" + } + ], + "confidence": 0 + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `createUniquenessCriteria` + +Creates a new UniquenessCriteria record. + +`POST /v1/uniqueness-criteria` + +**Request Body** + +**Sample Call** + +```bash +epilot deduplication createUniquenessCriteria \ + -d '{"schema":"string","matchRules":[{"name":"string","attributes":[{"attribute":"string"}],"confidence":0}]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot deduplication createUniquenessCriteria +``` + +With JSONata filter: + +```bash +epilot deduplication createUniquenessCriteria --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "schema": "string", + "matchRules": [ + { + "name": "string", + "attributes": [ + { + "attribute": "string" + } + ], + "confidence": 0 + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getUniquenessCriteria` + +Fetch a single UniquenessCriteria record. + +`GET /v1/uniqueness-criteria/{schema}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `schema` | path | string | Yes | Entity schema slug. | + +**Sample Call** + +```bash +epilot deduplication getUniquenessCriteria \ + -p schema=example +``` + +Using positional args for path parameters: + +```bash +epilot deduplication getUniquenessCriteria example +``` + +With JSONata filter: + +```bash +epilot deduplication getUniquenessCriteria -p schema=example --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "schema": "string", + "matchRules": [ + { + "name": "string", + "attributes": [ + { + "attribute": "string" + } + ], + "confidence": 0 + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateUniquenessCriteria` + +Replace the matchRules on an existing UniquenessCriteria record. + +`PUT /v1/uniqueness-criteria/{schema}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `schema` | path | string | Yes | Entity schema slug. | + +**Request Body** + +**Sample Call** + +```bash +epilot deduplication updateUniquenessCriteria \ + -p schema=example \ + -d '{"matchRules":[{"name":"string","attributes":[{"attribute":"string"}],"confidence":0}]}' +``` + +Using positional args for path parameters: + +```bash +epilot deduplication updateUniquenessCriteria example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot deduplication updateUniquenessCriteria -p schema=example +``` + +With JSONata filter: + +```bash +epilot deduplication updateUniquenessCriteria -p schema=example --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "schema": "string", + "matchRules": [ + { + "name": "string", + "attributes": [ + { + "attribute": "string" + } + ], + "confidence": 0 + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteUniquenessCriteria` + +Delete a UniquenessCriteria record. + +`DELETE /v1/uniqueness-criteria/{schema}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `schema` | path | string | Yes | Entity schema slug. | + +**Sample Call** + +```bash +epilot deduplication deleteUniquenessCriteria \ + -p schema=example +``` + +Using positional args for path parameters: + +```bash +epilot deduplication deleteUniquenessCriteria example +``` + +With JSONata filter: + +```bash +epilot deduplication deleteUniquenessCriteria -p schema=example --jsonata '$' +``` + +--- diff --git a/docs/cli/commands/design.md b/docs/cli/commands/design.md index 6ede275d..37e6b26c 100644 --- a/docs/cli/commands/design.md +++ b/docs/cli/commands/design.md @@ -5,7 +5,7 @@ description: "epilot CLI commands for the Design Builder API v2: quick start, co # Design Builder API v2 -- **Base URL:** `https://design-builder-api.epilot.io` +- **Base URL:** `https://design-builder-api.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/design](https://docs.epilot.io/api/design) ## Quick Start @@ -44,6 +44,7 @@ epilot design getAllDesigns - [`getDesign`](#getdesign) — Search for a especific design owned by user organization - [`updateDesign`](#updatedesign) — Update a especific design owned by user organization - [`deleteDesign`](#deletedesign) — Search and delete for a especific design owned by user organization +- [`duplicateDesign`](#duplicatedesign) — Duplicate an existing design owned by the user organization. The copy carries over the style, custom CSS and name (marke - [`getThemeFromDesign`](#getthemefromdesign) — Search for a especific design owned by user organization and parse them to a new or old theme - [`getFiles`](#getfiles) — List all files for the user organization bucket - [`uploadFile`](#uploadfile) — Upload a new file for the user organization bucket @@ -66,20 +67,34 @@ epilot design getAllDesigns With JSONata filter: ```bash -epilot design getAllDesigns --jsonata '$' +epilot design getAllDesigns --jsonata 'designs' ```
Sample Response ```json -[ - { - "designs": [ - {} - ] - } -] +{ + "designs": [ + { + "id": "string", + "created_at": "2021-01-30T08:30:00Z", + "created_by": "string", + "edited": true, + "last_modified_at": "string", + "brand_id": "string", + "brand_name": "string", + "user": {}, + "style_name": "string", + "style": {}, + "is_default": true, + "_manifest": ["string"], + "custom_theme": "string", + "use_custom_theme": true, + "design_tokens": {} + } + ] +} ```
@@ -116,67 +131,77 @@ epilot design addDesign \ }, "style_name": "string", "style": { - "logo": { - "main": { - "name": "string", - "display_name": "string", - "file_type": "LOGO", - "s3_object_key": "string", - "url": "string" - } - }, - "palette": { - "primary": "string", - "secondary": "string", - "error": "string", - "background": "string", - "paper": "string", - "navbar": "string", - "portal_login_background": "string" - }, - "typography": { - "font": { - "font_id": "string", - "font_name": "string", - "font_family": "string", - "font_weight_regular": "string", - "font_weight_medium": "string", - "font_weight_bold": "string", - "urls": [ - { - "type": "WOFF2", - "url": "string" - } - ] - }, - "primary": "string", - "secondary": "string" - }, - "shape": { - "border_radius": 0 - }, - "consumer": { - "widgets": [ - { - "id": "string", - "name": "string" - } - ], - "customer_portals": [ - { - "id": "string", - "name": "string" - } - ] - } + "logo": {}, + "palette": {}, + "typography": {}, + "shape": {}, + "consumer": {} }, "is_default": true, + "_manifest": ["string"], "custom_theme": "string", "use_custom_theme": true, "design_tokens": { "coupon": "string", "cashback": "string", - "custom_css": "string" + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" } } }' @@ -222,12 +247,70 @@ epilot design addDesign --jsonata 'design' "consumer": {} }, "is_default": true, + "_manifest": ["string"], "custom_theme": "string", "use_custom_theme": true, "design_tokens": { "coupon": "string", "cashback": "string", - "custom_css": "string" + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" } } } @@ -247,7 +330,7 @@ Search for a especific design owned by user organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `designId` | path | string | Yes | Id of the design | +| `designId` | path | string | Yes | | **Sample Call** @@ -296,12 +379,70 @@ epilot design getDesign -p designId=4a062990-a6a3-11eb-9828-4f3da7d4935a --jsona "consumer": {} }, "is_default": true, + "_manifest": ["string"], "custom_theme": "string", "use_custom_theme": true, "design_tokens": { "coupon": "string", "cashback": "string", - "custom_css": "string" + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" } } } @@ -321,7 +462,7 @@ Update a especific design owned by user organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `designId` | path | string | Yes | Id of the design | +| `designId` | path | string | Yes | | **Request Body** (required) @@ -349,67 +490,77 @@ epilot design updateDesign \ }, "style_name": "string", "style": { - "logo": { - "main": { - "name": "string", - "display_name": "string", - "file_type": "LOGO", - "s3_object_key": "string", - "url": "string" - } - }, - "palette": { - "primary": "string", - "secondary": "string", - "error": "string", - "background": "string", - "paper": "string", - "navbar": "string", - "portal_login_background": "string" - }, - "typography": { - "font": { - "font_id": "string", - "font_name": "string", - "font_family": "string", - "font_weight_regular": "string", - "font_weight_medium": "string", - "font_weight_bold": "string", - "urls": [ - { - "type": "WOFF2", - "url": "string" - } - ] - }, - "primary": "string", - "secondary": "string" - }, - "shape": { - "border_radius": 0 - }, - "consumer": { - "widgets": [ - { - "id": "string", - "name": "string" - } - ], - "customer_portals": [ - { - "id": "string", - "name": "string" - } - ] - } + "logo": {}, + "palette": {}, + "typography": {}, + "shape": {}, + "consumer": {} }, "is_default": true, + "_manifest": ["string"], "custom_theme": "string", "use_custom_theme": true, "design_tokens": { "coupon": "string", "cashback": "string", - "custom_css": "string" + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" } } }' @@ -445,7 +596,7 @@ Search and delete for a especific design owned by user organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `designId` | path | string | Yes | Id of the design | +| `designId` | path | string | Yes | | **Sample Call** @@ -468,6 +619,138 @@ epilot design deleteDesign -p designId=4a062990-a6a3-11eb-9828-4f3da7d4935a --js --- +### `duplicateDesign` + +Duplicate an existing design owned by the user organization. The copy carries over the style, custom CSS and name (marke + +`POST /v1/designs/{designId}/duplicate` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `designId` | path | string | Yes | | + +**Sample Call** + +```bash +epilot design duplicateDesign \ + -p designId=4a062990-a6a3-11eb-9828-4f3da7d4935a +``` + +Using positional args for path parameters: + +```bash +epilot design duplicateDesign 4a062990-a6a3-11eb-9828-4f3da7d4935a +``` + +With JSONata filter: + +```bash +epilot design duplicateDesign -p designId=4a062990-a6a3-11eb-9828-4f3da7d4935a --jsonata 'design' +``` + +
+Sample Response + +```json +{ + "design": { + "id": "string", + "created_at": "2021-01-30T08:30:00Z", + "created_by": "string", + "edited": true, + "last_modified_at": "string", + "brand_id": "string", + "brand_name": "string", + "user": { + "emailaddress": "string", + "fullname": "string", + "name": "string", + "userid": "string" + }, + "style_name": "string", + "style": { + "logo": {}, + "palette": {}, + "typography": {}, + "shape": {}, + "consumer": {} + }, + "is_default": true, + "_manifest": ["string"], + "custom_theme": "string", + "use_custom_theme": true, + "design_tokens": { + "coupon": "string", + "cashback": "string", + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" + } + } +} +``` + +
+ +--- + ### `getThemeFromDesign` Search for a especific design owned by user organization and parse them to a new or old theme @@ -478,9 +761,9 @@ Search for a especific design owned by user organization and parse them to a new | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `designId` | path | string | Yes | Id of the design | +| `designId` | path | string | Yes | | | `orgId` | query | string | No | Organization id of the user | -| `theme` | query | "NEW" \| "OLD" | Yes | Type of theme to be parsed and returned | +| `theme` | query | "NEW" \| "OLD" | Yes | | **Sample Call** @@ -499,14 +782,63 @@ epilot design getThemeFromDesign 4a062990-a6a3-11eb-9828-4f3da7d4935a With JSONata filter: ```bash -epilot design getThemeFromDesign -p designId=4a062990-a6a3-11eb-9828-4f3da7d4935a -p theme=NEW --jsonata '$' +epilot design getThemeFromDesign -p designId=4a062990-a6a3-11eb-9828-4f3da7d4935a -p theme=NEW --jsonata 'theme' ```
Sample Response ```json -{} +{ + "theme": "NEW", + "design": { + "id": "string", + "last_modified_at": "string", + "style_name": "string", + "style": { + "logo": { + "main": { + "name": "string", + "display_name": "string", + "file_type": "LOGO", + "s3_object_key": "string", + "url": "string", + "file_id": "string" + } + }, + "palette": { + "primary": "string", + "secondary": "string", + "error": "string", + "background": "string", + "paper": "string", + "navbar": "string", + "portal_login_background": "string" + }, + "typography": { + "font": { + "font_id": "string", + "font_name": "string", + "font_family": "string", + "font_weight_regular": "string", + "font_weight_medium": "string", + "font_weight_bold": "string", + "urls": [ + { + "type": "WOFF2", + "url": "string" + } + ] + }, + "primary": "string", + "secondary": "string" + } + }, + "custom_theme": "string", + "use_custom_theme": true, + "journey_design_tokens": {} + } +} ```
@@ -523,7 +855,7 @@ List all files for the user organization bucket | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `type` | query | "LOGO" \| "FONT" | No | Type of files to be returned | +| `type` | query | "LOGO" \| "FONT" \| "IMAGE" | No | Type of files to be returned | **Sample Call** @@ -547,7 +879,8 @@ epilot design getFiles --jsonata '$' "display_name": "string", "file_type": "LOGO", "s3_object_key": "string", - "url": "string" + "url": "string", + "file_id": "string" } ] ``` @@ -583,7 +916,8 @@ epilot design uploadFile --jsonata '$' "display_name": "string", "file_type": "LOGO", "s3_object_key": "string", - "url": "string" + "url": "string", + "file_id": "string" } ``` @@ -601,8 +935,8 @@ Search for a especific design owned by user organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `consumerId` | path | string | Yes | Id of the design | -| `application` | path | string | Yes | Type of application that uses the design | +| `consumerId` | path | string | Yes | | +| `application` | path | string | Yes | | **Sample Call** @@ -652,12 +986,70 @@ epilot design getConsumerDesign -p consumerId=4a062990-a6a3-11eb-9828-4f3da7d493 "consumer": {} }, "is_default": true, + "_manifest": ["string"], "custom_theme": "string", "use_custom_theme": true, "design_tokens": { "coupon": "string", "cashback": "string", - "custom_css": "string" + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" } } } @@ -677,7 +1069,7 @@ Add a consumer that uses a specific design | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `designId` | path | string | Yes | Id of the design | +| `designId` | path | string | Yes | | | `application` | path | string | Yes | Type of application that uses the design | **Request Body** (required) @@ -688,7 +1080,7 @@ Add a consumer that uses a specific design epilot design addConsumer \ -p designId=4a062990-a6a3-11eb-9828-4f3da7d4935a \ -p application=journey \ - -d '{"consumer_id":"string","consumer_name":"string","should_delete":"string"}' + -d '{"consumer_id":"4a062990-a6a3-11eb-9828-4f3da7d4935a","consumer_name":"string","should_delete":"string"}' ``` Using positional args for path parameters: @@ -721,7 +1113,7 @@ Remove a consumer that uses a specific design | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `designId` | path | string | Yes | Id of the design | +| `designId` | path | string | Yes | | | `application` | path | string | Yes | Type of application that uses the design | **Request Body** (required) @@ -732,7 +1124,7 @@ Remove a consumer that uses a specific design epilot design removeConsumer \ -p designId=4a062990-a6a3-11eb-9828-4f3da7d4935a \ -p application=journey \ - -d '{"consumer_id":"string","consumer_name":"string","should_delete":"string"}' + -d '{"consumer_id":"4a062990-a6a3-11eb-9828-4f3da7d4935a","should_delete":"string"}' ``` Using positional args for path parameters: diff --git a/docs/cli/commands/document.md b/docs/cli/commands/document.md index 12959b46..3f348055 100644 --- a/docs/cli/commands/document.md +++ b/docs/cli/commands/document.md @@ -44,6 +44,7 @@ epilot document getTemplateMeta - [`getTemplateMeta`](#gettemplatemeta) — Get metadata for a document template - [`generateDocumentV2`](#generatedocumentv2) — Generates documents from templates with variables. - [`convertDocument`](#convertdocument) — Converts a document to a different format. +- [`validateTemplate`](#validatetemplate) — Validates a document template's variable syntax and, optionally, proposes a hotfixed copy of it. ### `getTemplateMeta` @@ -51,7 +52,7 @@ Get metadata for a document template `POST /v2/documents:meta` -**Request Body** +**Request Body** (required) **Sample Call** @@ -112,7 +113,7 @@ Generates documents from templates with variables. - download - preview_url provides a link to download the file | -**Request Body** +**Request Body** (required) **Sample Call** @@ -133,7 +134,7 @@ epilot document generateDocumentV2 \ } }, "context_entity_id": "bcd0aab9-b544-42b0-8bfb-6d449d02eacc", - "user_id": 100321, + "user_id": "100321", "language": "de", "variable_payload": { "additionalProperties": "string" @@ -155,7 +156,7 @@ epilot document generateDocumentV2 \ "template_with_datatable": false, "enabled_template_settings_persistence": false, "misconfigured_margins": false, - "file_entity_id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p" + "file_entity_id": "123e4567-e89b-12d3-a456-426614174000" } }' ``` @@ -249,7 +250,7 @@ epilot document generateDocumentV2 --jsonata 'job_id' "template_with_datatable": false, "enabled_template_settings_persistence": false, "misconfigured_margins": false, - "file_entity_id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p" + "file_entity_id": "123e4567-e89b-12d3-a456-426614174000" } } ``` @@ -264,7 +265,7 @@ Converts a document to a different format. `POST /v2/documents:convert` -**Request Body** +**Request Body** (required) **Sample Call** @@ -319,3 +320,89 @@ epilot document convertDocument --jsonata 'output_document'
--- + +### `validateTemplate` + +Validates a document template's variable syntax and, optionally, proposes a hotfixed copy of it. + +`POST /v2/templates:validate` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot document validateTemplate +``` + +With request body: + +```bash +epilot document validateTemplate \ + -d '{ + "template_document": { + "filename": "Umzugsmeldung.xlsx", + "s3ref": { + "bucket": "document-api-prod", + "key": "uploads/my-template.pdf" + } + }, + "fix": true, + "fix_level": "safe" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot document validateTemplate +``` + +With JSONata filter: + +```bash +epilot document validateTemplate --jsonata 'valid' +``` + +
+Sample Response + +```json +{ + "valid": false, + "fixed": true, + "issues": [ + { + "id": "unopened_tag", + "file": "xl/sharedStrings.xml", + "location": "Tabelle1!N4", + "context": "…Datum: {system.date}} Unterschrift…", + "explanation": "The tag is missing an opening brace.", + "fixable": true, + "confidence": "high", + "rule": "balance_opening_delimiter", + "before": "{system.date}}", + "after": "{{system.date}}" + } + ], + "unresolved_errors": [ + { + "id": "string", + "context": "string", + "explanation": "string" + } + ], + "fixed_document": { + "s3ref": { + "bucket": "document-api-prod", + "key": "uploads/my-template.pdf" + }, + "filename": "Umzugsmeldung (fixed).xlsx", + "preview_url": "https://example.com/path" + } +} +``` + +
+ +--- diff --git a/docs/cli/commands/email-settings.md b/docs/cli/commands/email-settings.md index 4be55080..27bf05b9 100644 --- a/docs/cli/commands/email-settings.md +++ b/docs/cli/commands/email-settings.md @@ -60,17 +60,38 @@ epilot email-settings provisionEpilotEmailAddress - [`listInboxBuckets`](#listinboxbuckets) — Retrieves all inbox buckets for the organization. **O365 Outlook Connection** -- [`connectOutlook`](#connectoutlook) — Returns Microsoft authorization URL for Outlook OAuth. +- [`connectOutlook`](#connectoutlook) — Returns the Microsoft authorization URL for Outlook OAuth. - [`getOutlookConnectionStatus`](#getoutlookconnectionstatus) — Returns all Microsoft 365 / Outlook connections for the organization. +- [`getCalendarAdminConsentStatus`](#getcalendaradminconsentstatus) — Reports whether the caller's organization can connect personal Outlook +- [`getMyCalendarConnection`](#getmycalendarconnection) — Returns the calling user's personal Outlook calendar connection, +- [`disconnectMyCalendar`](#disconnectmycalendar) — Removes the calling user's personal calendar connection. - [`disconnectOutlook`](#disconnectoutlook) — Removes the Microsoft 365 / Outlook connection for a specific tenant. - [`connectOutlookMailbox`](#connectoutlookmailbox) — Connects an Outlook mailbox: - [`disconnectOutlookMailbox`](#disconnectoutlookmailbox) — Disconnects a single Outlook mailbox by email address. - [`startMailboxSync`](#startmailboxsync) — Triggers an Outlook mailbox sync for the specified email address. - [`getMailboxSyncStatus`](#getmailboxsyncstatus) — Returns the current or latest sync status for the specified mailbox. +- [`getMailboxSyncEstimate`](#getmailboxsyncestimate) — Counts the inbox and sent messages a mailbox sync would import for each timeframe, with the same date filter the - [`retryMailboxSync`](#retrymailboxsync) — Retries failed messages from a previous sync execution. +- [`cancelMailboxSync`](#cancelmailboxsync) — Stops the running sync of an Outlook mailbox and marks it CANCELLED. - [`getConnectedOutlookEmails`](#getconnectedoutlookemails) — Returns all Outlook email addresses connected to the organization. - [`outlookOAuthCallback`](#outlookoauthcallback) — Exchanges authorization code for tokens and stores them. +**Channels** +- [`connectMsTeams`](#connectmsteams) — Connects Microsoft Teams channel (click-to-call deep links, meetings) for the organization. +- [`disconnectMsTeams`](#disconnectmsteams) — Disconnects Microsoft Teams channel for the organization. +- [`getMsTeamsStatus`](#getmsteamsstatus) — Returns the connection status of the Microsoft Teams channel for the organization. + +**Custom SMTP** +- [`listSmtpConnections`](#listsmtpconnections) — Returns all custom SMTP connections configured for the organization. +- [`createSmtpConnection`](#createsmtpconnection) — Creates a new custom SMTP connection. Runs a live verify against the SMTP server +- [`getSmtpConnection`](#getsmtpconnection) — Returns a single custom SMTP connection by id. The password is never returned. +- [`updateSmtpConnection`](#updatesmtpconnection) — Partial update; omitted fields keep their existing values. The merged +- [`deleteSmtpConnection`](#deletesmtpconnection) — Deletes a custom SMTP connection. Messages already sent are unaffected. +- [`testSmtpConnection`](#testsmtpconnection) — Re-runs a live SMTP verify against the saved configuration (EHLO + AUTH + NOOP + QUIT) +- [`listSmtpSenders`](#listsmtpsenders) — Returns every address registered to send through a custom SMTP connection. +- [`connectSmtpSender`](#connectsmtpsender) — Registers an address as a sender on a custom SMTP connection: +- [`disconnectSmtpSender`](#disconnectsmtpsender) — Removes a sender address: deletes the email address and its binding to the SMTP + **Settings** - [`getSettings`](#getsettings) — Retrieves settings of a specific type for the organization. - [`addSetting`](#addsetting) — Creates a new setting of the specified type. @@ -78,9 +99,11 @@ epilot email-settings provisionEpilotEmailAddress - [`updateSetting`](#updatesetting) — Updates an existing setting identified by its ID. **Domains** +- [`getDomains`](#getdomains) — Retrieves all custom email domains for the organization. - [`addDomain`](#adddomain) — Adds a custom email domain to the organization. - [`deleteDomain`](#deletedomain) — Removes a custom email domain from the organization. - [`verifyNameServers`](#verifynameservers) — Verifies that the domain's name server (NS) records are correctly configured. +- [`verifyDnsRecords`](#verifydnsrecords) — Verifies that the domain's DNS records (MX, TXT, CNAME) are correctly configured - [`verifyDomain`](#verifydomain) — Verifies ownership and configuration of a custom email domain. ### `provisionEpilotEmailAddress` @@ -128,7 +151,8 @@ epilot email-settings provisionEpilotEmailAddress --jsonata '$' "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -181,7 +205,8 @@ epilot email-settings setEmailAddressPrimary --jsonata '$' "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -240,7 +265,8 @@ epilot email-settings getEmailAddress -p id=123e4567-e89b-12d3-a456-426614174000 "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -322,7 +348,8 @@ epilot email-settings updateEmailAddress -p id=123e4567-e89b-12d3-a456-426614174 "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -402,7 +429,8 @@ epilot email-settings listEmailAddresses --jsonata '$' "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ] ``` @@ -469,7 +497,8 @@ epilot email-settings addEmailAddress --jsonata '$' "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -785,14 +814,23 @@ epilot email-settings listInboxBuckets --jsonata '$' ### `connectOutlook` -Returns Microsoft authorization URL for Outlook OAuth. +Returns the Microsoft authorization URL for Outlook OAuth. -`GET /v2/outlook/connect` +`POST /v2/outlook/connect` + +**Request Body** (required) **Sample Call** ```bash -epilot email-settings connectOutlook +epilot email-settings connectOutlook \ + -d '{"mail":true,"calendar":true,"return_to":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot email-settings connectOutlook ``` With JSONata filter: @@ -841,6 +879,7 @@ epilot email-settings getOutlookConnectionStatus --jsonata 'connections' { "status": "connected", "action": "connect", + "action_reason": "expired", "connected_by_display_name": "string", "connected_by_email": "user@example.com", "connected_by_user_id": "string", @@ -852,7 +891,81 @@ epilot email-settings getOutlookConnectionStatus --jsonata 'connections' "is_token_valid": true } ], - "has_connections": true + "has_connections": true, + "teams_enabled": true +} +``` + +
+ +--- + +### `getCalendarAdminConsentStatus` + +Reports whether the caller's organization can connect personal Outlook + +`GET /v2/outlook/calendar/admin-consent-status` + +**Sample Call** + +```bash +epilot email-settings getCalendarAdminConsentStatus +``` + +With JSONata filter: + +```bash +epilot email-settings getCalendarAdminConsentStatus --jsonata 'admin_consented' +``` + +
+Sample Response + +```json +{ + "admin_consented": true, + "admin_consent_url": "https://example.com/path" +} +``` + +
+ +--- + +### `getMyCalendarConnection` + +Returns the calling user's personal Outlook calendar connection, + +`GET /v2/outlook/calendar/me` + +**Sample Call** + +```bash +epilot email-settings getMyCalendarConnection +``` + +With JSONata filter: + +```bash +epilot email-settings getMyCalendarConnection --jsonata 'connection' +``` + +
+Sample Response + +```json +{ + "connection": { + "user_id": "string", + "tenant_id": "string", + "status": "connected", + "scopes": ["string"], + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z" + } } ``` @@ -860,6 +973,26 @@ epilot email-settings getOutlookConnectionStatus --jsonata 'connections' --- +### `disconnectMyCalendar` + +Removes the calling user's personal calendar connection. + +`DELETE /v2/outlook/calendar/me` + +**Sample Call** + +```bash +epilot email-settings disconnectMyCalendar +``` + +With JSONata filter: + +```bash +epilot email-settings disconnectMyCalendar --jsonata '$' +``` + +--- + ### `disconnectOutlook` Removes the Microsoft 365 / Outlook connection for a specific tenant. @@ -902,6 +1035,102 @@ epilot email-settings disconnectOutlook --jsonata 'success' --- +### `connectMsTeams` + +Connects Microsoft Teams channel (click-to-call deep links, meetings) for the organization. + +`POST /v2/channels/msteams/connect` + +**Sample Call** + +```bash +epilot email-settings connectMsTeams +``` + +With JSONata filter: + +```bash +epilot email-settings connectMsTeams --jsonata 'connected' +``` + +
+Sample Response + +```json +{ + "connected": true, + "connected_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `disconnectMsTeams` + +Disconnects Microsoft Teams channel for the organization. + +`POST /v2/channels/msteams/disconnect` + +**Sample Call** + +```bash +epilot email-settings disconnectMsTeams +``` + +With JSONata filter: + +```bash +epilot email-settings disconnectMsTeams --jsonata 'connected' +``` + +
+Sample Response + +```json +{ + "connected": true +} +``` + +
+ +--- + +### `getMsTeamsStatus` + +Returns the connection status of the Microsoft Teams channel for the organization. + +`GET /v2/channels/msteams/status` + +**Sample Call** + +```bash +epilot email-settings getMsTeamsStatus +``` + +With JSONata filter: + +```bash +epilot email-settings getMsTeamsStatus --jsonata 'connected' +``` + +
+Sample Response + +```json +{ + "connected": true, + "connected_at": "1970-01-01T00:00:00.000Z", + "connected_by_user_id": "string" +} +``` + +
+ +--- + ### `connectOutlookMailbox` Connects an Outlook mailbox: @@ -912,9 +1141,23 @@ Connects an Outlook mailbox: **Sample Call** +```bash +epilot email-settings connectOutlookMailbox +``` + +With request body: + ```bash epilot email-settings connectOutlookMailbox \ - -d '{"email":"user@example.com","shared_inbox_id":"default","mailboxSyncTimeframe":"5m"}' + -d '{ + "email": "user@example.com", + "shared_inbox_id": "default", + "name": "string", + "user_ids": ["string"], + "group_ids": ["string"], + "default_signature_id": "string", + "mailboxSyncTimeframe": "5m" +}' ``` Using stdin pipe: @@ -948,7 +1191,8 @@ epilot email-settings connectOutlookMailbox --jsonata 'email_address' "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" }, "outlook_email": "user@example.com", "tenant_id": "string", @@ -1024,7 +1268,7 @@ Triggers an Outlook mailbox sync for the specified email address. ```bash epilot email-settings startMailboxSync \ -p email=user@example.com \ - -d '{"timeframe":"5m"}' + -d '{"timeframe":"5m","since":"1970-01-01T00:00:00.000Z"}' ``` Using positional args for path parameters: @@ -1086,6 +1330,7 @@ epilot email-settings getMailboxSyncStatus -p email=user@example.com --jsonata ' "execution_id": "string", "status": "RUNNING", "timeframe": "5m", + "timeframe_start": "1970-01-01T00:00:00.000Z", "started_at": "1970-01-01T00:00:00.000Z", "completed_at": "1970-01-01T00:00:00.000Z", "inbox": { @@ -1107,6 +1352,61 @@ epilot email-settings getMailboxSyncStatus -p email=user@example.com --jsonata ' --- +### `getMailboxSyncEstimate` + +Counts the inbox and sent messages a mailbox sync would import for each timeframe, with the same date filter the + +`GET /v2/outlook/mailbox/{email}/sync/estimate` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `email` | path | string (email) | Yes | Email address of the Outlook mailbox | +| `timeframes` | query | string | No | Comma-separated timeframes to estimate. Defaults to `1m,1y,2y`, or to none when `since` is given. | +| `since` | query | string (date-time) | No | Also estimate a custom period from this point up to now (returned with timeframe `custom`). At most 2 years back. | + +**Sample Call** + +```bash +epilot email-settings getMailboxSyncEstimate \ + -p email=user@example.com +``` + +Using positional args for path parameters: + +```bash +epilot email-settings getMailboxSyncEstimate user@example.com +``` + +With JSONata filter: + +```bash +epilot email-settings getMailboxSyncEstimate -p email=user@example.com --jsonata 'estimates' +``` + +
+Sample Response + +```json +{ + "estimates": [ + { + "timeframe": "5m", + "since": "1970-01-01T00:00:00.000Z", + "inbox_messages": 0, + "sent_messages": 0, + "total_messages": 0, + "estimated_duration_seconds": 0 + } + ] +} +``` + +
+ +--- + ### `retryMailboxSync` Retries failed messages from a previous sync execution. @@ -1149,6 +1449,51 @@ epilot email-settings retryMailboxSync -p email=user@example.com --jsonata '$' --- +### `cancelMailboxSync` + +Stops the running sync of an Outlook mailbox and marks it CANCELLED. + +`POST /v2/outlook/mailbox/{email}/sync/cancel` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `email` | path | string (email) | Yes | Email address of the Outlook mailbox | + +**Sample Call** + +```bash +epilot email-settings cancelMailboxSync \ + -p email=user@example.com +``` + +Using positional args for path parameters: + +```bash +epilot email-settings cancelMailboxSync user@example.com +``` + +With JSONata filter: + +```bash +epilot email-settings cancelMailboxSync -p email=user@example.com --jsonata 'execution_id' +``` + +
+Sample Response + +```json +{ + "execution_id": "string", + "status": "RUNNING" +} +``` + +
+ +--- + ### `getConnectedOutlookEmails` Returns all Outlook email addresses connected to the organization. @@ -1189,26 +1534,528 @@ epilot email-settings getConnectedOutlookEmails --jsonata 'outlook_emails' --- -### `outlookOAuthCallback` +### `listSmtpConnections` -Exchanges authorization code for tokens and stores them. +Returns all custom SMTP connections configured for the organization. -`GET /v2/outlook/oauth/callback` +`GET /v2/smtp/connections` -**Parameters** +**Sample Call** -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `code` | query | string | No | | -| `state` | query | string | Yes | | -| `session_state` | query | string | No | | -| `error` | query | string | No | | -| `error_description` | query | string | No | | -| `error_subcode` | query | string | No | | -| `client_info` | query | string | No | | -| `error_uri` | query | string | No | | +```bash +epilot email-settings listSmtpConnections +``` + +With JSONata filter: + +```bash +epilot email-settings listSmtpConnections --jsonata 'connections' +``` + +
+Sample Response + +```json +{ + "connections": [ + { + "connection_id": "string", + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "string", + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_by_user_id": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "last_tested_at": "1970-01-01T00:00:00.000Z", + "last_test_status": "ok", + "last_test_error": "string" + } + ], + "has_connections": true +} +``` + +
+ +--- + +### `createSmtpConnection` + +Creates a new custom SMTP connection. Runs a live verify against the SMTP server + +`POST /v2/smtp/connections` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `skip_test` | query | boolean | No | Save without running the live verify. Use when the server is not reachable from +epilot yet, or when a referenced `{{ env.* }}` secret has not been set. The +connection is stored untested — `last_test_s | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot email-settings createSmtpConnection +``` + +With request body: + +```bash +epilot email-settings createSmtpConnection \ + -d '{ + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "{{ env.smtp_password }}" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot email-settings createSmtpConnection +``` + +With JSONata filter: + +```bash +epilot email-settings createSmtpConnection --jsonata 'connection_id' +``` + +
+Sample Response + +```json +{ + "connection_id": "string", + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "string", + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_by_user_id": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "last_tested_at": "1970-01-01T00:00:00.000Z", + "last_test_status": "ok", + "last_test_error": "string" +} +``` + +
+ +--- + +### `getSmtpConnection` + +Returns a single custom SMTP connection by id. The password is never returned. + +`GET /v2/smtp/connections/{connectionId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `connectionId` | path | string | Yes | | + +**Sample Call** + +```bash +epilot email-settings getSmtpConnection \ + -p connectionId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot email-settings getSmtpConnection 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot email-settings getSmtpConnection -p connectionId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'connection_id' +``` + +
+Sample Response + +```json +{ + "connection_id": "string", + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "string", + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_by_user_id": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "last_tested_at": "1970-01-01T00:00:00.000Z", + "last_test_status": "ok", + "last_test_error": "string" +} +``` + +
+ +--- + +### `updateSmtpConnection` + +Partial update; omitted fields keep their existing values. The merged + +`PUT /v2/smtp/connections/{connectionId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `connectionId` | path | string | Yes | | +| `skip_test` | query | boolean | No | Save without running the live verify. Use when the server is not reachable from +epilot yet, or when a referenced `{{ env.* }}` secret has not been set. The +connection is stored untested — `last_test_s | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot email-settings updateSmtpConnection \ + -p connectionId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"smtp_host":"string","smtp_port":"string","smtp_secure":"tls","smtp_username":"string","smtp_password":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot email-settings updateSmtpConnection 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot email-settings updateSmtpConnection -p connectionId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot email-settings updateSmtpConnection -p connectionId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'connection_id' +``` + +
+Sample Response + +```json +{ + "connection_id": "string", + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "string", + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_by_user_id": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "last_tested_at": "1970-01-01T00:00:00.000Z", + "last_test_status": "ok", + "last_test_error": "string" +} +``` + +
+ +--- + +### `deleteSmtpConnection` + +Deletes a custom SMTP connection. Messages already sent are unaffected. + +`DELETE /v2/smtp/connections/{connectionId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `connectionId` | path | string | Yes | | + +**Sample Call** + +```bash +epilot email-settings deleteSmtpConnection \ + -p connectionId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot email-settings deleteSmtpConnection 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot email-settings deleteSmtpConnection -p connectionId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'success' +``` + +
+Sample Response + +```json +{ + "success": true, + "connection_id": "string" +} +``` + +
+ +--- + +### `testSmtpConnection` + +Re-runs a live SMTP verify against the saved configuration (EHLO + AUTH + NOOP + QUIT) + +`POST /v2/smtp/connections/{connectionId}/test` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `connectionId` | path | string | Yes | | + +**Sample Call** + +```bash +epilot email-settings testSmtpConnection \ + -p connectionId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot email-settings testSmtpConnection 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot email-settings testSmtpConnection -p connectionId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "ok", + "error": "string", + "tested_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listSmtpSenders` + +Returns every address registered to send through a custom SMTP connection. + +`GET /v2/smtp/senders` + +**Sample Call** + +```bash +epilot email-settings listSmtpSenders +``` + +With JSONata filter: + +```bash +epilot email-settings listSmtpSenders --jsonata 'senders' +``` + +
+Sample Response + +```json +{ + "senders": [ + { + "email": "user@example.com", + "connection_id": "string", + "reply_to_email": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "connected_by_user_id": "string" + } + ] +} +``` + +
+ +--- + +### `connectSmtpSender` + +Registers an address as a sender on a custom SMTP connection: + +`POST /v2/smtp/senders` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot email-settings connectSmtpSender +``` + +With request body: + +```bash +epilot email-settings connectSmtpSender \ + -d '{ + "email": "user@example.com", + "connection_id": "string", + "name": "string", + "reply_to_email": "string", + "shared_inbox_id": "default", + "user_ids": ["string"], + "group_ids": ["string"], + "default_signature_id": "string" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot email-settings connectSmtpSender +``` + +With JSONata filter: + +```bash +epilot email-settings connectSmtpSender --jsonata 'email_address' +``` + +
+Sample Response + +```json +{ + "email_address": { + "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-20T14:45:00Z", + "created_by": "user-123", + "updated_by": "user-456", + "address": "sales@yourcompany.com", + "name": "Sales Team", + "user_ids": ["user-123", "user-456"], + "group_ids": ["group-789"], + "default_signature_id": "sig-abc", + "shared_inbox_id": "inbox-xyz", + "is_active": true, + "is_primary": false, + "is_epilot_email_address": false, + "provider": "outlook" + }, + "sender": { + "email": "user@example.com", + "connection_id": "string", + "reply_to_email": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "connected_by_user_id": "string" + } +} +``` + +
+ +--- + +### `disconnectSmtpSender` + +Removes a sender address: deletes the email address and its binding to the SMTP + +`DELETE /v2/smtp/senders/{email}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `email` | path | string (email) | Yes | | + +**Sample Call** + +```bash +epilot email-settings disconnectSmtpSender \ + -p email=user@example.com +``` + +Using positional args for path parameters: + +```bash +epilot email-settings disconnectSmtpSender user@example.com +``` + +With JSONata filter: + +```bash +epilot email-settings disconnectSmtpSender -p email=user@example.com --jsonata 'email' +``` + +
+Sample Response + +```json +{ + "success": true, + "email": "user@example.com" +} +``` + +
+ +--- + +### `outlookOAuthCallback` + +Exchanges authorization code for tokens and stores them. + +`GET /v2/outlook/oauth/callback` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `code` | query | string | No | | +| `state` | query | string | Yes | | +| `session_state` | query | string | No | | +| `error` | query | string | No | | +| `error_description` | query | string | No | | +| `error_subcode` | query | string | No | | +| `client_info` | query | string | No | | +| `error_uri` | query | string | No | | | `admin_consent` | query | string | No | | | `tenant` | query | string | No | | +| `clientdata` | query | string | No | | **Sample Call** @@ -1248,7 +2095,7 @@ Retrieves settings of a specific type for the organization. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `type` | query | "signature" \| "email_domain" \| "email_address" \| "whitelist_email_address" \| "restrict_duplicates_within" | Yes | The type of settings to retrieve. Determines which category of +| `type` | query | "signature" \| "email_domain" \| "email_address" \| "whitelist_email_address" \| "restrict_duplicates_within" \| "allowed_recipient_domains" \| "auto_link_identifier_attributes" | Yes | The type of settings to retrieve. Determines which category of email settings will be returned. | | `id` | query | string | No | Optional ID to retrieve a specific setting. If omitted, all settings @@ -1280,6 +2127,8 @@ epilot email-settings getSettings -p type=signature --jsonata '$' "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1317,6 +2166,8 @@ epilot email-settings addSetting \ "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1348,6 +2199,8 @@ epilot email-settings addSetting --jsonata '$' "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1384,29 +2237,9 @@ cat body.json | epilot email-settings deleteSetting With JSONata filter: ```bash -epilot email-settings deleteSetting --jsonata 'id' -``` - -
-Sample Response - -```json -{ - "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", - "name": "Default Signature", - "org_id": "org-123", - "type": "signature", - "value": "Best regards, The Team", - "html": "

Best regards,
The Team

", - "created_at": "2024-01-15T10:30:00Z", - "updated_at": "2024-01-20T14:45:00Z", - "created_by": "user-123", - "updated_by": "user-456" -} +epilot email-settings deleteSetting --jsonata '$' ``` -
- --- ### `updateSetting` @@ -1442,6 +2275,8 @@ epilot email-settings updateSetting \ "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1478,6 +2313,8 @@ epilot email-settings updateSetting -p id=a10bd0ff-4391-4cfc-88ee-b19d718a9bf7 - "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1489,6 +2326,35 @@ epilot email-settings updateSetting -p id=a10bd0ff-4391-4cfc-88ee-b19d718a9bf7 - --- +### `getDomains` + +Retrieves all custom email domains for the organization. + +`GET /v1/email-settings/domain` + +**Sample Call** + +```bash +epilot email-settings getDomains +``` + +With JSONata filter: + +```bash +epilot email-settings getDomains --jsonata '$' +``` + +
+Sample Response + +```json +["string"] +``` + +
+ +--- + ### `addDomain` Adds a custom email domain to the organization. @@ -1528,6 +2394,8 @@ epilot email-settings addDomain --jsonata '$' "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1608,6 +2476,61 @@ epilot email-settings verifyNameServers --jsonata '$' "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-20T14:45:00Z", + "created_by": "user-123", + "updated_by": "user-456" + } +] +``` + +
+ +--- + +### `verifyDnsRecords` + +Verifies that the domain's DNS records (MX, TXT, CNAME) are correctly configured + +`POST /v1/email-settings/domain/dns-records:verify` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot email-settings verifyDnsRecords \ + -d '{"domain":"mail.yourcompany.com"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot email-settings verifyDnsRecords +``` + +With JSONata filter: + +```bash +epilot email-settings verifyDnsRecords --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", + "name": "Default Signature", + "org_id": "org-123", + "type": "signature", + "value": "Best regards, The Team", + "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1659,6 +2582,8 @@ epilot email-settings verifyDomain --jsonata '$' "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", diff --git a/docs/cli/commands/email-template.md b/docs/cli/commands/email-template.md index 382b07a7..71726b10 100644 --- a/docs/cli/commands/email-template.md +++ b/docs/cli/commands/email-template.md @@ -121,7 +121,8 @@ epilot email-template saveTemplate \ }, "system_template": false, "created_by": 1234, - "updated_by": 1234 + "updated_by": 1234, + "json_template": "string" }' ``` @@ -199,6 +200,7 @@ epilot email-template saveTemplate --jsonata '$' }, "created_by": 1234, "updated_by": 1234, + "json_template": "string", "system_template": false } ``` @@ -301,6 +303,7 @@ epilot email-template getTemplateDetail -p id=123e4567-e89b-12d3-a456-4266141740 }, "created_by": 1234, "updated_by": 1234, + "json_template": "string", "system_template": false }, "relations": [ @@ -392,7 +395,8 @@ epilot email-template updateTemplateDetail \ }, "system_template": false, "created_by": 1234, - "updated_by": 1234 + "updated_by": 1234, + "json_template": "string" }' ``` @@ -476,6 +480,7 @@ epilot email-template updateTemplateDetail -p id=123e4567-e89b-12d3-a456-4266141 }, "created_by": 1234, "updated_by": 1234, + "json_template": "string", "system_template": false } ``` @@ -610,6 +615,7 @@ epilot email-template replaceVariablesAsync --jsonata 'job_id' }, "created_by": 1234, "updated_by": 1234, + "json_template": "string", "system_template": false }, "relations": [ @@ -643,8 +649,9 @@ With request body: epilot email-template bulkSendMessage \ -d '{ "skip_creating_entities": true, + "complete_thread": false, "email_template_id": "511ceb90-f738-47aa-8b1e-915ace0ae13c", - "must_include_unsubscribe_link": true, + "must_include_unsubscribe_link": false, "recipient_query": "_schema:contact AND consent_email_marketing:active", "custom_variables": [ { @@ -675,11 +682,13 @@ epilot email-template bulkSendMessage --jsonata 'org_id' "org_id": "206801", "job_id": "8c086140-f33e-4bb7-a993-50c0f2402c7b", "skip_creating_entities": true, + "complete_thread": false, "status": "PROCESSING", "request": { "skip_creating_entities": true, + "complete_thread": false, "email_template_id": "511ceb90-f738-47aa-8b1e-915ace0ae13c", - "must_include_unsubscribe_link": true, + "must_include_unsubscribe_link": false, "recipient_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6", "3fa85f64-5717-4562-b3fc-2c963f66afa7", "3fa85f64-5717-4562-b3fc-2c963f66afa8"], "custom_variables": [ { diff --git a/docs/cli/commands/entity-mapping.md b/docs/cli/commands/entity-mapping.md index 18ac771f..43850ee8 100644 --- a/docs/cli/commands/entity-mapping.md +++ b/docs/cli/commands/entity-mapping.md @@ -93,13 +93,15 @@ epilot entity-mapping storeConfig \ "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -150,13 +152,15 @@ epilot entity-mapping storeConfig --jsonata '$' "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -230,13 +234,15 @@ epilot entity-mapping getConfig -p id=70542580-2b38-4bfc-af8d-bb90102f9f47 --jso "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -310,13 +316,15 @@ epilot entity-mapping deleteConfig -p id=70542580-2b38-4bfc-af8d-bb90102f9f47 -- "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -437,13 +445,15 @@ epilot entity-mapping storeNewVersion \ "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -500,13 +510,15 @@ epilot entity-mapping storeNewVersion -p id=70542580-2b38-4bfc-af8d-bb90102f9f47 "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -582,13 +594,15 @@ epilot entity-mapping getConfigVersion -p id=70542580-2b38-4bfc-af8d-bb90102f9f4 "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -641,6 +655,10 @@ epilot entity-mapping executeMapping \ "entity_id": "string", "entity_schema": "submission" }, + "loop_ref": { + "entity_id": "string", + "entity_schema": "submission" + }, "targets": [ { "id": "string", @@ -648,66 +666,15 @@ epilot entity-mapping executeMapping \ "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ] }' @@ -808,13 +775,15 @@ epilot entity-mapping searchConfigs --jsonata '$' "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -909,6 +878,7 @@ epilot entity-mapping executeRelations \ "target": "string", "target_tags": ["string"], "target_tags_include_source": false, + "target_entity_tags": ["string"], "override_with_source_filter": false, "source_filter": { "limit": 0, @@ -1019,13 +989,15 @@ epilot entity-mapping getMappingConfig -p id=70542580-2b38-4bfc-af8d-bb90102f9f4 "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -1090,13 +1062,15 @@ epilot entity-mapping putMappingConfig \ "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -1153,13 +1127,15 @@ epilot entity-mapping putMappingConfig -p id=70542580-2b38-4bfc-af8d-bb90102f9f4 "allow_failure": true, "target_schema": "string", "target_unique": ["string"], + "use_uniqueness_criteria": false, "loop_config": {}, "conditionMode": "oneOf", "conditions": [], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", diff --git a/docs/cli/commands/entity-ui.md b/docs/cli/commands/entity-ui.md new file mode 100644 index 00000000..a0d9da0f --- /dev/null +++ b/docs/cli/commands/entity-ui.md @@ -0,0 +1,209 @@ +--- +title: "Entity UI API" +description: "epilot CLI commands for the Entity UI API: quick start, common flags and every operation, callable from the command line." +--- + +# Entity UI API + +- **Base URL:** `https://entity-ui.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/entity-ui](https://docs.epilot.io/api/entity-ui) + +Stores the definitions of AI widgets rendered on entity pages. + +## Quick Start + +```bash +# List available operations +epilot entity-ui + +# Call an operation +epilot entity-ui putWidgetDefinition +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Widget Definitions** +- [`putWidgetDefinition`](#putwidgetdefinition) — Stores a widget definition and returns its `ref`. +- [`getWidgetDefinition`](#getwidgetdefinition) — Returns a stored widget definition in its canonical form. +- [`batchGetWidgetDefinitions`](#batchgetwidgetdefinitions) — Returns up to 20 stored widget definitions by `ref`. Refs that are not stored in the organization are + +### `putWidgetDefinition` + +Stores a widget definition and returns its `ref`. + +`PUT /v1/entity-ui/widget-definitions` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot entity-ui putWidgetDefinition +``` + +With request body: + +```bash +epilot entity-ui putWidgetDefinition \ + -d '{ + "version": 1, + "prompt": "string", + "manifest": { + "relations": {}, + "libs": ["echarts"], + "icons": ["string"] + }, + "html": "string", + "strings": { + "de": {}, + "en": {} + }, + "suggestions": { + "de": ["string"], + "en": ["string"] + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot entity-ui putWidgetDefinition +``` + +With JSONata filter: + +```bash +epilot entity-ui putWidgetDefinition --jsonata 'ref' +``` + +
+Sample Response + +```json +{ + "ref": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" +} +``` + +
+ +--- + +### `getWidgetDefinition` + +Returns a stored widget definition in its canonical form. + +`GET /v1/entity-ui/widget-definitions/{ref}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `ref` | path | string | Yes | Lowercase hex SHA-256 of the definition's RFC 8785 canonical JSON | + +**Sample Call** + +```bash +epilot entity-ui getWidgetDefinition \ + -p ref=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 +``` + +Using positional args for path parameters: + +```bash +epilot entity-ui getWidgetDefinition 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 +``` + +With JSONata filter: + +```bash +epilot entity-ui getWidgetDefinition -p ref=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 --jsonata 'version' +``` + +
+Sample Response + +```json +{ + "version": 1, + "prompt": "string", + "manifest": { + "relations": {}, + "libs": ["echarts"], + "icons": ["string"] + }, + "html": "string", + "strings": { + "de": {}, + "en": {} + }, + "suggestions": { + "de": ["string"], + "en": ["string"] + } +} +``` + +
+ +--- + +### `batchGetWidgetDefinitions` + +Returns up to 20 stored widget definitions by `ref`. Refs that are not stored in the organization are + +`POST /v1/entity-ui/widget-definitions/batch-get` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot entity-ui batchGetWidgetDefinitions \ + -d '{"refs":["9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot entity-ui batchGetWidgetDefinitions +``` + +With JSONata filter: + +```bash +epilot entity-ui batchGetWidgetDefinitions --jsonata 'definitions' +``` + +
+Sample Response + +```json +{ + "definitions": {}, + "missing": ["9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"] +} +``` + +
+ +--- diff --git a/docs/cli/commands/entity.md b/docs/cli/commands/entity.md index 43ee3730..32c14f2a 100644 --- a/docs/cli/commands/entity.md +++ b/docs/cli/commands/entity.md @@ -42,8 +42,9 @@ epilot entity listSchemas **Schemas** - [`listSchemas`](#listschemas) — Get the latest versions of all schemas -- [`getSchema`](#getschema) — By default gets the latest version of the Schema and to get the specific version of schema pass the id. -- [`putSchema`](#putschema) — Create or update a schema with a new version +- [`listSchemasV2`](#listschemasv2) — Get the latest versions of all schemas. +- [`getSchema`](#getschema) — Gets the latest version of the Schema. +- [`putSchema`](#putschema) — Create or update a schema with a new version. - [`deleteSchema`](#deleteschema) — Delete a schema, or a specific version of a schema - [`getJsonSchema`](#getjsonschema) — Get formal JSON schema definition draft 2020-12 for the given epilot schema - [`getSchemaExample`](#getschemaexample) — Get a full example entity for the given schema @@ -85,6 +86,9 @@ epilot entity listSchemas - [`deleteEntity`](#deleteentity) — Deletes an Entity - [`autocomplete`](#autocomplete) — Autocomplete entity attributes - [`wipeAllEntities`](#wipeallentities) — Creates a request to queue the deletion of all entities in the system. This is a destructive operation and should only b +- [`applyChangeset`](#applychangeset) — Applies the proposed value from a pending changeset to the entity attribute +- [`dismissChangeset`](#dismisschangeset) — Removes a pending changeset without applying it. The attribute value remains unchanged. +- [`listChangesets`](#listchangesets) — Returns all pending changesets for an entity. **Activity** - [`createActivity`](#createactivity) — Create an activity that can be displayed in activity feeds. @@ -105,6 +109,7 @@ epilot entity listSchemas **Import-Export** - [`exportEntities`](#exportentities) — Export entity data in a CSV-format. The export will export data as close as possible to what is visible on Entity UI tab - [`importEntities`](#importentities) — This endpoint enables the import of entities into the platform. +- [`abortEntityImport`](#abortentityimport) — Asks a running import to stop. Rows already imported are **kept** - this is a stop, not a **Saved Views** - [`listSavedViews`](#listsavedviews) — Get the Saved Views based on the schema @@ -146,7 +151,10 @@ Get the latest versions of all schemas | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `unpublished` | query | boolean | No | Return unpublished draft schemas | +| `latest` | query | boolean | No | No longer has any effect: schema freezing is retired and the latest version is always returned. + | | `exclude` | query | string[] | No | List of schema slugs to exclude from the results. Accepts a comma-separated list of slugs to exclude from the results. | +| `include` | query | string[] | No | List of schema slugs to include in the results. When provided, only these schemas are returned. Accepts a comma-separated list of slugs. | **Sample Call** @@ -172,6 +180,87 @@ epilot entity listSchemas --jsonata 'results[0]' "updated_at": "string", "comment": "string", "source": {}, + "frozen": true, + "latest": true, + "_summary": true, + "slug": "contact", + "version": 1, + "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "feature_flag": "FF_MY_FEATURE_FLAG", + "enable_setting": ["360_features"], + "name": "Contact", + "plural": "Contacts", + "description": "Example description", + "docs_url": "https://docs.epilot.io/docs/pricing/entities", + "category": "customer_relations", + "published": false, + "draft": false, + "icon": "person", + "title_template": "{{first_name}} {{last_name}}", + "ui_config": {}, + "capabilities": [], + "group_settings": [], + "layout_settings": {}, + "dialog_config": {}, + "attributes": [], + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "explicit_search_mappings": {}, + "group_headlines": [], + "conditions": [] + } + ] +} +``` + +
+ +--- + +### `listSchemasV2` + +Get the latest versions of all schemas. + +`GET /v2/entity/schemas` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `full` | query | boolean | No | Return full schemas including all attributes and capabilities | +| `unpublished` | query | boolean | No | Return unpublished draft schemas | +| `latest` | query | boolean | No | No longer has any effect: schema freezing is retired and the latest version is always returned. + | +| `exclude` | query | string[] | No | List of schema slugs to exclude from the results. Accepts a comma-separated list of slugs to exclude from the results. | +| `include` | query | string[] | No | List of schema slugs to include in the results. When provided, only these schemas are returned. Accepts a comma-separated list of slugs. | + +**Sample Call** + +```bash +epilot entity listSchemasV2 +``` + +With JSONata filter: + +```bash +epilot entity listSchemasV2 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "created_at": "string", + "updated_at": "string", + "comment": "string", + "source": {}, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -193,8 +282,10 @@ epilot entity listSchemas --jsonata 'results[0]' "dialog_config": {}, "attributes": [], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": {}, - "group_headlines": [] + "group_headlines": [], + "conditions": [] } ] } @@ -206,7 +297,7 @@ epilot entity listSchemas --jsonata 'results[0]' ### `getSchema` -By default gets the latest version of the Schema and to get the specific version of schema pass the id. +Gets the latest version of the Schema. `GET /v1/entity/schemas/{slug}` @@ -216,6 +307,8 @@ By default gets the latest version of the Schema and to get the specific version | ---- | -- | ---- | -------- | ----------- | | `slug` | path | string | Yes | Entity Type | | `id` | query | string (uuid) | No | | +| `latest` | query | boolean | No | No longer has any effect: schema freezing is retired and the latest version is always returned. + | **Sample Call** @@ -249,6 +342,9 @@ epilot entity getSchema -p slug=contact --jsonata '$' "id": "string", "type": "string" }, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -292,6 +388,20 @@ epilot entity getSchema -p slug=contact --jsonata '$' }, "sharing": { "show_sharing_button": true + }, + "grid_layout": { + "id": "string", + "columns": 0, + "cells": [0] + }, + "widget_order": ["string"], + "widget_visibility": { + "next_best_action": true, + "address_map": false + }, + "widget_widths": { + "address_map": "full_width", + "recent_communications": "one_third_width" } }, "capabilities": [ @@ -300,13 +410,16 @@ epilot entity getSchema -p slug=contact --jsonata '$' "name": "customer_messaging", "title": "Messaging", "attributes": [], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": {}, "ui_config": {}, "ui_hooks": [], "feature_flag": "FF_MY_FEATURE_FLAG", - "settings_flag": [] + "settings_flag": [], + "schemas": [] } ], "group_settings": [ @@ -343,6 +456,7 @@ epilot entity getSchema -p slug=contact --jsonata '$' } ], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": { "image": { "type": "keyword", @@ -363,6 +477,14 @@ epilot entity getSchema -p slug=contact --jsonata '$' "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } + ], + "conditions": [ + { + "id": "d5839b94-ba20-4225-a78e-76951d352bd6", + "name": "delivery_area", + "label": "Delivery Area", + "type": "string" + } ] } ``` @@ -373,7 +495,7 @@ epilot entity getSchema -p slug=contact --jsonata '$' ### `putSchema` -Create or update a schema with a new version +Create or update a schema with a new version. `PUT /v1/entity/schemas/{slug}` @@ -442,6 +564,20 @@ epilot entity putSchema \ }, "sharing": { "show_sharing_button": true + }, + "grid_layout": { + "id": "string", + "columns": 0, + "cells": [0] + }, + "widget_order": ["string"], + "widget_visibility": { + "next_best_action": true, + "address_map": false + }, + "widget_widths": { + "address_map": "full_width", + "recent_communications": "one_third_width" } }, "capabilities": [ @@ -450,13 +586,16 @@ epilot entity putSchema \ "name": "customer_messaging", "title": "Messaging", "attributes": [], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": {}, "ui_config": {}, "ui_hooks": [], "feature_flag": "FF_MY_FEATURE_FLAG", - "settings_flag": [] + "settings_flag": [], + "schemas": [] } ], "group_settings": [ @@ -493,6 +632,7 @@ epilot entity putSchema \ } ], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": { "image": { "type": "keyword", @@ -513,6 +653,14 @@ epilot entity putSchema \ "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } + ], + "conditions": [ + { + "id": "d5839b94-ba20-4225-a78e-76951d352bd6", + "name": "delivery_area", + "label": "Delivery Area", + "type": "string" + } ] }' ``` @@ -548,6 +696,9 @@ epilot entity putSchema -p slug=contact --jsonata '$' "id": "string", "type": "string" }, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -591,6 +742,20 @@ epilot entity putSchema -p slug=contact --jsonata '$' }, "sharing": { "show_sharing_button": true + }, + "grid_layout": { + "id": "string", + "columns": 0, + "cells": [0] + }, + "widget_order": ["string"], + "widget_visibility": { + "next_best_action": true, + "address_map": false + }, + "widget_widths": { + "address_map": "full_width", + "recent_communications": "one_third_width" } }, "capabilities": [ @@ -599,13 +764,16 @@ epilot entity putSchema -p slug=contact --jsonata '$' "name": "customer_messaging", "title": "Messaging", "attributes": [], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": {}, "ui_config": {}, "ui_hooks": [], "feature_flag": "FF_MY_FEATURE_FLAG", - "settings_flag": [] + "settings_flag": [], + "schemas": [] } ], "group_settings": [ @@ -642,6 +810,7 @@ epilot entity putSchema -p slug=contact --jsonata '$' } ], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": { "image": { "type": "keyword", @@ -662,6 +831,14 @@ epilot entity putSchema -p slug=contact --jsonata '$' "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } + ], + "conditions": [ + { + "id": "d5839b94-ba20-4225-a78e-76951d352bd6", + "name": "delivery_area", + "label": "Delivery Area", + "type": "string" + } ] } ``` @@ -940,6 +1117,9 @@ epilot entity getSchemaVersions -p slug=contact --jsonata 'versions' "updated_at": "string", "comment": "string", "source": {}, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -961,8 +1141,10 @@ epilot entity getSchemaVersions -p slug=contact --jsonata 'versions' "dialog_config": {}, "attributes": [], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": {}, - "group_headlines": [] + "group_headlines": [], + "conditions": [] } ], "drafts": [ @@ -972,6 +1154,9 @@ epilot entity getSchemaVersions -p slug=contact --jsonata 'versions' "updated_at": "string", "comment": "string", "source": {}, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -993,12 +1178,15 @@ epilot entity getSchemaVersions -p slug=contact --jsonata 'versions' "dialog_config": {}, "attributes": [], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": {}, - "group_headlines": [] + "group_headlines": [], + "conditions": [] } ], "versions_more": true, - "drafts_more": true + "drafts_more": true, + "frozen_version": "3fa85f64-5717-4562-b3fc-2c963f66afa6" } ``` @@ -1048,13 +1236,16 @@ epilot entity listAvailableCapabilities -p slug=contact --jsonata 'results[0]' "name": "customer_messaging", "title": "Messaging", "attributes": [], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": {}, "ui_config": {}, "ui_hooks": [], "feature_flag": "FF_MY_FEATURE_FLAG", - "settings_flag": [] + "settings_flag": [], + "schemas": [] } ] } @@ -1094,6 +1285,9 @@ epilot entity listSchemaBlueprints --jsonata 'results[0]' "updated_at": "string", "comment": "string", "source": {}, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -1115,8 +1309,10 @@ epilot entity listSchemaBlueprints --jsonata 'results[0]' "dialog_config": {}, "attributes": [], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": {}, - "group_headlines": [] + "group_headlines": [], + "conditions": [] } ] } @@ -1151,6 +1347,7 @@ epilot entity searchEntities \ "from": 0, "size": 10, "hydrate": false, + "anonymize": false, "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"], "aggs": { "contact-count-per-tag": { @@ -1276,6 +1473,7 @@ epilot entity listEntities \ "from": 0, "size": 10, "hydrate": false, + "anonymize": false, "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"], "aggs": { "contact-count-per-tag": { @@ -1405,7 +1603,8 @@ epilot entity queryEntityGraph \ } ] }, - "hydrate": false + "hydrate": false, + "apply_changesets": false }' ``` @@ -1871,7 +2070,12 @@ Gets Entity by id. | `id` | path | string (uuid) | Yes | Entity id | | `slug` | path | string | Yes | Entity Type | | `hydrate` | query | boolean | No | When true, enables entity hydration to resolve nested $relation & $relation_ref references in-place. | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | | `fields` | query | string[] | No | List of entity fields to include in results | +| `apply_changesets` | query | boolean | No | When true, applies pending changeset proposed values in-place on the response entity. +The response includes both the hydrated values and the raw _changesets field. +Does not mutate stored data — pure r | **Sample Call** @@ -2081,6 +2285,8 @@ Gets Entity and relations by id. | `id` | path | string (uuid) | Yes | Entity id | | `slug` | path | string | Yes | Entity Type | | `hydrate` | query | boolean | No | When true, enables entity hydration to resolve nested $relation & $relation_ref references in-place. | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | **Sample Call** @@ -2174,6 +2380,9 @@ Pending state on activity is automatically ended when activity is filled. | | `async` | query | boolean | No | Don't wait for updated entity to become available in Search API. Useful for large migrations | | `validate` | query | boolean | No | When true, enables entity validation against the entity schema. | +| `direct` | query | boolean | No | When true, bypasses changeset interception: attribute values in the payload +are written directly to the entity regardless of each attribute's `edit_mode`. +The write always lands, independently of any | **Request Body** @@ -2280,6 +2489,9 @@ Pending state on activity is automatically ended when activity is filled. | `dry_run` | query | boolean | No | Dry Run mode = return results but does not perform the operation. | | `async` | query | boolean | No | Don't wait for updated entity to become available in Search API. Useful for large migrations | | `validate` | query | boolean | No | When true, enables entity validation against the entity schema. | +| `direct` | query | boolean | No | When true, bypasses changeset interception: attribute values in the payload +are written directly to the entity regardless of each attribute's `edit_mode`. +The write always lands, independently of any | **Request Body** (required) @@ -2414,6 +2626,8 @@ Autocomplete entity attributes | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | | `input` | query | string | No | Input to autocomplete | | `attribute` | query | string | Yes | Autocomplete attribute | | `slug` | query | string | No | Limit results to entity schema | @@ -2580,6 +2794,8 @@ Get activity by id | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | | `id` | path | string (ulid) | Yes | Activity Id | | `operations_size` | query | number | No | Maximum number of operations to include in response (default: 10) | @@ -2637,7 +2853,10 @@ epilot entity getActivity -p id=01F130Q52Q6MWSNS8N2AVXV4JN --jsonata '$' "operation": "createEntity", "params": {}, "payload": {}, - "diff": {} + "diff": {}, + "source_context": {}, + "_workflow_origin": {}, + "_automation_chain": ["string"] } ] } @@ -2724,6 +2943,191 @@ epilot entity attachActivity -p id=01F130Q52Q6MWSNS8N2AVXV4JN --jsonata '$' --- +### `applyChangeset` + +Applies the proposed value from a pending changeset to the entity attribute + +`POST /v1/entity/{slug}/{id}/changesets/{attribute}:apply` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | string | Yes | Entity Type | +| `id` | path | string (uuid) | Yes | Entity id | +| `attribute` | path | string | Yes | Attribute name of the changeset to apply | + +**Sample Call** + +```bash +epilot entity applyChangeset \ + -p slug=contact \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -p attribute=example +``` + +Using positional args for path parameters: + +```bash +epilot entity applyChangeset contact 123e4567-e89b-12d3-a456-426614174000 example +``` + +With JSONata filter: + +```bash +epilot entity applyChangeset -p slug=contact -p id=123e4567-e89b-12d3-a456-426614174000 -p attribute=example --jsonata '$' +``` + +
+Sample Response + +```json +{ + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_schema": "contact", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "_acl": { + "view": ["org:456", "org:789"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] +} +``` + +
+ +--- + +### `dismissChangeset` + +Removes a pending changeset without applying it. The attribute value remains unchanged. + +`POST /v1/entity/{slug}/{id}/changesets/{attribute}:dismiss` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | string | Yes | Entity Type | +| `id` | path | string (uuid) | Yes | Entity id | +| `attribute` | path | string | Yes | Attribute name of the changeset to dismiss | + +**Request Body** + +**Sample Call** + +```bash +epilot entity dismissChangeset \ + -p slug=contact \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -p attribute=example \ + -d '{"reason":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot entity dismissChangeset contact 123e4567-e89b-12d3-a456-426614174000 example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot entity dismissChangeset -p slug=contact -p id=123e4567-e89b-12d3-a456-426614174000 -p attribute=example +``` + +With JSONata filter: + +```bash +epilot entity dismissChangeset -p slug=contact -p id=123e4567-e89b-12d3-a456-426614174000 -p attribute=example --jsonata '$' +``` + +
+Sample Response + +```json +{ + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_schema": "contact", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "_acl": { + "view": ["org:456", "org:789"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] +} +``` + +
+ +--- + +### `listChangesets` + +Returns all pending changesets for an entity. + +`GET /v1/entity/{slug}/{id}/changesets` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | +| `slug` | path | string | Yes | Entity Type | +| `id` | path | string (uuid) | Yes | Entity id | + +**Sample Call** + +```bash +epilot entity listChangesets \ + -p slug=contact \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot entity listChangesets contact 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot entity listChangesets -p slug=contact -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{} +``` + +
+ +--- + ### `getEntityActivityFeed` Get activity feed for an entity @@ -2734,6 +3138,8 @@ Get activity feed for an entity | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | | `slug` | path | string | Yes | Entity Type | | `id` | path | string (uuid) | Yes | Entity id | | `after` | query | string (date-time) | No | Get activities strictly after this timestamp. Cannot be used with 'before', 'start_date', 'end_date', or 'preset_range'. | @@ -2807,6 +3213,8 @@ Returns 1st level direct relations for an entity. | `slug` | path | string | Yes | Entity Type | | `id` | path | string (uuid) | Yes | Entity id | | `hydrate` | query | boolean | No | When true, enables entity hydration to resolve nested $relation & $relation_ref references in-place. | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | | `include_reverse` | query | boolean | No | When true, includes reverse relations in response (other entities pointing to this entity) | | `from` | query | number | No | Starting page number | | `size` | query | number | No | Number of results to return per page | @@ -3028,6 +3436,8 @@ Returns 1st level direct relations for an entity with pagination. | `slug` | path | string | Yes | Entity Type | | `id` | path | string (uuid) | Yes | Entity id | | `hydrate` | query | boolean | No | When true, enables entity hydration to resolve nested $relation & $relation_ref references in-place. | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | | `query` | query | string | No | Input to filter search results | | `include_reverse` | query | boolean | No | When true, includes reverse relations in response (other entities pointing to this entity) | | `from` | query | number | No | Starting page number | @@ -3110,6 +3520,8 @@ Returns 1st level direct relations for an entity with pagination. | `slug` | path | string | Yes | Entity Type | | `id` | path | string (uuid) | Yes | Entity id | | `hydrate` | query | boolean | No | When true, enables entity hydration to resolve nested $relation & $relation_ref references in-place. | +| `anonymize` | query | boolean | No | When true, anonymizes PII in the response: identifiers (names, emails, phone numbers, IBANs) are replaced +with deterministic pseudonyms (stable within an org), addresses are generalized to postal code | | `include_reverse` | query | boolean | No | When true, includes reverse relations in response (other entities pointing to this entity) *It gets overriden by mode query parameter.* | @@ -3377,6 +3789,7 @@ epilot entity exportEntities \ "from": 0, "size": 10, "hydrate": false, + "anonymize": false, "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"], "aggs": { "contact-count-per-tag": { @@ -3442,6 +3855,35 @@ epilot entity importEntities --jsonata '$' --- +### `abortEntityImport` + +Asks a running import to stop. Rows already imported are **kept** - this is a stop, not a + +`POST /v1/entity:abortImport` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `job_id` | query | string | Yes | The ID of the import job to stop. | +| `schema` | query | string | Yes | Slug of the schema being imported, used to authorize the caller. | + +**Sample Call** + +```bash +epilot entity abortEntityImport \ + -p job_id=abc123 \ + -p schema=example +``` + +With JSONata filter: + +```bash +epilot entity abortEntityImport -p job_id=abc123 -p schema=example --jsonata '$' +``` + +--- + ### `listSavedViews` Get the Saved Views based on the schema @@ -3456,6 +3898,7 @@ Get the Saved Views based on the schema | `sort` | query | string | No | The sort key to use if present | | `from` | query | number | No | | | `size` | query | number | No | Number of saved views to return | +| `q` | query | string | No | Free-text search on the saved view name (case-insensitive) | | `fields` | query | string[] | No | | **Sample Call** @@ -3487,7 +3930,8 @@ epilot entity listSavedViews --jsonata 'results[0]' "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3538,7 +3982,8 @@ epilot entity createSavedView \ "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3584,7 +4029,8 @@ epilot entity createSavedView --jsonata '$' "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3653,7 +4099,8 @@ epilot entity getSavedView -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3713,7 +4160,8 @@ epilot entity updateSavedView \ "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3765,7 +4213,8 @@ epilot entity updateSavedView -p id=123e4567-e89b-12d3-a456-426614174000 --jsona "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3822,7 +4271,8 @@ epilot entity patchSavedView \ "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3874,7 +4324,8 @@ epilot entity patchSavedView -p id=123e4567-e89b-12d3-a456-426614174000 --jsonat "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3965,7 +4416,8 @@ epilot entity listFavoriteViewsForUser --jsonata 'results[0]' "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -4417,7 +4869,7 @@ epilot entity updateClassificationsForTaxonomy -p taxonomySlug=example --jsonata "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } ], - "deleted": {} + "deleted": ["taxonomy-slug:classification-slug"] } ``` @@ -4765,6 +5217,8 @@ List taxonomy classifications in an organization based on taxonomy slug | `query` | query | string | No | The label names to search for (lowercase insensitive) | | `archived` | query | boolean | No | Filter by archived status. Deprecated. Use `include_archived` instead. | | `include_archived` | query | "true" \| "false" \| "only" | No | | +| `exclude_types` | query | "relation" \| "schema" \| "system" \| "relation" \| "schema" \| "system"[] | No | Taxonomy type(s) to exclude from the results. Useful to filter out relation labels, schema labels, and system labels. + | **Request Body** @@ -5180,6 +5634,7 @@ epilot entity createSchemaAttribute \ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5187,6 +5642,7 @@ epilot entity createSchemaAttribute \ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -5213,6 +5669,23 @@ epilot entity createSchemaAttribute \ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -5247,6 +5720,7 @@ epilot entity createSchemaAttribute --jsonata '$' "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5254,6 +5728,7 @@ epilot entity createSchemaAttribute --jsonata '$' "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -5280,6 +5755,23 @@ epilot entity createSchemaAttribute --jsonata '$' "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -5337,6 +5829,7 @@ epilot entity getSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9188 "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5344,6 +5837,7 @@ epilot entity getSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9188 "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -5370,6 +5864,23 @@ epilot entity getSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9188 "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -5418,6 +5929,7 @@ epilot entity putSchemaAttribute \ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5425,6 +5937,7 @@ epilot entity putSchemaAttribute \ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -5451,6 +5964,23 @@ epilot entity putSchemaAttribute \ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -5491,6 +6021,7 @@ epilot entity putSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9188 "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5498,6 +6029,7 @@ epilot entity putSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9188 "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -5524,6 +6056,23 @@ epilot entity putSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9188 "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -5581,6 +6130,7 @@ epilot entity deleteSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9 "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5588,6 +6138,7 @@ epilot entity deleteSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9 "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -5614,6 +6165,23 @@ epilot entity deleteSchemaAttribute -p composite_id=contact:97644baa-083f-4e49-9 "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -5659,6 +6227,7 @@ epilot entity createSchemaCapability \ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5666,6 +6235,7 @@ epilot entity createSchemaCapability \ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -5680,6 +6250,8 @@ epilot entity createSchemaCapability \ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -5696,6 +6268,7 @@ epilot entity createSchemaCapability \ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5703,6 +6276,7 @@ epilot entity createSchemaCapability \ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -5717,12 +6291,18 @@ epilot entity createSchemaCapability \ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -5739,7 +6319,10 @@ epilot entity createSchemaCapability \ "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -5749,6 +6332,11 @@ epilot entity createSchemaCapability \ "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" }' @@ -5786,6 +6374,7 @@ epilot entity createSchemaCapability --jsonata '$' "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5793,6 +6382,7 @@ epilot entity createSchemaCapability --jsonata '$' "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -5807,6 +6397,8 @@ epilot entity createSchemaCapability --jsonata '$' "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -5823,6 +6415,7 @@ epilot entity createSchemaCapability --jsonata '$' "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5830,6 +6423,7 @@ epilot entity createSchemaCapability --jsonata '$' "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -5844,12 +6438,18 @@ epilot entity createSchemaCapability --jsonata '$' "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -5866,7 +6466,10 @@ epilot entity createSchemaCapability --jsonata '$' "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -5876,6 +6479,11 @@ epilot entity createSchemaCapability --jsonata '$' "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" } @@ -5936,6 +6544,7 @@ epilot entity getSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5943,6 +6552,7 @@ epilot entity getSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -5957,6 +6567,8 @@ epilot entity getSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -5973,6 +6585,7 @@ epilot entity getSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -5980,6 +6593,7 @@ epilot entity getSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -5994,12 +6608,18 @@ epilot entity getSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -6016,7 +6636,10 @@ epilot entity getSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -6026,6 +6649,11 @@ epilot entity getSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" } @@ -6077,6 +6705,7 @@ epilot entity putSchemaCapability \ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -6084,6 +6713,7 @@ epilot entity putSchemaCapability \ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -6098,6 +6728,8 @@ epilot entity putSchemaCapability \ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -6114,6 +6746,7 @@ epilot entity putSchemaCapability \ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -6121,6 +6754,7 @@ epilot entity putSchemaCapability \ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -6135,12 +6769,18 @@ epilot entity putSchemaCapability \ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -6157,7 +6797,10 @@ epilot entity putSchemaCapability \ "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -6167,6 +6810,11 @@ epilot entity putSchemaCapability \ "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" }' @@ -6210,6 +6858,7 @@ epilot entity putSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -6217,6 +6866,7 @@ epilot entity putSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -6231,6 +6881,8 @@ epilot entity putSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -6247,6 +6899,7 @@ epilot entity putSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -6254,6 +6907,7 @@ epilot entity putSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -6268,12 +6922,18 @@ epilot entity putSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -6290,7 +6950,10 @@ epilot entity putSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -6300,6 +6963,11 @@ epilot entity putSchemaCapability -p composite_id=contact:97644baa-083f-4e49-918 "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" } @@ -6360,6 +7028,7 @@ epilot entity deleteSchemaCapability -p composite_id=contact:97644baa-083f-4e49- "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -6367,6 +7036,7 @@ epilot entity deleteSchemaCapability -p composite_id=contact:97644baa-083f-4e49- "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -6381,6 +7051,8 @@ epilot entity deleteSchemaCapability -p composite_id=contact:97644baa-083f-4e49- "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -6397,6 +7069,7 @@ epilot entity deleteSchemaCapability -p composite_id=contact:97644baa-083f-4e49- "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -6404,6 +7077,7 @@ epilot entity deleteSchemaCapability -p composite_id=contact:97644baa-083f-4e49- "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -6418,12 +7092,18 @@ epilot entity deleteSchemaCapability -p composite_id=contact:97644baa-083f-4e49- "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -6440,7 +7120,10 @@ epilot entity deleteSchemaCapability -p composite_id=contact:97644baa-083f-4e49- "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -6450,6 +7133,11 @@ epilot entity deleteSchemaCapability -p composite_id=contact:97644baa-083f-4e49- "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" } diff --git a/docs/cli/commands/environments.md b/docs/cli/commands/environments.md index 471e861d..944842e8 100644 --- a/docs/cli/commands/environments.md +++ b/docs/cli/commands/environments.md @@ -42,9 +42,12 @@ epilot environments listEnvironmentVariables **environments** - [`listEnvironmentVariables`](#listenvironmentvariables) — List all environment variables for the organization. Returns metadata only, no secret values. -- [`createEnvironmentVariable`](#createenvironmentvariable) — Create a new environment variable or secret for the organization. -- [`getEnvironmentVariable`](#getenvironmentvariable) — Get an environment variable by key. Returns value only for String type, omitted for SecretString. -- [`updateEnvironmentVariable`](#updateenvironmentvariable) — Create or update an environment variable. Acts as an upsert — creates the variable if it does not exist. +- [`createEnvironmentVariable`](#createenvironmentvariable) — Create a new environment variable or secret for the organization. If `group` is provided and the group does not yet exis +- [`listEnvironmentGroups`](#listenvironmentgroups) — List all environment groups for the organization. +- [`putEnvironmentGroup`](#putenvironmentgroup) — Create or update an environment group by name. Acts as an upsert — creates the group if it does not exist. +- [`deleteEnvironmentGroup`](#deleteenvironmentgroup) — Deletes a group. Variables assigned to this group become ungrouped. +- [`getEnvironmentVariable`](#getenvironmentvariable) — Get an environment variable by key. Returns value for non-secret types, omitted for SecretString. +- [`updateEnvironmentVariable`](#updateenvironmentvariable) — Create or update an environment variable. Acts as an upsert — creates the variable if it does not exist. If `group` is p - [`deleteEnvironmentVariable`](#deleteenvironmentvariable) — Delete an environment variable by key. ### `listEnvironmentVariables` @@ -74,8 +77,11 @@ epilot environments listEnvironmentVariables --jsonata 'items[0]' { "key": "string", "type": "String", + "item_type": "String", "description": "string", + "group": "string", "value": "string", + "protected": true, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z" } @@ -89,7 +95,7 @@ epilot environments listEnvironmentVariables --jsonata 'items[0]' ### `createEnvironmentVariable` -Create a new environment variable or secret for the organization. +Create a new environment variable or secret for the organization. If `group` is provided and the group does not yet exis `POST /v1/environments` @@ -99,7 +105,7 @@ Create a new environment variable or secret for the organization. ```bash epilot environments createEnvironmentVariable \ - -d '{"key":"string","type":"String","description":"string","value":"string"}' + -d '{"key":"string","type":"String","description":"string","group":"string","value":"string","protected":true}' ``` Using stdin pipe: @@ -121,8 +127,11 @@ epilot environments createEnvironmentVariable --jsonata 'key' { "key": "string", "type": "String", + "item_type": "String", "description": "string", + "group": "string", "value": "string", + "protected": true, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z" } @@ -132,9 +141,136 @@ epilot environments createEnvironmentVariable --jsonata 'key' --- +### `listEnvironmentGroups` + +List all environment groups for the organization. + +`GET /v1/environments/groups` + +**Sample Call** + +```bash +epilot environments listEnvironmentGroups +``` + +With JSONata filter: + +```bash +epilot environments listEnvironmentGroups --jsonata 'items[0]' +``` + +
+Sample Response + +```json +{ + "items": [ + { + "name": "string", + "description": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `putEnvironmentGroup` + +Create or update an environment group by name. Acts as an upsert — creates the group if it does not exist. + +`PUT /v1/environments/groups/{name}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `name` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot environments putEnvironmentGroup \ + -p name=example \ + -d '{"description":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot environments putEnvironmentGroup example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot environments putEnvironmentGroup -p name=example +``` + +With JSONata filter: + +```bash +epilot environments putEnvironmentGroup -p name=example --jsonata 'name' +``` + +
+Sample Response + +```json +{ + "name": "string", + "description": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteEnvironmentGroup` + +Deletes a group. Variables assigned to this group become ungrouped. + +`DELETE /v1/environments/groups/{name}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `name` | path | string | Yes | | + +**Sample Call** + +```bash +epilot environments deleteEnvironmentGroup \ + -p name=example +``` + +Using positional args for path parameters: + +```bash +epilot environments deleteEnvironmentGroup example +``` + +With JSONata filter: + +```bash +epilot environments deleteEnvironmentGroup -p name=example --jsonata '$' +``` + +--- + ### `getEnvironmentVariable` -Get an environment variable by key. Returns value only for String type, omitted for SecretString. +Get an environment variable by key. Returns value for non-secret types, omitted for SecretString. `GET /v1/environments/{key}` @@ -170,8 +306,11 @@ epilot environments getEnvironmentVariable -p key=example --jsonata 'key' { "key": "string", "type": "String", + "item_type": "String", "description": "string", + "group": "string", "value": "string", + "protected": true, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z" } @@ -183,7 +322,7 @@ epilot environments getEnvironmentVariable -p key=example --jsonata 'key' ### `updateEnvironmentVariable` -Create or update an environment variable. Acts as an upsert — creates the variable if it does not exist. +Create or update an environment variable. Acts as an upsert — creates the variable if it does not exist. If `group` is p `PUT /v1/environments/{key}` @@ -200,7 +339,7 @@ Create or update an environment variable. Acts as an upsert — creates the vari ```bash epilot environments updateEnvironmentVariable \ -p key=example \ - -d '{"type":"String","value":"string","description":"string"}' + -d '{"type":"String","value":"string","description":"string","group":"string","protected":true}' ``` Using positional args for path parameters: @@ -228,8 +367,11 @@ epilot environments updateEnvironmentVariable -p key=example --jsonata 'key' { "key": "string", "type": "String", + "item_type": "String", "description": "string", + "group": "string", "value": "string", + "protected": true, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z" } diff --git a/docs/cli/commands/erp-integration.md b/docs/cli/commands/erp-integration.md deleted file mode 100644 index cfbce798..00000000 --- a/docs/cli/commands/erp-integration.md +++ /dev/null @@ -1,2319 +0,0 @@ ---- -title: "ERP Integration API" -description: "epilot CLI commands for the ERP Integration API: quick start, common flags and every operation, callable from the command line." ---- - -# ERP Integration API - -- **Base URL:** `https://erp-integration-api.sls.epilot.io` -- **API Docs:** [https://docs.epilot.io/api/erp-integration](https://docs.epilot.io/api/erp-integration) - -API for integrating with ERP systems, handling tracking acknowledgments, triggering ERP processes, and processing ERP updates. - -## Quick Start - -```bash -# List available operations -epilot erp-integration - -# Call an operation -epilot erp-integration acknowledgeTracking -``` - -## Common Flags - -| Flag | Description | -| ---- | ----------- | -| `-p key=value` | Set a named parameter | -| `-d '{...}'` | Request body JSON | -| `-H 'Key: Value'` | Custom header | -| `-t, --token ` | Bearer token for authentication | -| `--profile ` | Use a named profile | -| `-s, --server ` | Override server base URL | -| `-i, --include` | Include response headers in output | -| `--json` | Output raw JSON (no formatting) | -| `-v, --verbose` | Verbose output (show request details) | -| `--jsonata ` | JSONata expression to transform response | -| `--definition ` | Override OpenAPI spec file/URL | -| `--guided` | Prompt for all parameters interactively | -| `--no-interactive` | Disable interactive prompts | - -## Operations - -**erp** -- [`acknowledgeTracking`](#acknowledgetracking) — Acknowledges an ERP tracking record by removing it from the tracking table, requires public authentication -- [`triggerErp`](#triggererp) — Triggers the ERP integration process -- [`processErpUpdatesEventsV3`](#processerpupdateseventsv3) — Handles updates from ERP systems using integration_id directly. -- [`simulateMappingV2`](#simulatemappingv2) — Test v2.0 mapping configuration by transforming a payload using the provided mapping rules without persisting data. -- [`simulateMapping`](#simulatemapping) — Test mapping configuration by transforming a payload using the provided mapping rules without persisting data. - -**integrations** -- [`listIntegrations`](#listintegrations) — Retrieve all integrations for the authenticated organization -- [`createIntegration`](#createintegration) — Create a new integration configuration -- [`getIntegration`](#getintegration) — Retrieve a specific integration by its ID -- [`updateIntegration`](#updateintegration) — Update an existing integration configuration -- [`deleteIntegration`](#deleteintegration) — Delete an integration and all its use cases -- [`queryEvents`](#queryevents) — Query events for a specific integration -- [`replayEvents`](#replayevents) — Replay one or more events for a specific integration. Events will be re-processed with their original payloads but with -- [`listUseCases`](#listusecases) — Retrieve all use cases for a specific integration -- [`createUseCase`](#createusecase) — Create a new use case for an integration -- [`getUseCase`](#getusecase) — Retrieve a specific use case by its ID -- [`updateUseCase`](#updateusecase) — Update an existing use case configuration -- [`deleteUseCase`](#deleteusecase) — Delete a use case from an integration -- [`listUseCaseHistory`](#listusecasehistory) — Retrieve historical versions of a use case's configuration. -- [`listIntegrationsV2`](#listintegrationsv2) — Retrieve all integrations with embedded use cases for the authenticated organization -- [`createIntegrationV2`](#createintegrationv2) — Create a new integration with embedded use cases. -- [`getIntegrationV2`](#getintegrationv2) — Retrieve a specific integration with all its embedded use cases -- [`updateIntegrationV2`](#updateintegrationv2) — Update an existing integration with embedded use cases. -- [`deleteIntegrationV2`](#deleteintegrationv2) — Delete an integration and all its use cases -- [`setIntegrationAppMapping`](#setintegrationappmapping) — Creates or updates a mapping from an app/component to an integration. -- [`deleteIntegrationAppMapping`](#deleteintegrationappmapping) — Removes a mapping from an app/component to an integration. -- [`getOutboundStatus`](#getoutboundstatus) — Get the status of all outbound use cases for a specific integration. - -**monitoring** -- [`queryInboundMonitoringEvents`](#queryinboundmonitoringevents) — Query inbound monitoring events for a specific integration. -- [`getMonitoringStats`](#getmonitoringstats) — Get aggregated statistics for both inbound and outbound monitoring events for a specific integration. -- [`getMonitoringTimeSeries`](#getmonitoringtimeseries) — Get time-series aggregated event counts for monitoring charts. -- [`queryAccessLogs`](#queryaccesslogs) — Query API access logs for a specific integration's organization. -- [`queryOutboundMonitoringEvents`](#queryoutboundmonitoringevents) — Query outbound monitoring events for a specific integration. - -### `acknowledgeTracking` - -Acknowledges an ERP tracking record by removing it from the tracking table, requires public authentication - -`POST /v1/erp/tracking/acknowledgement` - -**Request Body** - -**Sample Call** - -```bash -epilot erp-integration acknowledgeTracking \ - -d '{"ack_id":"string"}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration acknowledgeTracking -``` - -With JSONata filter: - -```bash -epilot erp-integration acknowledgeTracking --jsonata 'message' -``` - -
-Sample Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `triggerErp` - -Triggers the ERP integration process - -`POST /v1/erp/trigger` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration triggerErp -``` - -With request body: - -```bash -epilot erp-integration triggerErp \ - -d '{ - "execution_id": "string", - "org_id": "string", - "webhook_id": "string", - "flow_id": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "action_id": "string", - "flow_action_id": "string", - "flow_name": "string", - "activity_id": "string", - "entity_id": "string" -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration triggerErp -``` - -With JSONata filter: - -```bash -epilot erp-integration triggerErp --jsonata 'status_code' -``` - -
-Sample Response - -```json -{ - "status_code": "string", - "message": "string", - "body": {}, - "code": "string", - "status": "succeeded", - "start_date": "string", - "end_date": "string", - "event_id": "string" -} -``` - -
- ---- - -### `processErpUpdatesEventsV3` - -Handles updates from ERP systems using integration_id directly. - -`POST /v3/erp/updates/events` - -**Request Body** - -**Sample Call** - -```bash -epilot erp-integration processErpUpdatesEventsV3 \ - -d '{"integration_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","correlation_id":"string","events":[{},{}]}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration processErpUpdatesEventsV3 -``` - -With JSONata filter: - -```bash -epilot erp-integration processErpUpdatesEventsV3 --jsonata 'results[0]' -``` - -
-Sample Response - -```json -{ - "results": [ - { - "event_id": "string", - "status": "success", - "message": "string" - } - ] -} -``` - -
- ---- - -### `simulateMappingV2` - -Test v2.0 mapping configuration by transforming a payload using the provided mapping rules without persisting data. - -`POST /v2/erp/updates/mapping_simulation` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration simulateMappingV2 -``` - -With request body: - -```bash -epilot erp-integration simulateMappingV2 \ - -d '{ - "event_configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - }, - "format": "json", - "payload": "string" -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration simulateMappingV2 -``` - -With JSONata filter: - -```bash -epilot erp-integration simulateMappingV2 --jsonata 'entity_updates' -``` - -
-Sample Response - -```json -{ - "entity_updates": [ - { - "entity_slug": "string", - "unique_identifiers": {}, - "attributes": {} - } - ], - "meter_readings_updates": [ - { - "meter": { - "$entity_unique_ids": {} - }, - "meter_counter": { - "$entity_unique_ids": {} - }, - "attributes": {} - } - ], - "warnings": [ - { - "entity_schema": "string", - "field": "string", - "message": "string" - } - ] -} -``` - -
- ---- - -### `simulateMapping` - -Test mapping configuration by transforming a payload using the provided mapping rules without persisting data. - -`POST /v1/erp/updates/mapping_simulation` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration simulateMapping -``` - -With request body: - -```bash -epilot erp-integration simulateMapping \ - -d '{ - "mapping_configuration": { - "version": "1.0", - "mapping": { - "objects": {} - } - }, - "object_type": "string", - "format": "json", - "payload": "string" -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration simulateMapping -``` - -With JSONata filter: - -```bash -epilot erp-integration simulateMapping --jsonata 'entity_updates' -``` - -
-Sample Response - -```json -{ - "entity_updates": [ - { - "entity_slug": "string", - "unique_identifiers": {}, - "attributes": {} - } - ], - "meter_readings_updates": [ - { - "meter": { - "$entity_unique_ids": {} - }, - "meter_counter": { - "$entity_unique_ids": {} - }, - "attributes": {} - } - ], - "warnings": [ - { - "entity_schema": "string", - "field": "string", - "message": "string" - } - ] -} -``` - -
- ---- - -### `listIntegrations` - -Retrieve all integrations for the authenticated organization - -`GET /v1/integrations` - -**Sample Call** - -```bash -epilot erp-integration listIntegrations -``` - -With JSONata filter: - -```bash -epilot erp-integration listIntegrations --jsonata 'integrations' -``` - -
-Sample Response - -```json -{ - "integrations": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } - } - ] -} -``` - -
- ---- - -### `createIntegration` - -Create a new integration configuration - -`POST /v1/integrations` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration createIntegration -``` - -With request body: - -```bash -epilot erp-integration createIntegration \ - -d '{ - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration createIntegration -``` - -With JSONata filter: - -```bash -epilot erp-integration createIntegration --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } -} -``` - -
- ---- - -### `getIntegration` - -Retrieve a specific integration by its ID - -`GET /v1/integrations/{integrationId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Sample Call** - -```bash -epilot erp-integration getIntegration \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration getIntegration 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration getIntegration -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } -} -``` - -
- ---- - -### `updateIntegration` - -Update an existing integration configuration - -`PUT /v1/integrations/{integrationId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration updateIntegration \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration updateIntegration 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration updateIntegration -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration updateIntegration -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } -} -``` - -
- ---- - -### `deleteIntegration` - -Delete an integration and all its use cases - -`DELETE /v1/integrations/{integrationId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Sample Call** - -```bash -epilot erp-integration deleteIntegration \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration deleteIntegration 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration deleteIntegration -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' -``` - -
-Sample Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `queryEvents` - -Query events for a specific integration - -`POST /v1/integrations/{integrationId}/events` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration queryEvents \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration queryEvents \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "event_id": "string", - "event_type": "CREATE", - "correlation_id": "string", - "object_type": "string", - "event_name": "string", - "limit": 25, - "cursor": { - "event_time": "2025-10-31T12:34:56Z", - "event_id": "evt_1234567890abcdef" - } -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration queryEvents 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration queryEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration queryEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": [ - { - "event_type": "CREATE", - "object_type": "string", - "timestamp": "1970-01-01T00:00:00.000Z", - "format": "json", - "payload": "string", - "deduplication_id": "evt-2025-05-01-12345-create-bp" - } - ], - "next_cursor": { - "event_time": "2025-10-31T12:34:56Z", - "event_id": "evt_1234567890abcdef" - }, - "has_more": true -} -``` - -
- ---- - -### `replayEvents` - -Replay one or more events for a specific integration. Events will be re-processed with their original payloads but with - -`POST /v1/integrations/{integrationId}/events/replay` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration replayEvents \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"event_ids":["string"]}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration replayEvents 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration replayEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration replayEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'event_ids' -``` - -
-Sample Response - -```json -{ - "event_ids": ["string"] -} -``` - -
- ---- - -### `listUseCases` - -Retrieve all use cases for a specific integration - -`GET /v1/integrations/{integrationId}/use-cases` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Sample Call** - -```bash -epilot erp-integration listUseCases \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration listUseCases 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration listUseCases -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'use_cases' -``` - -
-Sample Response - -```json -{ - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": {} - } - ] -} -``` - -
- ---- - -### `createUseCase` - -Create a new use case for an integration - -`POST /v1/integrations/{integrationId}/use-cases` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration createUseCase \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration createUseCase \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "name": "string", - "slug": "string", - "enabled": true, - "type": "inbound", - "configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - } -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration createUseCase 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration createUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration createUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - } -} -``` - -
- ---- - -### `getUseCase` - -Retrieve a specific use case by its ID - -`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | -| `useCaseId` | path | string (uuid) | Yes | The use case ID | - -**Sample Call** - -```bash -epilot erp-integration getUseCase \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -p useCaseId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration getUseCase 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration getUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - } -} -``` - -
- ---- - -### `updateUseCase` - -Update an existing use case configuration - -`PUT /v1/integrations/{integrationId}/use-cases/{useCaseId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | -| `useCaseId` | path | string (uuid) | Yes | The use case ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration updateUseCase \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -p useCaseId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration updateUseCase \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -p useCaseId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "name": "string", - "slug": "string", - "enabled": true, - "change_description": "string", - "type": "inbound", - "configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - } -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration updateUseCase 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration updateUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration updateUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - } -} -``` - -
- ---- - -### `deleteUseCase` - -Delete a use case from an integration - -`DELETE /v1/integrations/{integrationId}/use-cases/{useCaseId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | -| `useCaseId` | path | string (uuid) | Yes | The use case ID | - -**Sample Call** - -```bash -epilot erp-integration deleteUseCase \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -p useCaseId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration deleteUseCase 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration deleteUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' -``` - -
-Sample Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `listUseCaseHistory` - -Retrieve historical versions of a use case's configuration. - -`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}/history` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | -| `useCaseId` | path | string (uuid) | Yes | The use case ID | -| `cursor` | query | string | No | Opaque pagination cursor. Pass the 'next_cursor' value from a previous -response to fetch the next page of results. - | - -**Sample Call** - -```bash -epilot erp-integration listUseCaseHistory \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -p useCaseId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration listUseCaseHistory 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration listUseCaseHistory -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'history' -``` - -
-Sample Response - -```json -{ - "history": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "history_created_at": "1970-01-01T00:00:00.000Z", - "type": "inbound", - "configuration": {} - } - ], - "next_cursor": "string" -} -``` - -
- ---- - -### `listIntegrationsV2` - -Retrieve all integrations with embedded use cases for the authenticated organization - -`GET /v2/integrations` - -**Sample Call** - -```bash -epilot erp-integration listIntegrationsV2 -``` - -With JSONata filter: - -```bash -epilot erp-integration listIntegrationsV2 --jsonata 'integrations' -``` - -
-Sample Response - -```json -{ - "integrations": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [], - "settings": {}, - "use_cases": [] - } - ] -} -``` - -
- ---- - -### `createIntegrationV2` - -Create a new integration with embedded use cases. - -`POST /v2/integrations` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration createIntegrationV2 -``` - -With request body: - -```bash -epilot erp-integration createIntegrationV2 \ - -d '{ - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - }, - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "enabled": true, - "change_description": "string", - "type": "inbound", - "configuration": {} - } - ] -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration createIntegrationV2 -``` - -With JSONata filter: - -```bash -epilot erp-integration createIntegrationV2 --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - }, - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": {} - } - ] -} -``` - -
- ---- - -### `getIntegrationV2` - -Retrieve a specific integration with all its embedded use cases - -`GET /v2/integrations/{integrationId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Sample Call** - -```bash -epilot erp-integration getIntegrationV2 \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration getIntegrationV2 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration getIntegrationV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - }, - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": {} - } - ] -} -``` - -
- ---- - -### `updateIntegrationV2` - -Update an existing integration with embedded use cases. - -`PUT /v2/integrations/{integrationId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID (client-provided) | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration updateIntegrationV2 \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration updateIntegrationV2 \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - }, - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "enabled": true, - "change_description": "string", - "type": "inbound", - "configuration": {} - } - ] -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration updateIntegrationV2 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration updateIntegrationV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration updateIntegrationV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - }, - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": {} - } - ] -} -``` - -
- ---- - -### `deleteIntegrationV2` - -Delete an integration and all its use cases - -`DELETE /v2/integrations/{integrationId}` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Sample Call** - -```bash -epilot erp-integration deleteIntegrationV2 \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration deleteIntegrationV2 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration deleteIntegrationV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' -``` - -
-Sample Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `setIntegrationAppMapping` - -Creates or updates a mapping from an app/component to an integration. - -`PUT /v1/integrations/{integrationId}/app-mapping` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID to map to | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration setIntegrationAppMapping \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration setIntegrationAppMapping \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "app_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "component_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "overwrite": false -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration setIntegrationAppMapping 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration setIntegrationAppMapping -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration setIntegrationAppMapping -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'integration_id' -``` - -
-Sample Response - -```json -{ - "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" -} -``` - -
- ---- - -### `deleteIntegrationAppMapping` - -Removes a mapping from an app/component to an integration. - -`DELETE /v1/integrations/{integrationId}/app-mapping` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID (used for authorization, must match the mapping) | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration deleteIntegrationAppMapping \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"app_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","component_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration deleteIntegrationAppMapping 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration deleteIntegrationAppMapping -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration deleteIntegrationAppMapping -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' -``` - -
-Sample Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `queryInboundMonitoringEvents` - -Query inbound monitoring events for a specific integration. - -`POST /v1/integrations/{integrationId}/monitoring/inbound-events` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration queryInboundMonitoringEvents \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration queryInboundMonitoringEvents \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "event_type": "CREATE", - "sync_type": "entity", - "status": "success", - "error_category": "validation", - "correlation_id": "string", - "object_type": "string", - "event_name": "string", - "event_id": "string", - "from_date": "2025-01-01T00:00:00Z", - "to_date": "2025-01-31T23:59:59Z", - "limit": 50, - "cursor": { - "completed_at": "1970-01-01T00:00:00.000Z", - "event_id": "string" - } -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration queryInboundMonitoringEvents 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration queryInboundMonitoringEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration queryInboundMonitoringEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": [ - { - "org_id": "string", - "event_id": "string", - "correlation_id": "string", - "integration_id": "string", - "use_case_id": "string", - "event_type": "CREATE", - "object_type": "string", - "sync_type": "entity", - "status": "success", - "error_code": "string", - "error_message": "string", - "error_category": "validation", - "processing_duration_ms": 0, - "received_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" - } - ], - "next_cursor": { - "completed_at": "1970-01-01T00:00:00.000Z", - "event_id": "string" - }, - "has_more": true -} -``` - -
- ---- - -### `getMonitoringStats` - -Get aggregated statistics for both inbound and outbound monitoring events for a specific integration. - -`POST /v1/integrations/{integrationId}/monitoring/stats` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration getMonitoringStats \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration getMonitoringStats \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "from_date": "2025-01-01T00:00:00Z", - "to_date": "2025-01-31T23:59:59Z", - "inbound_group_by": ["use_case_id", "status"], - "outbound_group_by": ["event_name", "status"] -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration getMonitoringStats 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration getMonitoringStats -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration getMonitoringStats -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'inbound' -``` - -
-Sample Response - -```json -{ - "inbound": { - "total_events": 0, - "total_correlations": 0, - "success_count": 0, - "error_count": 0, - "skipped_count": 0, - "warning_count": 0, - "success_rate": 0, - "last_error_at": "1970-01-01T00:00:00.000Z", - "breakdown": [ - {} - ] - }, - "outbound": { - "total_events": 0, - "success_count": 0, - "error_count": 0, - "pending_count": 0, - "success_rate": 0, - "last_error_at": "1970-01-01T00:00:00.000Z", - "breakdown": [ - {} - ] - } -} -``` - -
- ---- - -### `getMonitoringTimeSeries` - -Get time-series aggregated event counts for monitoring charts. - -`POST /v1/integrations/{integrationId}/monitoring/timeseries` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration getMonitoringTimeSeries \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"from_date":"2025-01-01T00:00:00Z","to_date":"2025-01-31T23:59:59Z","interval":"1h","direction":"both"}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration getMonitoringTimeSeries 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration getMonitoringTimeSeries -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration getMonitoringTimeSeries -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'interval' -``` - -
-Sample Response - -```json -{ - "interval": "5m", - "from_date": "1970-01-01T00:00:00.000Z", - "to_date": "1970-01-01T00:00:00.000Z", - "buckets": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "inbound": { - "success_count": 0, - "error_count": 0, - "warning_count": 0, - "skipped_count": 0, - "total_count": 0 - }, - "outbound": { - "success_count": 0, - "error_count": 0, - "pending_count": 0, - "total_count": 0 - } - } - ] -} -``` - -
- ---- - -### `getOutboundStatus` - -Get the status of all outbound use cases for a specific integration. - -`GET /v1/integrations/{integrationId}/outbound-status` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Sample Call** - -```bash -epilot erp-integration getOutboundStatus \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration getOutboundStatus 123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration getOutboundStatus -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'useCases' -``` - -
-Sample Response - -```json -{ - "useCases": [ - { - "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "useCaseEnabled": true, - "eventCatalogEvent": "contract.created", - "eventEnabled": true, - "webhooks": [ - { - "webhookId": "string", - "webhookName": "string", - "enabled": true - } - ], - "status": "ok", - "conflicts": [ - { - "type": "event_disabled", - "webhookId": "string", - "message": "string" - } - ] - } - ] -} -``` - -
- ---- - -### `queryAccessLogs` - -Query API access logs for a specific integration's organization. - -`POST /v1/integrations/{integrationId}/monitoring/access-logs` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID (used for tenant authorization) | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration queryAccessLogs \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration queryAccessLogs \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "token_id": "api_5ZugdRXasLfWBypHi93Fk", - "service": "entity", - "method": "GET", - "path": "/v1/entity", - "status": 200, - "from_date": "2025-01-01T00:00:00Z", - "to_date": "2025-01-31T23:59:59Z", - "limit": 50, - "cursor": { - "timestamp": "1970-01-01T00:00:00.000Z", - "request_id": "string" - } -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration queryAccessLogs 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration queryAccessLogs -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration queryAccessLogs -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "environment": "string", - "service": "string", - "request_id": "string", - "method": "string", - "path": "string", - "status": 0, - "response_latency_ms": 0, - "response_length": 0, - "token_id": "string", - "org_id": "string", - "origin": "string", - "source_ip": "string" - } - ], - "next_cursor": { - "timestamp": "1970-01-01T00:00:00.000Z", - "request_id": "string" - }, - "has_more": true -} -``` - -
- ---- - -### `queryOutboundMonitoringEvents` - -Query outbound monitoring events for a specific integration. - -`POST /v1/integrations/{integrationId}/monitoring/outbound-events` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `integrationId` | path | string (uuid) | Yes | The integration ID | - -**Request Body** (required) - -**Sample Call** - -```bash -epilot erp-integration queryOutboundMonitoringEvents \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With request body: - -```bash -epilot erp-integration queryOutboundMonitoringEvents \ - -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{ - "event_name": "automation_flow_target", - "status": "succeeded", - "webhook_config_id": "string", - "from_date": "2025-01-01T00:00:00Z", - "to_date": "2025-01-31T23:59:59Z", - "limit": 50, - "cursor": { - "created_at": "1970-01-01T00:00:00.000Z", - "event_id": "string" - } -}' -``` - -Using positional args for path parameters: - -```bash -epilot erp-integration queryOutboundMonitoringEvents 123e4567-e89b-12d3-a456-426614174000 -``` - -Using stdin pipe: - -```bash -cat body.json | epilot erp-integration queryOutboundMonitoringEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 -``` - -With JSONata filter: - -```bash -epilot erp-integration queryOutboundMonitoringEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' -``` - -
-Sample Response - -```json -{ - "data": [ - { - "org_id": "string", - "event_id": "string", - "event_name": "string", - "status": "succeeded", - "url": "string", - "http_method": "string", - "http_response": {}, - "webhook_config_id": "string", - "metadata": {}, - "execution_context": {}, - "payload": {}, - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z" - } - ], - "next_cursor": { - "created_at": "1970-01-01T00:00:00.000Z", - "event_id": "string" - }, - "has_more": true -} -``` - -
- ---- diff --git a/docs/cli/commands/event-catalog.md b/docs/cli/commands/event-catalog.md index a7dbb730..46069778 100644 --- a/docs/cli/commands/event-catalog.md +++ b/docs/cli/commands/event-catalog.md @@ -42,11 +42,19 @@ epilot event-catalog listEvents **Event Catalog** - [`listEvents`](#listevents) — Retrieve list of available business events +- [`createCustomEvent`](#createcustomevent) — Reserve an org-scoped custom event name and persist its immutable v1.0 draft definition. Custom events are always projec - [`getEvent`](#getevent) — Retrieve the configuration of a specific business event +- [`replaceCustomEventDraft`](#replacecustomeventdraft) — Replace the complete v1.0 definition of an org-scoped custom event while it is still an - [`patchEvent`](#patchevent) — Update the configuration of a specific business event for the organization -- [`getEventJSONSchema`](#geteventjsonschema) — Retrieve the JSON Schema of a specific business event -- [`getEventExample`](#geteventexample) — Generate a sample event payload based on the event's JSON Schema +- [`deprecateCustomEvent`](#deprecatecustomevent) — Soft-deprecate an org-scoped custom event. Definitions and v1.0 history remain readable. +- [`previewCustomEvent`](#previewcustomevent) — Assemble and fully validate a persisted custom-event draft without publishing it. +- [`publishCustomEventDefinition`](#publishcustomeventdefinition) — Conditionally activate an immutable custom-event v1.0 definition. +- [`getEventJSONSchema`](#geteventjsonschema) — Retrieve the JSON Schema of a specific business event. Pass an optional +- [`getEventExample`](#geteventexample) — Generate a sample event payload based on the event's JSON Schema. Pass an +- [`listEventVersions`](#listeventversions) — List every known version of an event, along with the `latest` - [`searchEventHistory`](#searcheventhistory) — Paginated history of events +- [`searchEventHistoryV2`](#searcheventhistoryv2) — Paginated history of events with projected/lightweight payload (v2). +- [`getHistoricalEvent`](#gethistoricalevent) — Fetch a single historical event by id with full hydration - [`triggerEvent`](#triggerevent) — Explicitly trigger an event by providing input field values and an optional entity seed ### `listEvents` @@ -77,7 +85,7 @@ epilot event-catalog listEvents --jsonata 'results[0]' "event_name": "AddMeterReading", "event_title": "Add Meter Reading", "event_description": "Triggered when a new meter reading is added", - "event_version": "1.0.0", + "event_version": "1.0", "event_status": "active", "event_tags": ["builtin", "metering", "erp"], "schema_fields": {}, @@ -101,11 +109,191 @@ epilot event-catalog listEvents --jsonata 'results[0]' "operation": ["createEntity", "updateEntity"], "schema": ["contact", "contract", "order"], "attribute": ["email", "phone", "status"], - "purpose": ["Kündigung", "Umzug/Auszug"] + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] }, "enabled": true, "auto_trigger": true, - "automation_trigger": true + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" + } + ] + } + ] +} +``` + +
+ +--- + +### `createCustomEvent` + +Reserve an org-scoped custom event name and persist its immutable v1.0 draft definition. Custom events are always projec + +`POST /v1/events` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot event-catalog createCustomEvent +``` + +With request body: + +```bash +epilot event-catalog createCustomEvent \ + -d '{ + "event_name": "string", + "event_title": "string", + "event_description": "string", + "event_tags": ["string"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": false, + "automation_trigger_seed_node": "string", + "mapping": { + "mode": "guided", + "jsonata": "string" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "example": {} +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot event-catalog createCustomEvent +``` + +With JSONata filter: + +```bash +epilot event-catalog createCustomEvent --jsonata '$' +``` + +
+Sample Response + +```json +{ + "event_name": "AddMeterReading", + "event_title": "Add Meter Reading", + "event_description": "Triggered when a new meter reading is added", + "event_version": "1.0", + "event_status": "active", + "event_tags": ["builtin", "metering", "erp"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "enabled": true, + "auto_trigger": true, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" } ] } @@ -130,20 +318,457 @@ Retrieve the configuration of a specific business event **Sample Call** ```bash -epilot event-catalog getEvent \ +epilot event-catalog getEvent \ + -p event_name=example +``` + +Using positional args for path parameters: + +```bash +epilot event-catalog getEvent example +``` + +With JSONata filter: + +```bash +epilot event-catalog getEvent -p event_name=example --jsonata '$' +``` + +
+Sample Response + +```json +{ + "event_name": "AddMeterReading", + "event_title": "Add Meter Reading", + "event_description": "Triggered when a new meter reading is added", + "event_version": "1.0", + "event_status": "active", + "event_tags": ["builtin", "metering", "erp"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "enabled": true, + "auto_trigger": true, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" + } + ] +} +``` + +
+ +--- + +### `replaceCustomEventDraft` + +Replace the complete v1.0 definition of an org-scoped custom event while it is still an + +`PUT /v1/events/{event_name}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_name` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot event-catalog replaceCustomEventDraft \ + -p event_name=example +``` + +With request body: + +```bash +epilot event-catalog replaceCustomEventDraft \ + -p event_name=example \ + -d '{ + "event_name": "string", + "event_title": "string", + "event_description": "string", + "event_tags": ["string"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": false, + "automation_trigger_seed_node": "string", + "mapping": { + "mode": "guided", + "jsonata": "string" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "example": {} +}' +``` + +Using positional args for path parameters: + +```bash +epilot event-catalog replaceCustomEventDraft example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot event-catalog replaceCustomEventDraft -p event_name=example +``` + +With JSONata filter: + +```bash +epilot event-catalog replaceCustomEventDraft -p event_name=example --jsonata '$' +``` + +
+Sample Response + +```json +{ + "event_name": "AddMeterReading", + "event_title": "Add Meter Reading", + "event_description": "Triggered when a new meter reading is added", + "event_version": "1.0", + "event_status": "active", + "event_tags": ["builtin", "metering", "erp"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "enabled": true, + "auto_trigger": true, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" + } + ] +} +``` + +
+ +--- + +### `patchEvent` + +Update the configuration of a specific business event for the organization + +`PATCH /v1/events/{event_name}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_name` | path | string | Yes | Unique human readable name of the event | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot event-catalog patchEvent \ + -p event_name=example \ + -d '{"enabled":true,"auto_trigger":true,"success_criteria":[{"entity_schema":"contract","attribute":"installment_amount"}]}' +``` + +Using positional args for path parameters: + +```bash +epilot event-catalog patchEvent example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot event-catalog patchEvent -p event_name=example +``` + +With JSONata filter: + +```bash +epilot event-catalog patchEvent -p event_name=example --jsonata '$' +``` + +
+Sample Response + +```json +{ + "event_name": "AddMeterReading", + "event_title": "Add Meter Reading", + "event_description": "Triggered when a new meter reading is added", + "event_version": "1.0", + "event_status": "active", + "event_tags": ["builtin", "metering", "erp"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "enabled": true, + "auto_trigger": true, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" + } + ] +} +``` + +
+ +--- + +### `deprecateCustomEvent` + +Soft-deprecate an org-scoped custom event. Definitions and v1.0 history remain readable. + +`DELETE /v1/events/{event_name}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_name` | path | string | Yes | | + +**Sample Call** + +```bash +epilot event-catalog deprecateCustomEvent \ + -p event_name=example +``` + +Using positional args for path parameters: + +```bash +epilot event-catalog deprecateCustomEvent example +``` + +With JSONata filter: + +```bash +epilot event-catalog deprecateCustomEvent -p event_name=example --jsonata '$' +``` + +--- + +### `previewCustomEvent` + +Assemble and fully validate a persisted custom-event draft without publishing it. + +`POST /v1/events/{event_name}:preview` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_name` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot event-catalog previewCustomEvent \ -p event_name=example ``` +With request body: + +```bash +epilot event-catalog previewCustomEvent \ + -p event_name=example \ + -d '{ + "seed": { + "entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "node_id": "ticket" + }, + "_trigger_source_type": "automation", + "_trigger_source": "execution-id/action-id" +}' +``` + Using positional args for path parameters: ```bash -epilot event-catalog getEvent example +epilot event-catalog previewCustomEvent example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot event-catalog previewCustomEvent -p event_name=example ``` With JSONata filter: ```bash -epilot event-catalog getEvent -p event_name=example --jsonata '$' +epilot event-catalog previewCustomEvent -p event_name=example --jsonata 'payload' ```
@@ -151,38 +776,13 @@ epilot event-catalog getEvent -p event_name=example --jsonata '$' ```json { - "event_name": "AddMeterReading", - "event_title": "Add Meter Reading", - "event_description": "Triggered when a new meter reading is added", - "event_version": "1.0.0", - "event_status": "active", - "event_tags": ["builtin", "metering", "erp"], - "schema_fields": {}, - "entity_graph": { - "nodes": [ - { - "id": "contact", - "schema": "contact", - "cardinality": "one", - "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] - } - ], - "edges": [ - { - "from": "contact", - "to": "billing_account" - } - ] - }, - "entity_operation": { - "operation": ["createEntity", "updateEntity"], - "schema": ["contact", "contract", "order"], - "attribute": ["email", "phone", "status"], - "purpose": ["Kündigung", "Umzug/Auszug"] - }, - "enabled": true, - "auto_trigger": true, - "automation_trigger": true + "payload": {}, + "errors": [ + { + "path": "string", + "message": "string" + } + ] } ``` @@ -190,84 +790,44 @@ epilot event-catalog getEvent -p event_name=example --jsonata '$' --- -### `patchEvent` +### `publishCustomEventDefinition` -Update the configuration of a specific business event for the organization +Conditionally activate an immutable custom-event v1.0 definition. -`PATCH /v1/events/{event_name}` +`POST /v1/events/{event_name}:publish` **Parameters** | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `event_name` | path | string | Yes | Unique human readable name of the event | +| `event_name` | path | string | Yes | | -**Request Body** (required) +**Request Body** **Sample Call** ```bash -epilot event-catalog patchEvent \ - -p event_name=example -``` - -With request body: - -```bash -epilot event-catalog patchEvent \ +epilot event-catalog publishCustomEventDefinition \ -p event_name=example \ - -d '{ - "event_name": "AddMeterReading", - "event_title": "Add Meter Reading", - "event_description": "Triggered when a new meter reading is added", - "event_version": "1.0.0", - "event_status": "active", - "event_tags": ["builtin", "metering", "erp"], - "schema_fields": {}, - "entity_graph": { - "nodes": [ - { - "id": "contact", - "schema": "contact", - "cardinality": "one", - "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] - } - ], - "edges": [ - { - "from": "contact", - "to": "billing_account" - } - ] - }, - "entity_operation": { - "operation": ["createEntity", "updateEntity"], - "schema": ["contact", "contract", "order"], - "attribute": ["email", "phone", "status"], - "purpose": ["Kündigung", "Umzug/Auszug"] - }, - "enabled": true, - "auto_trigger": true, - "automation_trigger": true -}' + -d '{"enabled":true,"auto_trigger":true,"base_auto_trigger_enabled":true}' ``` Using positional args for path parameters: ```bash -epilot event-catalog patchEvent example +epilot event-catalog publishCustomEventDefinition example ``` Using stdin pipe: ```bash -cat body.json | epilot event-catalog patchEvent -p event_name=example +cat body.json | epilot event-catalog publishCustomEventDefinition -p event_name=example ``` With JSONata filter: ```bash -epilot event-catalog patchEvent -p event_name=example --jsonata '$' +epilot event-catalog publishCustomEventDefinition -p event_name=example --jsonata '$' ```
@@ -278,7 +838,7 @@ epilot event-catalog patchEvent -p event_name=example --jsonata '$' "event_name": "AddMeterReading", "event_title": "Add Meter Reading", "event_description": "Triggered when a new meter reading is added", - "event_version": "1.0.0", + "event_version": "1.0", "event_status": "active", "event_tags": ["builtin", "metering", "erp"], "schema_fields": {}, @@ -302,11 +862,39 @@ epilot event-catalog patchEvent -p event_name=example --jsonata '$' "operation": ["createEntity", "updateEntity"], "schema": ["contact", "contract", "order"], "attribute": ["email", "phone", "status"], - "purpose": ["Kündigung", "Umzug/Auszug"] + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] }, "enabled": true, "auto_trigger": true, - "automation_trigger": true + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" + } + ] } ``` @@ -316,7 +904,7 @@ epilot event-catalog patchEvent -p event_name=example --jsonata '$' ### `getEventJSONSchema` -Retrieve the JSON Schema of a specific business event +Retrieve the JSON Schema of a specific business event. Pass an optional `GET /v1/events/{event_name}/json_schema` @@ -325,6 +913,7 @@ Retrieve the JSON Schema of a specific business event | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `event_name` | path | string | Yes | Unique human readable name of the event | +| `Epilot-Event-Version` | header | string | No | Event payload version (`MAJOR.MINOR`). Defaults to the event's latest version. | **Sample Call** @@ -371,7 +960,7 @@ epilot event-catalog getEventJSONSchema -p event_name=example --jsonata '$' }, "_event_version": { "type": "string", - "description": "Event version (semver)" + "description": "Event payload version (MAJOR.MINOR)" }, "_event_source": { "type": "string", @@ -457,7 +1046,7 @@ epilot event-catalog getEventJSONSchema -p event_name=example --jsonata '$' ### `getEventExample` -Generate a sample event payload based on the event's JSON Schema +Generate a sample event payload based on the event's JSON Schema. Pass an `GET /v1/events/{event_name}/example` @@ -466,6 +1055,7 @@ Generate a sample event payload based on the event's JSON Schema | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `event_name` | path | string | Yes | Unique human readable name of the event | +| `Epilot-Event-Version` | header | string | No | Event payload version (`MAJOR.MINOR`). Defaults to the event's latest version. | **Sample Call** @@ -497,6 +1087,67 @@ epilot event-catalog getEventExample -p event_name=example --jsonata '$' --- +### `listEventVersions` + +List every known version of an event, along with the `latest` + +`GET /v1/events/{event_name}/versions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_name` | path | string | Yes | Unique human readable name of the event | + +**Sample Call** + +```bash +epilot event-catalog listEventVersions \ + -p event_name=example +``` + +Using positional args for path parameters: + +```bash +epilot event-catalog listEventVersions example +``` + +With JSONata filter: + +```bash +epilot event-catalog listEventVersions -p event_name=example --jsonata 'event_name' +``` + +
+Sample Response + +```json +{ + "event_name": "MeterReadingAdded", + "latest": "1.0", + "versions": [ + { + "version": "1.0", + "released_at": "2025-11-15", + "change_summary": "string", + "change_notes": "string", + "changes": [ + { + "field": "reading", + "op": "added", + "type_old": "string", + "type_new": "string" + } + ] + } + ] +} +``` + +
+ +--- + ### `searchEventHistory` Paginated history of events @@ -566,7 +1217,7 @@ epilot event-catalog searchEventHistory -p event_name=example --jsonata 'results "_event_time": "2024-01-01T12:00:00Z", "_event_id": "01FZ4Z5FZ5FZ5FZ5FZ5FZ5FZ5F", "_event_name": "MeterReading", - "_event_version": "1.0.0", + "_event_version": "1.0", "_event_source": "api", "_trigger_source_type": "api", "_trigger_source": "user_123456", @@ -596,6 +1247,160 @@ epilot event-catalog searchEventHistory -p event_name=example --jsonata 'results --- +### `searchEventHistoryV2` + +Paginated history of events with projected/lightweight payload (v2). + +`POST /v2/events/{event_name}:history` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_name` | path | string | Yes | Unique human readable name of the event | + +**Request Body** + +**Sample Call** + +```bash +epilot event-catalog searchEventHistoryV2 \ + -p event_name=example +``` + +With request body: + +```bash +epilot event-catalog searchEventHistoryV2 \ + -p event_name=example \ + -d '{ + "limit": 10, + "cursor": { + "event_time": "2025-10-31 12:34:56", + "event_id": "evt_1234567890abcdef" + }, + "timestamp": { + "from": "2025-10-01T00:00:00Z", + "to": "2025-10-31T23:59:59Z" + }, + "event_id": "evt_1234567890abcdef", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] +}' +``` + +Using positional args for path parameters: + +```bash +epilot event-catalog searchEventHistoryV2 example +``` + +Using stdin pipe: + +```bash +cat body.json | epilot event-catalog searchEventHistoryV2 -p event_name=example +``` + +With JSONata filter: + +```bash +epilot event-catalog searchEventHistoryV2 -p event_name=example --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "_org_id": "string", + "_event_time": "1970-01-01T00:00:00.000Z", + "_event_id": "string", + "_event_name": "string", + "_event_version": "1.0", + "_event_source": "string", + "_trigger_source_type": "api", + "_trigger_source": "string", + "_ack_id": "string" + } + ], + "next_cursor": { + "event_time": "2025-10-31T12:34:56Z", + "event_id": "evt_1234567890abcdef" + } +} +``` + +
+ +--- + +### `getHistoricalEvent` + +Fetch a single historical event by id with full hydration + +`GET /v2/events/{event_name}/history/{event_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `event_name` | path | string | Yes | Unique human readable name of the event | +| `event_id` | path | string | Yes | Unique event identifier (ULID) | + +**Sample Call** + +```bash +epilot event-catalog getHistoricalEvent \ + -p event_name=example \ + -p event_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot event-catalog getHistoricalEvent example 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot event-catalog getHistoricalEvent -p event_name=example -p event_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '_org_id' +``` + +
+Sample Response + +```json +{ + "_org_id": "org_123456", + "_event_time": "2024-01-01T12:00:00Z", + "_event_id": "01FZ4Z5FZ5FZ5FZ5FZ5FZ5FZ5F", + "_event_name": "MeterReading", + "_event_version": "1.0", + "_event_source": "api", + "_trigger_source_type": "api", + "_trigger_source": "user_123456", + "reading_value": 123.45, + "reading_date": "2024-01-01T11:59:00Z", + "read_by": "John Doe", + "reason": "regular", + "direction": "feed-out", + "source": "portal", + "meter_id": "550e8400-e29b-41d4-a716-446655440000", + "counter_id": "660e8400-e29b-41d4-a716-446655440000", + "meter_number": "MT123456789", + "obis_number": "1-0:1.8.0", + "unit": "kWh", + "customer_id": "770e8400-e29b-41d4-a716-446655440000", + "contract_id": "880e8400-e29b-41d4-a716-446655440000" +} +``` + +
+ +--- + ### `triggerEvent` Explicitly trigger an event by providing input field values and an optional entity seed @@ -625,12 +1430,10 @@ epilot event-catalog triggerEvent \ -d '{ "seed": { "entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "node_id": "string" + "node_id": "ticket" }, - "fields": {}, - "skip_hydration": ["string"], - "_trigger_source_type": "string", - "_trigger_source": "string" + "_trigger_source_type": "automation", + "_trigger_source": "execution-id/action-id" }' ``` diff --git a/docs/cli/commands/file.md b/docs/cli/commands/file.md index 93c3b94a..754cd14b 100644 --- a/docs/cli/commands/file.md +++ b/docs/cli/commands/file.md @@ -48,6 +48,17 @@ epilot file uploadFileV2 - [`downloadFile`](#downloadfile) — Generate a pre-signed download URL for a file. - [`downloadS3File`](#downloads3file) — Generate a pre-signed download URL for a file using its S3 reference. - [`downloadFiles`](#downloadfiles) — Bulk generate pre-signed download URLs for multiple files in a single request. +- [`createZipJob`](#createzipjob) — Create a background job to ZIP multiple files and send a download link via email. +- [`getZipJob`](#getzipjob) — Get the status of a ZIP job +- [`getFileSummary`](#getfilesummary) — Get summary text for a file entity together with the current summary job status when available. +- [`getFileSummaryFeedback`](#getfilesummaryfeedback) — Get the authenticated user's feedback for the current generated file summary. +- [`putFileSummaryFeedback`](#putfilesummaryfeedback) — Upsert thumbs up/down feedback for the current generated file summary. +- [`createFileSummaryJob`](#createfilesummaryjob) — Create or return the current AI summary job for a file entity. +- [`getCurrentFileSummaryJob`](#getcurrentfilesummaryjob) — Get the latest AI summary job for the file entity's current source. +- [`getFileSummaryJob`](#getfilesummaryjob) — Get an AI summary job by id. +- [`generateFileSummary`](#generatefilesummary) — Compatibility alias for creating or returning the current AI summary job for a file entity. +- [`getFileText`](#getfiletext) — Get the plain-text representation of a file entity. Returns status `not_ready` while text is being prepared and `unsuppo +- [`validateFile`](#validatefile) — Validate an uploaded file against one or more document validation rules - [`verifyCustomDownloadUrl`](#verifycustomdownloadurl) — Verify that a custom download URL is valid and has not expired. - [`uploadFilePublic`](#uploadfilepublic) — Create a pre-signed S3 URL for uploading a file without authentication. @@ -62,10 +73,10 @@ epilot file uploadFileV2 - [`deleteSession`](#deletesession) — End a browser session by deleting the token cookie. **Public Links** -- [`listPublicLinksForFile`](#listpubliclinksforfile) — **Not yet implemented.** +- [`listPublicLinksForFile`](#listpubliclinksforfile) — Fetches all public links previously generated for a file - [`generatePublicLink`](#generatepubliclink) — Generate a public link to share a private file externally. - [`accessPublicLink`](#accesspubliclink) — Access a file via its public link. -- [`revokePublicLink`](#revokepubliclink) — **Not yet implemented.** +- [`revokePublicLink`](#revokepubliclink) — Revokes a given public link by ID **File Collections** - [`getUserSchemaFileCollections`](#getuserschemafilecollections) — Get all file collections for the current user within a specific schema. @@ -180,9 +191,16 @@ epilot file saveFileV2 \ "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "s3ref": {} }' ``` @@ -216,9 +234,16 @@ epilot file saveFileV2 --jsonata '$' "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "source_url": "https://productengineer-content.s3.eu-west-1.amazonaws.com/product-engineer-checklist.pdf", "s3ref": {}, "versions": [ @@ -227,7 +252,8 @@ epilot file saveFileV2 --jsonata '$' "filename": "document.pdf", "size_bytes": 1234, "readable_size": "1.2 MB", - "mime_type": "image/jpeg" + "mime_type": "image/jpeg", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8" } ], "_updated_at": "1970-01-01T00:00:00.000Z", @@ -302,9 +328,16 @@ epilot file getFile -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata '$' "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "source_url": "https://productengineer-content.s3.eu-west-1.amazonaws.com/product-engineer-checklist.pdf", "s3ref": {}, "versions": [ @@ -313,7 +346,8 @@ epilot file getFile -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata '$' "filename": "document.pdf", "size_bytes": 1234, "readable_size": "1.2 MB", - "mime_type": "image/jpeg" + "mime_type": "image/jpeg", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8" } ], "_updated_at": "1970-01-01T00:00:00.000Z", @@ -388,9 +422,16 @@ epilot file deleteFile -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata '$' "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "source_url": "https://productengineer-content.s3.eu-west-1.amazonaws.com/product-engineer-checklist.pdf", "s3ref": {}, "versions": [ @@ -399,7 +440,8 @@ epilot file deleteFile -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata '$' "filename": "document.pdf", "size_bytes": 1234, "readable_size": "1.2 MB", - "mime_type": "image/jpeg" + "mime_type": "image/jpeg", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8" } ], "_updated_at": "1970-01-01T00:00:00.000Z", @@ -436,6 +478,9 @@ Generate a pre-signed download URL for a file. | `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | | `version` | query | number | No | Index of the file version to download (0 = latest) | | `attachment` | query | boolean | No | Controls the Content-Disposition header. Set to `true` to trigger browser download dialog, `false` to display inline. | +| `x-track` | query | object | No | Download-attribution channel. Provide any number of query parameters whose names +start with `x-track-` (e.g. `x-track-portal-id`, `x-track-contact-id`); each is signed +into the pre-signed URL verbatim | **Sample Call** @@ -479,7 +524,10 @@ Generate a pre-signed download URL for a file using its S3 reference. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `s3_key` | query | string | Yes | The S3 object key | +| `s3_key` | query | string | Yes | The S3 object key, as returned in `s3ref.key` of the file entity. + +Note: object keys store the filename segment percent-encoded. For example, a file named +`Straße 1.pdf` is stored under the key `.../S | | `s3_bucket` | query | string | Yes | The S3 bucket name | | `attachment` | query | boolean | No | Controls the Content-Disposition header. Set to `true` to trigger browser download dialog, `false` to display inline. | @@ -487,14 +535,14 @@ Generate a pre-signed download URL for a file using its S3 reference. ```bash epilot file downloadS3File \ - -p s3_key=123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf \ + -p s3_key=123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/Stra%C3%9Fe%201.pdf \ -p s3_bucket=epilot-prod-user-content ``` With JSONata filter: ```bash -epilot file downloadS3File -p s3_key=123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf -p s3_bucket=epilot-prod-user-content --jsonata 'download_url' +epilot file downloadS3File -p s3_key=123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/Stra%C3%9Fe%201.pdf -p s3_bucket=epilot-prod-user-content --jsonata 'download_url' ```
@@ -553,6 +601,553 @@ epilot file downloadFiles --jsonata '$' --- +### `createZipJob` + +Create a background job to ZIP multiple files and send a download link via email. + +`POST /v1/files:zipJob` + +**Request Body** + +**Sample Call** + +```bash +epilot file createZipJob \ + -d '{}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot file createZipJob +``` + +With JSONata filter: + +```bash +epilot file createZipJob --jsonata '$' +``` + +--- + +### `getZipJob` + +Get the status of a ZIP job + +`GET /v1/files:zipJob/{job_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `job_id` | path | string (uuid) | Yes | The UUID of the ZIP job | + +**Sample Call** + +```bash +epilot file getZipJob \ + -p job_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot file getZipJob 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot file getZipJob -p job_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'job_id' +``` + +
+Sample Response + +```json +{ + "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "completed", + "progress": { + "total_files": 100, + "downloaded_files": 75, + "failed_files": 2 + }, + "result": { + "file_entity_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8", + "download_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/files.zip?X-Amz-...", + "expires_at": "2024-01-02T12:00:00Z", + "zip_size_bytes": 104857600 + }, + "error": "Failed to download file: access denied", + "created_at": "2024-01-01T12:00:00Z", + "created_by": "10234", + "org_id": "123", + "updated_at": "2024-01-01T12:05:00Z" +} +``` + +
+ +--- + +### `getFileSummary` + +Get summary text for a file entity together with the current summary job status when available. + +`GET /v1/files/{id}/summary` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | + +**Sample Call** + +```bash +epilot file getFileSummary \ + -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +Using positional args for path parameters: + +```bash +epilot file getFileSummary ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +With JSONata filter: + +```bash +epilot file getFileSummary -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "queued", + "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "feedback_available": true, + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string" +} +``` + +
+ +--- + +### `getFileSummaryFeedback` + +Get the authenticated user's feedback for the current generated file summary. + +`GET /v1/files/{id}/summary/feedback` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | + +**Sample Call** + +```bash +epilot file getFileSummaryFeedback \ + -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +Using positional args for path parameters: + +```bash +epilot file getFileSummaryFeedback ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +With JSONata filter: + +```bash +epilot file getFileSummaryFeedback -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata 'feedback' +``` + +
+Sample Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +### `putFileSummaryFeedback` + +Upsert thumbs up/down feedback for the current generated file summary. + +`PUT /v1/files/{id}/summary/feedback` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot file putFileSummaryFeedback \ + -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 \ + -d '{"rating":"up","comment":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot file putFileSummaryFeedback ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot file putFileSummaryFeedback -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +With JSONata filter: + +```bash +epilot file putFileSummaryFeedback -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata 'feedback' +``` + +
+Sample Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +### `createFileSummaryJob` + +Create or return the current AI summary job for a file entity. + +`POST /v1/files/{id}/summary-jobs` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | + +**Sample Call** + +```bash +epilot file createFileSummaryJob \ + -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +Using positional args for path parameters: + +```bash +epilot file createFileSummaryJob ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +With JSONata filter: + +```bash +epilot file createFileSummaryJob -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata '$' +``` + +--- + +### `getCurrentFileSummaryJob` + +Get the latest AI summary job for the file entity's current source. + +`GET /v1/files/{id}/summary-jobs/current` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | + +**Sample Call** + +```bash +epilot file getCurrentFileSummaryJob \ + -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +Using positional args for path parameters: + +```bash +epilot file getCurrentFileSummaryJob ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +With JSONata filter: + +```bash +epilot file getCurrentFileSummaryJob -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata 'job_id' +``` + +
+Sample Response + +```json +{ + "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "file_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8", + "status": "queued", + "error": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getFileSummaryJob` + +Get an AI summary job by id. + +`GET /v1/files/{id}/summary-jobs/{job_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | +| `job_id` | path | string (uuid) | Yes | The UUID of the summary job | + +**Sample Call** + +```bash +epilot file getFileSummaryJob \ + -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 \ + -p job_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot file getFileSummaryJob ef7d985c-2385-44f4-9c71-ae06a52264f8 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot file getFileSummaryJob -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 -p job_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'job_id' +``` + +
+Sample Response + +```json +{ + "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "file_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8", + "status": "queued", + "error": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `generateFileSummary` + +Compatibility alias for creating or returning the current AI summary job for a file entity. + +`POST /v1/files/{id}/summary:generate` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | + +**Sample Call** + +```bash +epilot file generateFileSummary \ + -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +Using positional args for path parameters: + +```bash +epilot file generateFileSummary ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +With JSONata filter: + +```bash +epilot file generateFileSummary -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata '$' +``` + +--- + +### `getFileText` + +Get the plain-text representation of a file entity. Returns status `not_ready` while text is being prepared and `unsuppo + +`GET /v1/files/{id}/text` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string \| string (uuid) | Yes | The UUID of the file entity | + +**Sample Call** + +```bash +epilot file getFileText \ + -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +Using positional args for path parameters: + +```bash +epilot file getFileText ef7d985c-2385-44f4-9c71-ae06a52264f8 +``` + +With JSONata filter: + +```bash +epilot file getFileText -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 --jsonata 'status' +``` + +
+Sample Response + +```json +{ + "status": "ready", + "text": "string", + "truncated": true, + "total_chars": 0 +} +``` + +
+ +--- + +### `validateFile` + +Validate an uploaded file against one or more document validation rules + +`POST /v1/files/validations` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot file validateFile \ + -d '{"file":{"entity_id":"ef7d985c-2385-44f4-9c71-ae06a52264f8"},"rule_ids":["string"]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot file validateFile +``` + +With JSONata filter: + +```bash +epilot file validateFile --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "id": "string", + "status": "completed", + "file": { + "entity_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8", + "s3ref": {}, + "filename": "string", + "mime_type": "string", + "size_bytes": 0 + }, + "observation": { + "facts": { + "mime_type": "string", + "size_bytes": 0, + "page_count": 0, + "longer_edge_px": 0, + "is_blank": true, + "is_password_protected": true + }, + "judgements": {}, + "document_type": { + "slug": "string", + "confidence": 0 + } + }, + "results": [ + { + "rule_id": "string", + "rule_title": "string", + "level": "basic", + "is_valid": true, + "failed_parts": ["string"], + "warnings": ["string"], + "conditions": [ + { + "id": "string", + "operator": "string", + "outcome": "pass", + "blocking": true, + "message": "string", + "evidence": "string", + "explanation": "string" + } + ] + } + ], + "created_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + ### `previewFile` Generate a thumbnail preview for a file entity. @@ -735,7 +1330,7 @@ epilot file deleteSession --jsonata '$' ### `listPublicLinksForFile` -**Not yet implemented.** +Fetches all public links previously generated for a file `GET /v1/files/{id}/public/links` @@ -863,7 +1458,7 @@ epilot file accessPublicLink -p id=13d22918-36bd-4227-9ad4-2cb978788c8d -p filen ### `revokePublicLink` -**Not yet implemented.** +Revokes a given public link by ID `DELETE /v1/files/public/links/{id}` @@ -1246,9 +1841,16 @@ epilot file getFilesInCollection -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 -p c "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "source_url": "https://productengineer-content.s3.eu-west-1.amazonaws.com/product-engineer-checklist.pdf", "s3ref": {}, "versions": [ @@ -1257,7 +1859,8 @@ epilot file getFilesInCollection -p id=ef7d985c-2385-44f4-9c71-ae06a52264f8 -p c "filename": "document.pdf", "size_bytes": 1234, "readable_size": "1.2 MB", - "mime_type": "image/jpeg" + "mime_type": "image/jpeg", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8" } ], "_updated_at": "1970-01-01T00:00:00.000Z", diff --git a/docs/cli/commands/identity.md b/docs/cli/commands/identity.md new file mode 100644 index 00000000..1b6de3a4 --- /dev/null +++ b/docs/cli/commands/identity.md @@ -0,0 +1,1282 @@ +--- +title: "Identity API" +description: "epilot CLI commands for the Identity API: quick start, common flags and every operation, callable from the command line." +--- + +# Identity API + +- **Base URL:** `https://id.epilot.cloud` +- **API Docs:** [https://docs.epilot.io/api/identity](https://docs.epilot.io/api/identity) + +epilot as an OpenID Connect provider ("Sign in with epilot"). + +## Quick Start + +```bash +# List available operations +epilot identity + +# Call an operation +epilot identity listClients +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Operator Clients** +- [`listClients`](#listclients) — List registered partner clients. The client secret is never returned. +- [`createOidcClient`](#createoidcclient) — Create a partner client in `draft` status. The client secret is returned exactly once in this +- [`getOidcClient`](#getoidcclient) — Read a partner client. The client secret is never returned. +- [`updateClient`](#updateclient) — Replace the mutable configuration of a client. `config_version` must equal the current +- [`retireClient`](#retireclient) — Retire a client. The record is kept as a tombstone, the `client_id` is never reused, every +- [`activateClient`](#activateclient) — Activate a `draft` or `suspended` client. Validates that every redirect URI is an absolute +- [`suspendClient`](#suspendclient) — Immediately block the client for every organization. Provider-side artefacts (codes, tokens, +- [`rotateClientSecret`](#rotateclientsecret) — Issue a new client secret. The new secret is returned exactly once. The previous secret + +**Operator Organizations** +- [`listClientOrganizations`](#listclientorganizations) — List the organizations enabled on a client, including suspended and revoked ones. +- [`enableClientOrganization`](#enableclientorganization) — Enable an epilot organization on a client, recording the customer's authorization policy +- [`getClientOrganization`](#getclientorganization) — Read one organization enablement. +- [`updateClientOrganization`](#updateclientorganization) — Record a new version of the customer's authorization policy. `expected_policy_version` must +- [`revokeClientOrganization`](#revokeclientorganization) — Revoke an organization's enablement. The record is kept as an audited tombstone; future +- [`suspendClientOrganization`](#suspendclientorganization) — Temporarily block one organization on this client. Reversible with `activateClientOrganization`. +- [`activateClientOrganization`](#activateclientorganization) — Resume a suspended organization on this client. Revoked enablements cannot be re-activated; enabling the organization ag + +**Session** +- [`createIdentitySession`](#createidentitysession) — Called by the epilot portal through the portal-host proxy after every persisted 360 session. +- [`deleteIdentitySession`](#deleteidentitysession) — Clears the `identity_session` cookie. Called by the portal on logout. + +**Launch** +- [`launchClient`](#launchclient) — One validated place for partner start links (manager UI, hosted apps). Redirects the browser to the + +### `listClients` + +List registered partner clients. The client secret is never returned. + +`GET /v1/identity/operator/clients` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `partner_key` | query | string | No | Filter by partner key | +| `status` | query | "draft" \| "active" \| "suspended" \| "retired" | No | | +| `size` | query | number | No | | +| `cursor` | query | string | No | Opaque cursor from a previous response | + +**Sample Call** + +```bash +epilot identity listClients +``` + +With JSONata filter: + +```bash +epilot identity listClients --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createOidcClient` + +Create a partner client in `draft` status. The client secret is returned exactly once in this + +`POST /v1/identity/operator/clients` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot identity createOidcClient +``` + +With request body: + +```bash +epilot identity createOidcClient \ + -d '{ + "partner_key": "babelforce", + "display_name": "Babelforce", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "scopes_allowed": ["openid"] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot identity createOidcClient +``` + +With JSONata filter: + +```bash +epilot identity createOidcClient --jsonata '$' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string", + "client_secret": "string" +} +``` + +
+ +--- + +### `getOidcClient` + +Read a partner client. The client secret is never returned. + +`GET /v1/identity/operator/clients/{client_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot identity getOidcClient \ + -p client_id=bf-prod-x7k2 +``` + +Using positional args for path parameters: + +```bash +epilot identity getOidcClient bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity getOidcClient -p client_id=bf-prod-x7k2 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `updateClient` + +Replace the mutable configuration of a client. `config_version` must equal the current + +`PUT /v1/identity/operator/clients/{client_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot identity updateClient \ + -p client_id=bf-prod-x7k2 +``` + +With request body: + +```bash +epilot identity updateClient \ + -p client_id=bf-prod-x7k2 \ + -d '{ + "config_version": 1, + "allow_sector_change": false, + "display_name": "string", + "description": "string", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "scopes_allowed": ["openid"] +}' +``` + +Using positional args for path parameters: + +```bash +epilot identity updateClient bf-prod-x7k2 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot identity updateClient -p client_id=bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity updateClient -p client_id=bf-prod-x7k2 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `retireClient` + +Retire a client. The record is kept as a tombstone, the `client_id` is never reused, every + +`DELETE /v1/identity/operator/clients/{client_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot identity retireClient \ + -p client_id=bf-prod-x7k2 +``` + +Using positional args for path parameters: + +```bash +epilot identity retireClient bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity retireClient -p client_id=bf-prod-x7k2 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `activateClient` + +Activate a `draft` or `suspended` client. Validates that every redirect URI is an absolute + +`POST /v1/identity/operator/clients/{client_id}:activate` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot identity activateClient \ + -p client_id=bf-prod-x7k2 +``` + +Using positional args for path parameters: + +```bash +epilot identity activateClient bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity activateClient -p client_id=bf-prod-x7k2 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `suspendClient` + +Immediately block the client for every organization. Provider-side artefacts (codes, tokens, + +`POST /v1/identity/operator/clients/{client_id}:suspend` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot identity suspendClient \ + -p client_id=bf-prod-x7k2 \ + -d '{"reason":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot identity suspendClient bf-prod-x7k2 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot identity suspendClient -p client_id=bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity suspendClient -p client_id=bf-prod-x7k2 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `rotateClientSecret` + +Issue a new client secret. The new secret is returned exactly once. The previous secret + +`POST /v1/identity/operator/clients/{client_id}:rotateSecret` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot identity rotateClientSecret \ + -p client_id=bf-prod-x7k2 \ + -d '{"compromise_mode":false,"migration_window_seconds":86400}' +``` + +Using positional args for path parameters: + +```bash +epilot identity rotateClientSecret bf-prod-x7k2 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot identity rotateClientSecret -p client_id=bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity rotateClientSecret -p client_id=bf-prod-x7k2 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string", + "client_secret": "string" +} +``` + +
+ +--- + +### `listClientOrganizations` + +List the organizations enabled on a client, including suspended and revoked ones. + +`GET /v1/identity/operator/clients/{client_id}/organizations` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | +| `status` | query | "active" \| "suspended" \| "revoked" | No | | + +**Sample Call** + +```bash +epilot identity listClientOrganizations \ + -p client_id=bf-prod-x7k2 +``` + +Using positional args for path parameters: + +```bash +epilot identity listClientOrganizations bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity listClientOrganizations -p client_id=bf-prod-x7k2 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" + } + ] +} +``` + +
+ +--- + +### `enableClientOrganization` + +Enable an epilot organization on a client, recording the customer's authorization policy + +`POST /v1/identity/operator/clients/{client_id}/organizations` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot identity enableClientOrganization \ + -p client_id=bf-prod-x7k2 +``` + +With request body: + +```bash +epilot identity enableClientOrganization \ + -p client_id=bf-prod-x7k2 \ + -d '{ + "org_id": "739224", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot identity enableClientOrganization bf-prod-x7k2 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot identity enableClientOrganization -p client_id=bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity enableClientOrganization -p client_id=bf-prod-x7k2 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `getClientOrganization` + +Read one organization enablement. + +`GET /v1/identity/operator/clients/{client_id}/organizations/{org_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | +| `org_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot identity getClientOrganization \ + -p client_id=bf-prod-x7k2 \ + -p org_id=739224 +``` + +Using positional args for path parameters: + +```bash +epilot identity getClientOrganization bf-prod-x7k2 739224 +``` + +With JSONata filter: + +```bash +epilot identity getClientOrganization -p client_id=bf-prod-x7k2 -p org_id=739224 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `updateClientOrganization` + +Record a new version of the customer's authorization policy. `expected_policy_version` must + +`PUT /v1/identity/operator/clients/{client_id}/organizations/{org_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | +| `org_id` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot identity updateClientOrganization \ + -p client_id=bf-prod-x7k2 \ + -p org_id=739224 +``` + +With request body: + +```bash +epilot identity updateClientOrganization \ + -p client_id=bf-prod-x7k2 \ + -p org_id=739224 \ + -d '{ + "expected_policy_version": 1, + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot identity updateClientOrganization bf-prod-x7k2 739224 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot identity updateClientOrganization -p client_id=bf-prod-x7k2 -p org_id=739224 +``` + +With JSONata filter: + +```bash +epilot identity updateClientOrganization -p client_id=bf-prod-x7k2 -p org_id=739224 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `revokeClientOrganization` + +Revoke an organization's enablement. The record is kept as an audited tombstone; future + +`DELETE /v1/identity/operator/clients/{client_id}/organizations/{org_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | +| `org_id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot identity revokeClientOrganization \ + -p client_id=bf-prod-x7k2 \ + -p org_id=739224 \ + -d '{"reason":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot identity revokeClientOrganization bf-prod-x7k2 739224 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot identity revokeClientOrganization -p client_id=bf-prod-x7k2 -p org_id=739224 +``` + +With JSONata filter: + +```bash +epilot identity revokeClientOrganization -p client_id=bf-prod-x7k2 -p org_id=739224 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `suspendClientOrganization` + +Temporarily block one organization on this client. Reversible with `activateClientOrganization`. + +`POST /v1/identity/operator/clients/{client_id}/organizations/{org_id}:suspend` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | +| `org_id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot identity suspendClientOrganization \ + -p client_id=bf-prod-x7k2 \ + -p org_id=739224 \ + -d '{"reason":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot identity suspendClientOrganization bf-prod-x7k2 739224 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot identity suspendClientOrganization -p client_id=bf-prod-x7k2 -p org_id=739224 +``` + +With JSONata filter: + +```bash +epilot identity suspendClientOrganization -p client_id=bf-prod-x7k2 -p org_id=739224 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `activateClientOrganization` + +Resume a suspended organization on this client. Revoked enablements cannot be re-activated; enabling the organization ag + +`POST /v1/identity/operator/clients/{client_id}/organizations/{org_id}:activate` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | +| `org_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot identity activateClientOrganization \ + -p client_id=bf-prod-x7k2 \ + -p org_id=739224 +``` + +Using positional args for path parameters: + +```bash +epilot identity activateClientOrganization bf-prod-x7k2 739224 +``` + +With JSONata filter: + +```bash +epilot identity activateClientOrganization -p client_id=bf-prod-x7k2 -p org_id=739224 --jsonata 'client_id' +``` + +
+Sample Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "partner_account": { + "id": "string", + "label": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `createIdentitySession` + +Called by the epilot portal through the portal-host proxy after every persisted 360 session. + +`GET /v1/identity/session` + +**Sample Call** + +```bash +epilot identity createIdentitySession +``` + +With JSONata filter: + +```bash +epilot identity createIdentitySession --jsonata 'org_id' +``` + +
+Sample Response + +```json +{ + "org_id": "739224", + "user_id": "string", + "expires_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteIdentitySession` + +Clears the `identity_session` cookie. Called by the portal on logout. + +`DELETE /v1/identity/session` + +**Sample Call** + +```bash +epilot identity deleteIdentitySession +``` + +With JSONata filter: + +```bash +epilot identity deleteIdentitySession --jsonata '$' +``` + +--- + +### `launchClient` + +One validated place for partner start links (manager UI, hosted apps). Redirects the browser to the + +`GET /v1/identity/launch/{client_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `client_id` | path | string | Yes | | +| `target` | query | string (uri) | No | Deep link inside the partner application to continue to after login | +| `extra` | query | object | No | Any other query parameters (marketing tags on a start link, parameters a proxy appends) are accepted +and ignored. Start links and the session hop must never fail on an unknown parameter. + | + +**Sample Call** + +```bash +epilot identity launchClient \ + -p client_id=bf-prod-x7k2 +``` + +Using positional args for path parameters: + +```bash +epilot identity launchClient bf-prod-x7k2 +``` + +With JSONata filter: + +```bash +epilot identity launchClient -p client_id=bf-prod-x7k2 --jsonata '$' +``` + +--- diff --git a/docs/cli/commands/integration-toolkit.md b/docs/cli/commands/integration-toolkit.md new file mode 100644 index 00000000..a31ac0a3 --- /dev/null +++ b/docs/cli/commands/integration-toolkit.md @@ -0,0 +1,4822 @@ +--- +title: "Integration Toolkit API" +description: "epilot CLI commands for the Integration Toolkit API: quick start, common flags and every operation, callable from the command line." +--- + +# Integration Toolkit API + +- **Base URL:** `https://integration-toolkit.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/integration-toolkit](https://docs.epilot.io/api/integration-toolkit) + +API for integrating with external systems in a standardised way. + +## Quick Start + +```bash +# List available operations +epilot integration-toolkit + +# Call an operation +epilot integration-toolkit acknowledgeTracking +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**erp** +- [`acknowledgeTracking`](#acknowledgetracking) — Acknowledges an ERP tracking record by removing it from the tracking table, requires public authentication +- [`triggerErp`](#triggererp) — Triggers the ERP integration process +- [`processErpUpdatesEventsV3`](#processerpupdateseventsv3) — Handles updates from ERP systems using integration_id directly. +- [`simulateMappingV2`](#simulatemappingv2) — Test v2.0 mapping configuration by transforming a payload using the provided mapping rules without persisting data. +- [`simulateDirect`](#simulatedirect) — Dry run for direct-mode payloads: validates a `DirectPayload` against a `direct: true` +- [`simulateMapping`](#simulatemapping) — Test mapping configuration by transforming a payload using the provided mapping rules without persisting data. + +**integrations** +- [`listIntegrations`](#listintegrations) — Retrieve all integrations for the authenticated organization +- [`createIntegration`](#createintegration) — Create a new integration configuration +- [`getIntegration`](#getintegration) — Retrieve a specific integration by its ID +- [`updateIntegration`](#updateintegration) — Update an existing integration configuration +- [`deleteIntegration`](#deleteintegration) — Delete an integration and all its use cases +- [`queryEvents`](#queryevents) — Query events for a specific integration +- [`replayEvents`](#replayevents) — Replay one or more events for a specific integration. Events will be re-processed with their original payloads but with +- [`listUseCases`](#listusecases) — Retrieve all use cases for a specific integration +- [`createUseCase`](#createusecase) — Create a new use case for an integration +- [`getUseCase`](#getusecase) — Retrieve a specific use case by its ID +- [`updateUseCase`](#updateusecase) — Update an existing use case configuration +- [`deleteUseCase`](#deleteusecase) — Delete a use case from an integration +- [`listUseCaseHistory`](#listusecasehistory) — Retrieve historical versions of a use case's configuration. +- [`listDocumentationPages`](#listdocumentationpages) — Retrieve all documentation pages of an integration, without their markdown content. +- [`getDocumentationPage`](#getdocumentationpage) — Retrieve a single documentation page including its markdown content +- [`upsertDocumentationPage`](#upsertdocumentationpage) — Create or update the documentation page identified by docId. +- [`deleteDocumentationPage`](#deletedocumentationpage) — Delete a documentation page +- [`listIntegrationsV2`](#listintegrationsv2) — Retrieve all integrations with embedded use cases for the authenticated organization +- [`createIntegrationV2`](#createintegrationv2) — Create a new integration with embedded use cases. +- [`getIntegrationV2`](#getintegrationv2) — Retrieve a specific integration with all its embedded use cases +- [`updateIntegrationV2`](#updateintegrationv2) — Update an existing integration with embedded use cases. +- [`deleteIntegrationV2`](#deleteintegrationv2) — Delete an integration and all its use cases +- [`listNotificationHistory`](#listnotificationhistory) — Returns the cursor-paginated, newest-first notification history for an +- [`testSendNotification`](#testsendnotification) — Renders and sends ONE representative notification of the requested kind/type to +- [`getNotificationStatus`](#getnotificationstatus) — Returns the live per-rule alert state and (for 'auto' rules) the current +- [`getSecureProxyWhitelist`](#getsecureproxywhitelist) — Returns the current allowed_domains, allowed_ips, and vpc_mode for a secure_proxy use case. +- [`updateSecureProxyWhitelist`](#updatesecureproxywhitelist) — Replaces allowed_domains and/or allowed_ips on a secure_proxy use case. +- [`listSecureProxyWhitelistHistory`](#listsecureproxywhitelisthistory) — Returns the most recent USECASE_HISTORY entries for a secure_proxy use case, +- [`setIntegrationAppMapping`](#setintegrationappmapping) — Creates or updates a mapping from an app/component to an integration. +- [`deleteIntegrationAppMapping`](#deleteintegrationappmapping) — Removes a mapping from an app/component to an integration. +- [`getOutboundStatus`](#getoutboundstatus) — Get the status of all outbound use cases for a specific integration. +- [`getEntitySyncStatus`](#getentitysyncstatus) — Get the inbound ERP sync status of an entity: when each integration last +- [`pollOutboundMessages`](#polloutboundmessages) — Poll outbound messages for an integration's poll-mode use cases. +- [`ackOutboundMessages`](#ackoutboundmessages) — Acknowledge polled outbound messages. Acks are validated against the +- [`listOutboundDlqMessages`](#listoutbounddlqmessages) — List an integration's dead-lettered outbound queue messages +- [`redriveOutboundDlqMessages`](#redriveoutbounddlqmessages) — Redrive selected dead-lettered messages back into the live stream. +- [`unblockOutboundStream`](#unblockoutboundstream) — Unblock an integration's outbound stream halted by the `block` +- [`listSecureProxies`](#listsecureproxies) — Lists all secure_proxy use cases across all integrations for the authenticated organization. +- [`generateTypesPreview`](#generatetypespreview) — Analyses the JSONata mappings of all managed-call use cases in the integration and returns scaffolded type descriptors. +- [`generateTypes`](#generatetypes) — Generates a complete TypeScript npm package with typed interfaces for all managed-call use cases. This is a stateless op +- [`commitTypes`](#committypes) — Commits the generated types by locking use case configurations and updating version tracking. Should be called after the + +**monitoring** +- [`queryAccessLogs`](#queryaccesslogs) — Query API access logs for a specific integration's organization. +- [`queryMonitoringEventsV2`](#querymonitoringeventsv2) — Query monitoring events from the unified erp_monitoring_v2 table. +- [`getMonitoringStatsV2`](#getmonitoringstatsv2) — Get aggregated statistics from the unified erp_monitoring_v2 table. +- [`getMonitoringTimeSeriesV2`](#getmonitoringtimeseriesv2) — Get time-series aggregated event counts from the unified erp_monitoring_v2 table. +- [`getAssociatedMonitoringEvents`](#getassociatedmonitoringevents) — Returns all monitoring events sharing the same event_id, ordered chronologically. +- [`ingestExternalMonitoringEvents`](#ingestexternalmonitoringevents) — Ingest monitoring spans produced by an EXTERNAL system (e.g. an integration +- [`getMonitoringTraceByCorrelation`](#getmonitoringtracebycorrelation) — Returns the cross-system event trace for a `correlation_id`: every monitoring + +**proxy** +- [`secureProxy`](#secureproxy) — Routes an HTTP request through a VPC with either static IP egress or VPN secure link access. + +**managed-call** +- [`managedCallExecute`](#managedcallexecute) — Execute a managed call operation synchronously. The slug in the path acts as the RPC method name. + +**erp-imports** +- [`listErpImports`](#listerpimports) — List recent pricing-file import jobs for the org, newest first. +- [`createErpImport`](#createerpimport) — Register an already-uploaded file (S3 ref) as a pricing-file import job. Returns the job and a file preview. Nothing run +- [`getErpImport`](#geterpimport) — Get a pricing-file import job (status, counts, result links). +- [`deleteErpImport`](#deleteerpimport) — Remove an import and the file it owns. Allowed from any status: an import whose run is still in flight is stopped by the +- [`validateErpImport`](#validateerpimport) — Choose the use case to read this file with, and start the validate phase. +- [`suggestErpImportUseCases`](#suggesterpimportusecases) — Rank the org's inbound use cases against this file's columns — the input to the ranked picker ("matches 6 of your 7 colu +- [`executeErpImport`](#executeerpimport) — Confirm and run the write phase of a validated import. Only a READY job may be executed; any other status returns 409. +- [`abortErpImport`](#aborterpimport) — Ask a running import to stop. Valid while the job is VALIDATING or PROCESSING; any other status returns 409. + +### `acknowledgeTracking` + +Acknowledges an ERP tracking record by removing it from the tracking table, requires public authentication + +`POST /v1/erp/tracking/acknowledgement` + +**Request Body** + +**Sample Call** + +```bash +epilot integration-toolkit acknowledgeTracking \ + -d '{"ack_id":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit acknowledgeTracking +``` + +With JSONata filter: + +```bash +epilot integration-toolkit acknowledgeTracking --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `triggerErp` + +Triggers the ERP integration process + +`POST /v1/erp/trigger` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit triggerErp +``` + +With request body: + +```bash +epilot integration-toolkit triggerErp \ + -d '{ + "execution_id": "string", + "org_id": "string", + "webhook_id": "string", + "flow_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "action_id": "string", + "flow_action_id": "string", + "flow_name": "string", + "activity_id": "string", + "entity_id": "string" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit triggerErp +``` + +With JSONata filter: + +```bash +epilot integration-toolkit triggerErp --jsonata 'status_code' +``` + +
+Sample Response + +```json +{ + "status_code": "string", + "message": "string", + "body": {}, + "code": "string", + "status": "succeeded", + "start_date": "string", + "end_date": "string", + "event_id": "string" +} +``` + +
+ +--- + +### `processErpUpdatesEventsV3` + +Handles updates from ERP systems using integration_id directly. + +`POST /v3/erp/updates/events` + +**Request Body** + +**Sample Call** + +```bash +epilot integration-toolkit processErpUpdatesEventsV3 +``` + +With request body: + +```bash +epilot integration-toolkit processErpUpdatesEventsV3 \ + -d '{ + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "correlation_id": "string", + "group_id": "customer-42", + "events": [ + {}, + {} + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit processErpUpdatesEventsV3 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit processErpUpdatesEventsV3 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "event_id": "string", + "status": "success", + "message": "string" + } + ] +} +``` + +
+ +--- + +### `simulateMappingV2` + +Test v2.0 mapping configuration by transforming a payload using the provided mapping rules without persisting data. + +`POST /v2/erp/updates/mapping_simulation` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit simulateMappingV2 +``` + +With request body: + +```bash +epilot integration-toolkit simulateMappingV2 \ + -d '{ + "event_configuration": { + "direct": true, + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + }, + "format": "json", + "payload": "string" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit simulateMappingV2 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit simulateMappingV2 --jsonata 'entity_updates' +``` + +
+Sample Response + +```json +{ + "entity_updates": [ + { + "entity_slug": "string", + "unique_identifiers": {}, + "attributes": {}, + "pricing": { + "config": {}, + "data": [ + {} + ] + }, + "mode": "upsert" + } + ], + "meter_readings_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "attributes": {}, + "mode": "upsert" + } + ], + "prune_scope_updates": [ + { + "entity_slug": "string", + "scope": { + "scope_mode": "relations", + "schema": "string", + "unique_ids": {}, + "query": {} + }, + "keep_unique_ids": [ + {} + ], + "deletion_mode": "delete" + } + ], + "meter_readings_prune_scope_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "keep_external_ids": ["string"], + "source": "string" + } + ], + "warnings": [ + { + "entity_schema": "string", + "field": "string", + "message": "string" + } + ] +} +``` + +
+ +--- + +### `simulateDirect` + +Dry run for direct-mode payloads: validates a `DirectPayload` against a `direct: true` + +`POST /v1/erp/updates/direct_simulation` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit simulateDirect +``` + +With request body: + +```bash +epilot integration-toolkit simulateDirect \ + -d '{ + "event_configuration": { + "direct": true, + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + }, + "payload": "string" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit simulateDirect +``` + +With JSONata filter: + +```bash +epilot integration-toolkit simulateDirect --jsonata 'valid' +``` + +
+Sample Response + +```json +{ + "valid": true, + "errors": [ + { + "code": "DIRECT_PAYLOAD_INVALID", + "message": "string", + "operation_index": 0 + } + ], + "warnings": [ + { + "entity_schema": "string", + "field": "string", + "message": "string" + } + ], + "entity_updates": [ + { + "entity_slug": "string", + "unique_identifiers": {}, + "attributes": {}, + "pricing": { + "config": {}, + "data": [ + {} + ] + }, + "mode": "upsert", + "unique_identifiers_metadata": {} + } + ], + "meter_reading_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "attributes": {}, + "mode": "upsert", + "_config": { + "reading_matching": "external_id" + } + } + ] +} +``` + +
+ +--- + +### `simulateMapping` + +Test mapping configuration by transforming a payload using the provided mapping rules without persisting data. + +`POST /v1/erp/updates/mapping_simulation` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit simulateMapping +``` + +With request body: + +```bash +epilot integration-toolkit simulateMapping \ + -d '{ + "mapping_configuration": { + "version": "1.0", + "mapping": { + "objects": {} + } + }, + "object_type": "string", + "format": "json", + "payload": "string" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit simulateMapping +``` + +With JSONata filter: + +```bash +epilot integration-toolkit simulateMapping --jsonata 'entity_updates' +``` + +
+Sample Response + +```json +{ + "entity_updates": [ + { + "entity_slug": "string", + "unique_identifiers": {}, + "attributes": {}, + "pricing": { + "config": {}, + "data": [ + {} + ] + }, + "mode": "upsert" + } + ], + "meter_readings_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "attributes": {}, + "mode": "upsert" + } + ], + "prune_scope_updates": [ + { + "entity_slug": "string", + "scope": { + "scope_mode": "relations", + "schema": "string", + "unique_ids": {}, + "query": {} + }, + "keep_unique_ids": [ + {} + ], + "deletion_mode": "delete" + } + ], + "meter_readings_prune_scope_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "keep_external_ids": ["string"], + "source": "string" + } + ], + "warnings": [ + { + "entity_schema": "string", + "field": "string", + "message": "string" + } + ] +} +``` + +
+ +--- + +### `listIntegrations` + +Retrieve all integrations for the authenticated organization + +`GET /v1/integrations` + +**Sample Call** + +```bash +epilot integration-toolkit listIntegrations +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listIntegrations --jsonata 'integrations' +``` + +
+Sample Response + +```json +{ + "integrations": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [], + "maps": [], + "settings": {}, + "integration_type": "erp", + "connector_config": {}, + "protected": true, + "_manifest": ["string"] + } + ] +} +``` + +
+ +--- + +### `createIntegration` + +Create a new integration configuration + +`POST /v1/integrations` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit createIntegration +``` + +With request body: + +```bash +epilot integration-toolkit createIntegration \ + -d '{ + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit createIntegration +``` + +With JSONata filter: + +```bash +epilot integration-toolkit createIntegration --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"] +} +``` + +
+ +--- + +### `getIntegration` + +Retrieve a specific integration by its ID + +`GET /v1/integrations/{integrationId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Sample Call** + +```bash +epilot integration-toolkit getIntegration \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getIntegration 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getIntegration -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"] +} +``` + +
+ +--- + +### `updateIntegration` + +Update an existing integration configuration + +`PUT /v1/integrations/{integrationId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit updateIntegration \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit updateIntegration 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit updateIntegration -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit updateIntegration -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"] +} +``` + +
+ +--- + +### `deleteIntegration` + +Delete an integration and all its use cases + +`DELETE /v1/integrations/{integrationId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Sample Call** + +```bash +epilot integration-toolkit deleteIntegration \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit deleteIntegration 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit deleteIntegration -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `queryEvents` + +Query events for a specific integration + +`POST /v1/integrations/{integrationId}/events` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit queryEvents \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit queryEvents \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "event_id": "string", + "event_type": "CREATE", + "correlation_id": "string", + "object_type": "string", + "event_name": "string", + "use_case_id": "string", + "limit": 25, + "cursor": { + "event_time": "2025-10-31T12:34:56Z", + "event_id": "evt_1234567890abcdef" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit queryEvents 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit queryEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit queryEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": [ + { + "event_type": "CREATE", + "object_type": "string", + "timestamp": "1970-01-01T00:00:00.000Z", + "format": "json", + "payload": "string", + "deduplication_id": "evt-2025-05-01-12345-create-bp", + "correlation_id": "bp-8f3a2c-7d4e-4b1a-9c2f-1e6d5a4b3c21", + "use_case_id": "string" + } + ], + "next_cursor": { + "event_time": "2025-10-31T12:34:56Z", + "event_id": "evt_1234567890abcdef" + }, + "has_more": true +} +``` + +
+ +--- + +### `replayEvents` + +Replay one or more events for a specific integration. Events will be re-processed with their original payloads but with + +`POST /v1/integrations/{integrationId}/events/replay` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit replayEvents \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"event_ids":["string"]}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit replayEvents 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit replayEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit replayEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "replayed": 2, + "results": [ + { + "event_id": "string", + "status": "success", + "replay_event_id": "string", + "message": "string" + } + ], + "event_ids": ["string"] +} +``` + +
+ +--- + +### `listUseCases` + +Retrieve all use cases for a specific integration + +`GET /v1/integrations/{integrationId}/use-cases` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Sample Call** + +```bash +epilot integration-toolkit listUseCases \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit listUseCases 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listUseCases -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'use_cases' +``` + +
+Sample Response + +```json +{ + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": {} + } + ] +} +``` + +
+ +--- + +### `createUseCase` + +Create a new use case for an integration + +`POST /v1/integrations/{integrationId}/use-cases` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit createUseCase \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit createUseCase \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "name": "string", + "slug": "string", + "enabled": true, + "type": "inbound", + "configuration": { + "direct": true, + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit createUseCase 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit createUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit createUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": { + "direct": true, + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + } +} +``` + +
+ +--- + +### `getUseCase` + +Retrieve a specific use case by its ID + +`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `useCaseId` | path | string (uuid) | Yes | The use case ID | + +**Sample Call** + +```bash +epilot integration-toolkit getUseCase \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p useCaseId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getUseCase 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": { + "direct": true, + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + } +} +``` + +
+ +--- + +### `updateUseCase` + +Update an existing use case configuration + +`PUT /v1/integrations/{integrationId}/use-cases/{useCaseId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `useCaseId` | path | string (uuid) | Yes | The use case ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit updateUseCase \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p useCaseId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit updateUseCase \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p useCaseId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "name": "string", + "slug": "string", + "enabled": true, + "change_description": "string", + "type": "inbound", + "configuration": { + "direct": true, + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit updateUseCase 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit updateUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit updateUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": { + "direct": true, + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + } +} +``` + +
+ +--- + +### `deleteUseCase` + +Delete a use case from an integration + +`DELETE /v1/integrations/{integrationId}/use-cases/{useCaseId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `useCaseId` | path | string (uuid) | Yes | The use case ID | + +**Sample Call** + +```bash +epilot integration-toolkit deleteUseCase \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p useCaseId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit deleteUseCase 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit deleteUseCase -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `listUseCaseHistory` + +Retrieve historical versions of a use case's configuration. + +`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}/history` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `useCaseId` | path | string (uuid) | Yes | The use case ID | +| `cursor` | query | string | No | Opaque pagination cursor. Pass the 'next_cursor' value from a previous +response to fetch the next page of results. + | + +**Sample Call** + +```bash +epilot integration-toolkit listUseCaseHistory \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p useCaseId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit listUseCaseHistory 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listUseCaseHistory -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'history' +``` + +
+Sample Response + +```json +{ + "history": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "history_created_at": "1970-01-01T00:00:00.000Z", + "type": "inbound", + "configuration": {} + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `listDocumentationPages` + +Retrieve all documentation pages of an integration, without their markdown content. + +`GET /v1/integrations/{integrationId}/documentation` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Sample Call** + +```bash +epilot integration-toolkit listDocumentationPages \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit listDocumentationPages 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listDocumentationPages -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'pages' +``` + +
+Sample Response + +```json +{ + "pages": [ + { + "id": "general", + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "scope": "integration", + "use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string" + } + ] +} +``` + +
+ +--- + +### `getDocumentationPage` + +Retrieve a single documentation page including its markdown content + +`GET /v1/integrations/{integrationId}/documentation/{docId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `docId` | path | string | Yes | 'general' for the integration-wide page, otherwise a use case ID | + +**Sample Call** + +```bash +epilot integration-toolkit getDocumentationPage \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p docId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getDocumentationPage 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getDocumentationPage -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p docId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "general", + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "scope": "integration", + "use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "content": "string" +} +``` + +
+ +--- + +### `upsertDocumentationPage` + +Create or update the documentation page identified by docId. + +`PUT /v1/integrations/{integrationId}/documentation/{docId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `docId` | path | string | Yes | 'general' for the integration-wide page, otherwise a use case ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit upsertDocumentationPage \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p docId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"title":"string","content":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit upsertDocumentationPage 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit upsertDocumentationPage -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p docId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit upsertDocumentationPage -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p docId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "general", + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "scope": "integration", + "use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "content": "string" +} +``` + +
+ +--- + +### `deleteDocumentationPage` + +Delete a documentation page + +`DELETE /v1/integrations/{integrationId}/documentation/{docId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `docId` | path | string | Yes | 'general' for the integration-wide page, otherwise a use case ID | + +**Sample Call** + +```bash +epilot integration-toolkit deleteDocumentationPage \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p docId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit deleteDocumentationPage 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit deleteDocumentationPage -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p docId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `listIntegrationsV2` + +Retrieve all integrations with embedded use cases for the authenticated organization + +`GET /v2/integrations` + +**Sample Call** + +```bash +epilot integration-toolkit listIntegrationsV2 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listIntegrationsV2 --jsonata 'integrations' +``` + +
+Sample Response + +```json +{ + "integrations": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [], + "maps": [], + "settings": {}, + "integration_type": "erp", + "connector_config": {}, + "protected": true, + "_manifest": ["string"], + "use_cases": [] + } + ] +} +``` + +
+ +--- + +### `createIntegrationV2` + +Create a new integration with embedded use cases. + +`POST /v2/integrations` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit createIntegrationV2 +``` + +With request body: + +```bash +epilot integration-toolkit createIntegrationV2 \ + -d '{ + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"], + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "enabled": true, + "change_description": "string", + "type": "inbound", + "configuration": {} + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit createIntegrationV2 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit createIntegrationV2 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"], + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": {} + } + ] +} +``` + +
+ +--- + +### `getIntegrationV2` + +Retrieve a specific integration with all its embedded use cases + +`GET /v2/integrations/{integrationId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Sample Call** + +```bash +epilot integration-toolkit getIntegrationV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getIntegrationV2 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getIntegrationV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"], + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": {} + } + ] +} +``` + +
+ +--- + +### `updateIntegrationV2` + +Update an existing integration with embedded use cases. + +`PUT /v2/integrations/{integrationId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID (client-provided) | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit updateIntegrationV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit updateIntegrationV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"], + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "enabled": true, + "change_description": "string", + "type": "inbound", + "configuration": {} + } + ] +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit updateIntegrationV2 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit updateIntegrationV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit updateIntegrationV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"], + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": {} + } + ] +} +``` + +
+ +--- + +### `deleteIntegrationV2` + +Delete an integration and all its use cases + +`DELETE /v2/integrations/{integrationId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Sample Call** + +```bash +epilot integration-toolkit deleteIntegrationV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit deleteIntegrationV2 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit deleteIntegrationV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `listNotificationHistory` + +Returns the cursor-paginated, newest-first notification history for an + +`GET /v2/integrations/{integrationId}/notifications/history` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `cursor` | query | string | No | Opaque base64 pagination cursor returned as `next_cursor` by a prior page. | +| `limit` | query | number | No | Requested number of items to return. Values above 100 are accepted and clamped server-side to 100 (the enforcement point is the handler, not this schema), so a large value never 400s at the contract l | +| `type` | query | string | No | Optional notification type filter (e.g. `critical_error`, `error_threshold`). | + +**Sample Call** + +```bash +epilot integration-toolkit listNotificationHistory \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit listNotificationHistory 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listNotificationHistory -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'history' +``` + +
+Sample Response + +```json +{ + "history": [ + { + "id": "string", + "type": "string", + "state_transition": "string", + "severity": "error", + "title": "string", + "occurred_at": "1970-01-01T00:00:00.000Z", + "notified": true, + "suppressed_reason": "muted", + "recipients": ["string"], + "context": {}, + "created_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `testSendNotification` + +Renders and sends ONE representative notification of the requested kind/type to + +`POST /v2/integrations/{integrationId}/notifications/test` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit testSendNotification \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"kind":"alert","type":"string","channels":["email"]}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit testSendNotification 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit testSendNotification -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit testSendNotification -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `getNotificationStatus` + +Returns the live per-rule alert state and (for 'auto' rules) the current + +`GET /v2/integrations/{integrationId}/notifications/status` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `include` | query | "baseline_series" | No | Add `baseline_series` to also return all 168 hour-of-week buckets per +'auto' rule (heavier; omit for just the current-bucket markers). + | + +**Sample Call** + +```bash +epilot integration-toolkit getNotificationStatus \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getNotificationStatus 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getNotificationStatus -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'health' +``` + +
+Sample Response + +```json +{ + "health": "healthy", + "evaluated_at": "1970-01-01T00:00:00.000Z", + "rules": [ + { + "rule_id": "string", + "state": "ok", + "last_fired_at": "1970-01-01T00:00:00.000Z", + "last_cleared_at": "1970-01-01T00:00:00.000Z", + "last_evaluation": { + "evaluated_at": "1970-01-01T00:00:00.000Z", + "observed": 0, + "threshold": 0, + "suppressed_reason": "sample_size" + }, + "baseline": { + "is_mature": true, + "computed_at": "1970-01-01T00:00:00.000Z", + "median": 0, + "mad": 0, + "upper": 0, + "buckets": [ + { + "dow": 1, + "hour": 0, + "median": 0, + "mad": 0 + } + ] + } + } + ] +} +``` + +
+ +--- + +### `getSecureProxyWhitelist` + +Returns the current allowed_domains, allowed_ips, and vpc_mode for a secure_proxy use case. + +`GET /v2/integrations/{integrationId}/use-cases/{useCaseId}/secure-proxy-whitelist` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `useCaseId` | path | string (uuid) | Yes | The use case ID | + +**Sample Call** + +```bash +epilot integration-toolkit getSecureProxyWhitelist \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p useCaseId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getSecureProxyWhitelist 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getSecureProxyWhitelist -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'vpc_mode' +``` + +
+Sample Response + +```json +{ + "vpc_mode": "static_ip", + "allowed_domains": ["string"], + "allowed_ips": ["string"] +} +``` + +
+ +--- + +### `updateSecureProxyWhitelist` + +Replaces allowed_domains and/or allowed_ips on a secure_proxy use case. + +`PUT /v2/integrations/{integrationId}/use-cases/{useCaseId}/secure-proxy-whitelist` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `useCaseId` | path | string (uuid) | Yes | The use case ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit updateSecureProxyWhitelist \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p useCaseId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"allowed_domains":["string"],"allowed_ips":["string"]}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit updateSecureProxyWhitelist 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit updateSecureProxyWhitelist -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit updateSecureProxyWhitelist -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'vpc_mode' +``` + +
+Sample Response + +```json +{ + "vpc_mode": "static_ip", + "allowed_domains": ["string"], + "allowed_ips": ["string"] +} +``` + +
+ +--- + +### `listSecureProxyWhitelistHistory` + +Returns the most recent USECASE_HISTORY entries for a secure_proxy use case, + +`GET /v2/integrations/{integrationId}/use-cases/{useCaseId}/secure-proxy-whitelist/history` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `useCaseId` | path | string (uuid) | Yes | The use case ID (must be of type secure_proxy) | +| `limit` | query | number | No | Maximum number of history entries to return. Default 10, max 50. +Capped at the service-layer page size (20) so `limit > 20` is silently +clamped to 20. UI-08 requests 5-10 for the panel view. + | + +**Sample Call** + +```bash +epilot integration-toolkit listSecureProxyWhitelistHistory \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p useCaseId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit listSecureProxyWhitelistHistory 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listSecureProxyWhitelistHistory -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p useCaseId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'history' +``` + +
+Sample Response + +```json +{ + "history": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "history_created_at": "1970-01-01T00:00:00.000Z", + "type": "secure_proxy", + "configuration": { + "vpc_mode": "static_ip", + "allowed_domains": ["string"], + "allowed_ips": ["string"] + } + } + ] +} +``` + +
+ +--- + +### `setIntegrationAppMapping` + +Creates or updates a mapping from an app/component to an integration. + +`PUT /v1/integrations/{integrationId}/app-mapping` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID to map to | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit setIntegrationAppMapping \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit setIntegrationAppMapping \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "app_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "component_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "overwrite": false +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit setIntegrationAppMapping 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit setIntegrationAppMapping -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit setIntegrationAppMapping -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'integration_id' +``` + +
+Sample Response + +```json +{ + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" +} +``` + +
+ +--- + +### `deleteIntegrationAppMapping` + +Removes a mapping from an app/component to an integration. + +`DELETE /v1/integrations/{integrationId}/app-mapping` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID (used for authorization, must match the mapping) | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit deleteIntegrationAppMapping \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"app_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","component_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit deleteIntegrationAppMapping 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit deleteIntegrationAppMapping -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit deleteIntegrationAppMapping -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `getOutboundStatus` + +Get the status of all outbound use cases for a specific integration. + +`GET /v1/integrations/{integrationId}/outbound-status` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Sample Call** + +```bash +epilot integration-toolkit getOutboundStatus \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getOutboundStatus 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getOutboundStatus -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'useCases' +``` + +
+Sample Response + +```json +{ + "useCases": [ + { + "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "useCaseEnabled": true, + "eventCatalogEvent": "contract.created", + "eventEnabled": true, + "webhooks": [ + { + "webhookId": "string", + "webhookName": "string", + "enabled": true + } + ], + "status": "ok", + "conflicts": [ + { + "type": "event_disabled", + "webhookId": "string", + "message": "string" + } + ], + "poll": { + "queue_depth": 0, + "oldest_unconsumed_age_seconds": 0, + "last_poll_at": "1970-01-01T00:00:00.000Z", + "last_ack_at": "1970-01-01T00:00:00.000Z", + "blocked": true, + "dlq_count": 0 + }, + "file_proxy": [ + { + "mapping_id": "string", + "use_case_slug": "string", + "resolved": true, + "target_use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "target_enabled": true, + "target_updated_at": "1970-01-01T00:00:00.000Z", + "unresolved_reason": "not_found" + } + ] + } + ] +} +``` + +
+ +--- + +### `getEntitySyncStatus` + +Get the inbound ERP sync status of an entity: when each integration last + +`GET /v1/integrations/entities/{entityId}/sync-status` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `entityId` | path | string (uuid) | Yes | The entity ID | +| `integration_id` | query | string (uuid) | No | Narrow the result to a single integration | + +**Sample Call** + +```bash +epilot integration-toolkit getEntitySyncStatus \ + -p entityId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getEntitySyncStatus 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getEntitySyncStatus -p entityId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'entity_id' +``` + +
+Sample Response + +```json +{ + "entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "sync_states": [ + { + "entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "entity_slug": "contract", + "use_case_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "last_changed_at": "1970-01-01T00:00:00.000Z", + "last_operation": "create", + "last_event_id": "string", + "readings_last_synced_at": "1970-01-01T00:00:00.000Z", + "readings_last_operation": "upsert", + "readings_last_event_id": "string" + } + ] +} +``` + +
+ +--- + +### `pollOutboundMessages` + +Poll outbound messages for an integration's poll-mode use cases. + +`POST /v1/integrations/{integrationId}/outbound/messages/poll` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** + +**Sample Call** + +```bash +epilot integration-toolkit pollOutboundMessages \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"limit":10}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit pollOutboundMessages 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit pollOutboundMessages -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit pollOutboundMessages -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'messages' +``` + +
+Sample Response + +```json +{ + "messages": [ + { + "id": "string", + "lease_token": "string", + "use_case_id": "string", + "event_name": "string", + "event_id": "string", + "group": "string", + "payload": {}, + "enqueued_at": "1970-01-01T00:00:00.000Z" + } + ], + "visibility_timeout_seconds": 0, + "has_more": true +} +``` + +
+ +--- + +### `ackOutboundMessages` + +Acknowledge polled outbound messages. Acks are validated against the + +`POST /v1/integrations/{integrationId}/outbound/messages/ack` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit ackOutboundMessages \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"acks":[{"id":"string","lease_token":"string"}]}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit ackOutboundMessages 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit ackOutboundMessages -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit ackOutboundMessages -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "id": "string", + "status": "accepted", + "reason": "stale_lease" + } + ] +} +``` + +
+ +--- + +### `listOutboundDlqMessages` + +List an integration's dead-lettered outbound queue messages + +`GET /v1/integrations/{integrationId}/outbound/messages/dlq` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `limit` | query | number | No | Maximum number of DLQ entries to return | +| `next_token` | query | string | No | Opaque pagination token from a previous response | + +**Sample Call** + +```bash +epilot integration-toolkit listOutboundDlqMessages \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit listOutboundDlqMessages 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listOutboundDlqMessages -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'items[0]' +``` + +
+Sample Response + +```json +{ + "items": [ + { + "id": "string", + "use_case_id": "string", + "event_name": "string", + "event_id": "string", + "enqueued_at": "1970-01-01T00:00:00.000Z", + "dead_lettered_at": "1970-01-01T00:00:00.000Z", + "delivery_attempts": 0, + "reason": "string", + "expires_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_token": "string" +} +``` + +
+ +--- + +### `redriveOutboundDlqMessages` + +Redrive selected dead-lettered messages back into the live stream. + +`POST /v1/integrations/{integrationId}/outbound/messages/dlq/redrive` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit redriveOutboundDlqMessages \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"ids":["string"]}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit redriveOutboundDlqMessages 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit redriveOutboundDlqMessages -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit redriveOutboundDlqMessages -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "id": "string", + "status": "redriven" + } + ] +} +``` + +
+ +--- + +### `unblockOutboundStream` + +Unblock an integration's outbound stream halted by the `block` + +`POST /v1/integrations/{integrationId}/outbound/messages/unblock` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** + +**Sample Call** + +```bash +epilot integration-toolkit unblockOutboundStream \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"reason":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit unblockOutboundStream 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit unblockOutboundStream -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit unblockOutboundStream -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'unblocked' +``` + +
+Sample Response + +```json +{ + "unblocked": true, + "dead_lettered_id": "string" +} +``` + +
+ +--- + +### `queryAccessLogs` + +Query API access logs for a specific integration's organization. + +`POST /v1/integrations/{integrationId}/monitoring/access-logs` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID (used for tenant authorization) | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit queryAccessLogs \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit queryAccessLogs \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "token_id": "api_5ZugdRXasLfWBypHi93Fk", + "service": "entity", + "method": "GET", + "path": "/v1/entity", + "status": 200, + "from_date": "2025-01-01T00:00:00Z", + "to_date": "2025-01-31T23:59:59Z", + "limit": 50, + "cursor": { + "timestamp": "1970-01-01T00:00:00.000Z", + "request_id": "string" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit queryAccessLogs 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit queryAccessLogs -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit queryAccessLogs -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "environment": "string", + "service": "string", + "request_id": "string", + "method": "string", + "path": "string", + "status": 0, + "response_latency_ms": 0, + "response_length": 0, + "token_id": "string", + "org_id": "string", + "origin": "string", + "source_ip": "string" + } + ], + "next_cursor": { + "timestamp": "1970-01-01T00:00:00.000Z", + "request_id": "string" + }, + "has_more": true +} +``` + +
+ +--- + +### `queryMonitoringEventsV2` + +Query monitoring events from the unified erp_monitoring_v2 table. + +`POST /v2/integrations/{integrationId}/monitoring/events` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit queryMonitoringEventsV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit queryMonitoringEventsV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "use_case_id": "string", + "use_case_type": "inbound", + "level": "success", + "code": "string", + "event_id": "string", + "correlation_id": "string", + "from_date": "2025-01-01T00:00:00Z", + "to_date": "2025-01-31T23:59:59Z", + "limit": 50, + "cursor": { + "created_at": "1970-01-01T00:00:00.000Z", + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit queryMonitoringEventsV2 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit queryMonitoringEventsV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit queryMonitoringEventsV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "integration_id": "string", + "event_id": "string", + "correlation_id": "string", + "use_case_id": "string", + "use_case_type": "inbound", + "level": "success", + "code": "string", + "message": "string", + "detail": {}, + "created_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": { + "created_at": "1970-01-01T00:00:00.000Z", + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "has_more": true +} +``` + +
+ +--- + +### `getMonitoringStatsV2` + +Get aggregated statistics from the unified erp_monitoring_v2 table. + +`POST /v2/integrations/{integrationId}/monitoring/stats` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit getMonitoringStatsV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit getMonitoringStatsV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "from_date": "2025-01-01T00:00:00Z", + "to_date": "2025-01-31T23:59:59Z", + "use_case_type": "inbound", + "use_case_types": ["inbound"], + "group_by": "use_case_id", + "source": "monitoring" +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getMonitoringStatsV2 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit getMonitoringStatsV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getMonitoringStatsV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'total_events' +``` + +
+Sample Response + +```json +{ + "total_events": 0, + "success_count": 0, + "error_count": 0, + "warning_count": 0, + "skipped_count": 0, + "info_count": 0, + "ack_timeout_count": 0, + "success_rate": 0, + "last_error_at": "1970-01-01T00:00:00.000Z", + "breakdown": [ + {} + ] +} +``` + +
+ +--- + +### `getMonitoringTimeSeriesV2` + +Get time-series aggregated event counts from the unified erp_monitoring_v2 table. + +`POST /v2/integrations/{integrationId}/monitoring/time-series` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit getMonitoringTimeSeriesV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit getMonitoringTimeSeriesV2 \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "from_date": "2025-01-01T00:00:00Z", + "to_date": "2025-01-31T23:59:59Z", + "interval": "5m", + "use_case_type": "inbound", + "group_by": "use_case_type" +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getMonitoringTimeSeriesV2 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit getMonitoringTimeSeriesV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getMonitoringTimeSeriesV2 -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'interval' +``` + +
+Sample Response + +```json +{ + "interval": "5m", + "from_date": "1970-01-01T00:00:00.000Z", + "to_date": "1970-01-01T00:00:00.000Z", + "buckets": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "success_count": 0, + "error_count": 0, + "warning_count": 0, + "skipped_count": 0, + "info_count": 0, + "total_count": 0, + "breakdown": [ + { + "use_case_type": "inbound", + "use_case_id": "string", + "success_count": 0, + "error_count": 0, + "warning_count": 0, + "skipped_count": 0, + "info_count": 0, + "total_count": 0 + } + ] + } + ] +} +``` + +
+ +--- + +### `getAssociatedMonitoringEvents` + +Returns all monitoring events sharing the same event_id, ordered chronologically. + +`GET /v2/integrations/{integrationId}/monitoring/events/{eventId}/associated` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `eventId` | path | string | Yes | The event ID to get associated events for | + +**Sample Call** + +```bash +epilot integration-toolkit getAssociatedMonitoringEvents \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p eventId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getAssociatedMonitoringEvents 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getAssociatedMonitoringEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p eventId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'monitoring_events' +``` + +
+Sample Response + +```json +{ + "monitoring_events": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "integration_id": "string", + "event_id": "string", + "correlation_id": "string", + "use_case_id": "string", + "use_case_type": "inbound", + "level": "success", + "code": "string", + "message": "string", + "detail": {}, + "created_at": "1970-01-01T00:00:00.000Z" + } + ], + "inbound_event": {} +} +``` + +
+ +--- + +### `ingestExternalMonitoringEvents` + +Ingest monitoring spans produced by an EXTERNAL system (e.g. an integration + +`POST /v2/integrations/{integrationId}/monitoring/external-events` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit ingestExternalMonitoringEvents \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit ingestExternalMonitoringEvents \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "events": [ + { + "correlation_id": "string", + "level": "string", + "use_case_slug": "string", + "occurred_at": "1970-01-01T00:00:00.000Z", + "message": "string", + "detail": {} + } + ] +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit ingestExternalMonitoringEvents 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit ingestExternalMonitoringEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit ingestExternalMonitoringEvents -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `getMonitoringTraceByCorrelation` + +Returns the cross-system event trace for a `correlation_id`: every monitoring + +`GET /v2/integrations/{integrationId}/monitoring/traces/{correlationId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | The integration ID | +| `correlationId` | path | string | Yes | The trace id (correlation_id) shared across systems | + +**Sample Call** + +```bash +epilot integration-toolkit getMonitoringTraceByCorrelation \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -p correlationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getMonitoringTraceByCorrelation 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getMonitoringTraceByCorrelation -p integrationId=123e4567-e89b-12d3-a456-426614174000 -p correlationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'correlation_id' +``` + +
+Sample Response + +```json +{ + "correlation_id": "string", + "status": "success", + "started_at": "1970-01-01T00:00:00.000Z", + "ended_at": "1970-01-01T00:00:00.000Z", + "span_count": 0, + "truncated": true, + "spans": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "integration_id": "string", + "event_id": "string", + "correlation_id": "string", + "use_case_id": "string", + "use_case_type": "inbound", + "level": "success", + "code": "string", + "message": "string", + "detail": {}, + "created_at": "1970-01-01T00:00:00.000Z" + } + ], + "inbound_event": {} +} +``` + +
+ +--- + +### `listSecureProxies` + +Lists all secure_proxy use cases across all integrations for the authenticated organization. + +`GET /v1/integrations/secure-proxies` + +**Sample Call** + +```bash +epilot integration-toolkit listSecureProxies +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listSecureProxies --jsonata 'secure_proxies' +``` + +
+Sample Response + +```json +{ + "secure_proxies": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "enabled": true, + "vpc_mode": "static_ip", + "allowed_domains": ["string"], + "allowed_ips": ["string"], + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integration_name": "string" + } + ] +} +``` + +
+ +--- + +### `secureProxy` + +Routes an HTTP request through a VPC with either static IP egress or VPN secure link access. + +`POST /v1/secure-proxy` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit secureProxy +``` + +With request body: + +```bash +epilot integration-toolkit secureProxy \ + -d '{ + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "use_case_slug": "string", + "url": "https://example.com/path", + "method": "GET", + "headers": {}, + "body": {}, + "response_type": "json" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit secureProxy +``` + +With JSONata filter: + +```bash +epilot integration-toolkit secureProxy --jsonata 'status_code' +``` + +
+Sample Response + +```json +{ + "status_code": 0, + "headers": {}, + "body": {} +} +``` + +
+ +--- + +### `managedCallExecute` + +Execute a managed call operation synchronously. The slug in the path acts as the RPC method name. + +`POST /v1/managed-call/{slug}/execute` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | string | Yes | Use case slug (acts as the RPC method name) | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit managedCallExecute \ + -p slug=contact \ + -d '{"integration_id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","payload":{},"correlation_id":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit managedCallExecute contact +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit managedCallExecute -p slug=contact +``` + +With JSONata filter: + +```bash +epilot integration-toolkit managedCallExecute -p slug=contact --jsonata '$' +``` + +
+Sample Response + +```json +{} +``` + +
+ +--- + +### `generateTypesPreview` + +Analyses the JSONata mappings of all managed-call use cases in the integration and returns scaffolded type descriptors. + +`POST /v1/integrations/{integrationId}/generate-types-preview` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | | + +**Sample Call** + +```bash +epilot integration-toolkit generateTypesPreview \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit generateTypesPreview 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit generateTypesPreview -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'integration_name' +``` + +--- + +### `generateTypes` + +Generates a complete TypeScript npm package with typed interfaces for all managed-call use cases. This is a stateless op + +`POST /v1/integrations/{integrationId}/generate-types` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit generateTypes \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot integration-toolkit generateTypes \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "package_name": "@epilot/hems-cleverpv", + "version": "1.0.0", + "description": "string", + "domain_package": "@epilot/hems", + "domain_map_name": "HemsUseCaseMap", + "annotations": {} +}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit generateTypes 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit generateTypes -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit generateTypes -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'package_name' +``` + +
+Sample Response + +```json +{ + "package_name": "string", + "version": "string", + "files": {}, + "warnings": ["string"] +} +``` + +
+ +--- + +### `commitTypes` + +Commits the generated types by locking use case configurations and updating version tracking. Should be called after the + +`POST /v1/integrations/{integrationId}/commit-types` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `integrationId` | path | string (uuid) | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit commitTypes \ + -p integrationId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"package_name":"@epilot/hems-cleverpv","version":"1.0.0","annotations":{}}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit commitTypes 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit commitTypes -p integrationId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit commitTypes -p integrationId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'committed' +``` + +
+Sample Response + +```json +{ + "committed": true, + "warnings": ["string"] +} +``` + +
+ +--- + +### `listErpImports` + +List recent pricing-file import jobs for the org, newest first. + +`GET /v2/erp/imports` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `limit` | query | number | No | Page size. Values above 100 are clamped to 100. | +| `cursor` | query | string | No | Opaque cursor from a prior page's `next_cursor`. | + +**Sample Call** + +```bash +epilot integration-toolkit listErpImports +``` + +With JSONata filter: + +```bash +epilot integration-toolkit listErpImports --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "import_id": "string", + "org_id": "string", + "created_by": "string", + "integration_id": "string", + "use_case_slug": "string", + "format": "csv", + "status": "PENDING", + "s3_input_ref": { + "bucket": "string", + "key": "string" + }, + "size_bytes": 0, + "column_count": 0, + "validation": { + "total_rows": 0, + "blocking": 0, + "warnings": 0, + "entities": {}, + "entity_details": [ + { + "mapping_index": 0, + "entity_schema": "string", + "business_key": {}, + "variants": 0, + "versions": 0 + } + ], + "entity_details_truncated": true, + "issues": [ + { + "code": "UNIQUE_ID_COLUMN_MISSING", + "severity": "warning", + "columns": [ + { + "name": "string", + "entity": "string" + } + ], + "subject": "string", + "row": 0 + } + ] + }, + "progress": { + "processed_rows": 0, + "total_rows": 0 + }, + "error": { + "code": "VALIDATION_BLOCKED", + "message": "string" + }, + "correlation_id": "string", + "activity_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createErpImport` + +Register an already-uploaded file (S3 ref) as a pricing-file import job. Returns the job and a file preview. Nothing run + +`POST /v2/erp/imports` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit createErpImport \ + -d '{"s3_reference":{"bucket":"string","key":"string"},"include_preview":false,"import_id":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit createErpImport +``` + +With JSONata filter: + +```bash +epilot integration-toolkit createErpImport --jsonata 'job' +``` + +
+Sample Response + +```json +{ + "job": { + "import_id": "string", + "org_id": "string", + "created_by": "string", + "integration_id": "string", + "use_case_slug": "string", + "format": "csv", + "status": "PENDING", + "s3_input_ref": { + "bucket": "string", + "key": "string" + }, + "size_bytes": 0, + "column_count": 0, + "validation": { + "total_rows": 0, + "blocking": 0, + "warnings": 0, + "entities": {}, + "entity_details": [ + { + "mapping_index": 0, + "entity_schema": "string", + "business_key": {}, + "variants": 0, + "versions": 0 + } + ], + "entity_details_truncated": true, + "issues": [ + { + "code": "UNIQUE_ID_COLUMN_MISSING", + "severity": "warning", + "columns": [ + { + "name": "string", + "entity": "string" + } + ], + "subject": "string", + "row": 0 + } + ] + }, + "progress": { + "processed_rows": 0, + "total_rows": 0 + }, + "error": { + "code": "VALIDATION_BLOCKED", + "message": "string" + }, + "correlation_id": "string", + "activity_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + }, + "preview": { + "columns": ["string"], + "rows": [ + ["string"] + ] + } +} +``` + +
+ +--- + +### `getErpImport` + +Get a pricing-file import job (status, counts, result links). + +`GET /v2/erp/imports/{importId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `importId` | path | string | Yes | | + +**Sample Call** + +```bash +epilot integration-toolkit getErpImport \ + -p importId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit getErpImport 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit getErpImport -p importId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'import_id' +``` + +
+Sample Response + +```json +{ + "import_id": "string", + "org_id": "string", + "created_by": "string", + "integration_id": "string", + "use_case_slug": "string", + "format": "csv", + "status": "PENDING", + "s3_input_ref": { + "bucket": "string", + "key": "string" + }, + "size_bytes": 0, + "column_count": 0, + "validation": { + "total_rows": 0, + "blocking": 0, + "warnings": 0, + "entities": {}, + "entity_details": [ + { + "mapping_index": 0, + "entity_schema": "string", + "business_key": {}, + "variants": 0, + "versions": 0 + } + ], + "entity_details_truncated": true, + "issues": [ + { + "code": "UNIQUE_ID_COLUMN_MISSING", + "severity": "warning", + "columns": [ + { + "name": "string", + "entity": "string" + } + ], + "subject": "string", + "row": 0 + } + ] + }, + "progress": { + "processed_rows": 0, + "total_rows": 0 + }, + "error": { + "code": "VALIDATION_BLOCKED", + "message": "string" + }, + "correlation_id": "string", + "activity_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteErpImport` + +Remove an import and the file it owns. Allowed from any status: an import whose run is still in flight is stopped by the + +`DELETE /v2/erp/imports/{importId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `importId` | path | string | Yes | | + +**Sample Call** + +```bash +epilot integration-toolkit deleteErpImport \ + -p importId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit deleteErpImport 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit deleteErpImport -p importId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `validateErpImport` + +Choose the use case to read this file with, and start the validate phase. + +`POST /v2/erp/imports/{importId}:validate` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `importId` | path | string | Yes | | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot integration-toolkit validateErpImport \ + -p importId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"integration_id":"string","use_case_slug":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit validateErpImport 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit validateErpImport -p importId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit validateErpImport -p importId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `suggestErpImportUseCases` + +Rank the org's inbound use cases against this file's columns — the input to the ranked picker ("matches 6 of your 7 colu + +`POST /v2/erp/imports/{importId}:suggest-use-cases` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `importId` | path | string | Yes | | + +**Sample Call** + +```bash +epilot integration-toolkit suggestErpImportUseCases \ + -p importId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit suggestErpImportUseCases 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit suggestErpImportUseCases -p importId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'file_columns' +``` + +
+Sample Response + +```json +{ + "file_columns": 0, + "suggestions": [ + { + "integration_id": "string", + "integration_name": "string", + "use_case_slug": "string", + "use_case_name": "string", + "entity_types": 0, + "matched_columns": 0 + } + ] +} +``` + +
+ +--- + +### `executeErpImport` + +Confirm and run the write phase of a validated import. Only a READY job may be executed; any other status returns 409. + +`POST /v2/erp/imports/{importId}:execute` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `importId` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot integration-toolkit executeErpImport \ + -p importId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"ack_warnings":true}' +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit executeErpImport 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot integration-toolkit executeErpImport -p importId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit executeErpImport -p importId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `abortErpImport` + +Ask a running import to stop. Valid while the job is VALIDATING or PROCESSING; any other status returns 409. + +`POST /v2/erp/imports/{importId}:abort` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `importId` | path | string | Yes | | + +**Sample Call** + +```bash +epilot integration-toolkit abortErpImport \ + -p importId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot integration-toolkit abortErpImport 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot integration-toolkit abortErpImport -p importId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- diff --git a/docs/cli/commands/journey.md b/docs/cli/commands/journey.md index 6b8d3e5c..14f70e33 100644 --- a/docs/cli/commands/journey.md +++ b/docs/cli/commands/journey.md @@ -44,6 +44,13 @@ epilot journey getJourneysByOrgId -p id=123 - [`getJourneysByOrgId`](#getjourneysbyorgid) — Get all journeys by organization id - [`getJourney`](#getjourney) — Get journey by id. Private journeys requires valid private token to be passed - [`removeJourney`](#removejourney) — Remove journey by id +- [`listJourneyRevisions`](#listjourneyrevisions) — Lists the journey's revision history, newest first. Metadata only, no configuration payload. `is_published` says whether +- [`createJourneyRevision`](#createjourneyrevision) — Creates a revision: an immutable copy of the complete journey configuration, identified by `revision_id`. Nothing custom +- [`getJourneyRevision`](#getjourneyrevision) — Returns one revision with its full configuration, in the shape the builder holds a journey in, so it can be loaded strai +- [`publishJourneyRevision`](#publishjourneyrevision) — Makes one revision the published version, the one customers receive, in a single transaction: the revision's configurati +- [`getJourneyPublishState`](#getjourneypublishstate) — Answers which revision is the published version without paging through the history. A journey that has not adopted versi +- [`getJourneyEnvironment`](#getjourneyenvironment) — Resolve the environment variables referenced by this journey. Only browser-safe value types are returned. +- [`getJourneyEnvironmentVariables`](#getjourneyenvironmentvariables) — List the organization's environment variables that a journey block may use as an options source. Only Map variables that - [`getJourneyProducts`](#getjourneyproducts) — Get products available in the journey by id. requires public journey token to be passed. - [`createJourney`](#createjourney) — Create a Journey - [`updateJourney`](#updatejourney) — Update a Journey @@ -114,6 +121,8 @@ Get journey by id. Private journeys requires valid private token to be passed | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `id` | path | string (uuid) | Yes | Journey ID | +| `version` | query | number | No | Revision row to read. `0` (default) is the journey record, the published version every customer receives; a positive integer `n` reads revision row `n` (used by config-engine for history reads). Disti | +| `revision_id` | query | string | No | Serve the named revision instead of the published version, so a save-and-continue session can stay on the revision it started on. Only revisions that have been published at least once are served on th | | `source` | query | string | No | What source ID. Journey or Entity ID | | `orgId` | query | string | No | Organization ID | @@ -153,6 +162,7 @@ epilot journey getJourney -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata ' "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -188,10 +198,13 @@ epilot journey getJourney -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata ' "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -207,6 +220,7 @@ epilot journey getJourney -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata ' "templateId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "targetedCustomer": "string", "description": "string", "organizationSettings": {}, @@ -216,26 +230,35 @@ epilot journey getJourney -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata ' "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "useAustrianLabels": true, "enableDarkMode": true, "accessMode": "PUBLIC", + "authGate": { + "stepId": "string" + }, "isPublished": true, "status": "string", "isActive": true, "savingProgress": { - "savingMode": "auto", - "supportedVersion": 0 + "mode": "auto", + "supportedRevision": 0 }, "thirdPartyCookies": true }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "createdBy": "string", "updatedBy": "string", "__lastModifiedAt": "string", @@ -244,7 +267,8 @@ epilot journey getJourney -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata ' "deletedAt": "string", "version": 0, "revisions": 0, - "featureFlags": {} + "featureFlags": {}, + "revision_id": "42" } ``` @@ -285,6 +309,582 @@ epilot journey removeJourney -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonat --- +### `listJourneyRevisions` + +Lists the journey's revision history, newest first. Metadata only, no configuration payload. `is_published` says whether + +`GET /v1/journey/configuration/{id}/revisions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | Journey ID | +| `limit` | query | number | No | Maximum number of revisions to return | +| `cursor` | query | string | No | Opaque pagination cursor, taken from a previous response's `next_cursor` | + +**Sample Call** + +```bash +epilot journey listJourneyRevisions \ + -p id=509cdffe-424f-457a-95c2-9708c304ce77 +``` + +Using positional args for path parameters: + +```bash +epilot journey listJourneyRevisions 509cdffe-424f-457a-95c2-9708c304ce77 +``` + +With JSONata filter: + +```bash +epilot journey listJourneyRevisions -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "revision_id": "42", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "Summer campaign", + "description": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "is_published": true, + "mapping_config_version": 12 + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createJourneyRevision` + +Creates a revision: an immutable copy of the complete journey configuration, identified by `revision_id`. Nothing custom + +`POST /v1/journey/configuration/{id}/revisions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | Journey ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot journey createJourneyRevision \ + -p id=509cdffe-424f-457a-95c2-9708c304ce77 +``` + +With request body: + +```bash +epilot journey createJourneyRevision \ + -p id=509cdffe-424f-457a-95c2-9708c304ce77 \ + -d '{ + "journeyId": "string", + "organizationId": "string", + "brandId": "string", + "name": "string", + "steps": [ + { + "showStepName": true, + "title": "string", + "subTitle": "string", + "showStepSubtitle": true, + "showStepper": true, + "showStepperLabels": true, + "stepperType": "numbers", + "hideNextButton": true, + "name": "string", + "stepId": "string", + "schema": {}, + "uischema": {}, + "maxWidth": "small" + } + ], + "design": { + "logoUrl": "string", + "theme": {}, + "designTokens": {} + }, + "rules": [ + { + "type": "inject", + "sourceType": "journey", + "source": "string", + "target": "string" + } + ], + "logics": [ + { + "autoGeneratedId": "string", + "conditions": ["string"], + "actions": ["string"] + } + ], + "logicsV4": {}, + "contextSchema": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "paramKey": "string", + "isRequired": true, + "shouldLoadEntity": true, + "description": "string" + } + ], + "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], + "settings": { + "embedOptions": { + "mode": "full-screen", + "lang": "de", + "width": "string", + "topBar": true, + "scrollToTop": true, + "button": {} + }, + "safeModeAutomation": true, + "canary": true, + "designId": "string", + "templateId": "string", + "entityId": "string", + "mappingsAutomationId": "string", + "newMappings": true, + "targetedCustomer": "string", + "description": "string", + "organizationSettings": {}, + "publicToken": "string", + "runtimeEntities": ["ORDER"], + "filePurposes": ["string"], + "entityTags": ["string"], + "addressSuggestionsFileUrl": "string", + "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, + "useNewDesign": true, + "useAustrianLabels": true, + "enableDarkMode": true, + "accessMode": "PUBLIC", + "authGate": { + "stepId": "string" + }, + "isPublished": true, + "status": "string", + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + }, + "thirdPartyCookies": true + }, + "validationRules": { + "block1": "rule123", + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] + } + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "createdBy": "string", + "updatedBy": "string", + "__lastModifiedAt": "string", + "parent_revision_id": "41", + "based_on_revision_id": "37", + "mapping_config_version": 12, + "revision_name": "Changes to Steps and Logic" +}' +``` + +Using positional args for path parameters: + +```bash +epilot journey createJourneyRevision 509cdffe-424f-457a-95c2-9708c304ce77 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot journey createJourneyRevision -p id=509cdffe-424f-457a-95c2-9708c304ce77 +``` + +With JSONata filter: + +```bash +epilot journey createJourneyRevision -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata 'revision_id' +``` + +
+Sample Response + +```json +{ + "revision_id": "42", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "Summer campaign", + "description": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "is_published": true, + "mapping_config_version": 12 +} +``` + +
+ +--- + +### `getJourneyRevision` + +Returns one revision with its full configuration, in the shape the builder holds a journey in, so it can be loaded strai + +`GET /v1/journey/configuration/{id}/revisions/{revision_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | Journey ID | +| `revision_id` | path | string | Yes | Revision ID, as returned in a revision summary | + +**Sample Call** + +```bash +epilot journey getJourneyRevision \ + -p id=509cdffe-424f-457a-95c2-9708c304ce77 \ + -p revision_id=42 +``` + +Using positional args for path parameters: + +```bash +epilot journey getJourneyRevision 509cdffe-424f-457a-95c2-9708c304ce77 42 +``` + +With JSONata filter: + +```bash +epilot journey getJourneyRevision -p id=509cdffe-424f-457a-95c2-9708c304ce77 -p revision_id=42 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "revision_id": "42", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "Summer campaign", + "description": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "is_published": true, + "mapping_config_version": 12, + "configuration": { + "journeyId": "string", + "organizationId": "string", + "brandId": "string", + "name": "string", + "steps": [ + {} + ], + "design": { + "logoUrl": "string", + "theme": {}, + "designTokens": {} + }, + "rules": [ + {} + ], + "logics": [ + {} + ], + "logicsV4": {}, + "contextSchema": [ + {} + ], + "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], + "settings": { + "embedOptions": {}, + "safeModeAutomation": true, + "canary": true, + "designId": "string", + "templateId": "string", + "entityId": "string", + "mappingsAutomationId": "string", + "newMappings": true, + "targetedCustomer": "string", + "description": "string", + "organizationSettings": {}, + "publicToken": "string", + "runtimeEntities": ["ORDER"], + "filePurposes": ["string"], + "entityTags": ["string"], + "addressSuggestionsFileUrl": "string", + "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, + "useNewDesign": true, + "useAustrianLabels": true, + "enableDarkMode": true, + "accessMode": "PUBLIC", + "authGate": {}, + "isPublished": true, + "status": "string", + "isActive": true, + "savingProgress": {}, + "thirdPartyCookies": true + }, + "validationRules": { + "block1": "rule123", + "block2": ["rule456", "rule789"], + "block3": {} + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "createdBy": "string", + "updatedBy": "string", + "__lastModifiedAt": "string", + "createdAt": "string", + "lastModifiedAt": "string", + "deletedAt": "string", + "version": 0, + "revisions": 0, + "featureFlags": {} + } +} +``` + +
+ +--- + +### `publishJourneyRevision` + +Makes one revision the published version, the one customers receive, in a single transaction: the revision's configurati + +`POST /v1/journey/configuration/{id}/publish` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | Journey ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot journey publishJourneyRevision \ + -p id=509cdffe-424f-457a-95c2-9708c304ce77 \ + -d '{"revision_id":"42","name":"Summer campaign","description":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot journey publishJourneyRevision 509cdffe-424f-457a-95c2-9708c304ce77 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot journey publishJourneyRevision -p id=509cdffe-424f-457a-95c2-9708c304ce77 +``` + +With JSONata filter: + +```bash +epilot journey publishJourneyRevision -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata 'revision_id' +``` + +
+Sample Response + +```json +{ + "revision_id": "42", + "name": "Summer campaign", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "post_publish_warnings": ["string"] +} +``` + +
+ +--- + +### `getJourneyPublishState` + +Answers which revision is the published version without paging through the history. A journey that has not adopted versi + +`GET /v1/journey/configuration/{id}/publish-state` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | Journey ID | + +**Sample Call** + +```bash +epilot journey getJourneyPublishState \ + -p id=509cdffe-424f-457a-95c2-9708c304ce77 +``` + +Using positional args for path parameters: + +```bash +epilot journey getJourneyPublishState 509cdffe-424f-457a-95c2-9708c304ce77 +``` + +With JSONata filter: + +```bash +epilot journey getJourneyPublishState -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata 'journey_id' +``` + +
+Sample Response + +```json +{ + "journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "published_revision_id": "42", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string" +} +``` + +
+ +--- + +### `getJourneyEnvironment` + +Resolve the environment variables referenced by this journey. Only browser-safe value types are returned. + +`GET /v1/journey/configuration/{id}/environment` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string (uuid) | Yes | Journey ID bound to the supplied journey access token | + +**Sample Call** + +```bash +epilot journey getJourneyEnvironment \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot journey getJourneyEnvironment 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot journey getJourneyEnvironment -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'items[0]' +``` + +
+Sample Response + +```json +{ + "items": [ + { + "datasourceId": "string", + "type": "Text", + "value": "string" + } + ], + "errors": [ + { + "datasourceId": "string", + "code": "not_found" + } + ] +} +``` + +
+ +--- + +### `getJourneyEnvironmentVariables` + +List the organization's environment variables that a journey block may use as an options source. Only Map variables that + +`GET /v1/journey/environment-variables` + +**Sample Call** + +```bash +epilot journey getJourneyEnvironmentVariables +``` + +With JSONata filter: + +```bash +epilot journey getJourneyEnvironmentVariables --jsonata 'items[0]' +``` + +
+Sample Response + +```json +{ + "items": [ + { + "key": "string", + "type": "Map", + "value": { + "fallbackLanguage": "de", + "options": [ + { + "key": "string", + "value": "string" + } + ] + }, + "description": "string" + } + ] +} +``` + +
+ +--- + ### `getJourneyProducts` Get products available in the journey by id. requires public journey token to be passed. @@ -335,10 +935,16 @@ epilot journey getJourneyProducts -p id=509cdffe-424f-457a-95c2-9708c304ce77 --j "_org": "string", "code": "string", "description": "string", - "feature": [], - "product_images": [], + "feature": [ + {} + ], + "product_images": [ + {} + ], "legal_footnote": "string", - "product_downloads": [], + "product_downloads": [ + {} + ], "price": {} } ] @@ -385,6 +991,7 @@ epilot journey createJourney \ "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -420,10 +1027,13 @@ epilot journey createJourney \ "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -439,6 +1049,7 @@ epilot journey createJourney \ "templateId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "targetedCustomer": "string", "description": "string", "organizationSettings": {}, @@ -448,26 +1059,35 @@ epilot journey createJourney \ "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "useAustrianLabels": true, "enableDarkMode": true, "accessMode": "PUBLIC", + "authGate": { + "stepId": "string" + }, "isPublished": true, "status": "string", "isActive": true, "savingProgress": { - "savingMode": "auto", - "supportedVersion": 0 + "mode": "auto", + "supportedRevision": 0 }, "thirdPartyCookies": true }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "createdBy": "string", "updatedBy": "string", "__lastModifiedAt": "string" @@ -503,6 +1123,7 @@ epilot journey createJourney --jsonata '$' "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -538,10 +1159,13 @@ epilot journey createJourney --jsonata '$' "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -557,6 +1181,7 @@ epilot journey createJourney --jsonata '$' "templateId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "targetedCustomer": "string", "description": "string", "organizationSettings": {}, @@ -566,26 +1191,35 @@ epilot journey createJourney --jsonata '$' "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "useAustrianLabels": true, "enableDarkMode": true, "accessMode": "PUBLIC", + "authGate": { + "stepId": "string" + }, "isPublished": true, "status": "string", "isActive": true, "savingProgress": { - "savingMode": "auto", - "supportedVersion": 0 + "mode": "auto", + "supportedRevision": 0 }, "thirdPartyCookies": true }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "createdBy": "string", "updatedBy": "string", "__lastModifiedAt": "string", @@ -633,6 +1267,7 @@ epilot journey updateJourney \ "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -668,10 +1303,13 @@ epilot journey updateJourney \ "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -687,6 +1325,7 @@ epilot journey updateJourney \ "templateId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "targetedCustomer": "string", "description": "string", "organizationSettings": {}, @@ -696,26 +1335,35 @@ epilot journey updateJourney \ "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "useAustrianLabels": true, "enableDarkMode": true, "accessMode": "PUBLIC", + "authGate": { + "stepId": "string" + }, "isPublished": true, "status": "string", "isActive": true, "savingProgress": { - "savingMode": "auto", - "supportedVersion": 0 + "mode": "auto", + "supportedRevision": 0 }, "thirdPartyCookies": true }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "createdBy": "string", "updatedBy": "string", "__lastModifiedAt": "string" @@ -792,6 +1440,8 @@ epilot journey patchUpdateJourney --jsonata 'createdJourney' {} ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": {}, "safeModeAutomation": true, @@ -800,6 +1450,7 @@ epilot journey patchUpdateJourney --jsonata 'createdJourney' "templateId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "targetedCustomer": "string", "description": "string", "organizationSettings": {}, @@ -809,10 +1460,15 @@ epilot journey patchUpdateJourney --jsonata 'createdJourney' "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "useAustrianLabels": true, "enableDarkMode": true, "accessMode": "PUBLIC", + "authGate": {}, "isPublished": true, "status": "string", "isActive": true, @@ -821,8 +1477,10 @@ epilot journey patchUpdateJourney --jsonata 'createdJourney' }, "validationRules": { "block1": "rule123", - "block2": {} + "block2": ["rule456", "rule789"], + "block3": {} }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "createdBy": "string", "updatedBy": "string", "__lastModifiedAt": "string", @@ -912,9 +1570,22 @@ Builds document generated from a template with journey values." **Sample Call** +```bash +epilot journey generateDocument +``` + +With request body: + ```bash epilot journey generateDocument \ - -d '{"file_id":"1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p","context_data":{"additionalProperties":"string"},"language":"de"}' + -d '{ + "file_id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p", + "context_data": { + "additionalProperties": "string" + }, + "context_entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "language": "de" +}' ``` Using stdin pipe: @@ -972,7 +1643,7 @@ epilot journey generateDocument --jsonata 'job_id' "template_with_datatable": false, "enabled_template_settings_persistence": false, "misconfigured_margins": false, - "file_entity_id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p" + "file_entity_id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d" } } ``` @@ -1017,6 +1688,7 @@ epilot journey createJourneyV2 \ "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -1052,10 +1724,13 @@ epilot journey createJourneyV2 \ "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1069,6 +1744,7 @@ epilot journey createJourneyV2 \ "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1078,16 +1754,30 @@ epilot journey createJourneyV2 \ "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1122,6 +1812,7 @@ epilot journey createJourneyV2 --jsonata 'journeyId' "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -1157,10 +1848,13 @@ epilot journey createJourneyV2 --jsonata 'journeyId' "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1174,6 +1868,7 @@ epilot journey createJourneyV2 --jsonata 'journeyId' "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1183,16 +1878,30 @@ epilot journey createJourneyV2 --jsonata 'journeyId' "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1233,6 +1942,7 @@ epilot journey updateJourneyV2 \ "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -1268,10 +1978,13 @@ epilot journey updateJourneyV2 \ "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1285,6 +1998,7 @@ epilot journey updateJourneyV2 \ "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1294,16 +2008,30 @@ epilot journey updateJourneyV2 \ "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1338,6 +2066,7 @@ epilot journey updateJourneyV2 --jsonata 'journeyId' "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -1373,10 +2102,13 @@ epilot journey updateJourneyV2 --jsonata 'journeyId' "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1390,6 +2122,7 @@ epilot journey updateJourneyV2 --jsonata 'journeyId' "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1399,16 +2132,30 @@ epilot journey updateJourneyV2 --jsonata 'journeyId' "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1462,6 +2209,7 @@ epilot journey patchUpdateJourneyV2 --jsonata 'journeyId' "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -1497,10 +2245,13 @@ epilot journey patchUpdateJourneyV2 --jsonata 'journeyId' "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1514,6 +2265,7 @@ epilot journey patchUpdateJourneyV2 --jsonata 'journeyId' "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1523,16 +2275,30 @@ epilot journey patchUpdateJourneyV2 --jsonata 'journeyId' "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1554,6 +2320,7 @@ Get journey by id | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `id` | path | string (uuid) | Yes | Journey ID | +| `version` | query | number | No | Revision row to read. `0` (default) is the journey record, the published version every customer receives; a positive integer `n` reads revision row `n` (used by config-engine for history reads). Disti | **Sample Call** @@ -1571,7 +2338,7 @@ epilot journey getJourneyV2 509cdffe-424f-457a-95c2-9708c304ce77 With JSONata filter: ```bash -epilot journey getJourneyV2 -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata 'journeyId' +epilot journey getJourneyV2 -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata '$' ```
@@ -1590,6 +2357,7 @@ epilot journey getJourneyV2 -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, "name": "string", "stepId": "string", @@ -1625,10 +2393,13 @@ epilot journey getJourneyV2 -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1642,6 +2413,7 @@ epilot journey getJourneyV2 -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1651,16 +2423,30 @@ epilot journey getJourneyV2 -p id=509cdffe-424f-457a-95c2-9708c304ce77 --jsonata "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] diff --git a/docs/cli/commands/kanban.md b/docs/cli/commands/kanban.md index 5a6e0ec3..6e09215d 100644 --- a/docs/cli/commands/kanban.md +++ b/docs/cli/commands/kanban.md @@ -8,6 +8,8 @@ description: "epilot CLI commands for the Kanban API: quick start, common flags - **Base URL:** `https://kanban.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/kanban](https://docs.epilot.io/api/kanban) +The Kanban API provides board management and data query capabilities for epilot's Kanban view feature. + ## Quick Start ```bash @@ -39,26 +41,26 @@ epilot kanban createKanbanBoard ## Operations **Kanban** -- [`createKanbanBoard`](#createkanbanboard) — Create a Kanban board -- [`getKanbanBoards`](#getkanbanboards) — Get all Kanban boards -- [`getKanbanBoard`](#getkanbanboard) — Get a Kanban board by ID. Use "default" as the boardId to get the organization's default board. -- [`updateKanbanBoard`](#updatekanbanboard) — Update a Kanban board -- [`patchKanbanBoard`](#patchkanbanboard) — Patch a Kanban board -- [`deleteKanbanBoard`](#deletekanbanboard) — Delete a Kanban board -- [`setDefaultKanbanBoard`](#setdefaultkanbanboard) — Set a board as the default board for the organization -- [`clearDefaultKanbanBoard`](#cleardefaultkanbanboard) — Remove the default board setting for the organization +- [`createKanbanBoard`](#createkanbanboard) — Creates a new Kanban board with the provided configuration. +- [`getKanbanBoards`](#getkanbanboards) — Returns a list of all Kanban boards accessible to the authenticated user. +- [`getKanbanBoard`](#getkanbanboard) — Retrieves a Kanban board by ID, including its full configuration (swimlanes, filters, sorting, card fields). +- [`updateKanbanBoard`](#updatekanbanboard) — Fully replaces the configuration of an existing Kanban board by ID. +- [`patchKanbanBoard`](#patchkanbanboard) — Partially updates fields of an existing Kanban board by ID. +- [`deleteKanbanBoard`](#deletekanbanboard) — Permanently deletes a Kanban board by ID. This action is irreversible. +- [`setDefaultKanbanBoard`](#setdefaultkanbanboard) — Sets a Kanban board as the default board for the organization. +- [`clearDefaultKanbanBoard`](#cleardefaultkanbanboard) — Removes the default board configuration for the organization. **Query** -- [`flowsAutocomplete`](#flowsautocomplete) — Autocomplete flows data -- [`executeFlowsQuery`](#executeflowsquery) — Query Flows Data for Kanban View. +- [`flowsAutocomplete`](#flowsautocomplete) — Returns autocomplete suggestions for a given attribute in the Flows dataset. +- [`executeFlowsQuery`](#executeflowsquery) — Executes a query against the Flows dataset and returns paginated results for use in Kanban card rendering. ### `createKanbanBoard` -Create a Kanban board +Creates a new Kanban board with the provided configuration. `POST /v1/kanban/board` -**Request Body** +**Request Body** (required) **Sample Call** @@ -121,6 +123,9 @@ epilot kanban createKanbanBoard \ "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } }' @@ -193,6 +198,9 @@ epilot kanban createKanbanBoard --jsonata '$' "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } } @@ -204,7 +212,7 @@ epilot kanban createKanbanBoard --jsonata '$' ### `getKanbanBoards` -Get all Kanban boards +Returns a list of all Kanban boards accessible to the authenticated user. `GET /v1/kanban/boards` @@ -253,7 +261,7 @@ epilot kanban getKanbanBoards --jsonata '$' ### `getKanbanBoard` -Get a Kanban board by ID. Use "default" as the boardId to get the organization's default board. +Retrieves a Kanban board by ID, including its full configuration (swimlanes, filters, sorting, card fields). `GET /v1/kanban/board/{boardId}` @@ -338,6 +346,9 @@ epilot kanban getKanbanBoard -p boardId=board-123 --jsonata '$' "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } } @@ -349,7 +360,7 @@ epilot kanban getKanbanBoard -p boardId=board-123 --jsonata '$' ### `updateKanbanBoard` -Update a Kanban board +Fully replaces the configuration of an existing Kanban board by ID. `PUT /v1/kanban/board/{boardId}` @@ -357,9 +368,9 @@ Update a Kanban board | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `boardId` | path | string | Yes | | +| `boardId` | path | string | Yes | The ID of the board to update. | -**Request Body** +**Request Body** (required) **Sample Call** @@ -424,6 +435,9 @@ epilot kanban updateKanbanBoard \ "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } }' @@ -502,6 +516,9 @@ epilot kanban updateKanbanBoard -p boardId=123e4567-e89b-12d3-a456-426614174000 "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } } @@ -513,7 +530,7 @@ epilot kanban updateKanbanBoard -p boardId=123e4567-e89b-12d3-a456-426614174000 ### `patchKanbanBoard` -Patch a Kanban board +Partially updates fields of an existing Kanban board by ID. `PATCH /v1/kanban/board/{boardId}` @@ -521,9 +538,9 @@ Patch a Kanban board | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `boardId` | path | string | Yes | | +| `boardId` | path | string | Yes | The ID of the board to patch. | -**Request Body** +**Request Body** (required) **Sample Call** @@ -619,6 +636,9 @@ epilot kanban patchKanbanBoard -p boardId=123e4567-e89b-12d3-a456-426614174000 - "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } } @@ -630,7 +650,7 @@ epilot kanban patchKanbanBoard -p boardId=123e4567-e89b-12d3-a456-426614174000 - ### `deleteKanbanBoard` -Delete a Kanban board +Permanently deletes a Kanban board by ID. This action is irreversible. `DELETE /v1/kanban/board/{boardId}` @@ -638,7 +658,7 @@ Delete a Kanban board | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `boardId` | path | string | Yes | | +| `boardId` | path | string | Yes | The ID of the board to delete. | **Sample Call** @@ -663,7 +683,7 @@ epilot kanban deleteKanbanBoard -p boardId=123e4567-e89b-12d3-a456-426614174000 ### `setDefaultKanbanBoard` -Set a board as the default board for the organization +Sets a Kanban board as the default board for the organization. `PUT /v1/kanban/org/default-board` @@ -677,13 +697,13 @@ Set a board as the default board for the organization ```bash epilot kanban setDefaultKanbanBoard \ - -p boardId=123e4567-e89b-12d3-a456-426614174000 + -p boardId=board-abc123 ``` With JSONata filter: ```bash -epilot kanban setDefaultKanbanBoard -p boardId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'message' +epilot kanban setDefaultKanbanBoard -p boardId=board-abc123 --jsonata 'message' ```
@@ -702,7 +722,7 @@ epilot kanban setDefaultKanbanBoard -p boardId=123e4567-e89b-12d3-a456-426614174 ### `clearDefaultKanbanBoard` -Remove the default board setting for the organization +Removes the default board configuration for the organization. `DELETE /v1/kanban/org/default-board` @@ -734,7 +754,7 @@ epilot kanban clearDefaultKanbanBoard --jsonata 'message' ### `flowsAutocomplete` -Autocomplete flows data +Returns autocomplete suggestions for a given attribute in the Flows dataset. `GET /v1/kanban/query/flows:autocomplete` @@ -742,8 +762,8 @@ Autocomplete flows data | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `input` | query | string | No | Input to autocomplete | -| `attribute` | query | string | Yes | Autocomplete attribute | +| `input` | query | string | No | Typed input string to filter autocomplete suggestions | +| `attribute` | query | string | Yes | The field name to autocomplete values for | | `size` | query | number | No | Maximum number of results to return | | `from` | query | number | No | Starting offset for pagination | @@ -776,11 +796,11 @@ epilot kanban flowsAutocomplete -p attribute=name --jsonata 'results[0]' ### `executeFlowsQuery` -Query Flows Data for Kanban View. +Executes a query against the Flows dataset and returns paginated results for use in Kanban card rendering. `POST /v1/kanban/query/flows:execute` -**Request Body** +**Request Body** (required) **Sample Call** @@ -808,6 +828,9 @@ epilot kanban executeFlowsQuery \ "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "from": 0, "size": 10 }' @@ -833,10 +856,10 @@ epilot kanban executeFlowsQuery --jsonata 'results[0]' "results": [ {} ], - "hits": 0, - "page_number": 0, - "page_size": 0, - "total_pages": 0 + "hits": 42, + "page_number": 1, + "page_size": 10, + "total_pages": 5 } ``` diff --git a/docs/cli/commands/message.md b/docs/cli/commands/message.md index a8323ea7..b11cb1bd 100644 --- a/docs/cli/commands/message.md +++ b/docs/cli/commands/message.md @@ -53,13 +53,17 @@ epilot message sendMessage - [`markReadMessageV2`](#markreadmessagev2) — Mark message as read within a scope - [`markUnreadMessage`](#markunreadmessage) — Mark message as unread - [`getUnread`](#getunread) — Get all unread messages by actor +- [`getUnreadCounts`](#getunreadcounts) — Unread counts for several named scopes in one request. - [`markUnreadMessageV2`](#markunreadmessagev2) — Mark message as unread within a scope +- [`spamMessage`](#spammessage) — Mark a single message as spam. Also marks the parent thread as spam if all messages in the thread are spam. +- [`unspamMessage`](#unspammessage) — Remove spam marking from a single message. Also removes spam from the parent thread if no other messages are spam. - [`getMessageV2`](#getmessagev2) — - Fetches message by ID **Threads** - [`searchThreads`](#searchthreads) — Search for threads of email messages. - [`searchThreadsV2`](#searchthreadsv2) — Search for threads of email messages. - [`searchIds`](#searchids) — Return all thread id's that match a criteria +- [`getAssigneeWorkload`](#getassigneeworkload) — Return the open-thread workload for a set of user ids. - [`updateThread`](#updatethread) — Modify thread metadata - [`deleteThread`](#deletethread) — Immediately and permanently delete a thread. This operation cannot be undone. - [`moveThread`](#movethread) — Move thread to a different Inbox @@ -68,6 +72,10 @@ epilot message sendMessage - [`getThreadTimeline`](#getthreadtimeline) — Get thread timeline - [`trashThread`](#trashthread) — Move a thread to trash - [`untrashThread`](#untrashthread) — Restore a trashed thread +- [`spamThread`](#spamthread) — Mark a thread as spam +- [`unspamThread`](#unspamthread) — Remove spam marking from a thread +- [`bulkMoveThreads`](#bulkmovethreads) — Move many threads to a different inbox +- [`bulkAssignThreads`](#bulkassignthreads) — Assign many threads - [`threadBulkActionsRead`](#threadbulkactionsread) — Perform a bulk action of marking an array of thread ids as read - [`threadBulkActionsUnread`](#threadbulkactionsunread) — Perform a bulk action of marking an array of thread ids as unread - [`threadBulkActionsFavorite`](#threadbulkactionsfavorite) — Perform a bulk action of marking an array of thread ids favorite @@ -168,6 +176,7 @@ epilot message updateMessage --jsonata '$' "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -221,7 +230,8 @@ epilot message updateMessage --jsonata '$' "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -284,6 +294,7 @@ epilot message getMessage -p id=4d74976d-fb64-47fd-85e2-65eea140f5eb --jsonata ' "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -337,7 +348,8 @@ epilot message getMessage -p id=4d74976d-fb64-47fd-85e2-65eea140f5eb --jsonata ' "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -442,6 +454,24 @@ epilot message searchMessages \ -d '{ "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3", "q": "subject:\"Request for solar panel price\" AND _tags:INBOX", + "view": { + "folder": "inbox", + "mailbox": "organization", + "labels": ["string"], + "purposes": ["string"], + "filters": ["unread"], + "from": ["string"], + "to": ["string"], + "assigned_to": ["string"], + "include_unassigned": true, + "date_from_days_ago": 0, + "date_to_days_ago": 0, + "email_filter": ["string"], + "text": "string", + "thread_ids": ["string"], + "pinned_by": "string" + }, + "user_groups": ["string"], "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"], "from": 0, "size": 10, @@ -481,63 +511,16 @@ epilot message searchMessages --jsonata 'results[0]' "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", - "from": { - "name": "epilot", - "address": "messaging@epilot.cloud", - "email_type": "INTERNAL", - "send_status": "SEND", - "send_error": {} - }, - "reply_to": { - "name": "epilot", - "address": "messaging@epilot.cloud", - "email_type": "INTERNAL", - "send_status": "SEND", - "send_error": {} - }, - "to": [ - { - "name": "epilot", - "address": "messaging@epilot.cloud", - "email_type": "INTERNAL", - "send_status": "SEND", - "send_error": {} - } - ], - "cc": [ - { - "name": "epilot", - "address": "messaging@epilot.cloud", - "email_type": "INTERNAL", - "send_status": "SEND", - "send_error": {} - } - ], - "bcc": [ - { - "name": "epilot", - "address": "messaging@epilot.cloud", - "email_type": "INTERNAL", - "send_status": "SEND", - "send_error": {} - } - ], - "file": { - "$relation": [ - { - "entity_id": "f820ce3b-07b0-45ae-bcc6-babb2f53f79f", - "filename": "Produktinformationen_epilot360_Double_Opt_in.pdf", - "is_message_attachment": true, - "may_be_signature_attachment": true, - "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", - "inline": false, - "send_as_link": false - } - ] - }, + "from": {}, + "reply_to": {}, + "to": [], + "cc": [], + "bcc": [], + "file": {}, "references": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com> ", "in_reply_to": "", "user_read_message": ["206801", "200109"], @@ -768,7 +751,69 @@ epilot message getUnread -p actor=example --jsonata 'count' "count": 14, "unread": 0, "drafts": 12, - "unassigned": 1 + "unassigned": 1, + "spam": 3 +} +``` + +
+ +--- + +### `getUnreadCounts` + +Unread counts for several named scopes in one request. + +`POST /v1/message/unread:counts` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot message getUnreadCounts +``` + +With request body: + +```bash +epilot message getUnreadCounts \ + -d '{ + "actor": "organization", + "email_filter": ["string"], + "user_groups": ["string"], + "scopes": [ + { + "name": "inbox-support", + "type": "organization", + "q": "_tags.keyword:inbox AND !_tags.keyword:trash", + "view_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3", + "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3" + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot message getUnreadCounts +``` + +With JSONata filter: + +```bash +epilot message getUnreadCounts --jsonata 'enabled' +``` + +
+Sample Response + +```json +{ + "enabled": true, + "counts": {}, + "omitted": ["string"] } ``` @@ -897,6 +942,24 @@ epilot message searchThreadsV2 \ -d '{ "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3", "q": "subject:\"Request for solar panel price\" AND _tags:INBOX", + "view": { + "folder": "inbox", + "mailbox": "organization", + "labels": ["string"], + "purposes": ["string"], + "filters": ["unread"], + "from": ["string"], + "to": ["string"], + "assigned_to": ["string"], + "include_unassigned": true, + "date_from_days_ago": 0, + "date_to_days_ago": 0, + "email_filter": ["string"], + "text": "string", + "thread_ids": ["string"], + "pinned_by": "string" + }, + "user_groups": ["string"], "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"], "from": 0, "size": 10, @@ -960,9 +1023,36 @@ Return all thread id's that match a criteria **Sample Call** +```bash +epilot message searchIds +``` + +With request body: + ```bash epilot message searchIds \ - -d '{"q":"subject:\"Request for solar panel price\" AND _tags:INBOX"}' + -d '{ + "view": { + "folder": "inbox", + "mailbox": "organization", + "labels": ["string"], + "purposes": ["string"], + "filters": ["unread"], + "from": ["string"], + "to": ["string"], + "assigned_to": ["string"], + "include_unassigned": true, + "date_from_days_ago": 0, + "date_to_days_ago": 0, + "email_filter": ["string"], + "text": "string", + "thread_ids": ["string"], + "pinned_by": "string" + }, + "user_groups": ["string"], + "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3", + "q": "subject:\"Request for solar panel price\" AND _tags:INBOX" +}' ``` Using stdin pipe: @@ -991,6 +1081,51 @@ epilot message searchIds --jsonata 'results[0]' --- +### `getAssigneeWorkload` + +Return the open-thread workload for a set of user ids. + +`POST /v2/message/threads:workload` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot message getAssigneeWorkload \ + -d '{"user_ids":["11000902","11001053"]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot message getAssigneeWorkload +``` + +With JSONata filter: + +```bash +epilot message getAssigneeWorkload --jsonata 'workloads' +``` + +
+Sample Response + +```json +{ + "workloads": [ + { + "user_id": "11000902", + "open_threads": 2 + } + ] +} +``` + +
+ +--- + ### `updateThread` Modify thread metadata @@ -1028,6 +1163,7 @@ epilot message updateThread --jsonata '$' "latest_message": { "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -1068,6 +1204,7 @@ epilot message updateThread --jsonata '$' "latest_trash_message": { "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -1292,12 +1429,24 @@ epilot message getThreadTimeline -p id=123e4567-e89b-12d3-a456-426614174000 --js { "events": [ { + "id": "string", "data": { "type": "THREAD_DONE", "user_id": "123", "organization_id": "456" }, - "timestamp": "2024-01-01T00:00:00.000Z" + "timestamp": "2024-01-01T00:00:00.000Z", + "message_id": "string", + "source": "user", + "automated": true, + "actor": { + "user_id": "string", + "email": "string" + }, + "automation": { + "id": "string", + "name": "string" + } } ] } @@ -1373,6 +1522,218 @@ epilot message untrashThread -p id=123e4567-e89b-12d3-a456-426614174000 --jsonat --- +### `spamThread` + +Mark a thread as spam + +`POST /v1/message/threads/{id}/spam` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Thread ID | + +**Sample Call** + +```bash +epilot message spamThread \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot message spamThread 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot message spamThread -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `unspamThread` + +Remove spam marking from a thread + +`POST /v1/message/threads/{id}/unspam` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Thread ID | + +**Sample Call** + +```bash +epilot message unspamThread \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot message unspamThread 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot message unspamThread -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `spamMessage` + +Mark a single message as spam. Also marks the parent thread as spam if all messages in the thread are spam. + +`POST /v1/message/messages/{id}/spam` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Message ID | + +**Sample Call** + +```bash +epilot message spamMessage \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot message spamMessage 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot message spamMessage -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `unspamMessage` + +Remove spam marking from a single message. Also removes spam from the parent thread if no other messages are spam. + +`POST /v1/message/messages/{id}/unspam` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | Message ID | + +**Sample Call** + +```bash +epilot message unspamMessage \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot message unspamMessage 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot message unspamMessage -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `bulkMoveThreads` + +Move many threads to a different inbox + +`POST /v1/message/threads/bulk:move` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot message bulkMoveThreads +``` + +With request body: + +```bash +epilot message bulkMoveThreads \ + -d '{ + "ids": ["6b299eda-4018-4554-8965-c4b5598e6531"], + "assign_to": ["206801"], + "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3", + "scopes": ["organization", "user"] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot message bulkMoveThreads +``` + +With JSONata filter: + +```bash +epilot message bulkMoveThreads --jsonata '$' +``` + +--- + +### `bulkAssignThreads` + +Assign many threads + +`POST /v1/message/threads/bulk:assign` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot message bulkAssignThreads +``` + +With request body: + +```bash +epilot message bulkAssignThreads \ + -d '{ + "ids": ["6b299eda-4018-4554-8965-c4b5598e6531"], + "assign_to": ["206801"], + "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3", + "scopes": ["organization", "user"] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot message bulkAssignThreads +``` + +With JSONata filter: + +```bash +epilot message bulkAssignThreads --jsonata '$' +``` + +--- + ### `threadBulkActionsRead` Perform a bulk action of marking an array of thread ids as read @@ -1383,9 +1744,20 @@ Perform a bulk action of marking an array of thread ids as read **Sample Call** +```bash +epilot message threadBulkActionsRead +``` + +With request body: + ```bash epilot message threadBulkActionsRead \ - -d '{"ids":["6b299eda-4018-4554-8965-c4b5598e6531"],"scopes":["organization","user"]}' + -d '{ + "ids": ["6b299eda-4018-4554-8965-c4b5598e6531"], + "assign_to": ["206801"], + "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3", + "scopes": ["organization", "user"] +}' ``` Using stdin pipe: @@ -1412,9 +1784,20 @@ Perform a bulk action of marking an array of thread ids as unread **Sample Call** +```bash +epilot message threadBulkActionsUnread +``` + +With request body: + ```bash epilot message threadBulkActionsUnread \ - -d '{"ids":["6b299eda-4018-4554-8965-c4b5598e6531"],"scopes":["organization","user"]}' + -d '{ + "ids": ["6b299eda-4018-4554-8965-c4b5598e6531"], + "assign_to": ["206801"], + "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3", + "scopes": ["organization", "user"] +}' ``` Using stdin pipe: @@ -1837,6 +2220,7 @@ Unassign thread from entities | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `id` | path | string | Yes | Thread ID | +| `unlink_mapped_entities` | query | boolean | No | When true, also removes unassigned entities from mapped_entities on related source entities | **Request Body** (required) @@ -2059,6 +2443,7 @@ epilot message createDraft --jsonata '$' "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -2112,7 +2497,8 @@ epilot message createDraft --jsonata '$' "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -2162,6 +2548,7 @@ epilot message sendDraft --jsonata '$' "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -2215,7 +2602,8 @@ epilot message sendDraft --jsonata '$' "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -2280,6 +2668,7 @@ epilot message getMessageV2 -p id=4d74976d-fb64-47fd-85e2-65eea140f5eb --jsonata "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -2333,7 +2722,8 @@ epilot message getMessageV2 -p id=4d74976d-fb64-47fd-85e2-65eea140f5eb --jsonata "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, diff --git a/docs/cli/commands/metering.md b/docs/cli/commands/metering.md index 8b1be534..5504834c 100644 --- a/docs/cli/commands/metering.md +++ b/docs/cli/commands/metering.md @@ -8,6 +8,8 @@ description: "epilot CLI commands for the Metering API: quick start, common flag - **Base URL:** `https://metering.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/metering](https://docs.epilot.io/api/metering) +The Metering API manages smart meter data, meter counters, and meter readings for epilot customers and administrators. + ## Quick Start ```bash @@ -39,31 +41,44 @@ epilot metering getCustomerMeters ## Operations **ECP** -- [`getCustomerMeters`](#getcustomermeters) — Retrieves all meters related to a customer. -- [`getMetersByContractId`](#getmetersbycontractid) — Retrieves all meters related to a contract. -- [`getMeter`](#getmeter) — Retrieves the details of a meter. -- [`updateMeter`](#updatemeter) — Updates the details of a meter. -- [`getMeterCounters`](#getmetercounters) — Retrieves all counters for a given meter. -- [`getCounterDetails`](#getcounterdetails) — Retrieves the details of a meter counter. -- [`createPortalMeterReadings`](#createportalmeterreadings) — Inserts multiple meter readings at once for a given meter. Limited to 2 readings per request. +- [`getCustomerMeters`](#getcustomermeters) — Retrieves all meters associated with the authenticated portal customer. +- [`getMetersByContractId`](#getmetersbycontractid) — Retrieves all meters associated with a given contract entity. +- [`getMeter`](#getmeter) — Retrieves the full details of a specific meter by ID, including related entities and available journey actions. +- [`updateMeter`](#updatemeter) — Partially updates the details of a meter entity by ID. +- [`getMeterCounters`](#getmetercounters) — Retrieves all meter counters associated with a given meter. +- [`getCounterDetails`](#getcounterdetails) — Retrieves the full details of a single meter counter by its ID. +- [`createPortalMeterReadings`](#createportalmeterreadings) — Inserts multiple meter readings at once for a given meter via the end customer portal. **ECP Admin** - [`createMeterReading`](#createmeterreading) — Inserts a new meter reading. - [`createMeterReadings`](#createmeterreadings) — Inserts multiple meter readings at once. Limited to 100 readings per request. -- [`batchWriteMeterReadings`](#batchwritemeterreadings) — Upserts/Deletes multiple meter readings at once. Limited to 100 readings per request. -- [`createMeterReadingFromSubmission`](#createmeterreadingfromsubmission) — Creates a reading from a journey submission. -- [`getAllowedReadingForMeter`](#getallowedreadingformeter) — Get allowed reading for the given meter -- [`createReadingWithMeter`](#createreadingwithmeter) — Creates a reading along with a meter. +- [`batchWriteMeterReadings`](#batchwritemeterreadings) — Upserts or deletes multiple meter readings at once. Limited to 100 readings per request. +- [`pruneMeterReadings`](#prunemeterreadings) — Deletes every reading of a meter whose `external_id` is NOT in the provided keep list — in a single request. +- [`createMeterReadingFromSubmission`](#createmeterreadingfromsubmission) — Creates meter readings from a journey submission payload. +- [`getAllowedReadingForMeter`](#getallowedreadingformeter) — Returns the allowed min/max reading range for each counter of the given meter. +- [`createReadingWithMeter`](#createreadingwithmeter) — Creates a meter reading along with meter lookup or creation by MA-LO ID and OBIS number. - [`getReadingsByInterval`](#getreadingsbyinterval) — Retrieves all readings specified in an interval. -- [`updateMeterReading`](#updatemeterreading) — Updates a meter reading. -- [`deleteMeterReading`](#deletemeterreading) — Deletes a meter reading. +- [`updateMeterReading`](#updatemeterreading) — Updates an existing meter reading identified by meter ID, counter ID, and timestamp. +- [`deleteMeterReading`](#deletemeterreading) — Permanently deletes a meter reading identified by meter ID, counter ID, and timestamp. + +**Metering** +- [`getReadingChangesets`](#getreadingchangesets) — GET /v1/metering/reading/{meter_id}/{counter_id}/changesets +- [`applyReadingChangeset`](#applyreadingchangeset) — Applies the proposed reading value to ClickHouse and removes the pending changeset. +- [`dismissReadingChangeset`](#dismissreadingchangeset) — Removes the pending changeset without applying it. The reading value remains unchanged. +- [`updateReadingChangeset`](#updatereadingchangeset) — Updates the proposed value of a pending changeset without going through the normal write path. ### `getCustomerMeters` -Retrieves all meters related to a customer. +Retrieves all meters associated with the authenticated portal customer. `GET /v1/metering/meter` +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `include_pending_changesets` | query | boolean | No | When true, the response includes a `pending_changesets` field with the list of pending reading changesets alongside the confirmed readings. | + **Sample Call** ```bash @@ -109,7 +124,7 @@ epilot metering getCustomerMeters --jsonata 'data' ], "used_for": "Domestic Usage", "manufacturer": "Energy One", - "calibration_date": "2022-10-10T00:00:00.000Z", + "calibration_date": "2022-10-10", "contract": { "$relation": [ { @@ -141,7 +156,7 @@ epilot metering getCustomerMeters --jsonata 'data' } ] }, - "last_reading": "2022-10-10T00:00:00.000Z", + "last_reading": "2022-10-10", "current_consumption": 100.5 } ] @@ -154,7 +169,7 @@ epilot metering getCustomerMeters --jsonata 'data' ### `getMetersByContractId` -Retrieves all meters related to a contract. +Retrieves all meters associated with a given contract entity. `GET /v1/metering/contract/meters/{contract_id}` @@ -216,7 +231,7 @@ epilot metering getMetersByContractId -p contract_id=123e4567-e89b-12d3-a456-426 ], "used_for": "Domestic Usage", "manufacturer": "Energy One", - "calibration_date": "2022-10-10T00:00:00.000Z", + "calibration_date": "2022-10-10", "contract": { "$relation": [ { @@ -244,7 +259,7 @@ epilot metering getMetersByContractId -p contract_id=123e4567-e89b-12d3-a456-426 ### `getMeter` -Retrieves the details of a meter. +Retrieves the full details of a specific meter by ID, including related entities and available journey actions. `GET /v1/metering/meter/{id}` @@ -306,7 +321,7 @@ epilot metering getMeter -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'd ], "used_for": "Domestic Usage", "manufacturer": "Energy One", - "calibration_date": "2022-10-10T00:00:00.000Z", + "calibration_date": "2022-10-10", "contract": { "$relation": [ { @@ -359,7 +374,7 @@ epilot metering getMeter -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'd ### `updateMeter` -Updates the details of a meter. +Partially updates the details of a meter entity by ID. `PATCH /v1/metering/meter/{id}` @@ -429,7 +444,7 @@ epilot metering updateMeter -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata ], "used_for": "Domestic Usage", "manufacturer": "Energy One", - "calibration_date": "2022-10-10T00:00:00.000Z", + "calibration_date": "2022-10-10", "contract": { "$relation": [ { @@ -456,7 +471,7 @@ epilot metering updateMeter -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata ### `getMeterCounters` -Retrieves all counters for a given meter. +Retrieves all meter counters associated with a given meter. `GET /v1/metering/counter` @@ -498,9 +513,9 @@ epilot metering getMeterCounters -p meter_id=123e4567-e89b-12d3-a456-42661417400 "transformer_ratio": 70, "unit": "string", "forecast_reading_value": 270, - "forecast_as_of": "2022-12-10T00:00:00.000Z", + "forecast_as_of": "2022-12-10", "current_consumption": 240, - "last_reading": "2022-10-10T00:00:00.000Z", + "last_reading": "2022-10-10", "conversion_factor": 3, "tariff_type": "ht" } @@ -514,7 +529,7 @@ epilot metering getMeterCounters -p meter_id=123e4567-e89b-12d3-a456-42661417400 ### `getCounterDetails` -Retrieves the details of a meter counter. +Retrieves the full details of a single meter counter by its ID. `GET /v1/metering/counter/{counter_id}` @@ -561,9 +576,9 @@ epilot metering getCounterDetails -p counter_id=123e4567-e89b-12d3-a456-42661417 "transformer_ratio": 70, "unit": "string", "forecast_reading_value": 270, - "forecast_as_of": "2022-12-10T00:00:00.000Z", + "forecast_as_of": "2022-12-10", "current_consumption": 240, - "last_reading": "2022-10-10T00:00:00.000Z", + "last_reading": "2022-10-10", "conversion_factor": 3, "tariff_type": "ht" } @@ -580,6 +595,12 @@ Inserts a new meter reading. `POST /v1/metering/reading` +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `direct` | query | boolean | No | When true, bypasses changeset interception and writes directly to ClickHouse. Used by trusted integrations (e.g., ERP sync) to confirm changes and auto-clear matching pending changesets. | + **Request Body** (required) **Sample Call** @@ -599,7 +620,7 @@ epilot metering createMeterReading \ "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -637,7 +658,7 @@ epilot metering createMeterReading --jsonata 'data' "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -671,6 +692,10 @@ Inserts multiple meter readings at once. Limited to 100 readings per request. | `skip_validation` | query | boolean | No | When set to true, all validations will be skipped and the system will allow the reading to be created. If set to false or not provided, the system performs the following validations: Validation Rule | +| `direct` | query | boolean | No | When true, bypasses changeset interception and writes directly to ClickHouse. Used by trusted integrations (e.g., ERP sync) to confirm changes and auto-clear matching pending changesets. | +| `create_ticket` | query | boolean | No | Controls whether a manual-intervention ("Übermittlung Zählerstand") ticket is created for the +written readings. Defaults to true, preserving portal/journey behaviour (readings with +source ECP or journ | **Request Body** (required) @@ -693,7 +718,7 @@ epilot metering createMeterReadings \ "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -734,7 +759,7 @@ epilot metering createMeterReadings --jsonata 'data' "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -756,7 +781,7 @@ epilot metering createMeterReadings --jsonata 'data' ### `createPortalMeterReadings` -Inserts multiple meter readings at once for a given meter. Limited to 2 readings per request. +Inserts multiple meter readings at once for a given meter via the end customer portal. `POST /v1/metering/readings/{meter_id}` @@ -765,6 +790,7 @@ Inserts multiple meter readings at once for a given meter. Limited to 2 readings | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `meter_id` | path | string | Yes | The ID of the meter. | +| `direct` | query | boolean | No | When true, bypasses changeset interception and writes directly to ClickHouse. Used by trusted integrations (e.g., ERP sync) to confirm changes and auto-clear matching pending changesets. | **Request Body** (required) @@ -789,7 +815,7 @@ epilot metering createPortalMeterReadings \ "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -836,7 +862,7 @@ epilot metering createPortalMeterReadings -p meter_id=123e4567-e89b-12d3-a456-42 "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -858,7 +884,7 @@ epilot metering createPortalMeterReadings -p meter_id=123e4567-e89b-12d3-a456-42 ### `batchWriteMeterReadings` -Upserts/Deletes multiple meter readings at once. Limited to 100 readings per request. +Upserts or deletes multiple meter readings at once. Limited to 100 readings per request. `POST /v2/metering/readings` @@ -871,6 +897,10 @@ Upserts/Deletes multiple meter readings at once. Limited to 100 readings per req If set to false or not provided, the system performs the following validations: Validation Rule | | `activity_id` | query | string (ulid) | No | Activity to include in event feed | +| `direct` | query | boolean | No | When true, bypasses changeset interception and writes directly to ClickHouse. Used by trusted integrations (e.g., ERP sync) to confirm changes and auto-clear matching pending changesets. | +| `create_ticket` | query | boolean | No | Controls whether a manual-intervention ("Übermittlung Zählerstand") ticket is created for the +written readings. Defaults to true, preserving portal/journey behaviour (readings with +source ECP or journ | **Request Body** (required) @@ -888,24 +918,24 @@ epilot metering batchWriteMeterReadings \ "identifiers": ["string"], "readings": [ { - "value": 240, - "read_by": "John Doe", - "reason": "", "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", - "source": "ECP", - "status": "valid", + "timestamp": "2022-10-10T10:00:00Z", "external_id": "string", - "remark": "Customer reported unusual consumption", "metadata": { "registration_id": "1234567890", "business_unit": "ABC" }, + "operation": "create", + "value": 240, + "source": "ECP", + "read_by": "John Doe", + "reason": "", + "status": "valid", + "remark": "Customer reported unusual consumption", "note": "string", - "unit": "string", - "operation": "create" + "unit": "string" } ] }' @@ -936,7 +966,7 @@ epilot metering batchWriteMeterReadings --jsonata 'data' "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -956,9 +986,74 @@ epilot metering batchWriteMeterReadings --jsonata 'data' --- +### `pruneMeterReadings` + +Deletes every reading of a meter whose `external_id` is NOT in the provided keep list — in a single request. + +`POST /v2/metering/readings/prune` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `async` | query | boolean | No | Don't wait for the deletions to become visible in GetReadings API. Useful for large prunes | +| `activity_id` | query | string (ulid) | No | Activity to include in event feed | +| `create_ticket` | query | boolean | No | Controls whether a manual-intervention ("Übermittlung Zählerstand") ticket is created for the +written readings. Defaults to true, preserving portal/journey behaviour (readings with +source ECP or journ | +| `dry_run` | query | boolean | No | When true, computes and returns the deleted/kept counts without deleting anything. | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot metering pruneMeterReadings +``` + +With request body: + +```bash +epilot metering pruneMeterReadings \ + -d '{ + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "source": "ECP", + "keep_external_ids": ["erp-reading-1", "erp-reading-2"] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot metering pruneMeterReadings +``` + +With JSONata filter: + +```bash +epilot metering pruneMeterReadings --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": { + "deleted_count": 42, + "kept_count": 12 + } +} +``` + +
+ +--- + ### `createMeterReadingFromSubmission` -Creates a reading from a journey submission. +Creates meter readings from a journey submission payload. `POST /v1/metering/reading/submission` @@ -1034,7 +1129,7 @@ epilot metering createMeterReadingFromSubmission --jsonata 'message' ### `getAllowedReadingForMeter` -Get allowed reading for the given meter +Returns the allowed min/max reading range for each counter of the given meter. `GET /v1/metering/allowed/reading/{meter_id}` @@ -1085,7 +1180,7 @@ epilot metering getAllowedReadingForMeter -p meter_id=123e4567-e89b-12d3-a456-42 ### `createReadingWithMeter` -Creates a reading along with a meter. +Creates a meter reading along with meter lookup or creation by MA-LO ID and OBIS number. `POST /v1/metering/reading/with-meter` @@ -1140,7 +1235,7 @@ epilot metering createReadingWithMeter --jsonata 'data' "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -1182,6 +1277,7 @@ If this value is provided as -1, then it returns all results at once. If this value is provided as "cumulative", then actual re | | `sort` | query | "asc" \| "desc" | No | If this value is provided as "asc", then the results will be sorted by the timestamp field in ascending order. If this value is provided as "desc", then the results will be sorted by the timestamp fie | +| `include_pending_changesets` | query | boolean | No | When true, the response includes a `pending_changesets` field with the list of pending reading changesets alongside the confirmed readings. | **Sample Call** @@ -1217,7 +1313,7 @@ epilot metering getReadingsByInterval -p meter_id=123e4567-e89b-12d3-a456-426614 "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -1241,7 +1337,7 @@ epilot metering getReadingsByInterval -p meter_id=123e4567-e89b-12d3-a456-426614 ### `updateMeterReading` -Updates a meter reading. +Updates an existing meter reading identified by meter ID, counter ID, and timestamp. `PUT /v1/metering/reading/{meter_id}/{counter_id}` @@ -1278,7 +1374,7 @@ epilot metering updateMeterReading \ "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -1320,7 +1416,7 @@ epilot metering updateMeterReading -p meter_id=123e4567-e89b-12d3-a456-426614174 "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -1341,7 +1437,7 @@ epilot metering updateMeterReading -p meter_id=123e4567-e89b-12d3-a456-426614174 ### `deleteMeterReading` -Deletes a meter reading. +Permanently deletes a meter reading identified by meter ID, counter ID, and timestamp. `DELETE /v1/metering/reading/{meter_id}/{counter_id}` @@ -1390,3 +1486,402 @@ epilot metering deleteMeterReading -p meter_id=123e4567-e89b-12d3-a456-426614174
--- + +### `getReadingChangesets` + +`GET /v1/metering/reading/{meter_id}/{counter_id}/changesets` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `meter_id` | path | string | Yes | The ID of the meter. | +| `counter_id` | path | string | Yes | The ID of the counter. | + +**Sample Call** + +```bash +epilot metering getReadingChangesets \ + -p meter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p counter_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot metering getReadingChangesets 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot metering getReadingChangesets -p meter_id=123e4567-e89b-12d3-a456-426614174000 -p counter_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'changesets' +``` + +
+Sample Response + +```json +{ + "changesets": [ + { + "changeset_id": "string", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "previous": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "edit_mode": "external", + "match_strategy": "exact", + "timestamp_tolerance": "exact", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "type": "user", + "id": "string" + }, + "source": "360", + "fuzzy_config": { + "percentage_threshold": 0.01, + "absolute_threshold": 0 + }, + "dismissed_reason": "string", + "dismissed_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `applyReadingChangeset` + +Applies the proposed reading value to ClickHouse and removes the pending changeset. + +`POST /v1/metering/reading/{meter_id}/{counter_id}/changesets/{changeset_id}:apply` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `meter_id` | path | string | Yes | The ID of the meter. | +| `counter_id` | path | string | Yes | The ID of the counter. | +| `changeset_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot metering applyReadingChangeset \ + -p meter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p counter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p changeset_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot metering applyReadingChangeset 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot metering applyReadingChangeset -p meter_id=123e4567-e89b-12d3-a456-426614174000 -p counter_id=123e4567-e89b-12d3-a456-426614174000 -p changeset_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'reading' +``` + +
+Sample Response + +```json +{ + "reading": { + "value": 240, + "read_by": "John Doe", + "reason": "", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "direction": "feed-in", + "timestamp": "2022-10-10", + "source": "ECP", + "status": "valid", + "external_id": "string", + "remark": "Customer reported unusual consumption", + "metadata": { + "registration_id": "1234567890", + "business_unit": "ABC" + }, + "note": "string", + "unit": "string" + }, + "changeset": { + "changeset_id": "string", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "previous": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "edit_mode": "external", + "match_strategy": "exact", + "timestamp_tolerance": "exact", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "type": "user", + "id": "string" + }, + "source": "360", + "fuzzy_config": { + "percentage_threshold": 0.01, + "absolute_threshold": 0 + }, + "dismissed_reason": "string", + "dismissed_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +### `dismissReadingChangeset` + +Removes the pending changeset without applying it. The reading value remains unchanged. + +`POST /v1/metering/reading/{meter_id}/{counter_id}/changesets/{changeset_id}:dismiss` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `meter_id` | path | string | Yes | The ID of the meter. | +| `counter_id` | path | string | Yes | The ID of the counter. | +| `changeset_id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot metering dismissReadingChangeset \ + -p meter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p counter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p changeset_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"reason":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot metering dismissReadingChangeset 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot metering dismissReadingChangeset -p meter_id=123e4567-e89b-12d3-a456-426614174000 -p counter_id=123e4567-e89b-12d3-a456-426614174000 -p changeset_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot metering dismissReadingChangeset -p meter_id=123e4567-e89b-12d3-a456-426614174000 -p counter_id=123e4567-e89b-12d3-a456-426614174000 -p changeset_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'changeset_id' +``` + +
+Sample Response + +```json +{ + "changeset_id": "string", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "previous": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "edit_mode": "external", + "match_strategy": "exact", + "timestamp_tolerance": "exact", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "type": "user", + "id": "string" + }, + "source": "360", + "fuzzy_config": { + "percentage_threshold": 0.01, + "absolute_threshold": 0 + }, + "dismissed_reason": "string", + "dismissed_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateReadingChangeset` + +Updates the proposed value of a pending changeset without going through the normal write path. + +`PATCH /v1/metering/reading/{meter_id}/{counter_id}/changesets/{changeset_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `meter_id` | path | string | Yes | The ID of the meter. | +| `counter_id` | path | string | Yes | The ID of the counter. | +| `changeset_id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot metering updateReadingChangeset \ + -p meter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p counter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p changeset_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot metering updateReadingChangeset \ + -p meter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p counter_id=123e4567-e89b-12d3-a456-426614174000 \ + -p changeset_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot metering updateReadingChangeset 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot metering updateReadingChangeset -p meter_id=123e4567-e89b-12d3-a456-426614174000 -p counter_id=123e4567-e89b-12d3-a456-426614174000 -p changeset_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot metering updateReadingChangeset -p meter_id=123e4567-e89b-12d3-a456-426614174000 -p counter_id=123e4567-e89b-12d3-a456-426614174000 -p changeset_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'changeset_id' +``` + +
+Sample Response + +```json +{ + "changeset_id": "string", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "previous": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "edit_mode": "external", + "match_strategy": "exact", + "timestamp_tolerance": "exact", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "type": "user", + "id": "string" + }, + "source": "360", + "fuzzy_config": { + "percentage_threshold": 0.01, + "absolute_threshold": 0 + }, + "dismissed_reason": "string", + "dismissed_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- diff --git a/docs/cli/commands/notes.md b/docs/cli/commands/notes.md index aaa84fec..6232a807 100644 --- a/docs/cli/commands/notes.md +++ b/docs/cli/commands/notes.md @@ -52,6 +52,10 @@ epilot notes createNote **Pinning** - [`pinNote`](#pinnote) — Pins a single Note entry based on it's Entity ID +**Archive** +- [`archiveNote`](#archivenote) — Archives a root Note entry by setting its `_archived_at` timestamp to the current server time. The same timestamp is cas +- [`unarchiveNote`](#unarchivenote) — Unarchives a root Note entry by clearing its `_archived_at` value. The clear cascades to every comment under the note so + **Reactions** - [`addNoteReaction`](#addnotereaction) — Adds an emoji reaction to a note - [`removeNoteReaction`](#removenotereaction) — Removes an emoji reaction from a note @@ -217,16 +221,20 @@ epilot notes updateNote \ } ], "pinned_at": "1970-01-01T00:00:00.000Z", - "created_by": { - "type": "user", - "user_id": "string", - "display_name": "string", - "org_id": "string", - "email": "string", - "phone": "string" - }, + "edited_at": "1970-01-01T00:00:00.000Z", + "created_by": [ + { + "type": "user", + "user_id": "string", + "display_name": "string", + "org_id": "string", + "email": "string", + "phone": "string" + } + ], "read_by": ["string"], - "reactions": {} + "reactions": {}, + "_archived_at": "1970-01-01T00:00:00.000Z" }' ``` @@ -334,9 +342,26 @@ Search for a paginated list of Notes based on one or more contexts **Sample Call** +```bash +epilot notes searchNotesByContext +``` + +With request body: + ```bash epilot notes searchNotesByContext \ - -d '{"contexts":[{"type":"workflow_execution","id":"string"}],"from":0,"size":10}' + -d '{ + "contexts": [ + { + "type": "workflow_execution", + "id": "string" + } + ], + "include_related_schemas": ["string"], + "filter": "active", + "from": 0, + "size": 10 +}' ``` Using stdin pipe: @@ -386,6 +411,72 @@ epilot notes pinNote -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' --- +### `archiveNote` + +Archives a root Note entry by setting its `_archived_at` timestamp to the current server time. The same timestamp is cas + +`POST /v1/note/{id}/archive` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | The Entity ID of the Note entry to archive | + +**Sample Call** + +```bash +epilot notes archiveNote \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot notes archiveNote 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot notes archiveNote -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'context_entities' +``` + +--- + +### `unarchiveNote` + +Unarchives a root Note entry by clearing its `_archived_at` value. The clear cascades to every comment under the note so + +`POST /v1/note/{id}/unarchive` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | The Entity ID of the Note entry to unarchive | + +**Sample Call** + +```bash +epilot notes unarchiveNote \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot notes unarchiveNote 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot notes unarchiveNote -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'context_entities' +``` + +--- + ### `getNoteContexts` Gets all the Entity and non-Entity records the Note is contextually attached to diff --git a/docs/cli/commands/notification.md b/docs/cli/commands/notification.md index 04d58854..0091e0a4 100644 --- a/docs/cli/commands/notification.md +++ b/docs/cli/commands/notification.md @@ -156,7 +156,8 @@ epilot notification getNotificationsV2 --jsonata 'results[0]' "email": false, "in_app": false } - } + }, + "allowed_channels": ["in_app"] } ] } @@ -263,7 +264,8 @@ epilot notification getNotifications --jsonata 'results[0]' "email": false, "in_app": false } - } + }, + "allowed_channels": ["in_app"] } ] } @@ -353,6 +355,7 @@ epilot notification createNotification \ "in_app": false } }, + "allowed_channels": ["in_app"], "read_state": false, "visibility_user_ids": ["1", "2", "3", "4", "5"] }' @@ -470,7 +473,8 @@ epilot notification getNotification -p id=1 --jsonata '$' "email": false, "in_app": false } - } + }, + "allowed_channels": ["in_app"] } ``` diff --git a/docs/cli/commands/organization.md b/docs/cli/commands/organization.md index ec92a8c3..95df759d 100644 --- a/docs/cli/commands/organization.md +++ b/docs/cli/commands/organization.md @@ -8,7 +8,7 @@ description: "epilot CLI commands for the Organization API: quick start, common - **Base URL:** `https://organization-v2.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/organization](https://docs.epilot.io/api/organization) -Manage epilot tenant organizations +The Organization API provides endpoints for managing epilot tenant organizations. ## Quick Start @@ -41,18 +41,26 @@ epilot organization getCurrentOrganization ## Operations **Organization** -- [`getCurrentOrganization`](#getcurrentorganization) — Get caller's current organization -- [`getOrganization`](#getorganization) — Get an organization -- [`updateOrganization`](#updateorganization) — Updates an organization +- [`getCurrentOrganization`](#getcurrentorganization) — Retrieves the organization associated with the authenticated user's current session. +- [`getOrganization`](#getorganization) — Retrieves detailed information about a specific organization by its unique identifier. +- [`updateOrganization`](#updateorganization) — Updates an organization's profile information. **Organization Settings** -- [`getSettings`](#getsettings) — Get full organization settings object -- [`putSettingsValue`](#putsettingsvalue) — Updates an organization setting -- [`deleteSettingsValue`](#deletesettingsvalue) — Updates an organization nsetting +- [`getSettings`](#getsettings) — Retrieves all configuration settings for an organization. +- [`putSettingsValue`](#putsettingsvalue) — Creates or updates a specific organization setting identified by its key. +- [`deleteSettingsValue`](#deletesettingsvalue) — Removes a specific organization setting identified by its key. +- [`notifySettingsValueUpdated`](#notifysettingsvalueupdated) — Sends an internal notification that an organization setting was updated. + +**Feature Settings** +- [`getOrganizationFeatureSettings`](#getorganizationfeaturesettings) — Get organization feature settings. + +**Announcements** +- [`getActiveAnnouncement`](#getactiveannouncement) — Returns the announcement (e.g. a subprocessor change notice) to show as a portal banner for the +- [`acknowledgeAnnouncement`](#acknowledgeannouncement) — Acknowledges an announcement on behalf of the caller's organization. Only org admins ### `getCurrentOrganization` -Get caller's current organization +Retrieves the organization associated with the authenticated user's current session. `GET /v2/organization/current` @@ -96,7 +104,8 @@ epilot organization getCurrentOrganization --jsonata 'id' "type": "Vendor", "symbol": "EPI", "pricing_tier": "professional", - "free_user_limit": 50 + "free_user_limit": 50, + "tags": ["test org"] } ``` @@ -106,7 +115,7 @@ epilot organization getCurrentOrganization --jsonata 'id' ### `getOrganization` -Get an organization +Retrieves detailed information about a specific organization by its unique identifier. `GET /v2/organization/{org_id}` @@ -114,7 +123,7 @@ Get an organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `org_id` | path | string | Yes | The Id of the organization. | +| `org_id` | path | string | Yes | The unique identifier of the organization to retrieve | **Sample Call** @@ -163,7 +172,8 @@ epilot organization getOrganization -p org_id=739224 --jsonata 'id' "type": "Vendor", "symbol": "EPI", "pricing_tier": "professional", - "free_user_limit": 50 + "free_user_limit": 50, + "tags": ["test org"] } ``` @@ -173,7 +183,7 @@ epilot organization getOrganization -p org_id=739224 --jsonata 'id' ### `updateOrganization` -Updates an organization +Updates an organization's profile information. `PATCH /v2/organization/{org_id}` @@ -181,9 +191,9 @@ Updates an organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `org_id` | path | string | Yes | The Id of the organization. | +| `org_id` | path | string | Yes | The unique identifier of the organization to update | -**Request Body** +**Request Body** (required) **Sample Call** @@ -221,7 +231,8 @@ epilot organization updateOrganization \ "type": "Vendor", "symbol": "EPI", "pricing_tier": "professional", - "free_user_limit": 50 + "free_user_limit": 50, + "tags": ["test org"] }' ``` @@ -271,7 +282,8 @@ epilot organization updateOrganization -p org_id=739224 --jsonata 'id' "type": "Vendor", "symbol": "EPI", "pricing_tier": "professional", - "free_user_limit": 50 + "free_user_limit": 50, + "tags": ["test org"] } ``` @@ -281,7 +293,7 @@ epilot organization updateOrganization -p org_id=739224 --jsonata 'id' ### `getSettings` -Get full organization settings object +Retrieves all configuration settings for an organization. `GET /v2/organization/{org_id}/settings` @@ -289,7 +301,7 @@ Get full organization settings object | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `org_id` | path | string | Yes | The Id of the organization. | +| `org_id` | path | string | Yes | The unique identifier of the organization | **Sample Call** @@ -317,7 +329,12 @@ epilot organization getSettings -p org_id=739224 --jsonata '$' { "double_opt_in": { "enabled": true - } + }, + "email_tracking": { + "enabled": true, + "track_opens": true + }, + "default_language": "de" } ``` @@ -327,7 +344,7 @@ epilot organization getSettings -p org_id=739224 --jsonata '$' ### `putSettingsValue` -Updates an organization setting +Creates or updates a specific organization setting identified by its key. `PUT /v2/organization/{org_id}/settings/{key}` @@ -335,36 +352,38 @@ Updates an organization setting | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `org_id` | path | string | Yes | The Id of the organization. | -| `key` | path | string | Yes | Organization setting key | +| `org_id` | path | string | Yes | The unique identifier of the organization | +| `key` | path | string | Yes | The setting key to create or update. +Common keys include: double_opt_in, email_tracking, default_language, workflow_notifications + | -**Request Body** +**Request Body** (required) **Sample Call** ```bash epilot organization putSettingsValue \ -p org_id=739224 \ - -p key=example \ + -p key=double_opt_in \ -d '{"enabled":true}' ``` Using positional args for path parameters: ```bash -epilot organization putSettingsValue 739224 example +epilot organization putSettingsValue 739224 double_opt_in ``` Using stdin pipe: ```bash -cat body.json | epilot organization putSettingsValue -p org_id=739224 -p key=example +cat body.json | epilot organization putSettingsValue -p org_id=739224 -p key=double_opt_in ``` With JSONata filter: ```bash -epilot organization putSettingsValue -p org_id=739224 -p key=example --jsonata '$' +epilot organization putSettingsValue -p org_id=739224 -p key=double_opt_in --jsonata '$' ```
@@ -382,7 +401,7 @@ epilot organization putSettingsValue -p org_id=739224 -p key=example --jsonata ' ### `deleteSettingsValue` -Updates an organization nsetting +Removes a specific organization setting identified by its key. `DELETE /v2/organization/{org_id}/settings/{key}` @@ -390,27 +409,220 @@ Updates an organization nsetting | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `org_id` | path | string | Yes | The Id of the organization. | -| `key` | path | string | Yes | Organization setting key | +| `org_id` | path | string | Yes | The unique identifier of the organization | +| `key` | path | string | Yes | The setting key to delete | **Sample Call** ```bash epilot organization deleteSettingsValue \ -p org_id=739224 \ - -p key=example + -p key=double_opt_in +``` + +Using positional args for path parameters: + +```bash +epilot organization deleteSettingsValue 739224 double_opt_in +``` + +With JSONata filter: + +```bash +epilot organization deleteSettingsValue -p org_id=739224 -p key=double_opt_in --jsonata '$' +``` + +--- + +### `notifySettingsValueUpdated` + +Sends an internal notification that an organization setting was updated. + +`POST /v2/organization/{org_id}/settings/{key}/notifications` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `org_id` | path | string | Yes | The unique identifier of the organization | +| `key` | path | string | Yes | The setting key that was updated | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot organization notifySettingsValueUpdated \ + -p org_id=739224 \ + -p key=360_features \ + -d '{"user_email":"string","org_name":"string","value":{"enabled":true}}' +``` + +Using positional args for path parameters: + +```bash +epilot organization notifySettingsValueUpdated 739224 360_features +``` + +Using stdin pipe: + +```bash +cat body.json | epilot organization notifySettingsValueUpdated -p org_id=739224 -p key=360_features +``` + +With JSONata filter: + +```bash +epilot organization notifySettingsValueUpdated -p org_id=739224 -p key=360_features --jsonata 'delivered' +``` + +
+Sample Response + +```json +{ + "delivered": true +} +``` + +
+ +--- + +### `getOrganizationFeatureSettings` + +Get organization feature settings. + +`GET /v2/organization/feature-settings` + +**Sample Call** + +```bash +epilot organization getOrganizationFeatureSettings +``` + +With JSONata filter: + +```bash +epilot organization getOrganizationFeatureSettings --jsonata 'version' +``` + +--- + +### `getActiveAnnouncement` + +Returns the announcement (e.g. a subprocessor change notice) to show as a portal banner for the + +`GET /v2/organization/announcements/active` + +**Sample Call** + +```bash +epilot organization getActiveAnnouncement +``` + +With JSONata filter: + +```bash +epilot organization getActiveAnnouncement --jsonata 'announcement' +``` + +
+Sample Response + +```json +{ + "announcement": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "subprocessor_change", + "message": { + "de": "Wir haben unsere Liste der Subdienstleister aktualisiert (gültig ab 01.11.2026). Bitte prüfe die Änderungen.", + "en": "We have updated our list of subprocessors (effective 01.11.2026). Please review the changes." + }, + "link_url": "string", + "list_version": "string", + "effective_date": "1970-01-01", + "window_days": 0, + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "expires_at": "1970-01-01T00:00:00.000Z", + "archived_at": "1970-01-01T00:00:00.000Z", + "archived_by": "string", + "materialized_at": "1970-01-01T00:00:00.000Z" + }, + "can_acknowledge": true +} +``` + +
+ +--- + +### `acknowledgeAnnouncement` + +Acknowledges an announcement on behalf of the caller's organization. Only org admins + +`POST /v2/organization/announcements/{announcement_id}/acknowledge` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `announcement_id` | path | string | Yes | Announcement id | + +**Request Body** + +**Sample Call** + +```bash +epilot organization acknowledgeAnnouncement \ + -p announcement_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"portal":"360"}' ``` Using positional args for path parameters: ```bash -epilot organization deleteSettingsValue 739224 example +epilot organization acknowledgeAnnouncement 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot organization acknowledgeAnnouncement -p announcement_id=123e4567-e89b-12d3-a456-426614174000 ``` With JSONata filter: ```bash -epilot organization deleteSettingsValue -p org_id=739224 -p key=example --jsonata '$' +epilot organization acknowledgeAnnouncement -p announcement_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'announcement_id' +``` + +
+Sample Response + +```json +{ + "announcement_id": "string", + "org_id": "string", + "org_name": "string", + "status": "acknowledged", + "acknowledged_by": { + "user_id": "string", + "name": "string", + "email": "string" + }, + "acknowledged_at": "1970-01-01T00:00:00.000Z", + "portal": "360", + "list_version": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" +} ``` +
+ --- diff --git a/docs/cli/commands/partner-directory.md b/docs/cli/commands/partner-directory.md index d7a0f267..5b2ec683 100644 --- a/docs/cli/commands/partner-directory.md +++ b/docs/cli/commands/partner-directory.md @@ -1,14 +1,14 @@ --- -title: "Partner API" -description: "epilot CLI commands for the Partner API: quick start, common flags and every operation, callable from the command line." +title: "Partner Directory API" +description: "epilot CLI commands for the Partner Directory API: quick start, common flags and every operation, callable from the command line." --- -# Partner API +# Partner Directory API - **Base URL:** `https://partner-directory-api.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/partner-directory](https://docs.epilot.io/api/partner-directory) -Management of Partners in epilot +The Partner Directory API enables organizations to manage partnerships within the epilot platform. ## Quick Start @@ -40,29 +40,30 @@ epilot partner-directory approvePartner -p id=e45a6dc2-3795-43a3-ae0f-6b6760f310 ## Operations -**partners** -- [`approvePartner`](#approvepartner) — Approve partner request -- [`rejectPartner`](#rejectpartner) — Reject partner request -- [`searchAssignable`](#searchassignable) — Search for assignable users/organizations from this organization and Partners -- [`batchGetAssignable`](#batchgetassignable) — Search for assignable users from this organization by its ids -- [`getPartnerByToken`](#getpartnerbytoken) — Get partner by token -- [`activatePartner`](#activatepartner) — Activate partner using an invite token -- [`searchGeolocationForText`](#searchgeolocationfortext) — Converts a given string, in the format of an address, to geo-location latitude and longitude -- [`invitePartnerV2`](#invitepartnerv2) — Invite a partner into collaboration. It will send an email to partner and ask to join into collaboration - -**partner_users** -- [`getPartnerUsers`](#getpartnerusers) — Get all users for a partner organization with their roles -- [`createPartnerUser`](#createpartneruser) — Create a new user in a partner organization -- [`deletePartnerUser`](#deletepartneruser) — Delete a user from a partner organization -- [`getPartnerRoles`](#getpartnerroles) — Get all roles for a partner organization -- [`createPartnerRole`](#createpartnerrole) — Create a role for a partner organization -- [`updatePartnerRole`](#updatepartnerrole) — Update a role for a partner organization -- [`assignPartnerUserRoles`](#assignpartneruserroles) — Assign roles to a user in a partner organization -- [`unassignPartnerUserRoles`](#unassignpartneruserroles) — Unassign roles from a user in a partner organization +**Partners** +- [`approvePartner`](#approvepartner) — Approves a pending partner request, allowing the partner to begin collaboration. +- [`rejectPartner`](#rejectpartner) — Rejects a pending partner request, declining the partnership. +- [`searchAssignable`](#searchassignable) — Search for users and organizations that can be assigned to tasks, workflows, or entities. +- [`batchGetAssignable`](#batchgetassignable) — Retrieve multiple assignable users or groups by their IDs in a single request. +- [`getPartnerByToken`](#getpartnerbytoken) — Retrieves partner information using an invitation token. +- [`activatePartner`](#activatepartner) — Activates a partner account using an invitation token. +- [`searchGeolocationForText`](#searchgeolocationfortext) — Converts an address string to geographic coordinates (latitude and longitude). +- [`invitePartnerV2`](#invitepartnerv2) — Sends an invitation email to a partner organization to begin collaboration. + +**Partner Users** +- [`getPartnerUsers`](#getpartnerusers) — Retrieves all users belonging to a partner organization along with their assigned roles. +- [`createPartnerUser`](#createpartneruser) — Creates a new user in a partner organization. +- [`deletePartnerUser`](#deletepartneruser) — Removes a user from a partner organization. +- [`getPartnerRoles`](#getpartnerroles) — Retrieves all roles defined for a partner organization. +- [`createPartnerRole`](#createpartnerrole) — Creates a new role for a partner organization. +- [`updatePartnerRole`](#updatepartnerrole) — Updates an existing role in a partner organization. +- [`deletePartnerRole`](#deletepartnerrole) — Delete a role from a partner organization +- [`assignPartnerUserRoles`](#assignpartneruserroles) — Assigns one or more roles to a user in a partner organization. +- [`unassignPartnerUserRoles`](#unassignpartneruserroles) — Removes one or more roles from a user in a partner organization. ### `approvePartner` -Approve partner request +Approves a pending partner request, allowing the partner to begin collaboration. `POST /v1/partners/{id}/approve` @@ -70,7 +71,7 @@ Approve partner request | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | The Id of partner | +| `id` | path | string | Yes | The unique identifier of the partner to approve | **Sample Call** @@ -99,14 +100,14 @@ epilot partner-directory approvePartner -p id=e45a6dc2-3795-43a3-ae0f-6b6760f310 "id": "e45a6dc2-3795-43a3-ae0f-6b6760f310fc", "organization_id": "123", "created_at": "2022-02-08T04:44:32.246Z", - "description": "Description", - "company_name": "Company name", - "invitation_token": "string", + "description": "Regional solar installation partner for Bavaria", + "company_name": "Acme Solar GmbH", + "invitation_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "invitation_email": "user@example.com", - "email": "user@example.com", - "owner_email": "user@example.com", - "signed_up_email": "user@example.com", - "partner_org_id": 123456, + "email": "contact@acme-solar.de", + "owner_email": "owner@acme-solar.de", + "signed_up_email": "admin@acme-solar.de", + "partner_org_id": "456789", "status": "Pending" } ``` @@ -117,7 +118,7 @@ epilot partner-directory approvePartner -p id=e45a6dc2-3795-43a3-ae0f-6b6760f310 ### `rejectPartner` -Reject partner request +Rejects a pending partner request, declining the partnership. `POST /v1/partners/{id}/reject` @@ -125,7 +126,7 @@ Reject partner request | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | The Id of partner | +| `id` | path | string | Yes | The unique identifier of the partner to reject | **Sample Call** @@ -154,14 +155,14 @@ epilot partner-directory rejectPartner -p id=e45a6dc2-3795-43a3-ae0f-6b6760f310f "id": "e45a6dc2-3795-43a3-ae0f-6b6760f310fc", "organization_id": "123", "created_at": "2022-02-08T04:44:32.246Z", - "description": "Description", - "company_name": "Company name", - "invitation_token": "string", + "description": "Regional solar installation partner for Bavaria", + "company_name": "Acme Solar GmbH", + "invitation_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "invitation_email": "user@example.com", - "email": "user@example.com", - "owner_email": "user@example.com", - "signed_up_email": "user@example.com", - "partner_org_id": 123456, + "email": "contact@acme-solar.de", + "owner_email": "owner@acme-solar.de", + "signed_up_email": "admin@acme-solar.de", + "partner_org_id": "456789", "status": "Pending" } ``` @@ -172,7 +173,7 @@ epilot partner-directory rejectPartner -p id=e45a6dc2-3795-43a3-ae0f-6b6760f310f ### `searchAssignable` -Search for assignable users/organizations from this organization and Partners +Search for users and organizations that can be assigned to tasks, workflows, or entities. `POST /v1/partners/assignables:search` @@ -189,11 +190,11 @@ With request body: ```bash epilot partner-directory searchAssignable \ -d '{ - "q": "", + "q": "john", "from": 0, "size": 25, - "org_ids": ["123"], - "portalUsersEntityIdScope": "", + "org_ids": ["123", "456"], + "portalUsersEntityIdScope": "f7c22299-ca72-4bca-8538-0a88eeefc947", "types": ["user", "partner_user", "partner_organization", "ecp", "group"] }' ``` @@ -215,11 +216,11 @@ epilot partner-directory searchAssignable --jsonata 'results[0]' ```json { - "hits": 25, + "hits": 42, "results": [ { "type": "user", - "display_name": "Example User", + "display_name": "John Smith", "image_uri": { "original": "https://epilot-staging-user-content.s3.eu-central-1.amazonaws.com/728/8043d909-71fc-4838-a363-1b15dc1d585c/epilot.png", "thumbnail_32": "https://file.sls.epilot.io/v1/files/public/preview?w=32&h=32&key=/728/8043d909-71fc-4838-a363-1b15dc1d585c/epilot.png" @@ -229,7 +230,7 @@ epilot partner-directory searchAssignable --jsonata 'results[0]' "activated_at": "2022-02-08T04:44:32.246Z", "status": "Active", "user_id": "456", - "email": "example@example.com" + "email": "john.smith@example.com" } ] } @@ -241,7 +242,7 @@ epilot partner-directory searchAssignable --jsonata 'results[0]' ### `batchGetAssignable` -Search for assignable users from this organization by its ids +Retrieve multiple assignable users or groups by their IDs in a single request. `POST /v1/partners/assignables:batchGet` @@ -251,7 +252,7 @@ Search for assignable users from this organization by its ids ```bash epilot partner-directory batchGetAssignable \ - -d '[{"user_id":"string","org_id":"string","group_id":"string"}]' + -d '[{"user_id":"456","org_id":"123","group_id":"group-789"}]' ``` Using stdin pipe: @@ -271,11 +272,11 @@ epilot partner-directory batchGetAssignable --jsonata 'results[0]' ```json { - "hits": 25, + "hits": 3, "results": [ { "type": "user", - "display_name": "Example User", + "display_name": "John Smith", "image_uri": { "original": "https://epilot-staging-user-content.s3.eu-central-1.amazonaws.com/728/8043d909-71fc-4838-a363-1b15dc1d585c/epilot.png", "thumbnail_32": "https://file.sls.epilot.io/v1/files/public/preview?w=32&h=32&key=/728/8043d909-71fc-4838-a363-1b15dc1d585c/epilot.png" @@ -285,7 +286,7 @@ epilot partner-directory batchGetAssignable --jsonata 'results[0]' "activated_at": "2022-02-08T04:44:32.246Z", "status": "Active", "user_id": "456", - "email": "example@example.com" + "email": "john.smith@example.com" } ] } @@ -297,7 +298,7 @@ epilot partner-directory batchGetAssignable --jsonata 'results[0]' ### `getPartnerByToken` -Get partner by token +Retrieves partner information using an invitation token. `GET /v1/partner-directory/public/getPartnerByToken` @@ -305,19 +306,19 @@ Get partner by token | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `token` | query | string | Yes | Invite Token | +| `token` | query | string | Yes | The invitation token received via email | **Sample Call** ```bash epilot partner-directory getPartnerByToken \ - -p token=example + -p token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` With JSONata filter: ```bash -epilot partner-directory getPartnerByToken -p token=example --jsonata 'id' +epilot partner-directory getPartnerByToken -p token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... --jsonata 'id' ```
@@ -328,14 +329,14 @@ epilot partner-directory getPartnerByToken -p token=example --jsonata 'id' "id": "e45a6dc2-3795-43a3-ae0f-6b6760f310fc", "organization_id": "123", "created_at": "2022-02-08T04:44:32.246Z", - "description": "Description", - "company_name": "Company name", - "invitation_token": "string", + "description": "Regional solar installation partner for Bavaria", + "company_name": "Acme Solar GmbH", + "invitation_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "invitation_email": "user@example.com", - "email": "user@example.com", - "owner_email": "user@example.com", - "signed_up_email": "user@example.com", - "partner_org_id": 123456, + "email": "contact@acme-solar.de", + "owner_email": "owner@acme-solar.de", + "signed_up_email": "admin@acme-solar.de", + "partner_org_id": "456789", "status": "Pending" } ``` @@ -346,7 +347,7 @@ epilot partner-directory getPartnerByToken -p token=example --jsonata 'id' ### `activatePartner` -Activate partner using an invite token +Activates a partner account using an invitation token. `POST /v1/partner-directory/public/activate` @@ -354,7 +355,7 @@ Activate partner using an invite token | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `token` | query | string | Yes | Invite Token | +| `token` | query | string | Yes | The invitation token received via email | **Request Body** @@ -362,27 +363,27 @@ Activate partner using an invite token ```bash epilot partner-directory activatePartner \ - -p token=example \ - -d '{"company_name":"Company name","signed_up_email":"user@example.com","organization_id":"string"}' + -p token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... \ + -d '{"company_name":"Acme Solar GmbH","signed_up_email":"admin@acme-solar.de","organization_id":"456"}' ``` Using stdin pipe: ```bash -cat body.json | epilot partner-directory activatePartner -p token=example +cat body.json | epilot partner-directory activatePartner -p token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` With JSONata filter: ```bash -epilot partner-directory activatePartner -p token=example --jsonata '$' +epilot partner-directory activatePartner -p token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... --jsonata '$' ``` --- ### `searchGeolocationForText` -Converts a given string, in the format of an address, to geo-location latitude and longitude +Converts an address string to geographic coordinates (latitude and longitude). `POST /v1/geolocation/text:search` @@ -414,8 +415,8 @@ epilot partner-directory searchGeolocationForText --jsonata 'lat' { "lat": 49.013, "lng": 12.101, - "addressLabel": "string", - "relevance": 0 + "addressLabel": "Auweg 1, 93055 Regensburg, Germany", + "relevance": 0.95 } ``` @@ -425,7 +426,7 @@ epilot partner-directory searchGeolocationForText --jsonata 'lat' ### `invitePartnerV2` -Invite a partner into collaboration. It will send an email to partner and ask to join into collaboration +Sends an invitation email to a partner organization to begin collaboration. `POST /v2/partners/{id}/invite` @@ -433,7 +434,7 @@ Invite a partner into collaboration. It will send an email to partner and ask to | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | The Id of partner | +| `id` | path | string | Yes | The unique identifier of the partner to invite | **Request Body** @@ -442,7 +443,7 @@ Invite a partner into collaboration. It will send an email to partner and ask to ```bash epilot partner-directory invitePartnerV2 \ -p id=e45a6dc2-3795-43a3-ae0f-6b6760f310fc \ - -d '{"language":"en"}' + -d '{"language":"de"}' ``` Using positional args for path parameters: @@ -471,14 +472,14 @@ epilot partner-directory invitePartnerV2 -p id=e45a6dc2-3795-43a3-ae0f-6b6760f31 "id": "e45a6dc2-3795-43a3-ae0f-6b6760f310fc", "organization_id": "123", "created_at": "2022-02-08T04:44:32.246Z", - "description": "Description", - "company_name": "Company name", - "invitation_token": "string", + "description": "Regional solar installation partner for Bavaria", + "company_name": "Acme Solar GmbH", + "invitation_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "invitation_email": "user@example.com", - "email": "user@example.com", - "owner_email": "user@example.com", - "signed_up_email": "user@example.com", - "partner_org_id": 123456, + "email": "contact@acme-solar.de", + "owner_email": "owner@acme-solar.de", + "signed_up_email": "admin@acme-solar.de", + "partner_org_id": "456789", "status": "Pending" } ``` @@ -489,7 +490,7 @@ epilot partner-directory invitePartnerV2 -p id=e45a6dc2-3795-43a3-ae0f-6b6760f31 ### `getPartnerUsers` -Get all users for a partner organization with their roles +Retrieves all users belonging to a partner organization along with their assigned roles. `GET /v2/partners/{orgId}/users` @@ -497,7 +498,7 @@ Get all users for a partner organization with their roles | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `orgId` | path | string | Yes | The organization ID of the partner | +| `orgId` | path | string | Yes | The organization ID of the partner whose users to retrieve | **Sample Call** @@ -527,7 +528,7 @@ epilot partner-directory getPartnerUsers -p orgId=123 --jsonata 'results[0]' { "id": "456", "name": "John Doe", - "email": "user@example.com", + "email": "user@partner.com", "status": "Active", "image": { "original": "https://example.com/path", @@ -535,9 +536,9 @@ epilot partner-directory getPartnerUsers -p orgId=123 --jsonata 'results[0]' }, "roles": [ { - "id": "role-123", - "slug": "admin", - "name": "Administrator" + "id": "123:partner_admin", + "slug": "partner_admin", + "name": "Partner Administrator" } ] } @@ -551,7 +552,7 @@ epilot partner-directory getPartnerUsers -p orgId=123 --jsonata 'results[0]' ### `createPartnerUser` -Create a new user in a partner organization +Creates a new user in a partner organization. `POST /v2/partners/{orgId}/users` @@ -559,7 +560,7 @@ Create a new user in a partner organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `orgId` | path | string | Yes | The Partner organization ID where the user should be created | +| `orgId` | path | string | Yes | The partner organization ID where the user will be created | **Request Body** @@ -568,7 +569,7 @@ Create a new user in a partner organization ```bash epilot partner-directory createPartnerUser \ -p orgId=123 \ - -d '{"email":"user@example.com","language":"en","roles":["role-123","role-456"]}' + -d '{"email":"newuser@partner.com","language":"de","roles":["123:partner_viewer"]}' ``` Using positional args for path parameters: @@ -607,7 +608,7 @@ epilot partner-directory createPartnerUser -p orgId=123 --jsonata 'id' ### `deletePartnerUser` -Delete a user from a partner organization +Removes a user from a partner organization. `DELETE /v2/partners/{orgId}/users/{userId}` @@ -616,26 +617,26 @@ Delete a user from a partner organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `orgId` | path | string | Yes | The organization ID of the partner | -| `userId` | path | string | Yes | The user ID to delete | +| `userId` | path | string | Yes | The unique identifier of the user to delete | **Sample Call** ```bash epilot partner-directory deletePartnerUser \ -p orgId=123 \ - -p userId=123e4567-e89b-12d3-a456-426614174000 + -p userId=456 ``` Using positional args for path parameters: ```bash -epilot partner-directory deletePartnerUser 123 123e4567-e89b-12d3-a456-426614174000 +epilot partner-directory deletePartnerUser 123 456 ``` With JSONata filter: ```bash -epilot partner-directory deletePartnerUser -p orgId=123 -p userId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot partner-directory deletePartnerUser -p orgId=123 -p userId=456 --jsonata '$' ```
@@ -651,7 +652,7 @@ epilot partner-directory deletePartnerUser -p orgId=123 -p userId=123e4567-e89b- ### `getPartnerRoles` -Get all roles for a partner organization +Retrieves all roles defined for a partner organization. `GET /v2/partners/{orgId}/roles` @@ -659,7 +660,7 @@ Get all roles for a partner organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `orgId` | path | string | Yes | The organization ID of the partner | +| `orgId` | path | string | Yes | The organization ID of the partner whose roles to retrieve | **Sample Call** @@ -687,10 +688,24 @@ epilot partner-directory getPartnerRoles -p orgId=123 --jsonata 'results[0]' { "results": [ { - "id": "role-123", - "slug": "admin", - "name": "Administrator", - "type": "share_role" + "id": "123:partner_admin", + "slug": "partner_admin", + "name": "Partner Administrator", + "type": "share_role", + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:*", + "effect": "allow", + "conditions": [ + { + "attribute": "workflows.primary.task_name", + "operation": "equals", + "values": ["Qualification"] + } + ] + } + ] } ] } @@ -702,7 +717,7 @@ epilot partner-directory getPartnerRoles -p orgId=123 --jsonata 'results[0]' ### `createPartnerRole` -Create a role for a partner organization +Creates a new role for a partner organization. `POST /v2/partners/{orgId}/roles` @@ -710,7 +725,7 @@ Create a role for a partner organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `orgId` | path | string | Yes | The organization ID of the partner | +| `orgId` | path | string | Yes | The organization ID of the partner where the role will be created | **Request Body** @@ -727,12 +742,12 @@ With request body: epilot partner-directory createPartnerRole \ -p orgId=123 \ -d '{ - "name": "Partner Admin", + "name": "Partner Administrator", "slug": "partner_admin", "grants": [ { "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "resource": "entity:123:contact:*", "effect": "allow", "conditions": [ { @@ -744,7 +759,7 @@ epilot partner-directory createPartnerRole \ "dependencies": [ { "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "resource": "entity:123:contact:*", "effect": "allow", "conditions": [ { @@ -783,10 +798,24 @@ epilot partner-directory createPartnerRole -p orgId=123 --jsonata 'id' ```json { - "id": "role-123", - "slug": "admin", - "name": "Administrator", - "type": "share_role" + "id": "123:partner_admin", + "slug": "partner_admin", + "name": "Partner Administrator", + "type": "share_role", + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:*", + "effect": "allow", + "conditions": [ + { + "attribute": "workflows.primary.task_name", + "operation": "equals", + "values": ["Qualification"] + } + ] + } + ] } ``` @@ -796,7 +825,7 @@ epilot partner-directory createPartnerRole -p orgId=123 --jsonata 'id' ### `updatePartnerRole` -Update a role for a partner organization +Updates an existing role in a partner organization. `PUT /v2/partners/{orgId}/roles/{roleId}` @@ -805,7 +834,7 @@ Update a role for a partner organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `orgId` | path | string | Yes | The organization ID of the partner | -| `roleId` | path | string | Yes | The role ID to update | +| `roleId` | path | string | Yes | The unique identifier of the role to update | **Request Body** @@ -814,7 +843,7 @@ Update a role for a partner organization ```bash epilot partner-directory updatePartnerRole \ -p orgId=123 \ - -p roleId=123e4567-e89b-12d3-a456-426614174000 + -p roleId=123:partner_sales ``` With request body: @@ -822,12 +851,12 @@ With request body: ```bash epilot partner-directory updatePartnerRole \ -p orgId=123 \ - -p roleId=123e4567-e89b-12d3-a456-426614174000 \ + -p roleId=123:partner_sales \ -d '{ "grants": [ { "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "resource": "entity:123:contact:*", "effect": "allow", "conditions": [ { @@ -839,7 +868,7 @@ epilot partner-directory updatePartnerRole \ "dependencies": [ { "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "resource": "entity:123:contact:*", "effect": "allow", "conditions": [ { @@ -861,19 +890,82 @@ epilot partner-directory updatePartnerRole \ Using positional args for path parameters: ```bash -epilot partner-directory updatePartnerRole 123 123e4567-e89b-12d3-a456-426614174000 +epilot partner-directory updatePartnerRole 123 123:partner_sales ``` Using stdin pipe: ```bash -cat body.json | epilot partner-directory updatePartnerRole -p orgId=123 -p roleId=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot partner-directory updatePartnerRole -p orgId=123 -p roleId=123:partner_sales +``` + +With JSONata filter: + +```bash +epilot partner-directory updatePartnerRole -p orgId=123 -p roleId=123:partner_sales --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "123:partner_admin", + "slug": "partner_admin", + "name": "Partner Administrator", + "type": "share_role", + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:*", + "effect": "allow", + "conditions": [ + { + "attribute": "workflows.primary.task_name", + "operation": "equals", + "values": ["Qualification"] + } + ] + } + ] +} +``` + +
+ +--- + +### `deletePartnerRole` + +Delete a role from a partner organization + +`DELETE /v2/partners/{orgId}/roles/{roleId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `orgId` | path | string | Yes | The organization ID of the partner | +| `roleId` | path | string | Yes | The role ID to delete | + +**Sample Call** + +```bash +epilot partner-directory deletePartnerRole \ + -p orgId=123 \ + -p roleId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot partner-directory deletePartnerRole 123 123e4567-e89b-12d3-a456-426614174000 ``` With JSONata filter: ```bash -epilot partner-directory updatePartnerRole -p orgId=123 -p roleId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +epilot partner-directory deletePartnerRole -p orgId=123 -p roleId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' ```
@@ -881,10 +973,24 @@ epilot partner-directory updatePartnerRole -p orgId=123 -p roleId=123e4567-e89b- ```json { - "id": "role-123", - "slug": "admin", - "name": "Administrator", - "type": "share_role" + "id": "123:partner_admin", + "slug": "partner_admin", + "name": "Partner Administrator", + "type": "share_role", + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:*", + "effect": "allow", + "conditions": [ + { + "attribute": "workflows.primary.task_name", + "operation": "equals", + "values": ["Qualification"] + } + ] + } + ] } ``` @@ -894,7 +1000,7 @@ epilot partner-directory updatePartnerRole -p orgId=123 -p roleId=123e4567-e89b- ### `assignPartnerUserRoles` -Assign roles to a user in a partner organization +Assigns one or more roles to a user in a partner organization. `POST /v2/partners/{orgId}/users/{userId}/roles` @@ -903,7 +1009,7 @@ Assign roles to a user in a partner organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `orgId` | path | string | Yes | The organization ID of the partner | -| `userId` | path | string | Yes | The user ID | +| `userId` | path | string | Yes | The unique identifier of the user to assign roles to | **Request Body** @@ -912,26 +1018,26 @@ Assign roles to a user in a partner organization ```bash epilot partner-directory assignPartnerUserRoles \ -p orgId=123 \ - -p userId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"roleIds":["role-123","role-456"]}' + -p userId=456 \ + -d '{"roleIds":["123:partner_admin","123:partner_viewer"]}' ``` Using positional args for path parameters: ```bash -epilot partner-directory assignPartnerUserRoles 123 123e4567-e89b-12d3-a456-426614174000 +epilot partner-directory assignPartnerUserRoles 123 456 ``` Using stdin pipe: ```bash -cat body.json | epilot partner-directory assignPartnerUserRoles -p orgId=123 -p userId=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot partner-directory assignPartnerUserRoles -p orgId=123 -p userId=456 ``` With JSONata filter: ```bash -epilot partner-directory assignPartnerUserRoles -p orgId=123 -p userId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +epilot partner-directory assignPartnerUserRoles -p orgId=123 -p userId=456 --jsonata 'results[0]' ```
@@ -956,7 +1062,7 @@ epilot partner-directory assignPartnerUserRoles -p orgId=123 -p userId=123e4567- ### `unassignPartnerUserRoles` -Unassign roles from a user in a partner organization +Removes one or more roles from a user in a partner organization. `DELETE /v2/partners/{orgId}/users/{userId}/roles` @@ -965,7 +1071,7 @@ Unassign roles from a user in a partner organization | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | | `orgId` | path | string | Yes | The organization ID of the partner | -| `userId` | path | string | Yes | The user ID | +| `userId` | path | string | Yes | The unique identifier of the user to remove roles from | **Request Body** @@ -974,26 +1080,26 @@ Unassign roles from a user in a partner organization ```bash epilot partner-directory unassignPartnerUserRoles \ -p orgId=123 \ - -p userId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"roleIds":["role-123","role-456"]}' + -p userId=456 \ + -d '{"roleIds":["123:partner_admin","123:partner_viewer"]}' ``` Using positional args for path parameters: ```bash -epilot partner-directory unassignPartnerUserRoles 123 123e4567-e89b-12d3-a456-426614174000 +epilot partner-directory unassignPartnerUserRoles 123 456 ``` Using stdin pipe: ```bash -cat body.json | epilot partner-directory unassignPartnerUserRoles -p orgId=123 -p userId=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot partner-directory unassignPartnerUserRoles -p orgId=123 -p userId=456 ``` With JSONata filter: ```bash -epilot partner-directory unassignPartnerUserRoles -p orgId=123 -p userId=123e4567-e89b-12d3-a456-426614174000 --jsonata 'results[0]' +epilot partner-directory unassignPartnerUserRoles -p orgId=123 -p userId=456 --jsonata 'results[0]' ```
diff --git a/docs/cli/commands/permissions.md b/docs/cli/commands/permissions.md index 27742fa4..eeb69bcd 100644 --- a/docs/cli/commands/permissions.md +++ b/docs/cli/commands/permissions.md @@ -102,7 +102,8 @@ epilot permissions listCurrentRoles --jsonata 'roles' ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ] } @@ -157,7 +158,8 @@ epilot permissions listAllRoles --jsonata 'roles' ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ] } @@ -219,7 +221,8 @@ epilot permissions createRole --jsonata '$' ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ``` @@ -295,7 +298,8 @@ epilot permissions searchRoles --jsonata 'results[0]' ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ] } @@ -361,7 +365,8 @@ epilot permissions getRole -p roleId=123:owner --jsonata '$' ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ``` @@ -416,7 +421,8 @@ epilot permissions putRole \ ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true }' ``` @@ -463,7 +469,8 @@ epilot permissions putRole -p roleId=123:owner --jsonata '$' ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ``` @@ -527,7 +534,8 @@ epilot permissions deleteRole -p roleId=123:owner --jsonata '$' ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ``` diff --git a/docs/cli/commands/pricing.md b/docs/cli/commands/pricing.md index 33457b9c..a169dc21 100644 --- a/docs/cli/commands/pricing.md +++ b/docs/cli/commands/pricing.md @@ -80,6 +80,25 @@ epilot pricing $calculatePricingDetails **Product Recommendations API** - [`$productRecommendations`](#$productrecommendations) — Get a list of product recommendations based on the search parameters. +**Conditional Pricing API** +- [`$getConditionSets`](#$getconditionsets) — Returns the condition sets built in for one conditional entity type: the situations a +- [`$resolveConditionalEntity`](#$resolveconditionalentity) — Resolves which of a conditional entity's variants apply, and returns each one composed: the +- [`$createConditionalVariant`](#$createconditionalvariant) — Creates one variant of a conditional entity, together with the first version carrying its +- [`$listConditionalVariants`](#$listconditionalvariants) — Lists a conditional entity's variants and the conditions each one pins — the browse, filter +- [`$getConditionalVariantTree`](#$getconditionalvarianttree) — The variants list, each row carrying the version in effect at `as_of` — the Entity UI's main +- [`$getActiveConditionalVariantVersion`](#$getactiveconditionalvariantversion) — Returns the version of this variant that is currently in effect — the one with the latest +- [`$replaceActiveConditionalVariantVersion`](#$replaceactiveconditionalvariantversion) — Replaces the values of the version currently in effect, wholesale. +- [`$patchActiveConditionalVariantVersion`](#$patchactiveconditionalvariantversion) — Changes only the fields it names on the version currently in effect. +- [`$deleteConditionalVariant`](#$deleteconditionalvariant) — Removes one variant of a conditional entity: the condition tuple it holds, its registration +- [`$listConditionalVariantVersions`](#$listconditionalvariantversions) — Lists one variant's versions — its whole timeline, oldest first, which is what expanding a row +- [`$appendConditionalVariantVersion`](#$appendconditionalvariantversion) — Appends a version to a variant: a new set of values taking effect at its own instant. +- [`$getConditionalVariantVersion`](#$getconditionalvariantversion) — Returns one specific version of a variant, by the instant it takes effect — what a form editing +- [`$replaceConditionalVariantVersion`](#$replaceconditionalvariantversion) — Replaces one version's values wholesale, addressed by its `valid_from`. +- [`$patchConditionalVariantVersion`](#$patchconditionalvariantversion) — Changes only the fields it names on one version, addressed by its `valid_from`. +- [`$deleteConditionalVariantVersion`](#$deleteconditionalvariantversion) — Removes one version of a variant. +- [`$batchUpsertConditionalVariants`](#$batchupsertconditionalvariants) — Writes up to 100 variants or versions in one call — the endpoint a bulk importer drives a +- [`$batchDeleteConditionalVariants`](#$batchdeleteconditionalvariants) — Removes up to 100 variants or versions in one call — the symmetric bulk withdrawal, so + ### `$calculatePricingDetails` Computes a set of pricing details that can be persisted on an entity with the pricing capability enabled, e.g: Orders or @@ -195,6 +214,7 @@ epilot pricing createOrder \ { "external_fees_mappings": [], "external_fees_metadata": {}, + "external_location_metadata": {}, "external_price_metadata": {}, "_immutable_pricing_details": {}, "coupon_ids": ["string"], @@ -224,6 +244,7 @@ epilot pricing createOrder \ { "external_fees_mappings": [], "external_fees_metadata": {}, + "external_location_metadata": {}, "external_price_metadata": {}, "_immutable_pricing_details": {}, "coupon_ids": ["string"], @@ -430,7 +451,7 @@ Update an existing Order | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `id` | path | string | Yes | Order entity ID | +| `id` | path | string (uuid) | Yes | Order entity ID | **Request Body** (required) @@ -452,6 +473,7 @@ epilot pricing putOrder \ { "external_fees_mappings": [], "external_fees_metadata": {}, + "external_location_metadata": {}, "external_price_metadata": {}, "_immutable_pricing_details": {}, "coupon_ids": ["string"], @@ -481,6 +503,7 @@ epilot pricing putOrder \ { "external_fees_mappings": [], "external_fees_metadata": {}, + "external_location_metadata": {}, "external_price_metadata": {}, "_immutable_pricing_details": {}, "coupon_ids": ["string"], @@ -1482,7 +1505,35 @@ epilot pricing $searchProviders -p X-Epilot-Org-ID=739224 -p integrationId=getag [ { "name": "string", - "code": "string" + "code": "string", + "type": "gas", + "additionalData": { + "gridOperators": [ + { + "name": "string", + "codeNumber": "string", + "validFrom": "1970-01-01", + "validUntil": "1970-01-01" + } + ], + "defaultSuppliers": [ + { + "name": "string", + "codeNumber": "string", + "validFrom": "1970-01-01", + "validUntil": "1970-01-01" + } + ], + "marketAreaDetails": { + "gasType": "L-Gas", + "marketArea": "string", + "virtualTradingPoint": "string" + } + }, + "_meta": { + "signature": "string", + "timestamp": 0 + } } ] ``` @@ -1768,6 +1819,12 @@ Returns the list of available external catalog products with computed prices bas `POST /v1/public/external-catalog/products` +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `x-epilot-org-id` | header | string | No | Organization ID (required when not using EpilotPublicAuth token) | + **Request Body** (required) **Sample Call** @@ -1854,6 +1911,12 @@ Returns the list of available external catalog products recommendations based on `POST /v1/public/external-catalog/product-recommendations` +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `x-epilot-org-id` | header | string | No | Organization ID (required when not using EpilotPublicAuth token) | + **Request Body** (required) **Sample Call** @@ -2091,3 +2154,1480 @@ epilot pricing $productRecommendations --jsonata 'results[0]'
--- + +### `$getConditionSets` + +Returns the condition sets built in for one conditional entity type: the situations a + +`GET /v1/conditional-pricing/{slug}/condition-sets` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type whose built-in condition sets to return | + +**Sample Call** + +```bash +epilot pricing $getConditionSets \ + -p slug=price +``` + +Using positional args for path parameters: + +```bash +epilot pricing $getConditionSets price +``` + +With JSONata filter: + +```bash +epilot pricing $getConditionSets -p slug=price --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "id": "delivery_area", + "label": "Delivery Area", + "description": "string", + "conditions": [ + { + "id": "d5839b94-ba20-4225-a78e-76951d352bd6", + "name": "postal_code", + "label": "Postal Code", + "type": "string", + "options": [ + "private", + { + "value": "commercial", + "title": "Commercial customers" + } + ], + "format": "zipcode" + } + ] + } + ] +} +``` + +
+ +--- + +### `$resolveConditionalEntity` + +Resolves which of a conditional entity's variants apply, and returns each one composed: the + +`POST /v1/conditional-pricing:resolve` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $resolveConditionalEntity +``` + +With request body: + +```bash +epilot pricing $resolveConditionalEntity \ + -d '{ + "schema": "product", + "entity_id": "price-sp26d1yo", + "context": { + "postal_code": "46045", + "consumption": { + "lt": 5000 + } + }, + "as_of": "2027-03-15T00:00:00Z", + "options": { + "resolve_one": false, + "hydrate": false + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $resolveConditionalEntity +``` + +With JSONata filter: + +```bash +epilot pricing $resolveConditionalEntity --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "_id": "price-sp26d1yo", + "_variant_id": "var-46045", + "_version_valid_from": "2027-01-01T00:00:00.000Z", + "_conditions": { + "postal_code": "46045", + "default": false + }, + "_inert_overrides": [ + { + "attribute": "unit_amount", + "reason": "ATTRIBUTE_NOT_OVERRIDABLE" + } + ] + } + ] +} +``` + +
+ +--- + +### `$createConditionalVariant` + +Creates one variant of a conditional entity, together with the first version carrying its + +`POST /v1/conditional-pricing/{slug}/entities/{entity_id}/variants` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity to add a variant to | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $createConditionalVariant \ + -p slug=price \ + -p entity_id=price-sp26d1yo +``` + +With request body: + +```bash +epilot pricing $createConditionalVariant \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -d '{ + "conditions": { + "postal_code": "46045" + }, + "default": false, + "valid_from": "2027-01-01T00:00:00Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $createConditionalVariant price price-sp26d1yo +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $createConditionalVariant -p slug=price -p entity_id=price-sp26d1yo +``` + +With JSONata filter: + +```bash +epilot pricing $createConditionalVariant -p slug=price -p entity_id=price-sp26d1yo --jsonata 'variant_id' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 0, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$listConditionalVariants` + +Lists a conditional entity's variants and the conditions each one pins — the browse, filter + +`POST /v1/conditional-pricing/{slug}/entities/{entity_id}/variants:list` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type the variants belong to | +| `entity_id` | path | string | Yes | The conditional entity whose variants to list | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $listConditionalVariants \ + -p slug=price \ + -p entity_id=price-sp26d1yo +``` + +With request body: + +```bash +epilot pricing $listConditionalVariants \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -d '{ + "conditions": { + "postal_code": "46045", + "consumption": { + "lt": 5000 + } + }, + "search": "460", + "sort": "conditions.postal_code:asc", + "from": 0, + "size": 10, + "cursor": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $listConditionalVariants price price-sp26d1yo +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $listConditionalVariants -p slug=price -p entity_id=price-sp26d1yo +``` + +With JSONata filter: + +```bash +epilot pricing $listConditionalVariants -p slug=price -p entity_id=price-sp26d1yo --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "hits": 8128, + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + } + } + ], + "next": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" +} +``` + +
+ +--- + +### `$getConditionalVariantTree` + +The variants list, each row carrying the version in effect at `as_of` — the Entity UI's main + +`POST /v1/conditional-pricing/{slug}/entities/{entity_id}/variants:tree` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type the variants belong to | +| `entity_id` | path | string | Yes | The conditional entity whose variants to list | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $getConditionalVariantTree \ + -p slug=price \ + -p entity_id=price-sp26d1yo +``` + +With request body: + +```bash +epilot pricing $getConditionalVariantTree \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -d '{ + "conditions": { + "postal_code": "46045", + "consumption": { + "lt": 5000 + } + }, + "search": "460", + "sort": "conditions.postal_code:asc", + "from": 0, + "size": 10, + "cursor": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0", + "as_of": "2027-03-15T00:00:00Z" +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $getConditionalVariantTree price price-sp26d1yo +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $getConditionalVariantTree -p slug=price -p entity_id=price-sp26d1yo +``` + +With JSONata filter: + +```bash +epilot pricing $getConditionalVariantTree -p slug=price -p entity_id=price-sp26d1yo --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "hits": 8128, + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "status": "active", + "version": { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string" + } + } + ], + "next": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" +} +``` + +
+ +--- + +### `$getActiveConditionalVariantVersion` + +Returns the version of this variant that is currently in effect — the one with the latest + +`GET /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline this call addresses | + +**Sample Call** + +```bash +epilot pricing $getActiveConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 +``` + +Using positional args for path parameters: + +```bash +epilot pricing $getActiveConditionalVariantVersion price price-sp26d1yo var-46045 +``` + +With JSONata filter: + +```bash +epilot pricing $getActiveConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 --jsonata 'variant_id' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3 +} +``` + +
+ +--- + +### `$replaceActiveConditionalVariantVersion` + +Replaces the values of the version currently in effect, wholesale. + +`PUT /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline this call addresses | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $replaceActiveConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 +``` + +With request body: + +```bash +epilot pricing $replaceActiveConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -d '{ + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_revision": 3, + "valid_from": "string", + "conditions": { + "postal_code": "46045" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $replaceActiveConditionalVariantVersion price price-sp26d1yo var-46045 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $replaceActiveConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 +``` + +With JSONata filter: + +```bash +epilot pricing $replaceActiveConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$patchActiveConditionalVariantVersion` + +Changes only the fields it names on the version currently in effect. + +`PATCH /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline this call addresses | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $patchActiveConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 +``` + +With request body: + +```bash +epilot pricing $patchActiveConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -d '{ + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_revision": 3, + "valid_from": "string", + "conditions": { + "postal_code": "46045" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $patchActiveConditionalVariantVersion price price-sp26d1yo var-46045 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $patchActiveConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 +``` + +With JSONata filter: + +```bash +epilot pricing $patchActiveConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$deleteConditionalVariant` + +Removes one variant of a conditional entity: the condition tuple it holds, its registration + +`DELETE /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant to remove | + +**Sample Call** + +```bash +epilot pricing $deleteConditionalVariant \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 +``` + +Using positional args for path parameters: + +```bash +epilot pricing $deleteConditionalVariant price price-sp26d1yo var-46045 +``` + +With JSONata filter: + +```bash +epilot pricing $deleteConditionalVariant -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 --jsonata 'variant_id' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "tuple_released": true, + "versions_deleted": 0 +} +``` + +
+ +--- + +### `$listConditionalVariantVersions` + +Lists one variant's versions — its whole timeline, oldest first, which is what expanding a row + +`GET /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline to list | +| `limit` | query | number | No | Versions per page. Defaults to 100, which is also the maximum; a larger value is clamped +silently. A variant's timeline is usually short enough to fit one page. + | +| `order` | query | "asc" \| "desc" | No | Which end of the timeline to read from: `asc` oldest first, `desc` newest first. Defaults +to `asc`. + +Baked into every cursor this read issues: a cursor resumes one direction, and replaying it +against | +| `cursor` | query | string | No | Continue from a previous response's `next`. Opaque: it encodes the position and the order +it was issued for, and nothing a client should read or construct. + | + +**Sample Call** + +```bash +epilot pricing $listConditionalVariantVersions \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 +``` + +Using positional args for path parameters: + +```bash +epilot pricing $listConditionalVariantVersions price price-sp26d1yo var-46045 +``` + +With JSONata filter: + +```bash +epilot pricing $listConditionalVariantVersions -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string" + } + ], + "next": "eyJzayI6IlYjcHJpY2Utc3AyNmQxeW8jdmFyLTQ2MDQ1IzIwMjYtMDEtMDFUMDA6MDA6MDAuMDAwWiIsIm9yZGVyIjoiYXNjIn0" +} +``` + +
+ +--- + +### `$appendConditionalVariantVersion` + +Appends a version to a variant: a new set of values taking effect at its own instant. + +`POST /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline this call addresses | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $appendConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 +``` + +With request body: + +```bash +epilot pricing $appendConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -d '{ + "valid_from": "2027-01-01T00:00:00Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "conditions": { + "postal_code": "46045" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $appendConditionalVariantVersion price price-sp26d1yo var-46045 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $appendConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 +``` + +With JSONata filter: + +```bash +epilot pricing $appendConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$getConditionalVariantVersion` + +Returns one specific version of a variant, by the instant it takes effect — what a form editing + +`GET /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline this call addresses | +| `valid_from` | path | string | Yes | The version to address, by the instant it takes effect. + +An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time +(`2026-01-01T00:00:00Z`), to at most millisecond precision. Written any acce | + +**Sample Call** + +```bash +epilot pricing $getConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -p valid_from=2027-01-01T00:00:00.000Z +``` + +Using positional args for path parameters: + +```bash +epilot pricing $getConditionalVariantVersion price price-sp26d1yo var-46045 2027-01-01T00:00:00.000Z +``` + +With JSONata filter: + +```bash +epilot pricing $getConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 -p valid_from=2027-01-01T00:00:00.000Z --jsonata 'variant_id' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3 +} +``` + +
+ +--- + +### `$replaceConditionalVariantVersion` + +Replaces one version's values wholesale, addressed by its `valid_from`. + +`PUT /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline this call addresses | +| `valid_from` | path | string | Yes | The version to address, by the instant it takes effect. + +An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time +(`2026-01-01T00:00:00Z`), to at most millisecond precision. Written any acce | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $replaceConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -p valid_from=2027-01-01T00:00:00.000Z +``` + +With request body: + +```bash +epilot pricing $replaceConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -p valid_from=2027-01-01T00:00:00.000Z \ + -d '{ + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_revision": 3, + "valid_from": "string", + "conditions": { + "postal_code": "46045" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $replaceConditionalVariantVersion price price-sp26d1yo var-46045 2027-01-01T00:00:00.000Z +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $replaceConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 -p valid_from=2027-01-01T00:00:00.000Z +``` + +With JSONata filter: + +```bash +epilot pricing $replaceConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 -p valid_from=2027-01-01T00:00:00.000Z --jsonata '$' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$patchConditionalVariantVersion` + +Changes only the fields it names on one version, addressed by its `valid_from`. + +`PATCH /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline this call addresses | +| `valid_from` | path | string | Yes | The version to address, by the instant it takes effect. + +An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time +(`2026-01-01T00:00:00Z`), to at most millisecond precision. Written any acce | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $patchConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -p valid_from=2027-01-01T00:00:00.000Z +``` + +With request body: + +```bash +epilot pricing $patchConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -p valid_from=2027-01-01T00:00:00.000Z \ + -d '{ + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_revision": 3, + "valid_from": "string", + "conditions": { + "postal_code": "46045" + } +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $patchConditionalVariantVersion price price-sp26d1yo var-46045 2027-01-01T00:00:00.000Z +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $patchConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 -p valid_from=2027-01-01T00:00:00.000Z +``` + +With JSONata filter: + +```bash +epilot pricing $patchConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 -p valid_from=2027-01-01T00:00:00.000Z --jsonata '$' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$deleteConditionalVariantVersion` + +Removes one version of a variant. + +`DELETE /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type this variant belongs to | +| `entity_id` | path | string | Yes | The conditional entity the variant belongs to | +| `variant_id` | path | string | Yes | The variant whose timeline this call addresses | +| `valid_from` | path | string | Yes | The version to address, by the instant it takes effect. + +An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time +(`2026-01-01T00:00:00Z`), to at most millisecond precision. Written any acce | +| `_revision` | query | number | Yes | The revision marker read from the version being deleted. The delete is refused if the +version has been written since. + +The same marker the write bodies carry as `_revision`. + | + +**Sample Call** + +```bash +epilot pricing $deleteConditionalVariantVersion \ + -p slug=price \ + -p entity_id=price-sp26d1yo \ + -p variant_id=var-46045 \ + -p valid_from=2027-01-01T00:00:00.000Z \ + -p _revision=3 +``` + +Using positional args for path parameters: + +```bash +epilot pricing $deleteConditionalVariantVersion price price-sp26d1yo var-46045 2027-01-01T00:00:00.000Z +``` + +With JSONata filter: + +```bash +epilot pricing $deleteConditionalVariantVersion -p slug=price -p entity_id=price-sp26d1yo -p variant_id=var-46045 -p valid_from=2027-01-01T00:00:00.000Z -p _revision=3 --jsonata 'variant_id' +``` + +
+Sample Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "valid_from": "2027-01-01T00:00:00.000Z", + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$batchUpsertConditionalVariants` + +Writes up to 100 variants or versions in one call — the endpoint a bulk importer drives a + +`POST /v1/conditional-pricing/{slug}/variants:batchUpsert` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type every item in this call writes under | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $batchUpsertConditionalVariants \ + -p slug=price +``` + +With request body: + +```bash +epilot pricing $batchUpsertConditionalVariants \ + -p slug=price \ + -d '{ + "correlation_id": "tariff-refresh-2027-01", + "items": [ + { + "entity_id": "price-sp26d1yo", + "conditions": { + "postal_code": "46045" + }, + "default": false, + "valid_from": "2027-01-01T00:00:00Z", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + } + } + ] +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $batchUpsertConditionalVariants price +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $batchUpsertConditionalVariants -p slug=price +``` + +With JSONata filter: + +```bash +epilot pricing $batchUpsertConditionalVariants -p slug=price --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "correlation_id": "tariff-refresh-2027-01", + "counts": { + "variant_created": 1, + "version_created": 1, + "updated": 1, + "skipped": 1, + "error": 1 + }, + "results": [ + { + "outcome": "variant_created", + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045", + "valid_from": "2027-01-01T00:00:00.000Z", + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ], + "error": { + "code": "SCHEMA_NOT_FOUND", + "details": { + "schema": "price" + } + } + } + ] +} +``` + +
+ +--- + +### `$batchDeleteConditionalVariants` + +Removes up to 100 variants or versions in one call — the symmetric bulk withdrawal, so + +`POST /v1/conditional-pricing/{slug}/variants:batchDelete` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `slug` | path | "product" \| "price" \| "coupon" | Yes | The conditional entity type every item in this call removes from | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot pricing $batchDeleteConditionalVariants \ + -p slug=price +``` + +With request body: + +```bash +epilot pricing $batchDeleteConditionalVariants \ + -p slug=price \ + -d '{ + "correlation_id": "postal-code-cleanup-2026-09", + "items": [ + { + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045", + "valid_from": "2027-01-01T00:00:00Z" + } + ] +}' +``` + +Using positional args for path parameters: + +```bash +epilot pricing $batchDeleteConditionalVariants price +``` + +Using stdin pipe: + +```bash +cat body.json | epilot pricing $batchDeleteConditionalVariants -p slug=price +``` + +With JSONata filter: + +```bash +epilot pricing $batchDeleteConditionalVariants -p slug=price --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "correlation_id": "postal-code-cleanup-2026-09", + "counts": { + "deleted": 1, + "skipped": 1, + "error": 1 + }, + "results": [ + { + "outcome": "deleted", + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045", + "valid_from": "2027-01-01T00:00:00.000Z", + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ], + "error": { + "code": "SCHEMA_NOT_FOUND", + "details": { + "schema": "price" + } + } + } + ] +} +``` + +
+ +--- diff --git a/docs/cli/commands/query.md b/docs/cli/commands/query.md new file mode 100644 index 00000000..d8224f9b --- /dev/null +++ b/docs/cli/commands/query.md @@ -0,0 +1,1112 @@ +--- +title: "Query API" +description: "epilot CLI commands for the Query API: quick start, common flags and every operation, callable from the command line." +--- + +# Query API + +- **Base URL:** `https://query.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/query](https://docs.epilot.io/api/query) + +The Query API provides access to epilot's business analytics capabilities, enabling teams to query entity operations, workflow executions, and automation data stored in the epilot data lake. + +## Quick Start + +```bash +# List available operations +epilot query + +# Call an operation +epilot query getAllViews +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Datalake V2** +- [`getAllViews`](#getallviews) — Retrieve all materialized data lake views configured for the organization. +- [`createOrUpdateView`](#createorupdateview) — Create or update a materialized SQL view in the epilot data lake. +- [`getView`](#getview) — Retrieve the definition and attributes of a specific data lake view by its slug. +- [`getAllRelationships`](#getallrelationships) — Retrieve all table relationships configured for the organization's data lake. +- [`createOrUpdateRelationship`](#createorupdaterelationship) — Define or update a relationship between two tables in the data lake. + +**Datasets** +- [`listAvailableDatasetsV2`](#listavailabledatasetsv2) — Lists all available datasets grouped by domain + +**Query** +- [`executeEntitiesQuery`](#executeentitiesquery) — Execute queries against entities datasets. +- [`executeWorkflowsQuery`](#executeworkflowsquery) — Query Workflow Analytics Datasets. +- [`executeAutomationQuery`](#executeautomationquery) — Query Automation Analytics Datasets. +- [`listWorkflowPhasesByDefinitionId`](#listworkflowphasesbydefinitionid) — Retrieves the workflow phases associated with a given workflow definition ID. +- [`listWorkflowDefinitions`](#listworkflowdefinitions) — Lists available worflow definitions with their ids, names and start times +- [`listPhaseNames`](#listphasenames) — Lists phase names of an org. + +**V1** +- [`listDatasets`](#listdatasets) — Get list of available datasets +- [`executeQuery`](#executequery) — Execute queries against datasets. + +**CredentialsV2** +- [`generateCredentialsV2`](#generatecredentialsv2) — Generate credentials for the epilot datalake for connecting other BI tools with ClickHouse +- [`listCredentialsV2`](#listcredentialsv2) — List all the credentialof Clickhouse for the organization here +- [`revokeCredentialsV2`](#revokecredentialsv2) — Revoke credentials for the epilot datalake for connecting other BI tools with Clickhouse + +**V2** +- [`executeQueryV2`](#executequeryv2) — Execute queries against datasets. +- [`getSemanticModel`](#getsemanticmodel) — Get the semantic model for agent/tool consumption. +- [`autocomplete`](#autocomplete) — Generic autocomplete endpoint for querying distinct values across datasets. +- [`workflowsAutocomplete`](#workflowsautocomplete) — Autocomplete Workflows data + +### `getAllViews` + +Retrieve all materialized data lake views configured for the organization. + +`GET /datalake/views` + +**Sample Call** + +```bash +epilot query getAllViews +``` + +With JSONata filter: + +```bash +epilot query getAllViews --jsonata 'views' +``` + +
+Sample Response + +```json +{ + "views": [ + { + "view_name": "some_view", + "source_dataset": "current_entities", + "view_slug": "some_view", + "attributes": [ + { + "name": "some_attribute", + "type": "string", + "description": "some description" + } + ] + }, + { + "view_name": "another_view", + "source_dataset": "taxonomies", + "view_slug": "another_view", + "attributes": [ + { + "name": "taxonomy_attribute", + "type": "string", + "description": "taxonomy attribute description" + } + ] + } + ] +} +``` + +
+ +--- + +### `createOrUpdateView` + +Create or update a materialized SQL view in the epilot data lake. + +`POST /datalake/views` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot query createOrUpdateView +``` + +With request body: + +```bash +epilot query createOrUpdateView \ + -d '{ + "view_name": "some_view", + "source_dataset": "current_entities", + "config": { + "schema": "some_schema", + "include_purpose_view": true, + "include_label_view": true, + "include_relation_view": true, + "relationship_attribute": ["some_relationship_attribute"] + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot query createOrUpdateView +``` + +With JSONata filter: + +```bash +epilot query createOrUpdateView --jsonata 'view_name' +``` + +
+Sample Response + +```json +{ + "view_name": "some_view", + "source_dataset": "current_entities", + "attributes": [ + { + "name": "some_attribute", + "type": "string", + "description": "some description" + } + ] +} +``` + +
+ +--- + +### `getView` + +Retrieve the definition and attributes of a specific data lake view by its slug. + +`GET /datalake/views/{view_slug}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `view_slug` | path | string | Yes | The URL-safe slug identifier of the view | + +**Sample Call** + +```bash +epilot query getView \ + -p view_slug=some_view +``` + +Using positional args for path parameters: + +```bash +epilot query getView some_view +``` + +With JSONata filter: + +```bash +epilot query getView -p view_slug=some_view --jsonata 'view_name' +``` + +
+Sample Response + +```json +{ + "view_name": "some_view", + "source_dataset": "current_entities", + "attributes": [ + { + "name": "some_attribute", + "type": "string", + "description": "some description" + } + ] +} +``` + +
+ +--- + +### `getAllRelationships` + +Retrieve all table relationships configured for the organization's data lake. + +`GET /datalake/relationships` + +**Sample Call** + +```bash +epilot query getAllRelationships +``` + +With JSONata filter: + +```bash +epilot query getAllRelationships --jsonata 'relationships' +``` + +
+Sample Response + +```json +{ + "relationships": [ + { + "relationship_name": "some_relationship", + "from_table": "some_table", + "to_table": "some_table", + "from_column": "some_column", + "to_column": "some_column", + "type": "one_to_many" + }, + { + "relationship_name": "another_relationship", + "from_table": "table_a", + "to_table": "table_b", + "from_column": "column_a", + "to_column": "column_b", + "type": "many_to_many" + } + ] +} +``` + +
+ +--- + +### `createOrUpdateRelationship` + +Define or update a relationship between two tables in the data lake. + +`POST /datalake/relationships` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot query createOrUpdateRelationship +``` + +With request body: + +```bash +epilot query createOrUpdateRelationship \ + -d '{ + "relationship_name": "some_relationship", + "from_table": "some_table", + "to_table": "some_table", + "from_column": "some_column", + "to_column": "some_column", + "type": "one_to_many" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot query createOrUpdateRelationship +``` + +With JSONata filter: + +```bash +epilot query createOrUpdateRelationship --jsonata 'relationship_name' +``` + +
+Sample Response + +```json +{ + "relationship_name": "some_relationship", + "from_table": "some_table", + "to_table": "some_table", + "from_column": "some_column", + "to_column": "some_column", + "type": "one_to_many" +} +``` + +
+ +--- + +### `listAvailableDatasetsV2` + +Lists all available datasets grouped by domain + +`GET /v2/query/datasets` + +**Sample Call** + +```bash +epilot query listAvailableDatasetsV2 +``` + +With JSONata filter: + +```bash +epilot query listAvailableDatasetsV2 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "domain": "entities", + "dataset": "entity_operations", + "endpoint": "/v2/query/domain/entities:execute" + }, + { + "domain": "workflows", + "dataset": "workflow_execution_time_series", + "endpoint": "/v2/query/domain/workflows:execute" + } + ] +} +``` + +
+ +--- + +### `executeEntitiesQuery` + +Execute queries against entities datasets. + +`POST /v2/query/domain/entities:execute` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `cache_expiration` | query | string (timestamp) | No | | +| `no_cache` | query | boolean | No | | + +**Request Body** + +**Sample Call** + +```bash +epilot query executeEntitiesQuery \ + -d '{"query":{}}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot query executeEntitiesQuery +``` + +With JSONata filter: + +```bash +epilot query executeEntitiesQuery --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "status": "FINISHED", + "timestamp": "1715621496068", + "results": [ + {} + ] +} +``` + +
+ +--- + +### `executeWorkflowsQuery` + +Query Workflow Analytics Datasets. + +`POST /v2/query/domain/workflows:execute` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `mock` | query | boolean | No | | +| `cache_expiration` | query | string (timestamp) | No | | +| `no_cache` | query | boolean | No | | + +**Request Body** + +**Sample Call** + +```bash +epilot query executeWorkflowsQuery +``` + +With request body: + +```bash +epilot query executeWorkflowsQuery \ + -d '{ + "dataset": "total_count_of_workflow_executions", + "workflow_definition_ids": ["string"], + "entity_schemas": ["string"], + "states": ["string"], + "group_time_by": "M", + "relative_time_range": "string", + "time_range_from": "string", + "time_range_to": "string", + "duration_threshold": 0 +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot query executeWorkflowsQuery +``` + +With JSONata filter: + +```bash +epilot query executeWorkflowsQuery --jsonata 'data' +``` + +
+Sample Response + +```json +{ + "data": [0, 1], + "labels": ["label1", "label2"], + "timestamp": "1715621496068" +} +``` + +
+ +--- + +### `executeAutomationQuery` + +Query Automation Analytics Datasets. + +`POST /v2/query/domain/automations:execute` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `from` | query | number | No | | +| `size` | query | number | No | | + +**Request Body** + +**Sample Call** + +```bash +epilot query executeAutomationQuery +``` + +With request body: + +```bash +epilot query executeAutomationQuery \ + -d '{ + "dataset": "automation_executions_overview", + "flow_ids": ["string"], + "execution_states": ["success", "failed", "scheduled"], + "relative_time_range": "all_time", + "time_range_from": "string", + "time_range_to": "string" +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot query executeAutomationQuery +``` + +With JSONata filter: + +```bash +epilot query executeAutomationQuery --jsonata '$' +``` + +
+Sample Response + +```json +{ + "hits": 100, + "results": [ + { + "flow_id": "1234567890", + "flow_name": "flow_name", + "execution_id": "execution_id", + "execution_status": "execution_status", + "entity_schema": "opportunity", + "entity_id": "entity_id", + "created_at": "execution_created_at", + "updated_at": "execution_updated_at", + "error": { + "message": "error_message", + "error_code": "error_code" + }, + "trigger_event": { + "type": "EntityOperation", + "trigger_type": "createEntity" + } + } + ] +} +``` + +
+ +--- + +### `listWorkflowPhasesByDefinitionId` + +Retrieves the workflow phases associated with a given workflow definition ID. + +`GET /v2/query/domain/workflows/definitions/{workflowDefinitionId}/phases` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `workflowDefinitionId` | path | string | Yes | The ID of the workflow definition to retrieve phases for. | + +**Sample Call** + +```bash +epilot query listWorkflowPhasesByDefinitionId \ + -p workflowDefinitionId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot query listWorkflowPhasesByDefinitionId 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot query listWorkflowPhasesByDefinitionId -p workflowDefinitionId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "id": "y0UdVCOI", + "name": "Initial Phase" + } +] +``` + +
+ +--- + +### `listWorkflowDefinitions` + +Lists available worflow definitions with their ids, names and start times + +`GET /v2/query/domain/workflows/definitions` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `mock` | query | boolean | No | | + +**Sample Call** + +```bash +epilot query listWorkflowDefinitions +``` + +With JSONata filter: + +```bash +epilot query listWorkflowDefinitions --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "id": "y0UdVCOI", + "name": "PV Kauf", + "max_date": "2023-05-31T00:00:00.000Z", + "min_date": "2023-01-00T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `listPhaseNames` + +Lists phase names of an org. + +`GET /v2/query/domain/workflows/phases` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `org_id` | query | string | No | | + +**Sample Call** + +```bash +epilot query listPhaseNames +``` + +With JSONata filter: + +```bash +epilot query listPhaseNames --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "id": "y0UdVCOI", + "name": "PV Kauf", + "max_date": "2023-05-31T00:00:00.000Z", + "min_date": "2023-01-00T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `listDatasets` + +Get list of available datasets + +`GET /v1/query/datasets` + +**Sample Call** + +```bash +epilot query listDatasets +``` + +With JSONata filter: + +```bash +epilot query listDatasets --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "dataset": "entity_operations" + }, + { + "dataset": "entities_timemachine" + } + ] +} +``` + +
+ +--- + +### `executeQuery` + +Execute queries against datasets. + +`POST /v1/query:execute` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `cache_expiration` | query | string (timestamp) | No | | +| `no_cache` | query | boolean | No | | + +**Request Body** + +**Sample Call** + +```bash +epilot query executeQuery \ + -d '{"query":{}}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot query executeQuery +``` + +With JSONata filter: + +```bash +epilot query executeQuery --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "status": "FINISHED", + "timestamp": "1715621496068", + "results": [ + {} + ] +} +``` + +
+ +--- + +### `generateCredentialsV2` + +Generate credentials for the epilot datalake for connecting other BI tools with ClickHouse + +`POST /v2/query/credentials:generate` + +**Sample Call** + +```bash +epilot query generateCredentialsV2 +``` + +With JSONata filter: + +```bash +epilot query generateCredentialsV2 --jsonata 'username' +``` + +
+Sample Response + +```json +{ + "username": "datalakeuser_sfsdfs_66", + "password": "***", + "endpoints": { + "host": "qjjcxsy87t.eu-central-1.aws.clickhouse.cloud", + "port": 8443 + }, + "database": "datawarehouse" +} +``` + +
+ +--- + +### `listCredentialsV2` + +List all the credentialof Clickhouse for the organization here + +`GET /v2/query/credentials:list` + +**Sample Call** + +```bash +epilot query listCredentialsV2 +``` + +With JSONata filter: + +```bash +epilot query listCredentialsV2 --jsonata 'users' +``` + +
+Sample Response + +```json +{ + "users": [ + { + "user_id": "string" + } + ] +} +``` + +
+ +--- + +### `revokeCredentialsV2` + +Revoke credentials for the epilot datalake for connecting other BI tools with Clickhouse + +`POST /v2/query/credentials:revoke` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `user_id` | query | string | No | | + +**Sample Call** + +```bash +epilot query revokeCredentialsV2 +``` + +With JSONata filter: + +```bash +epilot query revokeCredentialsV2 --jsonata 'success' +``` + +
+Sample Response + +```json +{ + "success": true +} +``` + +
+ +--- + +### `executeQueryV2` + +Execute queries against datasets. + +`POST /v2/query:execute` + +**Request Body** + +**Sample Call** + +```bash +epilot query executeQueryV2 \ + -d '{}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot query executeQueryV2 +``` + +With JSONata filter: + +```bash +epilot query executeQueryV2 --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "status": "FINISHED", + "timestamp": "1715621496068", + "results": [ + {} + ] +} +``` + +
+ +--- + +### `getSemanticModel` + +Get the semantic model for agent/tool consumption. + +`GET /v2/query/semantic-model` + +**Sample Call** + +```bash +epilot query getSemanticModel +``` + +With JSONata filter: + +```bash +epilot query getSemanticModel --jsonata 'entities' +``` + +
+Sample Response + +```json +{ + "entities": [ + { + "name": "current_contacts", + "displayName": "Contacts", + "schema": "entity" + } + ], + "relationships": [ + { + "from": "current_contacts", + "to": "opportunity_account_contact_relation", + "relationship": "hasMany", + "displayName": "Contact has many Opportunities" + } + ], + "capabilities": { + "aggregations": ["count", "count_distinct", "sum", "average", "min", "max", "median"], + "calculationTypes": [ + { + "type": "string", + "description": "string", + "parameters": {} + } + ], + "granularities": ["day", "week", "month", "quarter", "year"], + "filterOperators": [ + { + "operator": "string", + "description": "string" + } + ] + } +} +``` + +
+ +--- + +### `autocomplete` + +Generic autocomplete endpoint for querying distinct values across datasets. + +`GET /v2/query/autocomplete` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `dataset` | query | "workflows" \| "purposes" \| "sharing_configs" \| "partners" | Yes | The dataset category to autocomplete against | +| `input` | query | string | No | Input text to autocomplete | +| `attribute` | query | string | Yes | Attribute to autocomplete in table.column format (e.g., current_purposes.name) | +| `size` | query | number | No | Maximum number of results to return | + +**Sample Call** + +```bash +epilot query autocomplete \ + -p dataset=example \ + -p attribute=current_purposes.name +``` + +With JSONata filter: + +```bash +epilot query autocomplete -p dataset=example -p attribute=current_purposes.name --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": ["value"] +} +``` + +
+ +--- + +### `workflowsAutocomplete` + +Autocomplete Workflows data + +`GET /v2/query/workflows:autocomplete` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `input` | query | string | No | Input to autocomplete | +| `attribute` | query | string | Yes | Autocomplete attribute | +| `size` | query | number | No | Maximum number of results to return | + +**Sample Call** + +```bash +epilot query workflowsAutocomplete \ + -p attribute=name +``` + +With JSONata filter: + +```bash +epilot query workflowsAutocomplete -p attribute=name --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": ["value"] +} +``` + +
+ +--- diff --git a/docs/cli/commands/sharing.md b/docs/cli/commands/sharing.md new file mode 100644 index 00000000..3d0ea28a --- /dev/null +++ b/docs/cli/commands/sharing.md @@ -0,0 +1,1088 @@ +--- +title: "Sharing API" +description: "epilot CLI commands for the Sharing API: quick start, common flags and every operation, callable from the command line." +--- + +# Sharing API + +- **Base URL:** `https://sharing-api.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/sharing](https://docs.epilot.io/api/sharing) + +REST API for managing partner sharing configurations and entity sharing. + +## Quick Start + +```bash +# List available operations +epilot sharing + +# Call an operation +epilot sharing getSharingConfiguration -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Sharing Configuration** +- [`getSharingConfiguration`](#getsharingconfiguration) — Returns the sharing configuration for a specific partner organization, including shared entities, offered entities, and +- [`updateSharingConfiguration`](#updatesharingconfiguration) — Updates the sharing configuration for a partner, such as the user limit. Also patches the internal role if the user limi +- [`deleteSharingConfiguration`](#deletesharingconfiguration) — Deletes the sharing configuration for a partner, removing all shared and offered entity access. +- [`assignRoleToConfiguration`](#assignroletoconfiguration) — Assigns a template role to a partner sharing configuration. The role grants are copied into the configuration for entity +- [`getSharingConfigurations`](#getsharingconfigurations) — Returns sharing configurations for multiple partner organizations in a single batch request. +- [`searchPartnerSharingConfigurations`](#searchpartnersharingconfigurations) — Searches for partner sharing configurations that have access to the given entities. Returns configurations with their sh +- [`getConfigurationsByTemplateRole`](#getconfigurationsbytemplaterole) — Returns all partner sharing configurations that reference the given template role ID. Useful for checking role usage bef + +**Entity Sharing** +- [`shareEntityWithPartners`](#shareentitywithpartners) — Shares or unshares top-level entities with one or more partner organizations. Publishes sharing events for downstream pr +- [`shareChildEntityWithPartners`](#sharechildentitywithpartners) — Shares or unshares child entities (entities that belong to an already-shared parent) with partner organizations. + +**Entity Offering** +- [`offerEntityToPartners`](#offerentitytopartners) — Offers or unoffers entities to partner organizations using a First Come First Served model. Only one partner can accept +- [`getOfferStatus`](#getofferstatus) — Returns the current status of an entity offer (pending, accepted, expired). This is a public endpoint used from partner- +- [`acceptOffer`](#acceptoffer) — Accepts an entity offer on behalf of a partner organization. This is a public endpoint used from partner-facing pages wi + +### `getSharingConfiguration` + +Returns the sharing configuration for a specific partner organization, including shared entities, offered entities, and + +`GET /v1/sharing/configurations/{partner_org_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `partner_org_id` | path | string | Yes | Partner organization ID | + +**Sample Call** + +```bash +epilot sharing getSharingConfiguration \ + -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot sharing getSharingConfiguration 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot sharing getSharingConfiguration -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'sharing_org_id' +``` + +
+Sample Response + +```json +{ + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" +} +``` + +
+ +--- + +### `updateSharingConfiguration` + +Updates the sharing configuration for a partner, such as the user limit. Also patches the internal role if the user limi + +`PATCH /v1/sharing/configurations/{partner_org_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `partner_org_id` | path | string | Yes | Partner organization ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot sharing updateSharingConfiguration \ + -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"user_limit":0}' +``` + +Using positional args for path parameters: + +```bash +epilot sharing updateSharingConfiguration 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot sharing updateSharingConfiguration -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot sharing updateSharingConfiguration -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'sharing_org_id' +``` + +
+Sample Response + +```json +{ + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" +} +``` + +
+ +--- + +### `deleteSharingConfiguration` + +Deletes the sharing configuration for a partner, removing all shared and offered entity access. + +`DELETE /v1/sharing/configurations/{partner_org_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `partner_org_id` | path | string | Yes | Partner organization ID | + +**Sample Call** + +```bash +epilot sharing deleteSharingConfiguration \ + -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot sharing deleteSharingConfiguration 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot sharing deleteSharingConfiguration -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'sharing_org_id' +``` + +
+Sample Response + +```json +{ + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" +} +``` + +
+ +--- + +### `assignRoleToConfiguration` + +Assigns a template role to a partner sharing configuration. The role grants are copied into the configuration for entity + +`PUT /v1/sharing/configurations/{partner_org_id}/role` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `partner_org_id` | path | string | Yes | Partner organization ID | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot sharing assignRoleToConfiguration \ + -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"template_role_id":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot sharing assignRoleToConfiguration 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot sharing assignRoleToConfiguration -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot sharing assignRoleToConfiguration -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'sharing_org_id' +``` + +
+Sample Response + +```json +{ + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" +} +``` + +
+ +--- + +### `getSharingConfigurations` + +Returns sharing configurations for multiple partner organizations in a single batch request. + +`GET /v1/sharing/configurations` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `partner_org_ids` | query | string[] | Yes | Comma-separated list of partner organization IDs | + +**Sample Call** + +```bash +epilot sharing getSharingConfigurations \ + -p partner_org_ids=example +``` + +With JSONata filter: + +```bash +epilot sharing getSharingConfigurations -p partner_org_ids=example --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" + } +] +``` + +
+ +--- + +### `searchPartnerSharingConfigurations` + +Searches for partner sharing configurations that have access to the given entities. Returns configurations with their sh + +`POST /v1/sharing/configurations:search` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot sharing searchPartnerSharingConfigurations \ + -d '{"entities":[{"schema":"string","entity_id":"string","parent_entity_id":"string","offer_accepted":true}]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot sharing searchPartnerSharingConfigurations +``` + +With JSONata filter: + +```bash +epilot sharing searchPartnerSharingConfigurations --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" + } +] +``` + +
+ +--- + +### `getConfigurationsByTemplateRole` + +Returns all partner sharing configurations that reference the given template role ID. Useful for checking role usage bef + +`GET /v1/sharing/configurations/by-role/{template_role_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `template_role_id` | path | string | Yes | Template role ID to search for | + +**Sample Call** + +```bash +epilot sharing getConfigurationsByTemplateRole \ + -p template_role_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot sharing getConfigurationsByTemplateRole 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot sharing getConfigurationsByTemplateRole -p template_role_id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" + } +] +``` + +
+ +--- + +### `shareEntityWithPartners` + +Shares or unshares top-level entities with one or more partner organizations. Publishes sharing events for downstream pr + +`POST /v1/sharing/entities:share` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot sharing shareEntityWithPartners +``` + +With request body: + +```bash +epilot sharing shareEntityWithPartners \ + -d '{ + "share": [ + { + "partner_org_id": "string", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true + } + ] + } + ], + "unshare": [ + { + "partner_org_id": "string", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true + } + ] + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot sharing shareEntityWithPartners +``` + +With JSONata filter: + +```bash +epilot sharing shareEntityWithPartners --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" + } +] +``` + +
+ +--- + +### `shareChildEntityWithPartners` + +Shares or unshares child entities (entities that belong to an already-shared parent) with partner organizations. + +`POST /v1/sharing/entities:share-child` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot sharing shareChildEntityWithPartners +``` + +With request body: + +```bash +epilot sharing shareChildEntityWithPartners \ + -d '{ + "share": [ + { + "entity": { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true + }, + "partner_org_id": "string" + } + ], + "unshare": [ + { + "entity": { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true + }, + "partner_org_id": "string" + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot sharing shareChildEntityWithPartners +``` + +With JSONata filter: + +```bash +epilot sharing shareChildEntityWithPartners --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" + } +] +``` + +
+ +--- + +### `offerEntityToPartners` + +Offers or unoffers entities to partner organizations using a First Come First Served model. Only one partner can accept + +`POST /v1/sharing/entities:offer` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot sharing offerEntityToPartners +``` + +With request body: + +```bash +epilot sharing offerEntityToPartners \ + -d '{ + "offer": [ + { + "partner_org_id": "string", + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string" + } + ] + } + ], + "unoffer": [ + { + "partner_org_id": "string", + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string" + } + ] + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot sharing offerEntityToPartners +``` + +With JSONata filter: + +```bash +epilot sharing offerEntityToPartners --jsonata '$' +``` + +
+Sample Response + +```json +[ + { + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" + } +] +``` + +
+ +--- + +### `getOfferStatus` + +Returns the current status of an entity offer (pending, accepted, expired). This is a public endpoint used from partner- + +`GET /v1/sharing/offers/status` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `partner_org_id` | query | string | Yes | | +| `sharing_org_id` | query | string | Yes | | +| `entity_id` | query | string | Yes | | + +**Sample Call** + +```bash +epilot sharing getOfferStatus \ + -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 \ + -p sharing_org_id=123e4567-e89b-12d3-a456-426614174000 \ + -p entity_id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot sharing getOfferStatus -p partner_org_id=123e4567-e89b-12d3-a456-426614174000 -p sharing_org_id=123e4567-e89b-12d3-a456-426614174000 -p entity_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'entity._title' +``` + +
+Sample Response + +```json +{ + "entity": { + "_schema": "string", + "_id": "string", + "_title": "string", + "_created_at": "string", + "_updated_at": "string" + }, + "offer_status": "EXPIRED", + "status_changed_at": "string", + "offered_at": "string", + "accepted_by_org_id": "string" +} +``` + +
+ +--- + +### `acceptOffer` + +Accepts an entity offer on behalf of a partner organization. This is a public endpoint used from partner-facing pages wi + +`POST /v1/sharing/offers:accept` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot sharing acceptOffer \ + -d '{"partner_org_id":"string","sharing_org_id":"string","entity_id":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot sharing acceptOffer +``` + +With JSONata filter: + +```bash +epilot sharing acceptOffer --jsonata 'sharing_org_id' +``` + +
+Sample Response + +```json +{ + "sharing_org_id": "string", + "partner_org_id": "string", + "users": ["string"], + "partner_status": "REGISTERED", + "entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_accepted": true, + "updated_at": "string", + "created_at": "string" + } + ], + "offered_entities": [ + { + "schema": "string", + "entity_id": "string", + "parent_entity_id": "string", + "offer_status": "EXPIRED", + "offered_by_user_id": "string", + "updated_at": "string", + "created_at": "string" + } + ], + "template_role_id": "string", + "template_role_grants": [ + { + "action": "string", + "resource": "string", + "effect": "string" + } + ], + "generated_role_id": "string", + "user_limit": 0, + "created_at": "string", + "updated_at": "string" +} +``` + +
+ +--- diff --git a/docs/cli/commands/snapshot.md b/docs/cli/commands/snapshot.md new file mode 100644 index 00000000..41ade78a --- /dev/null +++ b/docs/cli/commands/snapshot.md @@ -0,0 +1,666 @@ +--- +title: "Snapshot API" +description: "epilot CLI commands for the Snapshot API: quick start, common flags and every operation, callable from the command line." +--- + +# Snapshot API + +- **Base URL:** `https://snapshot.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/snapshot](https://docs.epilot.io/api/snapshot) + +Point-in-time backups of epilot configuration with restore. + +## Quick Start + +```bash +# List available operations +epilot snapshot + +# Call an operation +epilot snapshot listSnapshots +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Snapshots** +- [`listSnapshots`](#listsnapshots) — List snapshots for the caller's organization, newest first. +- [`createSnapshot`](#createsnapshot) — Create a new snapshot of the given resources. Async — returns immediately +- [`captureOrgSnapshot`](#captureorgsnapshot) — Snapshot the caller's whole organization now. Creates a `scope: "org"` +- [`getSnapshot`](#getsnapshot) — Fetch a snapshot's metadata. Poll this endpoint to track create/restore progress. +- [`deleteSnapshot`](#deletesnapshot) — Delete a snapshot's metadata and S3 manifest. +- [`restoreSnapshot`](#restoresnapshot) — Restore a snapshot to the org. Async — returns immediately; client polls +- [`listSnapshotResources`](#listsnapshotresources) — List the resources captured in this snapshot. Returns lightweight +- [`getSnapshotResource`](#getsnapshotresource) — Fetch one captured resource with its full payload. For UI views +- [`listDependencies`](#listdependencies) — Walk the dependency tree for a set of resources and return the full + +**ScheduledSnapshots** +- [`getOrgSnapshotSchedule`](#getorgsnapshotschedule) — Return the scheduled-snapshot enrollment config for the caller's org. +- [`putOrgSnapshotSchedule`](#putorgsnapshotschedule) — Create or update the scheduled-snapshot enrollment config for the +- [`deleteOrgSnapshotSchedule`](#deleteorgsnapshotschedule) — Remove the scheduled-snapshot enrollment for the caller's org. + +### `listSnapshots` + +List snapshots for the caller's organization, newest first. + +`GET /v1/snapshots` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `cursor` | query | string | No | | +| `size` | query | number | No | | +| `resource` | query | string[] | No | Filter to snapshots containing one or more resources. Format +`:`. Split on the first colon — the `` half may +contain colons (e.g., role acl ids like `role:acl:internal:foo`). +Repeat the | +| `trigger` | query | "manual" \| "sync" \| "blueprint_install" \| "scheduled" | No | Filter to snapshots with a specific trigger. Uses the `byTrigger` GSI +for an efficient indexed query — no table scan. Only snapshots created +after the GSI was added carry this index entry; pre-existin | + +**Sample Call** + +```bash +epilot snapshot listSnapshots +``` + +With JSONata filter: + +```bash +epilot snapshot listSnapshots --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "page_size": 0, + "cursor": "string", + "results": [ + { + "id": "string", + "org_id": "string", + "name": "string", + "description": "string", + "trigger": "manual", + "blueprint_instance_id": "string", + "resource_counts": {}, + "create": { + "type": "create", + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status": "in_progress", + "error": "string", + "triggered_by": { + "name": "string", + "user_id": "string", + "token_id": "string" + } + }, + "restores": [ + { + "type": "create", + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status": "in_progress", + "error": "string", + "triggered_by": { + "name": "string", + "user_id": "string", + "token_id": "string" + } + } + ], + "matched_count": 0, + "scope": "selection", + "expires_at": "1970-01-01T00:00:00.000Z", + "capture_summary": { + "total": 0, + "captured": 0, + "skipped": 0, + "failed": 0 + } + } + ] +} +``` + +
+ +--- + +### `createSnapshot` + +Create a new snapshot of the given resources. Async — returns immediately + +`POST /v1/snapshots` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot snapshot createSnapshot +``` + +With request body: + +```bash +epilot snapshot createSnapshot \ + -d '{ + "name": "string", + "description": "string", + "trigger": "manual", + "blueprint_instance_id": "string", + "resources": [ + { + "type": "string", + "id": "string" + } + ] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot snapshot createSnapshot +``` + +With JSONata filter: + +```bash +epilot snapshot createSnapshot --jsonata '$' +``` + +--- + +### `captureOrgSnapshot` + +Snapshot the caller's whole organization now. Creates a `scope: "org"` + +`POST /v1/snapshots:capture-org` + +**Request Body** + +**Sample Call** + +```bash +epilot snapshot captureOrgSnapshot \ + -d '{"name":"string","retention":{"value":1,"unit":"days"},"excluded_types":["string"]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot snapshot captureOrgSnapshot +``` + +With JSONata filter: + +```bash +epilot snapshot captureOrgSnapshot --jsonata '$' +``` + +--- + +### `getSnapshot` + +Fetch a snapshot's metadata. Poll this endpoint to track create/restore progress. + +`GET /v1/snapshots/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot snapshot getSnapshot \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot snapshot getSnapshot 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot snapshot getSnapshot -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "org_id": "string", + "name": "string", + "description": "string", + "trigger": "manual", + "blueprint_instance_id": "string", + "resource_counts": {}, + "create": { + "type": "create", + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status": "in_progress", + "error": "string", + "triggered_by": { + "name": "string", + "user_id": "string", + "token_id": "string" + } + }, + "restores": [ + { + "type": "create", + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status": "in_progress", + "error": "string", + "triggered_by": { + "name": "string", + "user_id": "string", + "token_id": "string" + } + } + ], + "matched_count": 0, + "scope": "selection", + "expires_at": "1970-01-01T00:00:00.000Z", + "capture_summary": { + "total": 0, + "captured": 0, + "skipped": 0, + "failed": 0 + } +} +``` + +
+ +--- + +### `deleteSnapshot` + +Delete a snapshot's metadata and S3 manifest. + +`DELETE /v1/snapshots/{id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot snapshot deleteSnapshot \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot snapshot deleteSnapshot 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot snapshot deleteSnapshot -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `restoreSnapshot` + +Restore a snapshot to the org. Async — returns immediately; client polls + +`POST /v1/snapshots/{id}:restore` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | | + +**Request Body** + +**Sample Call** + +```bash +epilot snapshot restoreSnapshot \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"exclude_target_ids":["string"]}' +``` + +Using positional args for path parameters: + +```bash +epilot snapshot restoreSnapshot 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot snapshot restoreSnapshot -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot snapshot restoreSnapshot -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +--- + +### `listSnapshotResources` + +List the resources captured in this snapshot. Returns lightweight + +`GET /v1/snapshots/{id}/resources` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot snapshot listSnapshotResources \ + -p id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot snapshot listSnapshotResources 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot snapshot listSnapshotResources -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'resources' +``` + +
+Sample Response + +```json +{ + "resources": [ + { + "lineage_id": "string", + "target_id": "string", + "type": "string", + "name": "string" + } + ] +} +``` + +
+ +--- + +### `getSnapshotResource` + +Fetch one captured resource with its full payload. For UI views + +`GET /v1/snapshots/{id}/resources/{lineage_id}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `id` | path | string | Yes | | +| `lineage_id` | path | string | Yes | | + +**Sample Call** + +```bash +epilot snapshot getSnapshotResource \ + -p id=123e4567-e89b-12d3-a456-426614174000 \ + -p lineage_id=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot snapshot getSnapshotResource 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot snapshot getSnapshotResource -p id=123e4567-e89b-12d3-a456-426614174000 -p lineage_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'lineage_id' +``` + +
+Sample Response + +```json +{ + "lineage_id": "string", + "target_id": "string", + "type": "string", + "name": "string", + "captured": {} +} +``` + +
+ +--- + +### `getOrgSnapshotSchedule` + +Return the scheduled-snapshot enrollment config for the caller's org. + +`GET /v1/org-snapshot-schedule` + +**Sample Call** + +```bash +epilot snapshot getOrgSnapshotSchedule +``` + +With JSONata filter: + +```bash +epilot snapshot getOrgSnapshotSchedule --jsonata 'org_id' +``` + +
+Sample Response + +```json +{ + "org_id": "string", + "enabled": true, + "cron_expression": "cron(0 2 * * ? *)", + "timezone": "string", + "retention": { + "value": 1, + "unit": "days" + }, + "excluded_types": ["string"], + "schedule_name": "string", + "last_started_at": "1970-01-01T00:00:00.000Z", + "last_completed_at": "1970-01-01T00:00:00.000Z", + "last_status": "completed", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `putOrgSnapshotSchedule` + +Create or update the scheduled-snapshot enrollment config for the + +`PUT /v1/org-snapshot-schedule` + +**Request Body** + +**Sample Call** + +```bash +epilot snapshot putOrgSnapshotSchedule +``` + +With request body: + +```bash +epilot snapshot putOrgSnapshotSchedule \ + -d '{ + "enabled": true, + "cron_expression": "cron(0 2 * * ? *)", + "timezone": "Europe/Berlin", + "retention": { + "value": 1, + "unit": "days" + }, + "excluded_types": ["string"] +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot snapshot putOrgSnapshotSchedule +``` + +With JSONata filter: + +```bash +epilot snapshot putOrgSnapshotSchedule --jsonata 'org_id' +``` + +
+Sample Response + +```json +{ + "org_id": "string", + "enabled": true, + "cron_expression": "cron(0 2 * * ? *)", + "timezone": "string", + "retention": { + "value": 1, + "unit": "days" + }, + "excluded_types": ["string"], + "schedule_name": "string", + "last_started_at": "1970-01-01T00:00:00.000Z", + "last_completed_at": "1970-01-01T00:00:00.000Z", + "last_status": "completed", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteOrgSnapshotSchedule` + +Remove the scheduled-snapshot enrollment for the caller's org. + +`DELETE /v1/org-snapshot-schedule` + +**Sample Call** + +```bash +epilot snapshot deleteOrgSnapshotSchedule +``` + +With JSONata filter: + +```bash +epilot snapshot deleteOrgSnapshotSchedule --jsonata '$' +``` + +--- + +### `listDependencies` + +Walk the dependency tree for a set of resources and return the full + +`POST /v1/snapshots:list-dependencies` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot snapshot listDependencies \ + -d '{"resources":[{"type":"string","id":"string"}]}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot snapshot listDependencies +``` + +With JSONata filter: + +```bash +epilot snapshot listDependencies --jsonata 'dependencies' +``` + +
+Sample Response + +```json +{ + "dependencies": [ + { + "type": "string", + "id": "string" + } + ] +} +``` + +
+ +--- diff --git a/docs/cli/commands/target.md b/docs/cli/commands/target.md new file mode 100644 index 00000000..6b35deb5 --- /dev/null +++ b/docs/cli/commands/target.md @@ -0,0 +1,606 @@ +--- +title: "Target API" +description: "epilot CLI commands for the Target API: quick start, common flags and every operation, callable from the command line." +--- + +# Target API + +- **Base URL:** `https://target.sls.epilot.io` +- **API Docs:** [https://docs.epilot.io/api/target](https://docs.epilot.io/api/target) + +This API allows managing targets. + +## Quick Start + +```bash +# List available operations +epilot target + +# Call an operation +epilot target createTarget +``` + +## Common Flags + +| Flag | Description | +| ---- | ----------- | +| `-p key=value` | Set a named parameter | +| `-d '{...}'` | Request body JSON | +| `-H 'Key: Value'` | Custom header | +| `-t, --token ` | Bearer token for authentication | +| `--profile ` | Use a named profile | +| `-s, --server ` | Override server base URL | +| `-i, --include` | Include response headers in output | +| `--json` | Output raw JSON (no formatting) | +| `-v, --verbose` | Verbose output (show request details) | +| `--jsonata ` | JSONata expression to transform response | +| `--definition ` | Override OpenAPI spec file/URL | +| `--guided` | Prompt for all parameters interactively | +| `--no-interactive` | Disable interactive prompts | + +## Operations + +**Target** +- [`createTarget`](#createtarget) — Create a new target entity +- [`getTarget`](#gettarget) — Read a specific target entity by a given id +- [`updateTarget`](#updatetarget) — Completly replace a specific target entity's properties by a given id and a given payload +- [`patchTarget`](#patchtarget) — Partially update a specific target entity's properties by a given id and a given payload +- [`deleteTarget`](#deletetarget) — Delete a specific target entity by a given id + +### `createTarget` + +Create a new target entity + +`POST /v1/target` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot target createTarget +``` + +With request body: + +```bash +epilot target createTarget \ + -d '{ + "_schema": "target", + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_tags": ["string"], + "_purpose": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot target createTarget +``` + +With JSONata filter: + +```bash +epilot target createTarget --jsonata '$' +``` + +
+Sample Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +### `getTarget` + +Read a specific target entity by a given id + +`GET /v1/target/{targetId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `targetId` | path | string (uuid) | Yes | The target id | +| `hydrate` | query | boolean | No | Hydrates entities in relations when passed true | +| `strict` | query | boolean | No | When passed true, the response will contain only fields that match the schema, with non-matching fields included in `__additional` | + +**Sample Call** + +```bash +epilot target getTarget \ + -p targetId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot target getTarget 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot target getTarget -p targetId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +### `updateTarget` + +Completly replace a specific target entity's properties by a given id and a given payload + +`PUT /v1/target/{targetId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `targetId` | path | string (uuid) | Yes | The target id | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot target updateTarget \ + -p targetId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot target updateTarget \ + -p targetId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "_schema": "target", + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_tags": ["string"], + "_purpose": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +}' +``` + +Using positional args for path parameters: + +```bash +epilot target updateTarget 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot target updateTarget -p targetId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot target updateTarget -p targetId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +### `patchTarget` + +Partially update a specific target entity's properties by a given id and a given payload + +`PATCH /v1/target/{targetId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `targetId` | path | string (uuid) | Yes | The target id | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot target patchTarget \ + -p targetId=123e4567-e89b-12d3-a456-426614174000 +``` + +With request body: + +```bash +epilot target patchTarget \ + -p targetId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{ + "_schema": "target", + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_tags": ["string"], + "_purpose": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +}' +``` + +Using positional args for path parameters: + +```bash +epilot target patchTarget 123e4567-e89b-12d3-a456-426614174000 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot target patchTarget -p targetId=123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot target patchTarget -p targetId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +### `deleteTarget` + +Delete a specific target entity by a given id + +`DELETE /v1/target/{targetId}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `targetId` | path | string (uuid) | Yes | The target id | + +**Sample Call** + +```bash +epilot target deleteTarget \ + -p targetId=123e4567-e89b-12d3-a456-426614174000 +``` + +Using positional args for path parameters: + +```bash +epilot target deleteTarget 123e4567-e89b-12d3-a456-426614174000 +``` + +With JSONata filter: + +```bash +epilot target deleteTarget -p targetId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +``` + +
+Sample Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- diff --git a/docs/cli/commands/targeting.md b/docs/cli/commands/targeting.md index b2575166..6f2f4ad6 100644 --- a/docs/cli/commands/targeting.md +++ b/docs/cli/commands/targeting.md @@ -44,7 +44,9 @@ epilot targeting changeCampaignStatus -p campaign_id=b8c01433-5556-4e2b-aad4-6f5 - [`changeCampaignStatus`](#changecampaignstatus) — Change the status of a campaign to a desired status. - [`getCampaignJobStatus`](#getcampaignjobstatus) — Get the status of a campaign's automation job - [`getCampaignPortals`](#getcampaignportals) — Get the list of portals and its widgets where the campaign is used. +- [`setupCampaign`](#setupcampaign) — Creates a `campaign` entity together with its related entities and configurations in a single call. - [`matchCampaigns`](#matchcampaigns) — Match campaigns based on target entities. +- [`discoverCampaigns`](#discovercampaigns) — Given an entity, returns the Next Best Actions it should see on the Entity-UI channel. **Campaign Delivery** - [`retriggerCampaignAutomations`](#retriggercampaignautomations) — Retrigger automation executions for specific campaign recipients that have failed. @@ -57,7 +59,10 @@ epilot targeting changeCampaignStatus -p campaign_id=b8c01433-5556-4e2b-aad4-6f5 - [`createRecipient`](#createrecipient) — Creates a new recipient associated with a campaign. - [`updateRecipient`](#updaterecipient) — Updates a recipient's attributes. - [`updateRecipientPortalStatus`](#updaterecipientportalstatus) — Updates the portal status for a specific campaign recipient. +- [`updateRecipientEntityUiStatus`](#updaterecipiententityuistatus) — Records a Next Best Action interaction for a recipient on the Entity-UI channel. +- [`restoreRecipientEntityUiStatus`](#restorerecipiententityuistatus) — Reverses a dismissal so the Next Best Action becomes visible to the entity again. This is - [`getRecipients`](#getrecipients) — Get a paginated list of recipients for a campaign. +- [`getEmailStats`](#getemailstats) — Aggregate email delivery counts for a campaign, for the KPI summary on the campaign UI. ### `changeCampaignStatus` @@ -307,6 +312,93 @@ epilot targeting retriggerCampaignAutomations -p campaign_id=b8c01433-5556-4e2b- --- +### `setupCampaign` + +Creates a `campaign` entity together with its related entities and configurations in a single call. + +`POST /v1/campaign:setup` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot targeting setupCampaign +``` + +With request body: + +```bash +epilot targeting setupCampaign \ + -d '{ + "type": "tariff_change", + "product_recommendation": { + "name": "string", + "source_product_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "source_price_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "offers": [ + { + "target_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "items": [ + { + "product_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "price_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "highlight_config": {} + } + ] + } + ] + }, + "campaign": { + "name": "string", + "goal": "string", + "target_ids": ["b8c01433-5556-4e2b-aad4-6f5348d1df84"] + }, + "journey": { + "journey_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84" + }, + "channels": { + "portal_widget": { + "portal_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "block_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84" + }, + "email": { + "automation_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "template_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84" + } + } +}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot targeting setupCampaign +``` + +With JSONata filter: + +```bash +epilot targeting setupCampaign --jsonata '$' +``` + +
+Sample Response + +```json +{ + "type": "tariff_change", + "product_recommendation_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "campaign_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "journey_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "portal_widget_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84" +} +``` + +
+ +--- + ### `matchCampaigns` Match campaigns based on target entities. @@ -400,6 +492,102 @@ epilot targeting matchCampaigns --jsonata 'results[0]' --- +### `discoverCampaigns` + +Given an entity, returns the Next Best Actions it should see on the Entity-UI channel. + +`POST /v1/campaign:discover` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot targeting discoverCampaigns \ + -d '{"entity_id":"b8c01433-5556-4e2b-aad4-6f5348d1df84","entity_schema":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot targeting discoverCampaigns +``` + +With JSONata filter: + +```bash +epilot targeting discoverCampaigns --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "hits": 0, + "results": [ + { + "campaign_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "nba": { + "category": "string", + "icon": { + "name": "string", + "color": "string" + }, + "title": "string", + "body": "string", + "priority": "medium", + "is_dismissable": true, + "cta": { + "type": "journey", + "target": "string", + "context_params": [ + { + "key": "string", + "value": "string" + } + ] + } + }, + "status": "seen", + "status_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "dismissed": [ + { + "campaign_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "nba": { + "category": "string", + "icon": { + "name": "string", + "color": "string" + }, + "title": "string", + "body": "string", + "priority": "medium", + "is_dismissable": true, + "cta": { + "type": "journey", + "target": "string", + "context_params": [ + { + "key": "string", + "value": "string" + } + ] + } + }, + "status": "seen", + "status_updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + ### `matchTargets` Find targets from the provided list that include the provide entities. @@ -593,6 +781,29 @@ epilot targeting createRecipient -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1 "portal_status": "sent", "portal_status_updated_at": "1970-01-01T00:00:00.000Z", "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], "updated_at": "1970-01-01T00:00:00.000Z" } ``` @@ -656,6 +867,29 @@ epilot targeting updateRecipient -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1 "portal_status": "sent", "portal_status_updated_at": "1970-01-01T00:00:00.000Z", "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], "updated_at": "1970-01-01T00:00:00.000Z" } ``` @@ -719,6 +953,192 @@ epilot targeting updateRecipientPortalStatus -p campaign_id=b8c01433-5556-4e2b-a "portal_status": "sent", "portal_status_updated_at": "1970-01-01T00:00:00.000Z", "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateRecipientEntityUiStatus` + +Records a Next Best Action interaction for a recipient on the Entity-UI channel. + +`PATCH /v1/campaign/{campaign_id}/recipient/{recipient_id}/entity_ui:status` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `campaign_id` | path | string (uuid) | Yes | The campaign ID | +| `recipient_id` | path | string (uuid) | Yes | The entity ID of the recipient | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot targeting updateRecipientEntityUiStatus \ + -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 \ + -p recipient_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 \ + -d '{"status":"seen","entity_schema":"string"}' +``` + +Using positional args for path parameters: + +```bash +epilot targeting updateRecipientEntityUiStatus b8c01433-5556-4e2b-aad4-6f5348d1df84 b8c01433-5556-4e2b-aad4-6f5348d1df84 +``` + +Using stdin pipe: + +```bash +cat body.json | epilot targeting updateRecipientEntityUiStatus -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 -p recipient_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 +``` + +With JSONata filter: + +```bash +epilot targeting updateRecipientEntityUiStatus -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 -p recipient_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 --jsonata 'entity_id' +``` + +
+Sample Response + +```json +{ + "entity_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "entity_schema": "string", + "title": "string", + "automation_status": "pending", + "automation_execution_id": "string", + "portal_status": "sent", + "portal_status_updated_at": "1970-01-01T00:00:00.000Z", + "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `restoreRecipientEntityUiStatus` + +Reverses a dismissal so the Next Best Action becomes visible to the entity again. This is + +`POST /v1/campaign/{campaign_id}/recipient/{recipient_id}/entity_ui:restore` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `campaign_id` | path | string (uuid) | Yes | The campaign ID | +| `recipient_id` | path | string (uuid) | Yes | The entity ID of the recipient | + +**Sample Call** + +```bash +epilot targeting restoreRecipientEntityUiStatus \ + -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 \ + -p recipient_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 +``` + +Using positional args for path parameters: + +```bash +epilot targeting restoreRecipientEntityUiStatus b8c01433-5556-4e2b-aad4-6f5348d1df84 b8c01433-5556-4e2b-aad4-6f5348d1df84 +``` + +With JSONata filter: + +```bash +epilot targeting restoreRecipientEntityUiStatus -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 -p recipient_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 --jsonata 'entity_id' +``` + +
+Sample Response + +```json +{ + "entity_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "entity_schema": "string", + "title": "string", + "automation_status": "pending", + "automation_execution_id": "string", + "portal_status": "sent", + "portal_status_updated_at": "1970-01-01T00:00:00.000Z", + "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], "updated_at": "1970-01-01T00:00:00.000Z" } ``` @@ -741,8 +1161,12 @@ Get a paginated list of recipients for a campaign. | `limit` | query | number | No | Number of items to return | | `next` | query | string | No | Cursor for pagination | | `q` | query | string | No | Search by recipient title | -| `automation_status` | query | "pending" \| "in_progress" \| "success" \| "failed" \| "cancelled" | No | Filter by automation status | +| `automation_status` | query | "pending" \| "in_progress" \| "success" \| "failed" \| "cancelled"[] | No | Filter by automation status. Repeat the parameter to match multiple +statuses in one request +(e.g. automation_status=failed&automation_status=cancelled). + | | `portal_status` | query | "sent" \| "seen" \| "dismissed" \| "clicked" | No | Filter by portal status | +| `email_status` | query | "sent" \| "delivered" \| "bounced" \| "complained" \| "failed" | No | Filter by email delivery status (e.g. bounced, delivered). The response total reflects the count for the filtered status. | **Sample Call** @@ -778,6 +1202,29 @@ epilot targeting getRecipients -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df "portal_status": "sent", "portal_status_updated_at": "1970-01-01T00:00:00.000Z", "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], "updated_at": "1970-01-01T00:00:00.000Z" } ], @@ -789,3 +1236,59 @@ epilot targeting getRecipients -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df
--- + +### `getEmailStats` + +Aggregate email delivery counts for a campaign, for the KPI summary on the campaign UI. + +`GET /v1/campaign/{campaign_id}/email-stats` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `campaign_id` | path | string (uuid) | Yes | The campaign ID | + +**Sample Call** + +```bash +epilot targeting getEmailStats \ + -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 +``` + +Using positional args for path parameters: + +```bash +epilot targeting getEmailStats b8c01433-5556-4e2b-aad4-6f5348d1df84 +``` + +With JSONata filter: + +```bash +epilot targeting getEmailStats -p campaign_id=b8c01433-5556-4e2b-aad4-6f5348d1df84 --jsonata 'total_emailed' +``` + +
+Sample Response + +```json +{ + "total_emailed": 0, + "sent": 0, + "delivered": 0, + "bounced": 0, + "bounced_hard": 0, + "bounced_soft": 0, + "complained": 0, + "failed": 0, + "unsubscribed": 0, + "opened": 0, + "clicked": 0, + "total_opens": 0, + "total_clicks": 0 +} +``` + +
+ +--- diff --git a/docs/cli/commands/template-variables.md b/docs/cli/commands/template-variables.md index 621dd4b6..252b0048 100644 --- a/docs/cli/commands/template-variables.md +++ b/docs/cli/commands/template-variables.md @@ -177,6 +177,7 @@ epilot template-variables getVariableContext \ "context_data": {}, "template_name": "string", "template_tags": ["string"], + "template_id": "string", "variables_version": "2" } }' @@ -298,6 +299,7 @@ epilot template-variables replaceTemplates \ "context_data": {}, "template_name": "string", "template_tags": ["string"], + "template_id": "string", "variables_version": "2" } }' @@ -364,6 +366,7 @@ epilot template-variables replaceTemplatesV2 \ "context_data": {}, "template_name": "string", "template_tags": ["string"], + "template_id": "string", "variables_version": "2" } }' @@ -427,6 +430,7 @@ epilot template-variables getCustomVariables --jsonata '$' "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -473,6 +477,7 @@ epilot template-variables createCustomVariable \ "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -538,6 +543,7 @@ epilot template-variables createCustomVariable --jsonata 'id' "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -638,6 +644,7 @@ epilot template-variables searchCustomVariables --jsonata 'results[0]' "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": {}, @@ -697,6 +704,7 @@ epilot template-variables getCustomVariable -p id=rbse777b-3cf8-4bff-bb0c-253fd1 "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -776,6 +784,7 @@ epilot template-variables updateCustomVariable \ "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -847,6 +856,7 @@ epilot template-variables updateCustomVariable -p id=rbse777b-3cf8-4bff-bb0c-253 "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -955,6 +965,7 @@ epilot template-variables getBluePrintTableConfig --jsonata 'id' "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { diff --git a/docs/cli/commands/user.md b/docs/cli/commands/user.md index 55a883aa..292ac43b 100644 --- a/docs/cli/commands/user.md +++ b/docs/cli/commands/user.md @@ -43,14 +43,22 @@ epilot user signUpUser **User V2** - [`signUpUser`](#signupuser) — POST /v2/users/public/signup - [`getMeV2`](#getmev2) — Get currently logged in user +- [`listUserSettings`](#listusersettings) — List all setting scopes and keys available for the currently logged in user. Does not return setting values. +- [`getUserSettingsScope`](#getusersettingsscope) — Get all setting values for one scope for the currently logged in user. +- [`getUserSetting`](#getusersetting) — Get one setting value by scope and key for the currently logged in user. +- [`putUserSetting`](#putusersetting) — Create or replace one setting value for the currently logged in user. +- [`deleteUserSetting`](#deleteusersetting) — Delete one setting value for the currently logged in user. - [`listUsersV2`](#listusersv2) — Get the list of organization users - [`getUserV2`](#getuserv2) — Get user details by user id - [`updateUserV2`](#updateuserv2) — Update user details - [`deleteUserV2`](#deleteuserv2) — Delete user by user id - [`inviteUser`](#inviteuser) — Creates a new user in the caller's organization and sends an invite email to activate the user - [`resendUserInvitation`](#resenduserinvitation) — Resend user invitation email +- [`sendUserPasswordReset`](#senduserpasswordreset) — Send a password reset email to a user in your organization. - [`getGroupsForUser`](#getgroupsforuser) — Get groups of a user - [`verifyEmailWithToken`](#verifyemailwithtoken) — Update new email using an verification token +- [`requestPasswordReset`](#requestpasswordreset) — Request a password reset email for the given email address. Always +- [`resetPassword`](#resetpassword) — Set a new password using a reset token from the password reset email. - [`checkInviteToken`](#checkinvitetoken) — Check an invite token - [`activateUser`](#activateuser) — Activate user using an invite token - [`rejectInvite`](#rejectinvite) — Reject an invite @@ -227,10 +235,14 @@ epilot user getMeV2 --jsonata 'id' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -267,11 +279,54 @@ epilot user getMeV2 --jsonata 'id' "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } + ], + "tags": ["non-billable"] +} +``` + +
+ +--- + +### `listUserSettings` + +List all setting scopes and keys available for the currently logged in user. Does not return setting values. + +`GET /v2/users/me/settings` + +**Sample Call** + +```bash +epilot user listUserSettings +``` + +With JSONata filter: + +```bash +epilot user listUserSettings --jsonata 'results[0]' +``` + +
+Sample Response + +```json +{ + "results": [ + { + "scope": "calendar", + "keys": ["visible_calendars"] + } ] } ``` @@ -280,6 +335,199 @@ epilot user getMeV2 --jsonata 'id' --- +### `getUserSettingsScope` + +Get all setting values for one scope for the currently logged in user. + +`GET /v2/users/me/settings/{scope}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `scope` | path | string | Yes | User setting scope, for example calendar, navigation, or search | + +**Sample Call** + +```bash +epilot user getUserSettingsScope \ + -p scope=calendar +``` + +Using positional args for path parameters: + +```bash +epilot user getUserSettingsScope calendar +``` + +With JSONata filter: + +```bash +epilot user getUserSettingsScope -p scope=calendar --jsonata 'scope' +``` + +
+Sample Response + +```json +{ + "scope": "calendar", + "settings": { + "visible_calendars": { + "calendar_ids": ["holidays"] + } + } +} +``` + +
+ +--- + +### `getUserSetting` + +Get one setting value by scope and key for the currently logged in user. + +`GET /v2/users/me/settings/{scope}/{key}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `scope` | path | string | Yes | User setting scope | +| `key` | path | string | Yes | User setting key | + +**Sample Call** + +```bash +epilot user getUserSetting \ + -p scope=calendar \ + -p key=visible_calendars +``` + +Using positional args for path parameters: + +```bash +epilot user getUserSetting calendar visible_calendars +``` + +With JSONata filter: + +```bash +epilot user getUserSetting -p scope=calendar -p key=visible_calendars --jsonata 'scope' +``` + +
+Sample Response + +```json +{ + "scope": "calendar", + "key": "visible_calendars", + "value": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `putUserSetting` + +Create or replace one setting value for the currently logged in user. + +`PUT /v2/users/me/settings/{scope}/{key}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `scope` | path | string | Yes | User setting scope | +| `key` | path | string | Yes | User setting key | + +**Request Body** (required) + +**Sample Call** + +```bash +epilot user putUserSetting \ + -p scope=calendar \ + -p key=visible_calendars \ + -d '{}' +``` + +Using positional args for path parameters: + +```bash +epilot user putUserSetting calendar visible_calendars +``` + +Using stdin pipe: + +```bash +cat body.json | epilot user putUserSetting -p scope=calendar -p key=visible_calendars +``` + +With JSONata filter: + +```bash +epilot user putUserSetting -p scope=calendar -p key=visible_calendars --jsonata 'scope' +``` + +
+Sample Response + +```json +{ + "scope": "calendar", + "key": "visible_calendars", + "value": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteUserSetting` + +Delete one setting value for the currently logged in user. + +`DELETE /v2/users/me/settings/{scope}/{key}` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `scope` | path | string | Yes | User setting scope | +| `key` | path | string | Yes | User setting key | + +**Sample Call** + +```bash +epilot user deleteUserSetting \ + -p scope=calendar \ + -p key=visible_calendars +``` + +Using positional args for path parameters: + +```bash +epilot user deleteUserSetting calendar visible_calendars +``` + +With JSONata filter: + +```bash +epilot user deleteUserSetting -p scope=calendar -p key=visible_calendars --jsonata '$' +``` + +--- + ### `listUsersV2` Get the list of organization users @@ -321,10 +569,14 @@ epilot user listUsersV2 --jsonata 'results[0]' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -361,12 +613,19 @@ epilot user listUsersV2 --jsonata 'results[0]' "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] } ] } @@ -420,10 +679,14 @@ epilot user getUserV2 -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -460,12 +723,19 @@ epilot user getUserV2 -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] } ``` @@ -508,10 +778,14 @@ epilot user updateUserV2 \ "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -548,12 +822,19 @@ epilot user updateUserV2 \ "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] }' ``` @@ -588,10 +869,14 @@ epilot user updateUserV2 -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'i "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -628,12 +913,19 @@ epilot user updateUserV2 -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'i "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] } ``` @@ -743,10 +1035,14 @@ epilot user inviteUser --jsonata 'id' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -783,12 +1079,19 @@ epilot user inviteUser --jsonata 'id' "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] } ``` @@ -836,10 +1139,14 @@ epilot user resendUserInvitation --jsonata 'id' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -876,12 +1183,59 @@ epilot user resendUserInvitation --jsonata 'id' "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] +} +``` + +
+ +--- + +### `sendUserPasswordReset` + +Send a password reset email to a user in your organization. + +`POST /v2/users:sendPasswordReset` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot user sendUserPasswordReset \ + -d '{"email":"test@example.com"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot user sendUserPasswordReset +``` + +With JSONata filter: + +```bash +epilot user sendUserPasswordReset --jsonata 'success' +``` + +
+Sample Response + +```json +{ + "success": true } ``` @@ -941,10 +1295,14 @@ epilot user getGroupsForUser -p id=123e4567-e89b-12d3-a456-426614174000 --jsonat "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -957,12 +1315,18 @@ epilot user getGroupsForUser -p id=123e4567-e89b-12d3-a456-426614174000 --jsonat "image_uri": {}, "favorites": {}, "email_notification_setting": {}, + "in_app_notification_setting": {}, "properties": [], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ {} - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ] ``` @@ -1013,7 +1377,9 @@ epilot user getGroups --jsonata 'hits[0]' "updated_at": "2024-02-08T04:44:32.246Z", "created_by": "123", "crt_assignee": {}, - "users": [] + "users": [], + "image_uri": {}, + "abbreviation": "FN" } ] } @@ -1035,7 +1401,7 @@ Create a new group ```bash epilot user createGroup \ - -d '{"name":"Finance","user_ids":["123","456"]}' + -d '{"name":"Finance","user_ids":["123","456"],"image_uri":{"gradient_colors":["#0588f0","#3358d4"]},"abbreviation":"FN"}' ``` Using stdin pipe: @@ -1070,10 +1436,14 @@ epilot user createGroup --jsonata 'id' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1107,9 +1477,16 @@ epilot user createGroup --jsonata 'id' "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ {} ], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ @@ -1122,10 +1499,14 @@ epilot user createGroup --jsonata 'id' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1138,9 +1519,15 @@ epilot user createGroup --jsonata 'id' "image_uri": {}, "favorites": {}, "email_notification_setting": {}, - "properties": [] + "in_app_notification_setting": {}, + "properties": [], + "tags": ["non-billable"] } - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ``` @@ -1200,10 +1587,14 @@ epilot user getGroup -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1237,9 +1628,16 @@ epilot user getGroup -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ {} ], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ @@ -1252,10 +1650,14 @@ epilot user getGroup -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1268,9 +1670,15 @@ epilot user getGroup -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id' "image_uri": {}, "favorites": {}, "email_notification_setting": {}, - "properties": [] + "in_app_notification_setting": {}, + "properties": [], + "tags": ["non-billable"] } - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ``` @@ -1297,7 +1705,7 @@ Update group by id ```bash epilot user updateGroup \ -p id=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"name":"Finance","user_ids":["123","456"]}' + -d '{"name":"Finance","user_ids":["123","456"],"image_uri":{"gradient_colors":["#0588f0","#3358d4"]},"abbreviation":"FN"}' ``` Using positional args for path parameters: @@ -1338,10 +1746,14 @@ epilot user updateGroup -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1375,9 +1787,16 @@ epilot user updateGroup -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ {} ], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ @@ -1390,10 +1809,14 @@ epilot user updateGroup -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1406,9 +1829,15 @@ epilot user updateGroup -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'id "image_uri": {}, "favorites": {}, "email_notification_setting": {}, - "properties": [] + "in_app_notification_setting": {}, + "properties": [], + "tags": ["non-billable"] } - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ``` @@ -1500,10 +1929,14 @@ epilot user advanceUserAssignment -p id=123e4567-e89b-12d3-a456-426614174000 --j "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1537,9 +1970,16 @@ epilot user advanceUserAssignment -p id=123e4567-e89b-12d3-a456-426614174000 --j "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ {} ], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ @@ -1552,10 +1992,14 @@ epilot user advanceUserAssignment -p id=123e4567-e89b-12d3-a456-426614174000 --j "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1568,9 +2012,15 @@ epilot user advanceUserAssignment -p id=123e4567-e89b-12d3-a456-426614174000 --j "image_uri": {}, "favorites": {}, "email_notification_setting": {}, - "properties": [] + "in_app_notification_setting": {}, + "properties": [], + "tags": ["non-billable"] } - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ``` @@ -1786,6 +2236,86 @@ epilot user verifyEmailWithToken -p token=example --jsonata '$' --- +### `requestPasswordReset` + +Request a password reset email for the given email address. Always + +`POST /v2/users/public/requestPasswordReset` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot user requestPasswordReset \ + -d '{"email":"test@example.com"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot user requestPasswordReset +``` + +With JSONata filter: + +```bash +epilot user requestPasswordReset --jsonata 'message' +``` + +
+Sample Response + +```json +{ + "message": "If an account exists, a password reset email has been sent." +} +``` + +
+ +--- + +### `resetPassword` + +Set a new password using a reset token from the password reset email. + +`POST /v2/users/public/resetPassword` + +**Request Body** (required) + +**Sample Call** + +```bash +epilot user resetPassword \ + -d '{"email":"test@example.com","token":"string","password":"string"}' +``` + +Using stdin pipe: + +```bash +cat body.json | epilot user resetPassword +``` + +With JSONata filter: + +```bash +epilot user resetPassword --jsonata 'success' +``` + +
+Sample Response + +```json +{ + "success": true +} +``` + +
+ +--- + ### `checkInviteToken` Check an invite token @@ -1951,7 +2481,8 @@ epilot user getUserLoginParametersV2 -p username=example --jsonata 'login_parame "cognito_oauth_domain": "epilot-org-123", "cognito_oauth_scopes": ["openid"], "oauth_response_type": "code", - "passkey_enabled": true + "passkey_enabled": true, + "passkeys_registered": true } ] } @@ -2081,7 +2612,8 @@ epilot user resolveDiscoverableCredential --jsonata 'email' "cognito_oauth_domain": "epilot-org-123", "cognito_oauth_scopes": ["openid"], "oauth_response_type": "code", - "passkey_enabled": true + "passkey_enabled": true, + "passkeys_registered": true } ] } @@ -2509,7 +3041,8 @@ epilot user getUserLoginParameters -p username=example --jsonata 'login_paramete "cognito_oauth_domain": "epilot-org-123", "cognito_oauth_scopes": ["openid"], "oauth_response_type": "code", - "passkey_enabled": true + "passkey_enabled": true, + "passkeys_registered": true } ] } diff --git a/docs/cli/commands/validation-rules.md b/docs/cli/commands/validation-rules.md index 98f9173f..f99562a0 100644 --- a/docs/cli/commands/validation-rules.md +++ b/docs/cli/commands/validation-rules.md @@ -8,6 +8,8 @@ description: "epilot CLI commands for the Validation Rules API: quick start, com - **Base URL:** `https://validation-rules.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/validation-rules](https://docs.epilot.io/api/validation-rules) +The Validation Rules API manages reusable input validation rules for epilot journeys and entity attributes. + ## Quick Start ```bash @@ -39,17 +41,17 @@ epilot validation-rules getValidationRules ## Operations **Validation Rules** -- [`getValidationRules`](#getvalidationrules) — Gets all validation rules by organization Id -- [`createValidationRule`](#createvalidationrule) — Creates a new validation rule -- [`getValidationRuleById`](#getvalidationrulebyid) — Retrieves a specific validation rule by its ID -- [`updateValidationRule`](#updatevalidationrule) — Updates an existing validation rule partially by ID -- [`deleteValidationRule`](#deletevalidationrule) — Deletes a validation rule by ID -- [`addUsedByReference`](#addusedbyreference) — Adds a single reference to the usedBy array of a validation rule -- [`removeUsedByReference`](#removeusedbyreference) — Removes a specific reference from the usedBy array of a validation rule +- [`getValidationRules`](#getvalidationrules) — Returns all validation rules belonging to the authenticated user's organization. +- [`createValidationRule`](#createvalidationrule) — Creates a new validation rule for the authenticated organization. +- [`getValidationRuleById`](#getvalidationrulebyid) — Retrieves a specific validation rule by its unique ID. +- [`updateValidationRule`](#updatevalidationrule) — Partially updates an existing validation rule by ID. Only the fields provided in the request body are updated. +- [`deleteValidationRule`](#deletevalidationrule) — Permanently deletes a validation rule by ID. Any journeys or entity attributes referencing this rule should be updated b +- [`addUsedByReference`](#addusedbyreference) — Adds a single `used_by` reference to an existing validation rule. +- [`removeUsedByReference`](#removeusedbyreference) — Removes a specific `used_by` reference from an existing validation rule. ### `getValidationRules` -Gets all validation rules by organization Id +Returns all validation rules belonging to the authenticated user's organization. `GET /v1/validation-rules` @@ -77,8 +79,7 @@ epilot validation-rules getValidationRules --jsonata 'results[0]' "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -108,6 +109,11 @@ epilot validation-rules getValidationRules --jsonata 'results[0]' ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -126,11 +132,11 @@ epilot validation-rules getValidationRules --jsonata 'results[0]' ### `createValidationRule` -Creates a new validation rule +Creates a new validation rule for the authenticated organization. `POST /v1/validation-rules` -**Request Body** +**Request Body** (required) **Sample Call** @@ -148,8 +154,7 @@ epilot validation-rules createValidationRule \ "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -178,7 +183,12 @@ epilot validation-rules createValidationRule \ } ] } - } + }, + "contexts": [ + { + "schema": "contract" + } + ] }' ``` @@ -204,8 +214,7 @@ epilot validation-rules createValidationRule --jsonata '$' "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -235,6 +244,11 @@ epilot validation-rules createValidationRule --jsonata '$' ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -251,7 +265,7 @@ epilot validation-rules createValidationRule --jsonata '$' ### `getValidationRuleById` -Retrieves a specific validation rule by its ID +Retrieves a specific validation rule by its unique ID. `GET /v1/validation-rules/{ruleId}` @@ -265,19 +279,19 @@ Retrieves a specific validation rule by its ID ```bash epilot validation-rules getValidationRuleById \ - -p ruleId=123e4567-e89b-12d3-a456-426614174000 + -p ruleId=rule-abc123 ``` Using positional args for path parameters: ```bash -epilot validation-rules getValidationRuleById 123e4567-e89b-12d3-a456-426614174000 +epilot validation-rules getValidationRuleById rule-abc123 ``` With JSONata filter: ```bash -epilot validation-rules getValidationRuleById -p ruleId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot validation-rules getValidationRuleById -p ruleId=rule-abc123 --jsonata '$' ```
@@ -290,8 +304,7 @@ epilot validation-rules getValidationRuleById -p ruleId=123e4567-e89b-12d3-a456- "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -321,6 +334,11 @@ epilot validation-rules getValidationRuleById -p ruleId=123e4567-e89b-12d3-a456- ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -337,7 +355,7 @@ epilot validation-rules getValidationRuleById -p ruleId=123e4567-e89b-12d3-a456- ### `updateValidationRule` -Updates an existing validation rule partially by ID +Partially updates an existing validation rule by ID. Only the fields provided in the request body are updated. `PATCH /v1/validation-rules/{ruleId}` @@ -353,22 +371,21 @@ Updates an existing validation rule partially by ID ```bash epilot validation-rules updateValidationRule \ - -p ruleId=123e4567-e89b-12d3-a456-426614174000 + -p ruleId=rule-abc123 ``` With request body: ```bash epilot validation-rules updateValidationRule \ - -p ruleId=123e4567-e89b-12d3-a456-426614174000 \ + -p ruleId=rule-abc123 \ -d '{ "title": "string", "placeholder": "string", "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -397,26 +414,31 @@ epilot validation-rules updateValidationRule \ } ] } - } + }, + "contexts": [ + { + "schema": "contract" + } + ] }' ``` Using positional args for path parameters: ```bash -epilot validation-rules updateValidationRule 123e4567-e89b-12d3-a456-426614174000 +epilot validation-rules updateValidationRule rule-abc123 ``` Using stdin pipe: ```bash -cat body.json | epilot validation-rules updateValidationRule -p ruleId=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot validation-rules updateValidationRule -p ruleId=rule-abc123 ``` With JSONata filter: ```bash -epilot validation-rules updateValidationRule -p ruleId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot validation-rules updateValidationRule -p ruleId=rule-abc123 --jsonata '$' ```
@@ -429,8 +451,7 @@ epilot validation-rules updateValidationRule -p ruleId=123e4567-e89b-12d3-a456-4 "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -460,6 +481,11 @@ epilot validation-rules updateValidationRule -p ruleId=123e4567-e89b-12d3-a456-4 ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -476,7 +502,7 @@ epilot validation-rules updateValidationRule -p ruleId=123e4567-e89b-12d3-a456-4 ### `deleteValidationRule` -Deletes a validation rule by ID +Permanently deletes a validation rule by ID. Any journeys or entity attributes referencing this rule should be updated b `DELETE /v1/validation-rules/{ruleId}` @@ -490,26 +516,26 @@ Deletes a validation rule by ID ```bash epilot validation-rules deleteValidationRule \ - -p ruleId=123e4567-e89b-12d3-a456-426614174000 + -p ruleId=rule-abc123 ``` Using positional args for path parameters: ```bash -epilot validation-rules deleteValidationRule 123e4567-e89b-12d3-a456-426614174000 +epilot validation-rules deleteValidationRule rule-abc123 ``` With JSONata filter: ```bash -epilot validation-rules deleteValidationRule -p ruleId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot validation-rules deleteValidationRule -p ruleId=rule-abc123 --jsonata '$' ``` --- ### `addUsedByReference` -Adds a single reference to the usedBy array of a validation rule +Adds a single `used_by` reference to an existing validation rule. `POST /v1/validation-rules/{ruleId}/used-by` @@ -525,26 +551,26 @@ Adds a single reference to the usedBy array of a validation rule ```bash epilot validation-rules addUsedByReference \ - -p ruleId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"type":"journey","schema_slug":"string","source_id":"string"}' + -p ruleId=rule-abc123 \ + -d '{"type":"journey","source_id":"journey-xyz789"}' ``` Using positional args for path parameters: ```bash -epilot validation-rules addUsedByReference 123e4567-e89b-12d3-a456-426614174000 +epilot validation-rules addUsedByReference rule-abc123 ``` Using stdin pipe: ```bash -cat body.json | epilot validation-rules addUsedByReference -p ruleId=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot validation-rules addUsedByReference -p ruleId=rule-abc123 ``` With JSONata filter: ```bash -epilot validation-rules addUsedByReference -p ruleId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot validation-rules addUsedByReference -p ruleId=rule-abc123 --jsonata '$' ```
@@ -557,8 +583,7 @@ epilot validation-rules addUsedByReference -p ruleId=123e4567-e89b-12d3-a456-426 "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -588,6 +613,11 @@ epilot validation-rules addUsedByReference -p ruleId=123e4567-e89b-12d3-a456-426 ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -604,7 +634,7 @@ epilot validation-rules addUsedByReference -p ruleId=123e4567-e89b-12d3-a456-426 ### `removeUsedByReference` -Removes a specific reference from the usedBy array of a validation rule +Removes a specific `used_by` reference from an existing validation rule. `DELETE /v1/validation-rules/{ruleId}/used-by` @@ -620,26 +650,26 @@ Removes a specific reference from the usedBy array of a validation rule ```bash epilot validation-rules removeUsedByReference \ - -p ruleId=123e4567-e89b-12d3-a456-426614174000 \ - -d '{"type":"journey","schema_slug":"string","source_id":"string"}' + -p ruleId=rule-abc123 \ + -d '{"type":"journey","source_id":"journey-xyz789"}' ``` Using positional args for path parameters: ```bash -epilot validation-rules removeUsedByReference 123e4567-e89b-12d3-a456-426614174000 +epilot validation-rules removeUsedByReference rule-abc123 ``` Using stdin pipe: ```bash -cat body.json | epilot validation-rules removeUsedByReference -p ruleId=123e4567-e89b-12d3-a456-426614174000 +cat body.json | epilot validation-rules removeUsedByReference -p ruleId=rule-abc123 ``` With JSONata filter: ```bash -epilot validation-rules removeUsedByReference -p ruleId=123e4567-e89b-12d3-a456-426614174000 --jsonata '$' +epilot validation-rules removeUsedByReference -p ruleId=rule-abc123 --jsonata '$' ```
@@ -652,8 +682,7 @@ epilot validation-rules removeUsedByReference -p ruleId=123e4567-e89b-12d3-a456- "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -683,6 +712,11 @@ epilot validation-rules removeUsedByReference -p ruleId=123e4567-e89b-12d3-a456- ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", diff --git a/docs/cli/commands/webhooks.md b/docs/cli/commands/webhooks.md index 2479271e..797fc781 100644 --- a/docs/cli/commands/webhooks.md +++ b/docs/cli/commands/webhooks.md @@ -48,6 +48,7 @@ epilot webhooks getPublicKey -p orgId=123e4567-e89b-12d3-a456-426614174000 - [`getConfig`](#getconfig) — Get webhook config by id - [`updateConfig`](#updateconfig) — Update Webhook Client Config - [`deleteConfig`](#deleteconfig) — Delete Webhook Client Config +- [`testOAuth`](#testoauth) — Tests the OAuth client credentials configuration for a saved webhook by attempting - [`triggerWebhook`](#triggerwebhook) — Trigger a webhook - [`batchReplayEvents`](#batchreplayevents) — Replay a batch of webhook events - [`getEventById`](#geteventbyid) — Get a webhook event by its id @@ -441,6 +442,53 @@ epilot webhooks deleteConfig -p configId=CustomerRequest --jsonata '$' --- +### `testOAuth` + +Tests the OAuth client credentials configuration for a saved webhook by attempting + +`POST /v1/webhooks/configs/{configId}/test-oauth` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `configId` | path | string | Yes | Short uuid to identify the webhook configuration. | + +**Sample Call** + +```bash +epilot webhooks testOAuth \ + -p configId=7hj28aasgag2gha2 +``` + +Using positional args for path parameters: + +```bash +epilot webhooks testOAuth 7hj28aasgag2gha2 +``` + +With JSONata filter: + +```bash +epilot webhooks testOAuth -p configId=7hj28aasgag2gha2 --jsonata 'success' +``` + +
+Sample Response + +```json +{ + "success": true, + "expires_in": 3600, + "token_type": "Bearer", + "message": "OAuth token exchange successful" +} +``` + +
+ +--- + ### `triggerWebhook` Trigger a webhook @@ -542,7 +590,7 @@ Replay a batch of webhook events ```bash epilot webhooks batchReplayEvents \ -p configId=7hj28aasgag2gha2 \ - -d '{"eventIds":["2f1b7cf8-ff55-4359-966f-e56f39a52c94","48c984bf-466b-470b-b743-d07cea168243"]}' + -d '{"eventIds":["2f1b7cf8-ff55-4359-966f-e56f39a52c94","48c984bf-466b-470b-b743-d07cea168243"],"reapply_transform":false}' ``` Using positional args for path parameters: @@ -630,7 +678,11 @@ epilot webhooks getEventById -p configId=7hj28aasgag2gha2 -p eventId=123e4567-e8 }, "status": "succeeded", "http_method": "GET", - "payload": "string" + "payload": "string", + "original_payload": "string", + "retry_attempt": 0, + "can_reapply_transform": true, + "can_reapply_transform_reason": "available" } ``` @@ -651,12 +703,15 @@ Replay a webhook event | `configId` | path | string | Yes | Short uuid to identify the webhook configuration. | | `eventId` | path | string | Yes | Event id | +**Request Body** + **Sample Call** ```bash epilot webhooks replayEvent \ -p configId=7hj28aasgag2gha2 \ - -p eventId=123e4567-e89b-12d3-a456-426614174000 + -p eventId=123e4567-e89b-12d3-a456-426614174000 \ + -d '{"reapply_transform":false}' ``` Using positional args for path parameters: @@ -665,6 +720,12 @@ Using positional args for path parameters: epilot webhooks replayEvent 7hj28aasgag2gha2 123e4567-e89b-12d3-a456-426614174000 ``` +Using stdin pipe: + +```bash +cat body.json | epilot webhooks replayEvent -p configId=7hj28aasgag2gha2 -p eventId=123e4567-e89b-12d3-a456-426614174000 +``` + With JSONata filter: ```bash @@ -835,7 +896,11 @@ epilot webhooks getWebhookEventsV2 -p configId=7hj28aasgag2gha2 --jsonata 'data' }, "status": "succeeded", "http_method": "GET", - "payload": "string" + "payload": "string", + "original_payload": "string", + "retry_attempt": 0, + "can_reapply_transform": true, + "can_reapply_transform_reason": "available" } ], "next_cursor": { diff --git a/docs/cli/commands/workflow-definition.md b/docs/cli/commands/workflow-definition.md index 671d14f9..7cc52f3d 100644 --- a/docs/cli/commands/workflow-definition.md +++ b/docs/cli/commands/workflow-definition.md @@ -8,7 +8,9 @@ description: "epilot CLI commands for the Workflows Definitions: quick start, co - **Base URL:** `https://workflows-definition.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/workflow-definition](https://docs.epilot.io/api/workflow-definition) -Service for Workflow Definitions for different processes inside of an Organization +The Workflows Definitions API enables you to create, manage, and configure reusable workflow templates +within your organization. Workflow definitions serve as blueprints that define the structure and behavior +of business processes, which can then be instantiated as workflow executions. ## Quick Start @@ -42,8 +44,8 @@ epilot workflow-definition getMaxAllowedLimit **Workflows** - [`getMaxAllowedLimit`](#getmaxallowedlimit) — Get limits and number of created executions for an Organization. -- [`getDefinitions`](#getdefinitions) — Retrieve all Workflow Definitions from an Organization -- [`createDefinition`](#createdefinition) — Create a Workflow Definition. +- [`getDefinitions`](#getdefinitions) — Retrieve all V1 workflow definitions belonging to the authenticated organization. +- [`createDefinition`](#createdefinition) — Create a new V1 workflow definition. The definition consists of sections and steps - [`getDefinition`](#getdefinition) — Get specific Definition by id from the Organization. - [`updateDefinition`](#updatedefinition) — Update Workflow Definition. - [`deleteDefinition`](#deletedefinition) — Delete Workflow Definition. @@ -52,14 +54,12 @@ epilot workflow-definition getMaxAllowedLimit **Flows V2** - [`listFlowTemplates`](#listflowtemplates) — List all Flow Templates for a customer. Optionally, you can filter flow templates by trigger values. -- [`createFlowTemplate`](#createflowtemplate) — Create a new Flow Template. +- [`createFlowTemplate`](#createflowtemplate) — Create a new Flow Template (V2 workflow definition). - [`searchFlowTemplates`](#searchflowtemplates) — Search for flow templates by name, trigger type, enabled status, and more. -- [`getFlowTemplate`](#getflowtemplate) — Get specific FLow template for a customer +- [`getFlowTemplate`](#getflowtemplate) — Retrieve a specific flow template by its unique identifier. - [`updateFlowTemplate`](#updateflowtemplate) — Update Flow Template. - [`deleteFlowTemplate`](#deleteflowtemplate) — Delete Flow Template. -- [`duplicateFlowTemplate`](#duplicateflowtemplate) — Duplicate a Flow Template from an existing workflow. -- [`exportFlowTemplate`](#exportflowtemplate) — Export a Flow Template with all referenced automations resolved and bundled alongside. -- [`importFlowTemplate`](#importflowtemplate) — Import a Flow Template from an export payload. Creates all automations and the flow in the caller's organization. +- [`duplicateFlowTemplate`](#duplicateflowtemplate) — Create a copy of an existing flow template. The duplicated template will have a new **Closing Reason** - [`getAllClosingReasons`](#getallclosingreasons) — Get all Closing Reasons defined in the organization by default all Active. @@ -103,7 +103,7 @@ epilot workflow-definition getMaxAllowedLimit --jsonata 'currentNoOfWorkflows' ### `getDefinitions` -Retrieve all Workflow Definitions from an Organization +Retrieve all V1 workflow definitions belonging to the authenticated organization. `GET /v1/workflows/definitions` @@ -153,7 +153,8 @@ epilot workflow-definition getDefinitions --jsonata '$' {} ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] } ] ``` @@ -164,7 +165,7 @@ epilot workflow-definition getDefinitions --jsonata '$' ### `createDefinition` -Create a Workflow Definition. +Create a new V1 workflow definition. The definition consists of sections and steps `POST /v1/workflows/definitions` @@ -226,6 +227,7 @@ epilot workflow-definition createDefinition \ "type": "STEP", "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"] } ], @@ -241,7 +243,8 @@ epilot workflow-definition createDefinition \ } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] }' ``` @@ -307,6 +310,7 @@ epilot workflow-definition createDefinition --jsonata 'id' "type": "STEP", "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"] } ], @@ -322,7 +326,8 @@ epilot workflow-definition createDefinition --jsonata 'id' } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] } ``` @@ -386,7 +391,10 @@ epilot workflow-definition listFlowTemplates --jsonata 'results[0]' "closing_reasons": [], "entity_sync": [], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "limit_warnings": [] } ] } @@ -398,10 +406,16 @@ epilot workflow-definition listFlowTemplates --jsonata 'results[0]' ### `createFlowTemplate` -Create a new Flow Template. +Create a new Flow Template (V2 workflow definition). `POST /v2/flows/templates` +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `enforce_limits` | query | boolean | No | When true, size/count limit violations (max incoming edges per task, max branches, max entity-sync rules, ...) are enforced as 400 errors. Used by the flow-builder UI for interactive authoring. On upd | + **Request Body** (required) **Sample Call** @@ -447,6 +461,7 @@ epilot workflow-definition createFlowTemplate \ "id": "string", "type": "automation", "automation_id": "string", + "input_entity": "thread", "trigger_config": [] } ], @@ -472,6 +487,7 @@ epilot workflow-definition createFlowTemplate \ "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -487,6 +503,7 @@ epilot workflow-definition createFlowTemplate \ "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -522,7 +539,22 @@ epilot workflow-definition createFlowTemplate \ } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ] }' ``` @@ -575,6 +607,7 @@ epilot workflow-definition createFlowTemplate --jsonata '$' "id": "string", "type": "automation", "automation_id": "string", + "input_entity": "thread", "trigger_config": [] } ], @@ -600,6 +633,7 @@ epilot workflow-definition createFlowTemplate --jsonata '$' "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -615,6 +649,7 @@ epilot workflow-definition createFlowTemplate --jsonata '$' "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -650,7 +685,22 @@ epilot workflow-definition createFlowTemplate --jsonata '$' } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ] } ``` @@ -728,7 +778,10 @@ epilot workflow-definition searchFlowTemplates --jsonata 'results[0]' "closing_reasons": [], "entity_sync": [], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "limit_warnings": [] } ] } @@ -740,7 +793,7 @@ epilot workflow-definition searchFlowTemplates --jsonata 'results[0]' ### `getFlowTemplate` -Get specific FLow template for a customer +Retrieve a specific flow template by its unique identifier. `GET /v2/flows/templates/{flowId}` @@ -748,7 +801,7 @@ Get specific FLow template for a customer | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `flowId` | path | string | Yes | | +| `flowId` | path | string | Yes | Unique identifier of the flow template to retrieve. | **Sample Call** @@ -806,6 +859,7 @@ epilot workflow-definition getFlowTemplate -p flowId=7hj28akg --jsonata '$' "id": "string", "type": "automation", "automation_id": "string", + "input_entity": "thread", "trigger_config": [] } ], @@ -831,6 +885,7 @@ epilot workflow-definition getFlowTemplate -p flowId=7hj28akg --jsonata '$' "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -846,6 +901,7 @@ epilot workflow-definition getFlowTemplate -p flowId=7hj28akg --jsonata '$' "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -881,7 +937,22 @@ epilot workflow-definition getFlowTemplate -p flowId=7hj28akg --jsonata '$' } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ] } ``` @@ -899,7 +970,8 @@ Update Flow Template. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `flowId` | path | string | Yes | | +| `flowId` | path | string | Yes | Unique identifier of the flow template to update. | +| `enforce_limits` | query | boolean | No | When true, size/count limit violations (max incoming edges per task, max branches, max entity-sync rules, ...) are enforced as 400 errors. Used by the flow-builder UI for interactive authoring. On upd | **Request Body** (required) @@ -948,6 +1020,7 @@ epilot workflow-definition updateFlowTemplate \ "id": "string", "type": "automation", "automation_id": "string", + "input_entity": "thread", "trigger_config": [] } ], @@ -973,6 +1046,7 @@ epilot workflow-definition updateFlowTemplate \ "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -988,6 +1062,7 @@ epilot workflow-definition updateFlowTemplate \ "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1023,7 +1098,22 @@ epilot workflow-definition updateFlowTemplate \ } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ] }' ``` @@ -1082,6 +1172,7 @@ epilot workflow-definition updateFlowTemplate -p flowId=7hj28akg --jsonata '$' "id": "string", "type": "automation", "automation_id": "string", + "input_entity": "thread", "trigger_config": [] } ], @@ -1107,6 +1198,7 @@ epilot workflow-definition updateFlowTemplate -p flowId=7hj28akg --jsonata '$' "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -1122,6 +1214,7 @@ epilot workflow-definition updateFlowTemplate -p flowId=7hj28akg --jsonata '$' "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1157,7 +1250,22 @@ epilot workflow-definition updateFlowTemplate -p flowId=7hj28akg --jsonata '$' } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ] } ``` @@ -1175,7 +1283,7 @@ Delete Flow Template. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `flowId` | path | string | Yes | Id of the flow template to de deleted. | +| `flowId` | path | string | Yes | Unique identifier of the flow template to be deleted. | **Sample Call** @@ -1200,7 +1308,7 @@ epilot workflow-definition deleteFlowTemplate -p flowId=7hj28akg --jsonata '$' ### `duplicateFlowTemplate` -Duplicate a Flow Template from an existing workflow. +Create a copy of an existing flow template. The duplicated template will have a new `POST /v2/flows/templates/{flowId}/duplicate` @@ -1208,7 +1316,7 @@ Duplicate a Flow Template from an existing workflow. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `flowId` | path | string | Yes | | +| `flowId` | path | string | Yes | Unique identifier of the flow template to duplicate. | **Sample Call** @@ -1266,6 +1374,7 @@ epilot workflow-definition duplicateFlowTemplate -p flowId=7hj28akg --jsonata '$ "id": "string", "type": "automation", "automation_id": "string", + "input_entity": "thread", "trigger_config": [] } ], @@ -1291,6 +1400,7 @@ epilot workflow-definition duplicateFlowTemplate -p flowId=7hj28akg --jsonata '$ "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -1306,157 +1416,7 @@ epilot workflow-definition duplicateFlowTemplate -p flowId=7hj28akg --jsonata '$ "assigned_to": ["string"], "ecp": {}, "installer": {}, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL", - "automation_config": {}, - "trigger_mode": "manual", - "schedule": {}, - "created_automatically": false - } - ], - "edges": [ - { - "id": "string", - "from_id": "string", - "to_id": "string", - "condition_id": "string", - "none_met": true - } - ], - "closing_reasons": [ - { - "id": "string", - "title": "string", - "status": "ACTIVE", - "lastUpdateTime": "string", - "creationTime": "string" - } - ], - "entity_sync": [ - { - "trigger": {}, - "target": {}, - "value": {} - } - ], - "taxonomies": ["string"], - "singleClosingReasonSelection": true -} -``` - -
- ---- - -### `exportFlowTemplate` - -Export a Flow Template with all referenced automations resolved and bundled alongside. - -`GET /v2/flows/templates/{flowId}/export` - -**Parameters** - -| Name | In | Type | Required | Description | -| ---- | -- | ---- | -------- | ----------- | -| `flowId` | path | string | Yes | | - -**Sample Call** - -```bash -epilot workflow-definition exportFlowTemplate \ - -p flowId=7hj28akg -``` - -Using positional args for path parameters: - -```bash -epilot workflow-definition exportFlowTemplate 7hj28akg -``` - -With JSONata filter: - -```bash -epilot workflow-definition exportFlowTemplate -p flowId=7hj28akg --jsonata '$' -``` - -
-Sample Response - -```json -{ - "id": "string", - "org_id": "string", - "name": "string", - "description": "string", - "trigger": { - "type": "automation", - "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" - }, - "enabled": true, - "version": 2, - "created_at": "2021-04-27T12:01:13.000Z", - "updated_at": "2021-04-27T12:01:13.000Z", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" - }, - "assigned_to": ["string"], - "available_in_ecp": true, - "additional_triggers": [ - { - "id": "string", - "type": "manual", - "entity_schema": "string" - }, - { - "id": "string", - "type": "automation", - "automation_id": "string", - "trigger_config": [] - } - ], - "phases": [ - { - "id": "string", - "name": "string", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, - "assigned_to": ["string"], - "taxonomies": ["string"] - } - ], - "tasks": [ - { - "id": "string", - "name": "string", - "description": {}, - "journey": {}, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, - "requirements": [], - "assigned_to": ["string"], - "ecp": {}, - "installer": {}, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL" - }, - { - "id": "string", - "name": "string", - "description": {}, - "journey": {}, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, - "requirements": [], - "assigned_to": ["string"], - "ecp": {}, - "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1493,216 +1453,21 @@ epilot workflow-definition exportFlowTemplate -p flowId=7hj28akg --jsonata '$' ], "taxonomies": ["string"], "singleClosingReasonSelection": true, - "_resolved_automations": {} -} -``` - -
- ---- - -### `importFlowTemplate` - -Import a Flow Template from an export payload. Creates all automations and the flow in the caller's organization. - -`POST /v2/flows/templates/import` - -**Request Body** (required) - -**Sample Call** - -```bash -epilot workflow-definition importFlowTemplate -``` - -With request body: - -```bash -epilot workflow-definition importFlowTemplate \ - -d '{ - "id": "string", - "org_id": "string", - "name": "string", - "description": "string", - "trigger": { - "type": "automation", - "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" - }, - "enabled": true, - "version": 2, - "created_at": "2021-04-27T12:01:13.000Z", - "updated_at": "2021-04-27T12:01:13.000Z", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" - }, - "assigned_to": ["string"], - "available_in_ecp": true, - "additional_triggers": [ - { - "id": "string", - "type": "manual", - "entity_schema": "string" - }, - { - "id": "string", - "type": "automation", - "automation_id": "string", - "trigger_config": [] - } - ], - "phases": [ - { - "id": "string", - "name": "string", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, - "assigned_to": ["string"], - "taxonomies": ["string"] - } - ], - "tasks": [ - { - "id": "string", - "name": "string", - "description": {}, - "journey": {}, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, - "requirements": [], - "assigned_to": ["string"], - "ecp": {}, - "installer": {}, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL" - }, - { - "id": "string", - "name": "string", - "description": {}, - "journey": {}, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, - "requirements": [], - "assigned_to": ["string"], - "ecp": {}, - "installer": {}, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL", - "automation_config": {}, - "trigger_mode": "manual", - "schedule": {}, - "created_automatically": false - } - ], - "edges": [ - { - "id": "string", - "from_id": "string", - "to_id": "string", - "condition_id": "string", - "none_met": true + "_manifest": ["string"], + "linear": true, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] } - ], - "closing_reasons": [ - { - "id": "string", - "title": "string", - "status": "ACTIVE", - "lastUpdateTime": "string", - "creationTime": "string" - } - ], - "entity_sync": [ - { - "trigger": {}, - "target": {}, - "value": {} - } - ], - "taxonomies": ["string"], - "singleClosingReasonSelection": true, - "_resolved_automations": {} -}' -``` - -Using stdin pipe: - -```bash -cat body.json | epilot workflow-definition importFlowTemplate -``` - -With JSONata filter: - -```bash -epilot workflow-definition importFlowTemplate --jsonata 'flow' -``` - -
-Sample Response - -```json -{ - "flow": { - "id": "string", - "org_id": "string", - "name": "string", - "description": "string", - "trigger": { - "type": "automation", - "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" - }, - "enabled": true, - "version": 2, - "created_at": "2021-04-27T12:01:13.000Z", - "updated_at": "2021-04-27T12:01:13.000Z", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" - }, - "assigned_to": ["string"], - "available_in_ecp": true, - "additional_triggers": [ - {}, - {} - ], - "phases": [ - {} - ], - "tasks": [ - {}, - {} - ], - "edges": [ - {} - ], - "closing_reasons": [ - {} - ], - "entity_sync": [ - {} - ], - "taxonomies": ["string"], - "singleClosingReasonSelection": true - }, - "_id_mappings": { - "flow_id": { - "old": "string", - "new": "string" - }, - "task_ids": {}, - "automation_ids": {} - } + ] } ``` @@ -1791,6 +1556,7 @@ epilot workflow-definition getDefinition -p definitionId=7hj28a --jsonata 'id' "type": "STEP", "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"] } ], @@ -1806,7 +1572,8 @@ epilot workflow-definition getDefinition -p definitionId=7hj28a --jsonata 'id' } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] } ``` @@ -1886,6 +1653,7 @@ epilot workflow-definition updateDefinition \ "type": "STEP", "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"] } ], @@ -1901,7 +1669,8 @@ epilot workflow-definition updateDefinition \ } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] }' ``` @@ -1973,6 +1742,7 @@ epilot workflow-definition updateDefinition -p definitionId=7hj28a --jsonata 'id "type": "STEP", "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"] } ], @@ -1988,7 +1758,8 @@ epilot workflow-definition updateDefinition -p definitionId=7hj28a --jsonata 'id } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] } ``` @@ -2006,7 +1777,7 @@ Delete Workflow Definition. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `definitionId` | path | string | Yes | Id of the definition to de deleted. | +| `definitionId` | path | string | Yes | Unique identifier of the workflow definition to be deleted. | **Sample Call** @@ -2039,7 +1810,7 @@ Get all Closing Reasons defined in the organization by default all Active. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `includeInactive` | query | boolean | No | Filter Closing Reasons by status like active inactiv | +| `includeInactive` | query | boolean | No | When set to true, includes inactive closing reasons in the response. By default, only active closing reasons are returned. | **Sample Call** diff --git a/docs/cli/commands/workflow.md b/docs/cli/commands/workflow.md index 20d704b8..953b7415 100644 --- a/docs/cli/commands/workflow.md +++ b/docs/cli/commands/workflow.md @@ -8,7 +8,10 @@ description: "epilot CLI commands for the Workflows Executions: quick start, com - **Base URL:** `https://workflows-execution.sls.epilot.io` - **API Docs:** [https://docs.epilot.io/api/workflow](https://docs.epilot.io/api/workflow) -Service for Workflow Executions which covers executions of processes defined in an Organization +Overview +The Workflows Executions API manages the runtime instances of workflow processes within an organization. +While **Workflow Definitions** (managed by the Workflows Definitions API) serve as reusable templates +that define the structure, phases, and tasks of a process, **Workflow Executions** a ## Quick Start @@ -42,31 +45,33 @@ epilot workflow getExecutions **Workflow Executions** - [`getExecutions`](#getexecutions) — Retrieve Workflow Executions. Optionally, you can filter them by context & schema. Please be aware, these executions are -- [`createExecution`](#createexecution) — Create a Workflow Execution. Start a new workflow execution, based on a workflow definition (template). -- [`getExecution`](#getexecution) — Get a full workflow execution, included steps information, by execution id. +- [`createExecution`](#createexecution) — Creates a new V1 Workflow Execution from a workflow definition (template). +- [`getExecution`](#getexecution) — Retrieves a complete V1 workflow execution by ID, including all steps information. - [`updateExecution`](#updateexecution) — Patches updates like assignees, status, closingReason for a single Workflow Execution. - [`deleteExecution`](#deleteexecution) — Delete workflow execution by id. Workflow contexts will NOT be deleted. **Workflow Steps** - [`createStep`](#createstep) — Create a new step in current workflow execution. -- [`updateStep`](#updatestep) — Patches various changes to a workflow execution step. +- [`updateStep`](#updatestep) — Updates a workflow execution step with new values for status, assignees, due date, position, and more. - [`deleteStep`](#deletestep) — Deletes a step from a workflow execution. **Closing Reasons** - [`getClosingReasonExecution`](#getclosingreasonexecution) — Shows all Closing Reasons defined at the moment of starting the Workflow Execution. **Flows V2** -- [`startFlowExecution`](#startflowexecution) — Starts a new Flow Execution based on a flow template. -- [`getFlowExecution`](#getflowexecution) — Get a full flow execution, included tasks, phases, edges & analytics. +- [`startFlowExecution`](#startflowexecution) — Starts a new Flow Execution based on a flow template (definition). +- [`getFlowExecution`](#getflowexecution) — Retrieves a complete flow execution by ID, including all phases, tasks, edges, contexts, and analytics. - [`patchFlowExecution`](#patchflowexecution) — Patch flow execution with new assignees, status, analytics & other changes. - [`deleteFlowExecution`](#deleteflowexecution) — Deletes a specific execution of a flow, identified by id. Flow contexts will NOT be deleted. - [`searchFlowExecutions`](#searchflowexecutions) — Search Flow Executions for a specific Entity. -- [`patchTask`](#patchtask) — Changes various attributes of a flow task, like assignees, status, due date, etc. +- [`patchTask`](#patchtask) — Updates attributes of a flow task including status, assignees, due date, and more. - [`runTaskAutomation`](#runtaskautomation) — Runs configured automation for a flow task - [`executeTask`](#executetask) — Executes any kind of flow task immediately. - [`patchPhase`](#patchphase) — Apply updates to a phase within flow execution - [`addTask`](#addtask) — Create a new task in current workflow execution. - [`cancelTaskSchedule`](#canceltaskschedule) — Cancels a scheduled task, deleting the schedule and marking the task as skipped. +- [`reconcileAutomationTask`](#reconcileautomationtask) — Reconciles an automation task's status against its linked automation execution. +- [`runTaskScheduleNow`](#runtaskschedulenow) — Cancels the pending schedule for a task and immediately triggers its automation execution. ### `getExecutions` @@ -142,7 +147,7 @@ epilot workflow getExecutions --jsonata '$' ### `createExecution` -Create a Workflow Execution. Start a new workflow execution, based on a workflow definition (template). +Creates a new V1 Workflow Execution from a workflow definition (template). `POST /v1/workflows/executions` @@ -236,7 +241,7 @@ epilot workflow createExecution --jsonata '$' ### `getExecution` -Get a full workflow execution, included steps information, by execution id. +Retrieves a complete V1 workflow execution by ID, including all steps information. `GET /v1/workflows/executions/{executionId}` @@ -520,6 +525,11 @@ epilot workflow createStep -p executionId=wd56125gah --jsonata '$' "complete_task_automatically": true } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, "enabled": true, "requirements": [ { @@ -534,6 +544,7 @@ epilot workflow createStep -p executionId=wd56125gah --jsonata '$' "userIds": [0], "assignedTo": ["string"], "assignedToInProgress": "string", + "assignedToOnHold": "string", "status": "UNASSIGNED", "created": "string", "lastUpdated": "string", @@ -570,7 +581,7 @@ epilot workflow createStep -p executionId=wd56125gah --jsonata '$' ### `updateStep` -Patches various changes to a workflow execution step. +Updates a workflow execution step with new values for status, assignees, due date, position, and more. `PATCH /v1/workflows/executions/{executionId}/steps/{stepId}` @@ -578,8 +589,8 @@ Patches various changes to a workflow execution step. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `executionId` | path | string | Yes | Id of the execution | -| `stepId` | path | string | Yes | Short uuid (length 6) to identify the Workflow Execution Step. | +| `executionId` | path | string | Yes | Unique identifier of the workflow execution | +| `stepId` | path | string | Yes | Short unique identifier (typically 6 characters) of the step within the execution | **Request Body** (required) @@ -603,6 +614,7 @@ epilot workflow updateStep \ "userIds": [0], "assignedTo": ["string"], "assignedToInProgress": "string", + "assignedToOnHold": "string", "status": "UNASSIGNED", "dueDate": "string", "dynamicDueDate": { @@ -685,6 +697,11 @@ epilot workflow updateStep -p executionId=wd56125gah -p stepId=7hj28a --jsonata "complete_task_automatically": true } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, "enabled": true, "requirements": [ { @@ -699,6 +716,7 @@ epilot workflow updateStep -p executionId=wd56125gah -p stepId=7hj28a --jsonata "userIds": [0], "assignedTo": ["string"], "assignedToInProgress": "string", + "assignedToOnHold": "string", "status": "UNASSIGNED", "created": "string", "lastUpdated": "string", @@ -819,7 +837,7 @@ epilot workflow getClosingReasonExecution -p executionId=wd561 --jsonata 'reason ### `startFlowExecution` -Starts a new Flow Execution based on a flow template. +Starts a new Flow Execution based on a flow template (definition). `POST /v2/flows/executions` @@ -836,14 +854,20 @@ With request body: ```bash epilot workflow startFlowExecution \ -d '{ - "flow_template_id": "string", + "flow_template_id": "tpl_abc123def456", "trigger": { "type": "MANUAL", "automation_config": { "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" + "error_reason": "string", + "input_context": { + "source": "trigger", + "task_id": "string" + }, + "heal_attempts": 0, + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z" } }, "contexts": [ @@ -906,7 +930,8 @@ epilot workflow startFlowExecution --jsonata 'id' ], "crt_tasks": [ { - "id": "string" + "id": "string", + "crt_since": "1970-01-01T00:00:00.000Z" } ], "phases": [ @@ -943,6 +968,7 @@ epilot workflow startFlowExecution --jsonata 'id' "enabled": true, "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -987,10 +1013,14 @@ epilot workflow startFlowExecution --jsonata 'id' "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" + "error_reason": "string", + "input_context": {}, + "heal_attempts": 0, + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z" } }, - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "linear": true } ``` @@ -1000,7 +1030,7 @@ epilot workflow startFlowExecution --jsonata 'id' ### `getFlowExecution` -Get a full flow execution, included tasks, phases, edges & analytics. +Retrieves a complete flow execution by ID, including all phases, tasks, edges, contexts, and analytics. `GET /v2/flows/executions/{execution_id}` @@ -1008,25 +1038,27 @@ Get a full flow execution, included tasks, phases, edges & analytics. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | **Sample Call** ```bash epilot workflow getFlowExecution \ - -p execution_id=wd561 + -p execution_id=exec_abc123def456 ``` Using positional args for path parameters: ```bash -epilot workflow getFlowExecution wd561 +epilot workflow getFlowExecution exec_abc123def456 ``` With JSONata filter: ```bash -epilot workflow getFlowExecution -p execution_id=wd561 --jsonata 'id' +epilot workflow getFlowExecution -p execution_id=exec_abc123def456 --jsonata 'id' ```
@@ -1066,7 +1098,8 @@ epilot workflow getFlowExecution -p execution_id=wd561 --jsonata 'id' ], "crt_tasks": [ { - "id": "string" + "id": "string", + "crt_since": "1970-01-01T00:00:00.000Z" } ], "phases": [ @@ -1103,6 +1136,7 @@ epilot workflow getFlowExecution -p execution_id=wd561 --jsonata 'id' "enabled": true, "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1147,10 +1181,14 @@ epilot workflow getFlowExecution -p execution_id=wd561 --jsonata 'id' "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" + "error_reason": "string", + "input_context": {}, + "heal_attempts": 0, + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z" } }, - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "linear": true } ``` @@ -1168,7 +1206,9 @@ Patch flow execution with new assignees, status, analytics & other changes. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | **Request Body** (required) @@ -1176,14 +1216,14 @@ Patch flow execution with new assignees, status, analytics & other changes. ```bash epilot workflow patchFlowExecution \ - -p execution_id=wd561 + -p execution_id=exec_abc123def456 ``` With request body: ```bash epilot workflow patchFlowExecution \ - -p execution_id=wd561 \ + -p execution_id=exec_abc123def456 \ -d '{ "status": "STARTED", "assigned_to": ["string"], @@ -1223,19 +1263,19 @@ epilot workflow patchFlowExecution \ Using positional args for path parameters: ```bash -epilot workflow patchFlowExecution wd561 +epilot workflow patchFlowExecution exec_abc123def456 ``` Using stdin pipe: ```bash -cat body.json | epilot workflow patchFlowExecution -p execution_id=wd561 +cat body.json | epilot workflow patchFlowExecution -p execution_id=exec_abc123def456 ``` With JSONata filter: ```bash -epilot workflow patchFlowExecution -p execution_id=wd561 --jsonata 'id' +epilot workflow patchFlowExecution -p execution_id=exec_abc123def456 --jsonata 'id' ```
@@ -1275,7 +1315,8 @@ epilot workflow patchFlowExecution -p execution_id=wd561 --jsonata 'id' ], "crt_tasks": [ { - "id": "string" + "id": "string", + "crt_since": "1970-01-01T00:00:00.000Z" } ], "phases": [ @@ -1312,6 +1353,7 @@ epilot workflow patchFlowExecution -p execution_id=wd561 --jsonata 'id' "enabled": true, "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1356,10 +1398,14 @@ epilot workflow patchFlowExecution -p execution_id=wd561 --jsonata 'id' "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" + "error_reason": "string", + "input_context": {}, + "heal_attempts": 0, + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z" } }, - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "linear": true } ``` @@ -1377,26 +1423,30 @@ Deletes a specific execution of a flow, identified by id. Flow contexts will NOT | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | -| `soft` | query | boolean | No | If true, the execution will NOT be deleted permanently, but rather kept for archive purpose. | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | +| `soft` | query | boolean | No | When true, the execution is marked as deleted but retained in storage for archival +and audit purposes. When false (default), the execution is permanently removed. +Soft-deleted executions do not appear | **Sample Call** ```bash epilot workflow deleteFlowExecution \ - -p execution_id=wd561 + -p execution_id=exec_abc123def456 ``` Using positional args for path parameters: ```bash -epilot workflow deleteFlowExecution wd561 +epilot workflow deleteFlowExecution exec_abc123def456 ``` With JSONata filter: ```bash -epilot workflow deleteFlowExecution -p execution_id=wd561 --jsonata '$' +epilot workflow deleteFlowExecution -p execution_id=exec_abc123def456 --jsonata '$' ``` --- @@ -1457,7 +1507,8 @@ epilot workflow searchFlowExecutions --jsonata 'results[0]' "entity_sync": [], "taxonomies": ["string"], "trigger": {}, - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "linear": true } ] } @@ -1469,7 +1520,7 @@ epilot workflow searchFlowExecutions --jsonata 'results[0]' ### `patchTask` -Changes various attributes of a flow task, like assignees, status, due date, etc. +Updates attributes of a flow task including status, assignees, due date, and more. `PATCH /v2/flows/executions/{execution_id}/tasks/{task_id}` @@ -1477,8 +1528,12 @@ Changes various attributes of a flow task, like assignees, status, due date, etc | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | -| `task_id` | path | string | Yes | Id of the task | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | +| `task_id` | path | string | Yes | Unique identifier for a task within the execution. Each task has a unique ID +that distinguishes it from other tasks in the same execution. + | **Request Body** (required) @@ -1486,20 +1541,20 @@ Changes various attributes of a flow task, like assignees, status, due date, etc ```bash epilot workflow patchTask \ - -p execution_id=wd561 \ - -p task_id=7hj28a + -p execution_id=exec_abc123def456 \ + -p task_id=task_7hj28a ``` With request body: ```bash epilot workflow patchTask \ - -p execution_id=wd561 \ - -p task_id=7hj28a \ + -p execution_id=exec_abc123def456 \ + -p task_id=task_7hj28a \ -d '{ - "name": "string", + "name": "Review customer application", "status": "UNASSIGNED", - "due_date": "2021-04-27T12:00:00.000Z", + "due_date": "2026-05-28T00:00:00.000", "due_date_config": { "duration": 0, "unit": "minutes", @@ -1513,7 +1568,13 @@ epilot workflow patchTask \ "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" + "error_reason": "string", + "input_context": { + "source": "trigger", + "task_id": "string" + }, + "heal_attempts": 0, + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z" }, "description": { "enabled": true, @@ -1541,27 +1602,33 @@ epilot workflow patchTask \ "complete_task_automatically": true } }, - "next_condition_id": "string", - "revert_execution": false + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, + "next_condition_id": "cond_branch_approved", + "revert_execution": false, + "completed_via_journey": false }' ``` Using positional args for path parameters: ```bash -epilot workflow patchTask wd561 7hj28a +epilot workflow patchTask exec_abc123def456 task_7hj28a ``` Using stdin pipe: ```bash -cat body.json | epilot workflow patchTask -p execution_id=wd561 -p task_id=7hj28a +cat body.json | epilot workflow patchTask -p execution_id=exec_abc123def456 -p task_id=task_7hj28a ``` With JSONata filter: ```bash -epilot workflow patchTask -p execution_id=wd561 -p task_id=7hj28a --jsonata '$' +epilot workflow patchTask -p execution_id=exec_abc123def456 -p task_id=task_7hj28a --jsonata '$' ```
@@ -1606,7 +1673,8 @@ epilot workflow patchTask -p execution_id=wd561 -p task_id=7hj28a --jsonata '$' "status_updated_at": "1970-01-01T00:00:00.000Z", "in_progress_by": "string", "completed_by": "string", - "skipped_by": "string" + "skipped_by": "string", + "on_hold_by": "string" }, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", @@ -1634,6 +1702,11 @@ epilot workflow patchTask -p execution_id=wd561 -p task_id=7hj28a --jsonata '$' "complete_task_automatically": true } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1658,27 +1731,31 @@ Runs configured automation for a flow task | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | -| `task_id` | path | string | Yes | Id of the task | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | +| `task_id` | path | string | Yes | Unique identifier for a task within the execution. Each task has a unique ID +that distinguishes it from other tasks in the same execution. + | **Sample Call** ```bash epilot workflow runTaskAutomation \ - -p execution_id=wd561 \ - -p task_id=7hj28a + -p execution_id=exec_abc123def456 \ + -p task_id=task_7hj28a ``` Using positional args for path parameters: ```bash -epilot workflow runTaskAutomation wd561 7hj28a +epilot workflow runTaskAutomation exec_abc123def456 task_7hj28a ``` With JSONata filter: ```bash -epilot workflow runTaskAutomation -p execution_id=wd561 -p task_id=7hj28a --jsonata '$' +epilot workflow runTaskAutomation -p execution_id=exec_abc123def456 -p task_id=task_7hj28a --jsonata '$' ```
@@ -1723,7 +1800,8 @@ epilot workflow runTaskAutomation -p execution_id=wd561 -p task_id=7hj28a --json "status_updated_at": "1970-01-01T00:00:00.000Z", "in_progress_by": "string", "completed_by": "string", - "skipped_by": "string" + "skipped_by": "string", + "on_hold_by": "string" }, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", @@ -1751,6 +1829,11 @@ epilot workflow runTaskAutomation -p execution_id=wd561 -p task_id=7hj28a --json "complete_task_automatically": true } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1758,7 +1841,13 @@ epilot workflow runTaskAutomation -p execution_id=wd561 -p task_id=7hj28a --json "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" + "error_reason": "string", + "input_context": { + "source": "trigger", + "task_id": "string" + }, + "heal_attempts": 0, + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z" }, "automation_execution_id": "string", "trigger_mode": "manual", @@ -1786,27 +1875,31 @@ Executes any kind of flow task immediately. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | -| `task_id` | path | string | Yes | Id of the task | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | +| `task_id` | path | string | Yes | Unique identifier for a task within the execution. Each task has a unique ID +that distinguishes it from other tasks in the same execution. + | **Sample Call** ```bash epilot workflow executeTask \ - -p execution_id=wd561 \ - -p task_id=7hj28a + -p execution_id=exec_abc123def456 \ + -p task_id=task_7hj28a ``` Using positional args for path parameters: ```bash -epilot workflow executeTask wd561 7hj28a +epilot workflow executeTask exec_abc123def456 task_7hj28a ``` With JSONata filter: ```bash -epilot workflow executeTask -p execution_id=wd561 -p task_id=7hj28a --jsonata '$' +epilot workflow executeTask -p execution_id=exec_abc123def456 -p task_id=task_7hj28a --jsonata '$' ```
@@ -1851,7 +1944,8 @@ epilot workflow executeTask -p execution_id=wd561 -p task_id=7hj28a --jsonata '$ "status_updated_at": "1970-01-01T00:00:00.000Z", "in_progress_by": "string", "completed_by": "string", - "skipped_by": "string" + "skipped_by": "string", + "on_hold_by": "string" }, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", @@ -1879,6 +1973,11 @@ epilot workflow executeTask -p execution_id=wd561 -p task_id=7hj28a --jsonata '$ "complete_task_automatically": true } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1903,8 +2002,12 @@ Apply updates to a phase within flow execution | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | -| `phase_id` | path | string | Yes | Id of the phase | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | +| `phase_id` | path | string | Yes | Unique identifier for a phase within the execution. Phases group related tasks +together and track collective progress. + | **Request Body** (required) @@ -1912,16 +2015,16 @@ Apply updates to a phase within flow execution ```bash epilot workflow patchPhase \ - -p execution_id=wd561 \ - -p phase_id=9gjs2952j + -p execution_id=exec_abc123def456 \ + -p phase_id=phase_9gjs2952j ``` With request body: ```bash epilot workflow patchPhase \ - -p execution_id=wd561 \ - -p phase_id=9gjs2952j \ + -p execution_id=exec_abc123def456 \ + -p phase_id=phase_9gjs2952j \ -d '{ "name": "string", "due_date": "2021-04-27T12:00:00.000Z", @@ -1939,19 +2042,19 @@ epilot workflow patchPhase \ Using positional args for path parameters: ```bash -epilot workflow patchPhase wd561 9gjs2952j +epilot workflow patchPhase exec_abc123def456 phase_9gjs2952j ``` Using stdin pipe: ```bash -cat body.json | epilot workflow patchPhase -p execution_id=wd561 -p phase_id=9gjs2952j +cat body.json | epilot workflow patchPhase -p execution_id=exec_abc123def456 -p phase_id=phase_9gjs2952j ``` With JSONata filter: ```bash -epilot workflow patchPhase -p execution_id=wd561 -p phase_id=9gjs2952j --jsonata 'id' +epilot workflow patchPhase -p execution_id=exec_abc123def456 -p phase_id=phase_9gjs2952j --jsonata 'id' ```
@@ -1980,7 +2083,8 @@ epilot workflow patchPhase -p execution_id=wd561 -p phase_id=9gjs2952j --jsonata "status_updated_at": "1970-01-01T00:00:00.000Z", "in_progress_by": "string", "completed_by": "string", - "skipped_by": "string" + "skipped_by": "string", + "on_hold_by": "string" }, "taxonomies": ["string"], "loop_config": { @@ -2004,7 +2108,9 @@ Create a new task in current workflow execution. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | **Request Body** (required) @@ -2012,14 +2118,14 @@ Create a new task in current workflow execution. ```bash epilot workflow addTask \ - -p execution_id=wd561 + -p execution_id=exec_abc123def456 ``` With request body: ```bash epilot workflow addTask \ - -p execution_id=wd561 \ + -p execution_id=exec_abc123def456 \ -d '{ "previous_task_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "next_task_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -2041,7 +2147,13 @@ epilot workflow addTask \ "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" + "error_reason": "string", + "input_context": { + "source": "trigger", + "task_id": "string" + }, + "heal_attempts": 0, + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z" }, "phase_id": "string", "task_type": "MANUAL" @@ -2052,19 +2164,19 @@ epilot workflow addTask \ Using positional args for path parameters: ```bash -epilot workflow addTask wd561 +epilot workflow addTask exec_abc123def456 ``` Using stdin pipe: ```bash -cat body.json | epilot workflow addTask -p execution_id=wd561 +cat body.json | epilot workflow addTask -p execution_id=exec_abc123def456 ``` With JSONata filter: ```bash -epilot workflow addTask -p execution_id=wd561 --jsonata '$' +epilot workflow addTask -p execution_id=exec_abc123def456 --jsonata '$' ```
@@ -2109,7 +2221,8 @@ epilot workflow addTask -p execution_id=wd561 --jsonata '$' "status_updated_at": "1970-01-01T00:00:00.000Z", "in_progress_by": "string", "completed_by": "string", - "skipped_by": "string" + "skipped_by": "string", + "on_hold_by": "string" }, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", @@ -2137,6 +2250,11 @@ epilot workflow addTask -p execution_id=wd561 --jsonata '$' "complete_task_automatically": true } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -2161,27 +2279,330 @@ Cancels a scheduled task, deleting the schedule and marking the task as skipped. | Name | In | Type | Required | Description | | ---- | -- | ---- | -------- | ----------- | -| `execution_id` | path | string | Yes | Id of the execution | -| `task_id` | path | string | Yes | Id of the task | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | +| `task_id` | path | string | Yes | Unique identifier for a task within the execution. Each task has a unique ID +that distinguishes it from other tasks in the same execution. + | **Sample Call** ```bash epilot workflow cancelTaskSchedule \ - -p execution_id=wd561 \ - -p task_id=7hj28a + -p execution_id=exec_abc123def456 \ + -p task_id=task_7hj28a +``` + +Using positional args for path parameters: + +```bash +epilot workflow cancelTaskSchedule exec_abc123def456 task_7hj28a +``` + +With JSONata filter: + +```bash +epilot workflow cancelTaskSchedule -p execution_id=exec_abc123def456 -p task_id=task_7hj28a --jsonata '$' +``` + +--- + +### `reconcileAutomationTask` + +Reconciles an automation task's status against its linked automation execution. + +`POST /v2/flows/executions/{execution_id}/tasks/{task_id}/reconcile-automation` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | +| `task_id` | path | string | Yes | Unique identifier for a task within the execution. Each task has a unique ID +that distinguishes it from other tasks in the same execution. + | + +**Sample Call** + +```bash +epilot workflow reconcileAutomationTask \ + -p execution_id=exec_abc123def456 \ + -p task_id=task_7hj28a +``` + +Using positional args for path parameters: + +```bash +epilot workflow reconcileAutomationTask exec_abc123def456 task_7hj28a +``` + +With JSONata filter: + +```bash +epilot workflow reconcileAutomationTask -p execution_id=exec_abc123def456 -p task_id=task_7hj28a --jsonata 'id' +``` + +
+Sample Response + +```json +{ + "id": "string", + "flow_template_id": "string", + "org_id": "string", + "name": "string", + "created_at": "string", + "updated_at": "string", + "due_date": "string", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "status": "STARTED", + "assigned_to": ["string"], + "analytics": { + "started_at": "string", + "completed_at": "string", + "closed_at": "string", + "started_by": "string", + "closed_by": "string" + }, + "contexts": [ + { + "entity_id": "string", + "entity_schema": "string", + "is_primary": false + } + ], + "crt_tasks": [ + { + "id": "string", + "crt_since": "1970-01-01T00:00:00.000Z" + } + ], + "phases": [ + { + "id": "string", + "template_id": "string", + "name": "string", + "status": "OPEN", + "updated_at": "string", + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": {}, + "assigned_to": ["string"], + "analytics": {}, + "taxonomies": ["string"], + "loop_config": {} + } + ], + "tasks": [ + { + "id": "string", + "template_id": "string", + "name": "string", + "description": {}, + "status": "UNASSIGNED", + "journey": {}, + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": {}, + "requirements": [], + "assigned_to": ["string"], + "analytics": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "manually_created": true, + "enabled": true, + "ecp": {}, + "installer": {}, + "partner": {}, + "taxonomies": ["string"], + "phase_id": "string", + "task_type": "MANUAL", + "loop_config": {} + } + ], + "edges": [ + { + "id": "string", + "from_id": "string", + "to_id": "string", + "condition_id": "abc123", + "none_met": true + } + ], + "_execution_chain": { + "parent_execution_id": "string", + "parent_task_id": "string", + "depth": 0 + }, + "closing_reason": { + "selected_reasons": [ + {} + ], + "configured_reasons": [ + {} + ], + "extra_description": "string" + }, + "available_in_ecp": true, + "entity_sync": [ + { + "trigger": {}, + "target": {}, + "value": {} + } + ], + "taxonomies": ["string"], + "trigger": { + "type": "MANUAL", + "automation_config": { + "flow_id": "string", + "execution_id": "string", + "execution_status": "string", + "error_reason": "string", + "input_context": {}, + "heal_attempts": 0, + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z" + } + }, + "singleClosingReasonSelection": true, + "linear": true +} +``` + +
+ +--- + +### `runTaskScheduleNow` + +Cancels the pending schedule for a task and immediately triggers its automation execution. + +`POST /v2/flows/executions/{execution_id}/tasks/{task_id}/schedule/run-now` + +**Parameters** + +| Name | In | Type | Required | Description | +| ---- | -- | ---- | -------- | ----------- | +| `execution_id` | path | string | Yes | Unique identifier for the flow execution. This ID is generated when the execution +is created and remains constant throughout its lifecycle. + | +| `task_id` | path | string | Yes | Unique identifier for a task within the execution. Each task has a unique ID +that distinguishes it from other tasks in the same execution. + | + +**Sample Call** + +```bash +epilot workflow runTaskScheduleNow \ + -p execution_id=exec_abc123def456 \ + -p task_id=task_7hj28a ``` Using positional args for path parameters: ```bash -epilot workflow cancelTaskSchedule wd561 7hj28a +epilot workflow runTaskScheduleNow exec_abc123def456 task_7hj28a ``` With JSONata filter: ```bash -epilot workflow cancelTaskSchedule -p execution_id=wd561 -p task_id=7hj28a --jsonata '$' +epilot workflow runTaskScheduleNow -p execution_id=exec_abc123def456 -p task_id=task_7hj28a --jsonata '$' +``` + +
+Sample Response + +```json +{ + "id": "string", + "template_id": "string", + "name": "string", + "description": { + "enabled": true, + "value": "string" + }, + "status": "UNASSIGNED", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "complete_task_automatically": true + }, + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "requirements": [ + { + "task_id": "string", + "phase_id": "string", + "when": "TASK_FINISHED" + } + ], + "assigned_to": ["string"], + "analytics": { + "started_at": "1970-01-01T00:00:00.000Z", + "in_progress_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status_updated_at": "1970-01-01T00:00:00.000Z", + "in_progress_by": "string", + "completed_by": "string", + "skipped_by": "string", + "on_hold_by": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "manually_created": true, + "enabled": true, + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "complete_task_automatically": true + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "complete_task_automatically": true + } + }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, + "taxonomies": ["string"], + "phase_id": "string", + "task_type": "MANUAL", + "loop_config": { + "max_iterations": 3, + "crt_iterations": 0 + } +} ``` +
+ --- diff --git a/docs/cli/overview.md b/docs/cli/overview.md index 14fb83d7..ac910103 100644 --- a/docs/cli/overview.md +++ b/docs/cli/overview.md @@ -309,12 +309,15 @@ Per-API command reference with all operations, parameters, and sample calls. See | Access Token API | `epilot access-token` | [reference](commands/access-token.md) | | Address Suggestions API | `epilot address-suggestions` | [reference](commands/address-suggestions.md) | | Address API | `epilot address` | [reference](commands/address.md) | -| AI Agents API - OpenAPI 3.0 | `epilot ai-agents` | [reference](commands/ai-agents.md) | +| AI Agents API | `epilot ai-agents` | [reference](commands/ai-agents.md) | | App API | `epilot app` | [reference](commands/app.md) | | Audit Log | `epilot audit-logs` | [reference](commands/audit-logs.md) | | Automation API | `epilot automation` | [reference](commands/automation.md) | | Billing API | `epilot billing` | [reference](commands/billing.md) | | Blueprint Manifest API | `epilot blueprint-manifest` | [reference](commands/blueprint-manifest.md) | +| Calendar API | `epilot calendar` | [reference](commands/calendar.md) | +| epilot Chat API | `epilot chat` | [reference](commands/chat.md) | +| Configuration Hub API | `epilot configuration-hub` | [reference](commands/configuration-hub.md) | | Consent API | `epilot consent` | [reference](commands/consent.md) | | Portal API | `epilot customer-portal` | [reference](commands/customer-portal.md) | | Dashboard API | `epilot dashboard` | [reference](commands/dashboard.md) | @@ -325,12 +328,14 @@ Per-API command reference with all operations, parameters, and sample calls. See | Messaging Settings API | `epilot email-settings` | [reference](commands/email-settings.md) | | Email template API | `epilot email-template` | [reference](commands/email-template.md) | | Entity Mapping API | `epilot entity-mapping` | [reference](commands/entity-mapping.md) | +| Entity UI API | `epilot entity-ui` | [reference](commands/entity-ui.md) | | Entity API | `epilot entity` | [reference](commands/entity.md) | | Environments API | `epilot environments` | [reference](commands/environments.md) | -| ERP Integration API | `epilot erp-integration` | [reference](commands/erp-integration.md) | | Event Catalog API | `epilot event-catalog` | [reference](commands/event-catalog.md) | | File API | `epilot file` | [reference](commands/file.md) | | Iban API | `epilot iban` | [reference](commands/iban.md) | +| Identity API | `epilot identity` | [reference](commands/identity.md) | +| Integration Toolkit API | `epilot integration-toolkit` | [reference](commands/integration-toolkit.md) | | Journey API | `epilot journey` | [reference](commands/journey.md) | | Kanban API | `epilot kanban` | [reference](commands/kanban.md) | | Message API | `epilot message` | [reference](commands/message.md) | @@ -338,13 +343,17 @@ Per-API command reference with all operations, parameters, and sample calls. See | Notes API | `epilot notes` | [reference](commands/notes.md) | | Notification API | `epilot notification` | [reference](commands/notification.md) | | Organization API | `epilot organization` | [reference](commands/organization.md) | -| Partner API | `epilot partner-directory` | [reference](commands/partner-directory.md) | +| Partner Directory API | `epilot partner-directory` | [reference](commands/partner-directory.md) | | Permissions API | `epilot permissions` | [reference](commands/permissions.md) | | Pricing Tier API | `epilot pricing-tier` | [reference](commands/pricing-tier.md) | | Pricing API | `epilot pricing` | [reference](commands/pricing.md) | | Purpose API | `epilot purpose` | [reference](commands/purpose.md) | +| Query API | `epilot query` | [reference](commands/query.md) | | Sandbox API | `epilot sandbox` | [reference](commands/sandbox.md) | +| Sharing API | `epilot sharing` | [reference](commands/sharing.md) | +| Snapshot API | `epilot snapshot` | [reference](commands/snapshot.md) | | Submission API | `epilot submission` | [reference](commands/submission.md) | +| Target API | `epilot target` | [reference](commands/target.md) | | Targeting API | `epilot targeting` | [reference](commands/targeting.md) | | Template Variables API | `epilot template-variables` | [reference](commands/template-variables.md) | | User API | `epilot user` | [reference](commands/user.md) | diff --git a/docs/sdk/clients/access-token.md b/docs/sdk/clients/access-token.md index 82f6e4ff..a78cf2b1 100644 --- a/docs/sdk/clients/access-token.md +++ b/docs/sdk/clients/access-token.md @@ -38,7 +38,11 @@ const { data } = await accessTokenClient.createAccessToken(...) - [`getAccessTokenJwks`](#getaccesstokenjwks) - [`getAccessTokenOIDC`](#getaccesstokenoidc) - [`getPublicTokenJwks`](#getpublictokenjwks) +- [`getPortalPreviewTokenJwks`](#getportalpreviewtokenjwks) - [`getPublicTokenOIDC`](#getpublictokenoidc) +- [`getPortalPreviewTokenOIDC`](#getportalpreviewtokenoidc) +- [`getContactIdentificationTokenJwks`](#getcontactidentificationtokenjwks) +- [`getContactIdentificationTokenOIDC`](#getcontactidentificationtokenoidc) **Schemas** - [`AccessToken`](#accesstoken) @@ -47,13 +51,20 @@ const { data } = await accessTokenClient.createAccessToken(...) - [`AccessTokenType`](#accesstokentype) - [`AccessTokenJourneyId`](#accesstokenjourneyid) - [`PortalId`](#portalid) +- [`PortalUserId`](#portaluserid) +- [`ContactId`](#contactid) +- [`AllowedOperations`](#allowedoperations) - [`TokenParameters`](#tokenparameters) - [`ExpiresIn`](#expiresin) +- [`ReadOnly`](#readonly) +- [`Anonymize`](#anonymize) - [`AccessTokenParameters`](#accesstokenparameters) - [`JourneyTokenParameters`](#journeytokenparameters) - [`PortalTokenParameters`](#portaltokenparameters) - [`AssumeTokenParameters`](#assumetokenparameters) - [`AppTokenParameters`](#apptokenparameters) +- [`PortalPreviewTokenParameters`](#portalpreviewtokenparameters) +- [`ContactIdentificationTokenParameters`](#contactidentificationtokenparameters) - [`AccessTokenItem`](#accesstokenitem) - [`RoleId`](#roleid) - [`Assignments`](#assignments) @@ -71,7 +82,9 @@ const { data } = await client.createAccessToken( name: 'Postman Access Token', token_type: 'api', assignments: ['123:owner'], - expires_in: 3600 + expires_in: 3600, + read_only: true, + anonymize: true }, ) ``` @@ -88,8 +101,14 @@ const { data } = await client.createAccessToken( "token_type": "api", "journey_id": "string", "portal_id": "string", + "portal_user_id": "string", + "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_operations": ["getContact", "getContracts"], "assignments": ["123:owner"], - "last_used": "2026-02-24" + "read_only": true, + "anonymize": true, + "last_used": "2026-02-24", + "expires_at": "2026-03-01T12:00:00.000Z" } ``` @@ -121,8 +140,14 @@ const { data } = await client.listAccessTokens({ "token_type": "api", "journey_id": "string", "portal_id": "string", + "portal_user_id": "string", + "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_operations": ["getContact", "getContracts"], "assignments": ["123:owner"], - "last_used": "2026-02-24" + "read_only": true, + "anonymize": true, + "last_used": "2026-02-24", + "expires_at": "2026-03-01T12:00:00.000Z" } ] ``` @@ -154,8 +179,14 @@ const { data } = await client.revokeAccessToken({ "token_type": "api", "journey_id": "string", "portal_id": "string", + "portal_user_id": "string", + "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_operations": ["getContact", "getContracts"], "assignments": ["123:owner"], - "last_used": "2026-02-24" + "read_only": true, + "anonymize": true, + "last_used": "2026-02-24", + "expires_at": "2026-03-01T12:00:00.000Z" } ``` @@ -251,6 +282,38 @@ const { data } = await client.getPublicTokenJwks() --- +### `getPortalPreviewTokenJwks` + +Get jwks public key set to verify portal preview tokens generated by this API + +`GET /v1/access-tokens/portal-preview/.well-known/jwks.json` + +```ts +const { data } = await client.getPortalPreviewTokenJwks() +``` + +
+Response + +```json +{ + "keys": [ + { + "alg": "RS256", + "e": "AQAB", + "kid": "tXWU5mPMbRPczpbQwi6vbhLF4GgF3wlMDSyqo7pfeiw=", + "kty": "RSA", + "n": "h_QDoCjZ8W_trtYXaP7_S22wf5r5Wd9XBLED78oT44bJjQXn8ddcFV8Hik65_4IYXVX_hTTU4zpxe3H8vx2j7-Zz3O59mYMp5S0MzODNEdf5Y_2o19eis0brmAJniixsNlQ9LlYkdrVamrgaxHu3ZpP_99zkfFybYeuYoQNzb3PyrT8xVnz_USs_nlFMHpGUxvvz7gfKPqxcLvgLJr4cwI9yzaSY9CD4qW181QVcnL_WzpQ8xx6AuhhHZQ1l_3GG4InTk8ahE7U2ZHVu8RrX6d01pMgc3piEcet9RgFLnhbTg3YIiKGoAbN42wJn_x3lgIAC42T9mbmTsHyUdS6nUQ", + "use": "sig" + } + ] +} +``` + +
+ +--- + ### `getPublicTokenOIDC` OpenID Connect configuration for Access Token API a a public identity provider @@ -275,6 +338,86 @@ const { data } = await client.getPublicTokenOIDC() --- +### `getPortalPreviewTokenOIDC` + +OpenID Connect configuration for Access Token API a a portal preview identity provider + +`GET /v1/access-tokens/portal-preview/.well-known/openid-configuration` + +```ts +const { data } = await client.getPortalPreviewTokenOIDC() +``` + +
+Response + +```json +{ + "issuer": "https://access-token.sls.epilot.io/v1/access-tokens/portal-preview", + "jwks_uri": "https://access-token.sls.epilot.io/v1/access-tokens/portal-preview/.well-known/jwks.json" +} +``` + +
+ +--- + +### `getContactIdentificationTokenJwks` + +Get jwks public key set to verify contact identification tokens generated by this API + +`GET /v1/access-tokens/contact-identification/.well-known/jwks.json` + +```ts +const { data } = await client.getContactIdentificationTokenJwks() +``` + +
+Response + +```json +{ + "keys": [ + { + "alg": "RS256", + "e": "AQAB", + "kid": "tXWU5mPMbRPczpbQwi6vbhLF4GgF3wlMDSyqo7pfeiw=", + "kty": "RSA", + "n": "h_QDoCjZ8W_trtYXaP7_S22wf5r5Wd9XBLED78oT44bJjQXn8ddcFV8Hik65_4IYXVX_hTTU4zpxe3H8vx2j7-Zz3O59mYMp5S0MzODNEdf5Y_2o19eis0brmAJniixsNlQ9LlYkdrVamrgaxHu3ZpP_99zkfFybYeuYoQNzb3PyrT8xVnz_USs_nlFMHpGUxvvz7gfKPqxcLvgLJr4cwI9yzaSY9CD4qW181QVcnL_WzpQ8xx6AuhhHZQ1l_3GG4InTk8ahE7U2ZHVu8RrX6d01pMgc3piEcet9RgFLnhbTg3YIiKGoAbN42wJn_x3lgIAC42T9mbmTsHyUdS6nUQ", + "use": "sig" + } + ] +} +``` + +
+ +--- + +### `getContactIdentificationTokenOIDC` + +OpenID Connect configuration for Access Token API as a contact identification identity provider + +`GET /v1/access-tokens/contact-identification/.well-known/openid-configuration` + +```ts +const { data } = await client.getContactIdentificationTokenOIDC() +``` + +
+Response + +```json +{ + "issuer": "https://access-token.sls.epilot.io/v1/access-tokens/contact-identification", + "jwks_uri": "https://access-token.sls.epilot.io/v1/access-tokens/contact-identification/.well-known/jwks.json" +} +``` + +
+ +--- + ## Schemas ### `AccessToken` @@ -304,7 +447,7 @@ type AccessTokenName = string Access token type ```ts -type AccessTokenType = "api" | "journey" | "portal" | "assume" | "app" +type AccessTokenType = "api" | "journey" | "portal" | "assume" | "app" | "portal_preview" | "contact_identification" ``` ### `AccessTokenJourneyId` @@ -323,6 +466,30 @@ Portal ID for access token type "portal" type PortalId = string ``` +### `PortalUserId` + +Portal User ID for access token type "portal_preview" + +```ts +type PortalUserId = string +``` + +### `ContactId` + +Contact entity ID for access token type "contact_identification" + +```ts +type ContactId = string +``` + +### `AllowedOperations` + +openapi operationIds the token may call. Enforced by the API that consumes the token, which must additionally deny any operation not on this list. Baked into the token at issue time so widening the consumer's own allowlist later cannot retroactively widen a token that is already in circulation. + +```ts +type AllowedOperations = string[] +``` + ### `TokenParameters` ```ts @@ -331,6 +498,8 @@ type TokenParameters = { token_type?: "api" assignments?: string[] expires_in?: number | string + read_only?: boolean + anonymize?: boolean } | { name: string token_type?: "journey" @@ -345,11 +514,29 @@ type TokenParameters = { name: string token_type?: "assume" assignments?: string[] + read_only?: boolean + anonymize?: boolean } | { name: string token_type?: "app" assignments?: string[] expires_in?: number | string + read_only?: boolean + anonymize?: boolean +} | { + name: string + token_type?: "portal_preview" + portal_id: string + portal_user_id: string +} | { + name: string + token_type?: "contact_identification" + portal_id: string + contact_id: string + surface_id: string + allowed_operations: string[] + expires_in: number + email?: string } ``` @@ -359,6 +546,22 @@ type TokenParameters = { type ExpiresIn = number | string ``` +### `ReadOnly` + +When true, the issued token may only perform read-only actions. Any action guarded by permissions that is not read-only (i.e. not a view/export/download action) is denied, regardless of the roles the token carries. + +```ts +type ReadOnly = boolean +``` + +### `Anonymize` + +Forces PII anonymization on all entity data returned to this token. Cannot be disabled by the token bearer. See entity-api anonymized responses. + +```ts +type Anonymize = boolean +``` + ### `AccessTokenParameters` ```ts @@ -367,6 +570,8 @@ type AccessTokenParameters = { token_type?: "api" assignments?: string[] expires_in?: number | string + read_only?: boolean + anonymize?: boolean } ``` @@ -399,6 +604,8 @@ type AssumeTokenParameters = { name: string token_type?: "assume" assignments?: string[] + read_only?: boolean + anonymize?: boolean } ``` @@ -410,6 +617,36 @@ type AppTokenParameters = { token_type?: "app" assignments?: string[] expires_in?: number | string + read_only?: boolean + anonymize?: boolean +} +``` + +### `PortalPreviewTokenParameters` + +```ts +type PortalPreviewTokenParameters = { + name: string + token_type?: "portal_preview" + portal_id: string + portal_user_id: string +} +``` + +### `ContactIdentificationTokenParameters` + +A token that acts as one contact, issued after that contact was identified by a portal's registration identifiers rather than by logging in. Distinct from portal_preview, which impersonates an existing portal user for a 360 operator: this kind belongs to no user, is minted for an unauthenticated cal + +```ts +type ContactIdentificationTokenParameters = { + name: string + token_type?: "contact_identification" + portal_id: string + contact_id: string + surface_id: string + allowed_operations: string[] + expires_in: number + email?: string } ``` @@ -420,11 +657,17 @@ type AccessTokenItem = { id: string created_at: string // date-time name: string - token_type?: "api" | "journey" | "portal" | "assume" | "app" + token_type?: "api" | "journey" | "portal" | "assume" | "app" | "portal_preview" | "contact_identification" journey_id?: string portal_id?: string + portal_user_id?: string + contact_id?: string + allowed_operations?: string[] assignments?: string[] + read_only?: boolean + anonymize?: boolean last_used?: string // date + expires_at?: string // date-time } ``` diff --git a/docs/sdk/clients/ai-agents.md b/docs/sdk/clients/ai-agents.md index 9f76b017..b738238b 100644 --- a/docs/sdk/clients/ai-agents.md +++ b/docs/sdk/clients/ai-agents.md @@ -1,9 +1,9 @@ --- -title: "AI Agents API - OpenAPI 3.0" -description: "TypeScript SDK client for the epilot AI Agents API - OpenAPI 3.0: usage with @epilot/sdk, all operations and schemas." +title: "AI Agents API" +description: "TypeScript SDK client for the epilot AI Agents API: usage with @epilot/sdk, all operations and schemas." --- -# AI Agents API - OpenAPI 3.0 +# AI Agents API - **Base URL:** `https://ai-agents.sls.epilot.io` - **Full API Docs:** [https://docs.epilot.io/api/ai-agents](https://docs.epilot.io/api/ai-agents) @@ -36,17 +36,74 @@ const { data } = await aiAgentsClient.createAgent(...) - [`updateAgentById`](#updateagentbyid) - [`deleteAgentById`](#deleteagentbyid) +**Customer Chat** +- [`listCustomerChat`](#listcustomerchat) +- [`createCustomerChatAgent`](#createcustomerchatagent) +- [`listCustomerChatCapabilities`](#listcustomerchatcapabilities) +- [`getCustomerChatAgent`](#getcustomerchatagent) +- [`renameCustomerChatAgent`](#renamecustomerchatagent) +- [`deleteCustomerChatAgent`](#deletecustomerchatagent) +- [`saveCustomerChatConfig`](#savecustomerchatconfig) + +**Knowledge** +- [`listKnowledgeSources`](#listknowledgesources) +- [`createKnowledgeFileUpload`](#createknowledgefileupload) +- [`getKnowledgeSource`](#getknowledgesource) +- [`deleteKnowledgeSource`](#deleteknowledgesource) + **Agent Execution** - [`executeAgent`](#executeagent) +- [`executeAgentStream`](#executeagentstream) - [`listExecutions`](#listexecutions) - [`getExecution`](#getexecution) - [`cancelExecution`](#cancelexecution) - [`getExecutionTrace`](#getexecutiontrace) +- [`getExecutionFeedback`](#getexecutionfeedback) +- [`putExecutionFeedback`](#putexecutionfeedback) - [`approveExecution`](#approveexecution) - [`rejectExecution`](#rejectexecution) +- [`streamExecution`](#streamexecution) + +**Chat** +- [`chat`](#chat) + +**Conversations** +- [`listConversations`](#listconversations) +- [`getConversation`](#getconversation) +- [`deleteConversation`](#deleteconversation) +- [`submitConversationFeedback`](#submitconversationfeedback) **Schemas** +- [`AgentConfig`](#agentconfig) +- [`AppearanceConfig`](#appearanceconfig) +- [`LocalizedAppearance`](#localizedappearance) +- [`LocalizedFieldList`](#localizedfieldlist) +- [`CapabilityId`](#capabilityid) +- [`ActionAutonomy`](#actionautonomy) +- [`CapabilityState`](#capabilitystate) +- [`CapabilityInstance`](#capabilityinstance) +- [`CreateCustomerChatAgentRequest`](#createcustomerchatagentrequest) +- [`CustomerChatAgent`](#customerchatagent) +- [`CustomerChatCasRequest`](#customerchatcasrequest) +- [`DeleteCustomerChatAgentRequest`](#deletecustomerchatagentrequest) +- [`CustomerChatPlace`](#customerchatplace) +- [`EscalationConfig`](#escalationconfig) +- [`CustomerChatKnowledgeSource`](#customerchatknowledgesource) +- [`CustomerChatKnowledgeSourceType`](#customerchatknowledgesourcetype) +- [`ListCustomerChatResponse`](#listcustomerchatresponse) +- [`CustomerChatCapabilityCatalogEntry`](#customerchatcapabilitycatalogentry) +- [`ListCustomerChatCapabilitiesResponse`](#listcustomerchatcapabilitiesresponse) +- [`RenameCustomerChatAgentRequest`](#renamecustomerchatagentrequest) +- [`SaveCustomerChatConfigRequest`](#savecustomerchatconfigrequest) +- [`WebsiteHandover`](#websitehandover) - [`AgentId`](#agentid) +- [`KnowledgeSourceIds`](#knowledgesourceids) +- [`KnowledgeSource`](#knowledgesource) +- [`KnowledgeFileSource`](#knowledgefilesource) +- [`CreateKnowledgeFileUploadRequest`](#createknowledgefileuploadrequest) +- [`CreateKnowledgeFileUploadResponse`](#createknowledgefileuploadresponse) +- [`ListKnowledgeSourcesResponse`](#listknowledgesourcesresponse) +- [`AgentDomain`](#agentdomain) - [`CreateAgentRequest`](#createagentrequest) - [`UpdateAgentRequest`](#updateagentrequest) - [`AgentDefinition`](#agentdefinition) @@ -56,11 +113,21 @@ const { data } = await aiAgentsClient.createAgent(...) - [`RejectExecutionRequest`](#rejectexecutionrequest) - [`ExecuteAgentRequest`](#executeagentrequest) - [`ExecutionResponse`](#executionresponse) +- [`ExecutionIterationProjection`](#executioniterationprojection) +- [`ExecutionFeedback`](#executionfeedback) +- [`ExecutionFeedbackResponse`](#executionfeedbackresponse) +- [`PutExecutionFeedbackRequest`](#putexecutionfeedbackrequest) - [`ExecutionTrace`](#executiontrace) - [`ExecutionIteration`](#executioniteration) - [`PendingAction`](#pendingaction) - [`ExecutionError`](#executionerror) - [`ExecutionMetrics`](#executionmetrics) +- [`AgentExecutionEventStatus`](#agentexecutioneventstatus) +- [`AgentExecutionEvent`](#agentexecutionevent) +- [`KnowledgeSourceRegisteredEvent`](#knowledgesourceregisteredevent) +- [`KnowledgeFileSourceRegisteredEvent`](#knowledgefilesourceregisteredevent) +- [`KnowledgeSourceDeletedEvent`](#knowledgesourcedeletedevent) +- [`KnowledgeSourceProcessingCompletedEvent`](#knowledgesourceprocessingcompletedevent) - [`ToolPreview`](#toolpreview) - [`PreviewActionType`](#previewactiontype) - [`PreviewEntity`](#previewentity) @@ -79,6 +146,17 @@ const { data } = await aiAgentsClient.createAgent(...) - [`InputParametersSchema`](#inputparametersschema) - [`ModelConfig`](#modelconfig) - [`Error`](#error) +- [`ChatRequest`](#chatrequest) +- [`ChatMessage`](#chatmessage) +- [`StreamingOptions`](#streamingoptions) +- [`StreamEvent`](#streamevent) +- [`ExecutionResult`](#executionresult) +- [`ConversationItem`](#conversationitem) +- [`MessageItem`](#messageitem) +- [`MessageFeedback`](#messagefeedback) +- [`SubmitFeedbackRequest`](#submitfeedbackrequest) +- [`ListConversationsResponse`](#listconversationsresponse) +- [`ConversationWithMessages`](#conversationwithmessages) ### `createAgent` @@ -90,6 +168,8 @@ Create Agent definition const { data } = await client.createAgent( null, { + domain: 'customer_service', + availability: ['flows'], name: 'Email Reply Generator', description: 'string', category: 'message', @@ -99,7 +179,9 @@ const { data } = await client.createAgent( model_config: { model_id: 'anthropic.claude-3-5-sonnet-20241022-v2:0', temperature: 0.7, - max_tokens: 4096 + max_tokens: 4096, + thinking: false, + thinking_budget: 10000 }, max_iterations: 10, execution_pattern: 'direct', @@ -125,7 +207,8 @@ const { data } = await client.createAgent( /* ... 1 more */ ], required: ['target_schema'] - } + }, + knowledge_source_ids: ['3fa85f64-5717-4562-b3fc-2c963f66afa6'] }, ) ``` @@ -135,6 +218,7 @@ const { data } = await client.createAgent( ```json { + "domain": "customer_service", "agent_id": "skill:email-categorizer", "org_id": "string", "name": "string", @@ -149,7 +233,9 @@ const { data } = await client.createAgent( "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 0, "execution_pattern": "direct", @@ -175,6 +261,7 @@ const { data } = await client.createAgent( ], "required": ["target_schema"] }, + "knowledge_source_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"], "version": 0, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", @@ -207,6 +294,7 @@ const { data } = await client.listAgents({ { "agents": [ { + "domain": "customer_service", "agent_id": "skill:email-categorizer", "org_id": "string", "name": "string", @@ -221,7 +309,9 @@ const { data } = await client.listAgents({ "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 0, "execution_pattern": "direct", @@ -247,6 +337,7 @@ const { data } = await client.listAgents({ ], "required": ["target_schema"] }, + "knowledge_source_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"], "version": 0, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", @@ -278,6 +369,7 @@ const { data } = await client.getAgentById({ ```json { + "domain": "customer_service", "agent_id": "skill:email-categorizer", "org_id": "string", "name": "string", @@ -292,7 +384,9 @@ const { data } = await client.getAgentById({ "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 0, "execution_pattern": "direct", @@ -318,6 +412,7 @@ const { data } = await client.getAgentById({ ], "required": ["target_schema"] }, + "knowledge_source_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"], "version": 0, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", @@ -341,6 +436,8 @@ const { data } = await client.updateAgentById( agent_id: 'example', }, { + domain: 'customer_service', + availability: ['flows'], name: 'string', description: 'string', category: 'message', @@ -350,7 +447,9 @@ const { data } = await client.updateAgentById( model_config: { model_id: 'anthropic.claude-3-5-sonnet-20241022-v2:0', temperature: 0.7, - max_tokens: 4096 + max_tokens: 4096, + thinking: false, + thinking_budget: 10000 }, max_iterations: 1, execution_pattern: 'direct', @@ -376,7 +475,8 @@ const { data } = await client.updateAgentById( /* ... 1 more */ ], required: ['target_schema'] - } + }, + knowledge_source_ids: ['3fa85f64-5717-4562-b3fc-2c963f66afa6'] }, ) ``` @@ -386,6 +486,7 @@ const { data } = await client.updateAgentById( ```json { + "domain": "customer_service", "agent_id": "skill:email-categorizer", "org_id": "string", "name": "string", @@ -400,7 +501,9 @@ const { data } = await client.updateAgentById( "model_config": { "model_id": "anthropic.claude-3-5-sonnet-20241022-v2:0", "temperature": 0.7, - "max_tokens": 4096 + "max_tokens": 4096, + "thinking": false, + "thinking_budget": 10000 }, "max_iterations": 0, "execution_pattern": "direct", @@ -426,6 +529,7 @@ const { data } = await client.updateAgentById( ], "required": ["target_schema"] }, + "knowledge_source_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"], "version": 0, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", @@ -451,39 +555,14 @@ const { data } = await client.deleteAgentById({ --- -### `executeAgent` +### `listCustomerChat` -Execute an agent +List customer chat agents -`POST /v1/agents/{agent_id}/execute` +`GET /v1/customer-chat` ```ts -const { data } = await client.executeAgent( - { - agent_id: 'example', - }, - { - input: { - entity_id: 'string', - entity_schema: 'string', - workflow_id: 'string', - workflow_execution_id: 'string', - task_id: 'string', - custom_data: {}, - flow_context: [ - { - entity_id: 'string', - entity_schema: 'string' - } - ] - }, - parameters: {}, - execution_mode_override: 'automatic', - execution_context: 'flows', - callback_url: 'https://example.com/path', - timeout_ms: 30000 - }, -) +const { data } = await client.listCustomerChat() ```
@@ -491,87 +570,82 @@ const { data } = await client.executeAgent( ```json { - "execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "agent_id": "skill:email-categorizer", - "agent_source": "system", - "agent_name": "string", - "execution_context": "flows", - "org_id": "string", - "status": "pending", - "input": {}, - "parameters": {}, - "result": { - "response": "string", - "structured_output": {} - }, - "error": { - "code": "TIMEOUT", - "message": "string", - "details": {} - }, - "pending_action": { - "tool": "string", - "input": {}, - "description": "string", - "preview": { - "action": { - "type": "move", - "verb": "Move Thread" - }, - "source": { - "type": "inbox", - "id": "string", - "name": "Support Inbox", - "schema": "string", - "icon": "string", - "url": "string" - }, - "target": { - "type": "inbox", - "id": "string", - "name": "Support Inbox", - "schema": "string", - "icon": "string", - "url": "string" - }, - "changes": [ - { - "field": "string", - "label": "string", - "from": { - "type": "text", - "value": {}, - "values": ["string"], + "agents": [ + { + "org_id": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "place": "website", + "internal_name": "string", + "runtime_agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "config": { + "capabilities": [ + { + "type": "navigate_portal_pages", + "instanceId": "string", + "enabled": true, + "meterTypes": ["string"], + "ticketType": "string", + "allowedDomains": ["string"], + "autonomy": "draft", + "label": "string", + "guidance": "string", + "blockIds": ["string"], + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "searchDeviceDocs": true + } + ], + "knowledgeSources": [ + { "id": "string", - "name": "string", - "schema": "string", - "color": "success" + "type": "portal_page", + "title": "string", + "targetId": "string", + "detail": "string" + } + ], + "escalation": { + "websiteHandover": { + "kind": "phone", + "value": "string", + "journeyId": "string", + "journeyName": "string" + } + }, + "appearance": { + "displayName": "string", + "greeting": "string", + "starters": ["string"], + "language": "de", + "formOfAddress": "sie", + "languages": ["de"], + "translations": { + "de": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + }, + "en": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + } }, - "to": { - "type": "text", - "value": {}, - "values": ["string"], - "id": "string", - "name": "string", - "schema": "string", - "color": "success" + "needsReview": { + "de": ["displayName"], + "en": ["displayName"] } - } - ], - "metadata": {}, - "summary": "This email discusses solar panel installation and should be handled by the Service team." + }, + "instructions": "string", + "instructionTranslations": { + "de": "string", + "en": "string" + }, + "instructionsNeedsReview": ["de"] + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" } - }, - "metrics": { - "total_tokens": 0, - "input_tokens": 0, - "output_tokens": 0, - "total_cost_usd": 0, - "duration_ms": 0, - "iteration_count": 0 - }, - "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + ] } ``` @@ -579,18 +653,20 @@ const { data } = await client.executeAgent( --- -### `listExecutions` +### `createCustomerChatAgent` -List executions +Create a customer chat agent with default config -`GET /v1/executions` +`POST /v1/customer-chat` ```ts -const { data } = await client.listExecutions({ - agent_id: 'example', - status: 'example', - limit: 1, -}) +const { data } = await client.createCustomerChatAgent( + null, + { + place: 'website', + internal_name: 'string' + }, +) ```
@@ -598,92 +674,78 @@ const { data } = await client.listExecutions({ ```json { - "executions": [ - { - "execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "agent_id": "skill:email-categorizer", - "agent_source": "system", - "agent_name": "string", - "execution_context": "flows", - "org_id": "string", - "status": "pending", - "input": {}, - "parameters": {}, - "result": { - "response": "string", - "structured_output": {} - }, - "error": { - "code": "TIMEOUT", - "message": "string", - "details": {} - }, - "pending_action": { - "tool": "string", - "input": {}, - "description": "string", - "preview": { - "action": { - "type": "move", - "verb": "Move Thread" - }, - "source": { - "type": "inbox", - "id": "string", - "name": "Support Inbox", - "schema": "string", - "icon": "string", - "url": "string" - }, - "target": { - "type": "inbox", - "id": "string", - "name": "Support Inbox", - "schema": "string", - "icon": "string", - "url": "string" - }, - "changes": [ - { - "field": "string", - "label": "string", - "from": { - "type": "text", - "value": {}, - "values": ["string"], - "id": "string", - "name": "string", - "schema": "string", - "color": "success" - }, - "to": { - "type": "text", - "value": {}, - "values": ["string"], - "id": "string", - "name": "string", - "schema": "string", - "color": "success" - } - } - ], - "metadata": {}, - "summary": "This email discusses solar panel installation and should be handled by the Service team." + "org_id": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "place": "website", + "internal_name": "string", + "runtime_agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "config": { + "capabilities": [ + { + "type": "navigate_portal_pages", + "instanceId": "string", + "enabled": true, + "meterTypes": ["string"], + "ticketType": "string", + "allowedDomains": ["string"], + "autonomy": "draft", + "label": "string", + "guidance": "string", + "blockIds": ["string"], + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "searchDeviceDocs": true + } + ], + "knowledgeSources": [ + { + "id": "string", + "type": "portal_page", + "title": "string", + "targetId": "string", + "detail": "string" + } + ], + "escalation": { + "websiteHandover": { + "kind": "phone", + "value": "string", + "journeyId": "string", + "journeyName": "string" + } + }, + "appearance": { + "displayName": "string", + "greeting": "string", + "starters": ["string"], + "language": "de", + "formOfAddress": "sie", + "languages": ["de"], + "translations": { + "de": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + }, + "en": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] } }, - "metrics": { - "total_tokens": 0, - "input_tokens": 0, - "output_tokens": 0, - "total_cost_usd": 0, - "duration_ms": 0, - "iteration_count": 0 - }, - "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" - } - ], - "next_cursor": "string" + "needsReview": { + "de": ["displayName"], + "en": ["displayName"] + } + }, + "instructions": "string", + "instructionTranslations": { + "de": "string", + "en": "string" + }, + "instructionsNeedsReview": ["de"] + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" } ``` @@ -691,16 +753,14 @@ const { data } = await client.listExecutions({ --- -### `getExecution` +### `listCustomerChatCapabilities` -Get execution by ID +List the capability catalog -`GET /v1/executions/{execution_id}` +`GET /v1/customer-chat/capabilities` ```ts -const { data } = await client.getExecution({ - execution_id: 'example', -}) +const { data } = await client.listCustomerChatCapabilities() ```
@@ -708,17 +768,862 @@ const { data } = await client.getExecution({ ```json { - "execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "agent_id": "skill:email-categorizer", - "agent_source": "system", - "agent_name": "string", - "execution_context": "flows", - "org_id": "string", - "status": "pending", - "input": {}, - "parameters": {}, - "result": { - "response": "string", + "capabilities": [ + { + "id": "navigate_portal_pages", + "places": ["website"], + "singleInstance": true, + "requiresIntegration": true + } + ] +} +``` + +
+ +--- + +### `getCustomerChatAgent` + +Get a customer chat agent + +`GET /v1/customer-chat/{agent_id}` + +```ts +const { data } = await client.getCustomerChatAgent({ + agent_id: 'example', +}) +``` + +
+Response + +```json +{ + "org_id": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "place": "website", + "internal_name": "string", + "runtime_agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "config": { + "capabilities": [ + { + "type": "navigate_portal_pages", + "instanceId": "string", + "enabled": true, + "meterTypes": ["string"], + "ticketType": "string", + "allowedDomains": ["string"], + "autonomy": "draft", + "label": "string", + "guidance": "string", + "blockIds": ["string"], + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "searchDeviceDocs": true + } + ], + "knowledgeSources": [ + { + "id": "string", + "type": "portal_page", + "title": "string", + "targetId": "string", + "detail": "string" + } + ], + "escalation": { + "websiteHandover": { + "kind": "phone", + "value": "string", + "journeyId": "string", + "journeyName": "string" + } + }, + "appearance": { + "displayName": "string", + "greeting": "string", + "starters": ["string"], + "language": "de", + "formOfAddress": "sie", + "languages": ["de"], + "translations": { + "de": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + }, + "en": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + } + }, + "needsReview": { + "de": ["displayName"], + "en": ["displayName"] + } + }, + "instructions": "string", + "instructionTranslations": { + "de": "string", + "en": "string" + }, + "instructionsNeedsReview": ["de"] + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `renameCustomerChatAgent` + +Rename a customer chat agent + +`PATCH /v1/customer-chat/{agent_id}` + +```ts +const { data } = await client.renameCustomerChatAgent( + { + agent_id: 'example', + If-Match: 'example', + }, + { + internal_name: 'string', + updated_at: '1970-01-01T00:00:00.000Z' + }, +) +``` + +
+Response + +```json +{ + "org_id": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "place": "website", + "internal_name": "string", + "runtime_agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "config": { + "capabilities": [ + { + "type": "navigate_portal_pages", + "instanceId": "string", + "enabled": true, + "meterTypes": ["string"], + "ticketType": "string", + "allowedDomains": ["string"], + "autonomy": "draft", + "label": "string", + "guidance": "string", + "blockIds": ["string"], + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "searchDeviceDocs": true + } + ], + "knowledgeSources": [ + { + "id": "string", + "type": "portal_page", + "title": "string", + "targetId": "string", + "detail": "string" + } + ], + "escalation": { + "websiteHandover": { + "kind": "phone", + "value": "string", + "journeyId": "string", + "journeyName": "string" + } + }, + "appearance": { + "displayName": "string", + "greeting": "string", + "starters": ["string"], + "language": "de", + "formOfAddress": "sie", + "languages": ["de"], + "translations": { + "de": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + }, + "en": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + } + }, + "needsReview": { + "de": ["displayName"], + "en": ["displayName"] + } + }, + "instructions": "string", + "instructionTranslations": { + "de": "string", + "en": "string" + }, + "instructionsNeedsReview": ["de"] + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteCustomerChatAgent` + +Remove a customer chat agent and its runtime projection + +`DELETE /v1/customer-chat/{agent_id}` + +```ts +const { data } = await client.deleteCustomerChatAgent( + { + agent_id: 'example', + If-Match: 'example', + }, + { + updated_at: '1970-01-01T00:00:00.000Z', + portal_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + }, +) +``` + +--- + +### `saveCustomerChatConfig` + +Replace the AgentConfig and compile the runtime AgentRecord + +`PUT /v1/customer-chat/{agent_id}/config` + +```ts +const { data } = await client.saveCustomerChatConfig( + { + agent_id: 'example', + If-Match: 'example', + }, + { + config: { + capabilities: [ + { + type: 'navigate_portal_pages', + instanceId: 'string', + enabled: true, + meterTypes: ['string'], + ticketType: 'string', + allowedDomains: ['string'], + autonomy: 'draft', + label: 'string', + guidance: 'string', + blockIds: ['string'], + integrationId: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + searchDeviceDocs: true + } + ], + knowledgeSources: [ + { + id: 'string', + type: 'portal_page', + title: 'string', + targetId: 'string', + detail: 'string' + } + ], + escalation: { + websiteHandover: { + kind: 'phone', + value: 'string', + journeyId: 'string', + journeyName: 'string' + } + }, + appearance: { + displayName: 'string', + greeting: 'string', + starters: ['string'], + language: 'de', + formOfAddress: 'sie', + languages: ['de'], + translations: { + de: { + displayName: 'string', + greeting: 'string', + starters: ['string'] + }, + en: { + displayName: 'string', + greeting: 'string', + starters: ['string'] + } + }, + needsReview: { + de: ['displayName'], + en: ['displayName'] + } + }, + instructions: 'string', + instructionTranslations: { + de: 'string', + en: 'string' + }, + instructionsNeedsReview: ['de'] + }, + updated_at: '1970-01-01T00:00:00.000Z' + }, +) +``` + +
+Response + +```json +{ + "org_id": "string", + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "place": "website", + "internal_name": "string", + "runtime_agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "config": { + "capabilities": [ + { + "type": "navigate_portal_pages", + "instanceId": "string", + "enabled": true, + "meterTypes": ["string"], + "ticketType": "string", + "allowedDomains": ["string"], + "autonomy": "draft", + "label": "string", + "guidance": "string", + "blockIds": ["string"], + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "searchDeviceDocs": true + } + ], + "knowledgeSources": [ + { + "id": "string", + "type": "portal_page", + "title": "string", + "targetId": "string", + "detail": "string" + } + ], + "escalation": { + "websiteHandover": { + "kind": "phone", + "value": "string", + "journeyId": "string", + "journeyName": "string" + } + }, + "appearance": { + "displayName": "string", + "greeting": "string", + "starters": ["string"], + "language": "de", + "formOfAddress": "sie", + "languages": ["de"], + "translations": { + "de": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + }, + "en": { + "displayName": "string", + "greeting": "string", + "starters": ["string"] + } + }, + "needsReview": { + "de": ["displayName"], + "en": ["displayName"] + } + }, + "instructions": "string", + "instructionTranslations": { + "de": "string", + "en": "string" + }, + "instructionsNeedsReview": ["de"] + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listKnowledgeSources` + +List knowledge sources + +`GET /v1/knowledge/sources` + +```ts +const { data } = await client.listKnowledgeSources() +``` + +
+Response + +```json +{ + "sources": [ + { + "type": "file", + "source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "filename": "string", + "mime_type": "string", + "size_bytes": 0, + "ready": true, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `createKnowledgeFileUpload` + +Create a knowledge file upload + +`POST /v1/knowledge/file-uploads` + +```ts +const { data } = await client.createKnowledgeFileUpload( + null, + { + filename: 'string', + mime_type: 'string', + size_bytes: 1 + }, +) +``` + +
+Response + +```json +{ + "source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "upload_url": "https://example.com/path", + "upload_fields": {}, + "expires_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getKnowledgeSource` + +Get a knowledge source + +`GET /v1/knowledge/sources/{source_id}` + +```ts +const { data } = await client.getKnowledgeSource({ + source_id: 'example', +}) +``` + +
+Response + +```json +{ + "type": "file", + "source_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "filename": "string", + "mime_type": "string", + "size_bytes": 0, + "ready": true, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteKnowledgeSource` + +Delete a knowledge source + +`DELETE /v1/knowledge/sources/{source_id}` + +```ts +const { data } = await client.deleteKnowledgeSource({ + source_id: 'example', +}) +``` + +--- + +### `executeAgent` + +Execute an agent + +`POST /v1/agents/{agent_id}/execute` + +```ts +const { data } = await client.executeAgent( + { + agent_id: 'example', + }, + { + mode: 'auto', + input: { + message: 'string', + entity_id: 'string', + entity_schema: 'string', + workflow_id: 'string', + workflow_execution_id: 'string', + task_id: 'string', + custom_data: {}, + flow_context: [ + { + entity_id: 'string', + entity_schema: 'string' + } + ], + attachment: { + s3ref: { + bucket: 'string', + key: 'string' + }, + mime_type: 'string', + filename: 'string' + } + }, + parameters: {}, + execution_mode_override: 'automatic', + execution_context: 'flows', + callback_url: 'https://example.com/path', + timeout_ms: 30000 + }, +) +``` + +
+Response + +```json +{ + "execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "agent_id": "skill:email-categorizer", + "agent_source": "system", + "agent_name": "string", + "execution_context": "flows", + "org_id": "string", + "status": "pending", + "input": {}, + "parameters": {}, + "result": { + "response": "string", + "structured_output": {} + }, + "error": { + "code": "TIMEOUT", + "message": "string", + "details": {} + }, + "pending_action": { + "tool": "string", + "input": {}, + "description": "string", + "preview": { + "action": { + "type": "move", + "verb": "Move Thread" + }, + "source": { + "type": "inbox", + "id": "string", + "name": "Support Inbox", + "schema": "string", + "icon": "string", + "url": "string" + }, + "target": { + "type": "inbox", + "id": "string", + "name": "Support Inbox", + "schema": "string", + "icon": "string", + "url": "string" + }, + "changes": [ + { + "field": "string", + "label": "string", + "from": { + "type": "text", + "value": {}, + "values": ["string"], + "id": "string", + "name": "string", + "schema": "string", + "color": "success" + }, + "to": { + "type": "text", + "value": {}, + "values": ["string"], + "id": "string", + "name": "string", + "schema": "string", + "color": "success" + } + } + ], + "metadata": {}, + "summary": "This email discusses solar panel installation and should be handled by the Service team." + } + }, + "metrics": { + "total_tokens": 0, + "input_tokens": 0, + "output_tokens": 0, + "total_cost_usd": 0, + "duration_ms": 0, + "iteration_count": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `executeAgentStream` + +Execute an agent with streaming response + +`POST /v1/agents/{agent_id}/execute/stream` + +```ts +const { data } = await client.executeAgentStream( + { + agent_id: 'example', + }, + { + mode: 'auto', + input: { + message: 'string', + entity_id: 'string', + entity_schema: 'string', + workflow_id: 'string', + workflow_execution_id: 'string', + task_id: 'string', + custom_data: {}, + flow_context: [ + { + entity_id: 'string', + entity_schema: 'string' + } + ], + attachment: { + s3ref: { + bucket: 'string', + key: 'string' + }, + mime_type: 'string', + filename: 'string' + } + }, + parameters: {}, + execution_mode_override: 'automatic', + execution_context: 'flows', + callback_url: 'https://example.com/path', + timeout_ms: 30000 + }, +) +``` + +--- + +### `listExecutions` + +List executions + +`GET /v1/executions` + +```ts +const { data } = await client.listExecutions({ + agent_id: 'example', + status: 'example', + limit: 1, +}) +``` + +
+Response + +```json +{ + "executions": [ + { + "execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "agent_id": "skill:email-categorizer", + "agent_source": "system", + "agent_name": "string", + "execution_context": "flows", + "org_id": "string", + "status": "pending", + "input": {}, + "parameters": {}, + "result": { + "response": "string", + "structured_output": {} + }, + "error": { + "code": "TIMEOUT", + "message": "string", + "details": {} + }, + "pending_action": { + "tool": "string", + "input": {}, + "description": "string", + "preview": { + "action": { + "type": "move", + "verb": "Move Thread" + }, + "source": { + "type": "inbox", + "id": "string", + "name": "Support Inbox", + "schema": "string", + "icon": "string", + "url": "string" + }, + "target": { + "type": "inbox", + "id": "string", + "name": "Support Inbox", + "schema": "string", + "icon": "string", + "url": "string" + }, + "changes": [ + { + "field": "string", + "label": "string", + "from": { + "type": "text", + "value": {}, + "values": ["string"], + "id": "string", + "name": "string", + "schema": "string", + "color": "success" + }, + "to": { + "type": "text", + "value": {}, + "values": ["string"], + "id": "string", + "name": "string", + "schema": "string", + "color": "success" + } + } + ], + "metadata": {}, + "summary": "This email discusses solar panel installation and should be handled by the Service team." + } + }, + "metrics": { + "total_tokens": 0, + "input_tokens": 0, + "output_tokens": 0, + "total_cost_usd": 0, + "duration_ms": 0, + "iteration_count": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `getExecution` + +Get execution by ID + +`GET /v1/executions/{execution_id}` + +```ts +const { data } = await client.getExecution({ + execution_id: 'example', +}) +``` + +
+Response + +```json +{ + "execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "agent_id": "skill:email-categorizer", + "agent_source": "system", + "agent_name": "string", + "execution_context": "flows", + "org_id": "string", + "status": "pending", + "input": {}, + "parameters": {}, + "result": { + "response": "string", "structured_output": {} }, "error": { @@ -788,7 +1693,15 @@ const { data } = await client.getExecution({ "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -893,7 +1806,15 @@ const { data } = await client.cancelExecution({ "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -941,6 +1862,72 @@ const { data } = await client.getExecutionTrace({ --- +### `getExecutionFeedback` + +Get execution feedback + +`GET /v1/executions/{execution_id}/feedback` + +```ts +const { data } = await client.getExecutionFeedback({ + execution_id: 'example', +}) +``` + +
+Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +### `putExecutionFeedback` + +Submit execution feedback + +`PUT /v1/executions/{execution_id}/feedback` + +```ts +const { data } = await client.putExecutionFeedback( + { + execution_id: 'example', + }, + { + rating: 'up', + comment: 'string' + }, +) +``` + +
+Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + ### `approveExecution` Approve pending action @@ -953,7 +1940,9 @@ const { data } = await client.approveExecution( execution_id: 'example', }, { - reason: 'string' + reason: 'string', + approved_action_ids: ['string'], + rejected_action_ids: ['string'] }, ) ``` @@ -1043,7 +2032,15 @@ const { data } = await client.approveExecution( "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -1153,15 +2150,635 @@ const { data } = await client.rejectExecution( "iteration_count": 0 }, "started_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" + "completed_at": "1970-01-01T00:00:00.000Z", + "iterations": [ + { + "index": 0, + "tool": "string", + "status": "running", + "timestamp": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `streamExecution` + +Reconnect to execution stream + +`GET /v1/executions/{execution_id}/stream` + +```ts +const { data } = await client.streamExecution({ + execution_id: 'example', + from_sequence: 1, +}) +``` + +--- + +### `chat` + +Streaming chat with AI agent + +`POST /v1/chat` + +```ts +const { data } = await client.chat( + null, + { + agentId: 'string', + message: 'string', + conversationId: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + clientHistory: [ + { + role: 'user', + content: 'string', + tool_calls: [ + { + id: 'string', + name: 'string', + input: {}, + output: 'string' + } + ] + } + ], + context: { + entityId: 'string', + customData: {} + }, + streaming: { + mode: 'updates', + streamTokens: false, + includeMetadata: false + }, + preview_demo: true + }, +) +``` + +--- + +### `listConversations` + +List conversations + +`GET /v1/conversations` + +```ts +const { data } = await client.listConversations({ + agent_id: 'example', + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "conversations": [ + { + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "user_id": "string", + "agent_id": "string", + "title": "string", + "message_count": 0, + "last_message": "string", + "last_message_at": "1970-01-01T00:00:00.000Z", + "context": { + "entityId": "string", + "customData": {} + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `getConversation` + +Get conversation with messages + +`GET /v1/conversations/{conversation_id}` + +```ts +const { data } = await client.getConversation({ + conversation_id: 'example', + message_limit: 1, +}) +``` + +
+Response + +```json +{ + "conversation": { + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "user_id": "string", + "agent_id": "string", + "title": "string", + "message_count": 0, + "last_message": "string", + "last_message_at": "1970-01-01T00:00:00.000Z", + "context": { + "entityId": "string", + "customData": {} + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + }, + "messages": [ + { + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "role": "user", + "content": "string", + "timestamp": "1970-01-01T00:00:00.000Z", + "tool_calls": [ + { + "id": "string", + "name": "string", + "input": {}, + "output": "string" + } + ], + "token_count": 0, + "trace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } + } + ] +} +``` + +
+ +--- + +### `deleteConversation` + +Delete conversation + +`DELETE /v1/conversations/{conversation_id}` + +```ts +const { data } = await client.deleteConversation({ + conversation_id: 'example', +}) +``` + +--- + +### `submitConversationFeedback` + +Submit feedback for an assistant turn + +`POST /v1/conversations/{conversation_id}/feedback` + +```ts +const { data } = await client.submitConversationFeedback( + { + conversation_id: 'example', + }, + { + trace_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + rating: 'up', + comment: 'string' + }, +) +``` + +
+Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +## Schemas + +### `AgentConfig` + +```ts +type AgentConfig = { + capabilities: Array<{ + type: "navigate_portal_pages" | "search_portal_records" | "view_billing" | "view_meter_readings" | "view_contracts" | "search_web" | "open_quick_actions" | "view_hems_energy" + instanceId?: string + enabled: boolean + meterTypes?: string[] + ticketType?: string + allowedDomains?: string[] + autonomy?: "draft" | "approval" | "automatic" + label?: string + guidance?: string + blockIds?: string[] + integrationId?: string // uuid + searchDeviceDocs?: boolean + }> + knowledgeSources: Array<{ + id: string + type: "portal_page" | "document" | "catalogue" | "url" + title: string + targetId: string + detail?: string + }> + escalation: { + websiteHandover: { + kind: { ... } + value: { ... } + journeyId?: { ... } + journeyName?: { ... } + } + } + appearance: { + displayName: string + greeting: string + starters: string[] + language: "de" | "en" + formOfAddress: "sie" | "du" + languages?: "de" | "en"[] + translations?: { + de?: { ... } + en?: { ... } + } + needsReview?: { + de?: { ... } + en?: { ... } + } + } + instructions?: string + instructionTranslations?: { + de?: string + en?: string + } + instructionsNeedsReview?: "de" | "en"[] +} +``` + +### `AppearanceConfig` + +```ts +type AppearanceConfig = { + displayName: string + greeting: string + starters: string[] + language: "de" | "en" + formOfAddress: "sie" | "du" + languages?: "de" | "en"[] + translations?: { + de?: { + displayName: { ... } + greeting: { ... } + starters: { ... } + } + en?: { + displayName: { ... } + greeting: { ... } + starters: { ... } + } + } + needsReview?: { + de?: "displayName" | "greeting" | "starters"[] + en?: "displayName" | "greeting" | "starters"[] + } +} +``` + +### `LocalizedAppearance` + +```ts +type LocalizedAppearance = { + displayName: string + greeting: string + starters: string[] +} +``` + +### `LocalizedFieldList` + +```ts +type LocalizedFieldList = "displayName" | "greeting" | "starters"[] +``` + +### `CapabilityId` + +```ts +type CapabilityId = "navigate_portal_pages" | "search_portal_records" | "view_billing" | "view_meter_readings" | "view_contracts" | "search_web" | "open_quick_actions" | "view_hems_energy" +``` + +### `ActionAutonomy` + +Action capabilities only (`open_quick_actions`): per-capability autonomy. +`draft` = suggest only (proposal + deep link, nothing opens), +`approval` = the customer confirms in a card first, +`automatic` = run immediately. Defaults to `approval` when the +capability is enabled without one; unknown values + +```ts +type ActionAutonomy = "draft" | "approval" | "automatic" +``` + +### `CapabilityState` + +```ts +type CapabilityState = { + enabled: boolean + meterTypes?: string[] + ticketType?: string + allowedDomains?: string[] + autonomy?: "draft" | "approval" | "automatic" + label?: string + guidance?: string + blockIds?: string[] + integrationId?: string // uuid + searchDeviceDocs?: boolean +} +``` + +### `CapabilityInstance` + +```ts +type CapabilityInstance = { + type: "navigate_portal_pages" | "search_portal_records" | "view_billing" | "view_meter_readings" | "view_contracts" | "search_web" | "open_quick_actions" | "view_hems_energy" + instanceId?: string + enabled: boolean + meterTypes?: string[] + ticketType?: string + allowedDomains?: string[] + autonomy?: "draft" | "approval" | "automatic" + label?: string + guidance?: string + blockIds?: string[] + integrationId?: string // uuid + searchDeviceDocs?: boolean +} +``` + +### `CreateCustomerChatAgentRequest` + +```ts +type CreateCustomerChatAgentRequest = { + place: "website" | "portal" + internal_name?: string +} +``` + +### `CustomerChatAgent` + +```ts +type CustomerChatAgent = { + org_id: string + agent_id: string // uuid + place: "website" | "portal" + internal_name: string + runtime_agent_id: string // uuid + config: { + capabilities: Array<{ + type: { ... } + instanceId?: { ... } + enabled: { ... } + meterTypes?: { ... } + ticketType?: { ... } + allowedDomains?: { ... } + autonomy?: { ... } + label?: { ... } + guidance?: { ... } + blockIds?: { ... } + integrationId?: { ... } + searchDeviceDocs?: { ... } + }> + knowledgeSources: Array<{ + id: { ... } + type: { ... } + title: { ... } + targetId: { ... } + detail?: { ... } + }> + escalation: { + websiteHandover: { ... } + } + appearance: { + displayName: { ... } + greeting: { ... } + starters: { ... } + language: { ... } + formOfAddress: { ... } + languages?: { ... } + translations?: { ... } + needsReview?: { ... } + } + instructions?: string + instructionTranslations?: { + de?: { ... } + en?: { ... } + } + instructionsNeedsReview?: "de" | "en"[] + } + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `CustomerChatCasRequest` + +```ts +type CustomerChatCasRequest = { + updated_at?: string // date-time +} +``` + +### `DeleteCustomerChatAgentRequest` + +```ts +type DeleteCustomerChatAgentRequest = { + updated_at?: string // date-time + portal_id?: string // uuid +} +``` + +### `CustomerChatPlace` + +```ts +type CustomerChatPlace = "website" | "portal" +``` + +### `EscalationConfig` + +```ts +type EscalationConfig = { + websiteHandover: { + kind: "phone" | "email" | "journey" | "unset" + value: string + journeyId?: string + journeyName?: string + } +} +``` + +### `CustomerChatKnowledgeSource` + +```ts +type CustomerChatKnowledgeSource = { + id: string + type: "portal_page" | "document" | "catalogue" | "url" + title: string + targetId: string + detail?: string +} +``` + +### `CustomerChatKnowledgeSourceType` + +```ts +type CustomerChatKnowledgeSourceType = "portal_page" | "document" | "catalogue" | "url" +``` + +### `ListCustomerChatResponse` + +```ts +type ListCustomerChatResponse = { + agents: Array<{ + org_id: string + agent_id: string // uuid + place: "website" | "portal" + internal_name: string + runtime_agent_id: string // uuid + config: { + capabilities: { ... } + knowledgeSources: { ... } + escalation: { ... } + appearance: { ... } + instructions?: { ... } + instructionTranslations?: { ... } + instructionsNeedsReview?: { ... } + } + created_at: string // date-time + updated_at: string // date-time + }> +} +``` + +### `CustomerChatCapabilityCatalogEntry` + +```ts +type CustomerChatCapabilityCatalogEntry = { + id: "navigate_portal_pages" | "search_portal_records" | "view_billing" | "view_meter_readings" | "view_contracts" | "search_web" | "open_quick_actions" | "view_hems_energy" + places: "website" | "portal"[] + singleInstance?: boolean + requiresIntegration?: boolean +} +``` + +### `ListCustomerChatCapabilitiesResponse` + +```ts +type ListCustomerChatCapabilitiesResponse = { + capabilities: Array<{ + id: "navigate_portal_pages" | "search_portal_records" | "view_billing" | "view_meter_readings" | "view_contracts" | "search_web" | "open_quick_actions" | "view_hems_energy" + places: "website" | "portal"[] + singleInstance?: boolean + requiresIntegration?: boolean + }> +} +``` + +### `RenameCustomerChatAgentRequest` + +```ts +type RenameCustomerChatAgentRequest = { + internal_name: string + updated_at?: string // date-time } ``` -
+### `SaveCustomerChatConfigRequest` ---- +```ts +type SaveCustomerChatConfigRequest = { + config: { + capabilities: Array<{ + type: { ... } + instanceId?: { ... } + enabled: { ... } + meterTypes?: { ... } + ticketType?: { ... } + allowedDomains?: { ... } + autonomy?: { ... } + label?: { ... } + guidance?: { ... } + blockIds?: { ... } + integrationId?: { ... } + searchDeviceDocs?: { ... } + }> + knowledgeSources: Array<{ + id: { ... } + type: { ... } + title: { ... } + targetId: { ... } + detail?: { ... } + }> + escalation: { + websiteHandover: { ... } + } + appearance: { + displayName: { ... } + greeting: { ... } + starters: { ... } + language: { ... } + formOfAddress: { ... } + languages?: { ... } + translations?: { ... } + needsReview?: { ... } + } + instructions?: string + instructionTranslations?: { + de?: { ... } + en?: { ... } + } + instructionsNeedsReview?: "de" | "en"[] + } + updated_at?: string // date-time +} +``` -## Schemas +### `WebsiteHandover` + +```ts +type WebsiteHandover = { + kind: "phone" | "email" | "journey" | "unset" + value: string + journeyId?: string + journeyName?: string +} +``` ### `AgentId` @@ -1174,10 +2791,96 @@ Agent identifier. Can be either: type AgentId = string ``` +### `KnowledgeSourceIds` + +Knowledge source IDs available to this agent. An empty array clears the selection. + +```ts +type KnowledgeSourceIds = string // uuid[] +``` + +### `KnowledgeSource` + +```ts +type KnowledgeSource = { + type: "file" + source_id: string // uuid + filename: string + mime_type: string + size_bytes: number + ready: boolean + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `KnowledgeFileSource` + +```ts +type KnowledgeFileSource = { + type: "file" + source_id: string // uuid + filename: string + mime_type: string + size_bytes: number + ready: boolean + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `CreateKnowledgeFileUploadRequest` + +```ts +type CreateKnowledgeFileUploadRequest = { + filename: string + mime_type: string + size_bytes: number +} +``` + +### `CreateKnowledgeFileUploadResponse` + +```ts +type CreateKnowledgeFileUploadResponse = { + source_id: string // uuid + upload_url: string // uri + upload_fields: Record + expires_at: string // date-time +} +``` + +### `ListKnowledgeSourcesResponse` + +```ts +type ListKnowledgeSourcesResponse = { + sources: Array<{ + type: "file" + source_id: string // uuid + filename: string + mime_type: string + size_bytes: number + ready: boolean + created_at: string // date-time + updated_at: string // date-time + }> +} +``` + +### `AgentDomain` + +Business domain selected in the agent builder. + +```ts +type AgentDomain = "customer_service" | "sales" | "billing" | "metering_grid" | "other" +``` + ### `CreateAgentRequest` ```ts type CreateAgentRequest = { + domain?: "customer_service" | "sales" | "billing" | "metering_grid" | "other" + availability?: "flows" | "copilot" | "portals" | "website" | "all"[] name: string description?: string category?: "message" | "entity" | "document" | "classification" | "custom" @@ -1188,6 +2891,8 @@ type CreateAgentRequest = { model_id?: string temperature?: number max_tokens?: number + thinking?: boolean + thinking_budget?: number } max_iterations?: number execution_pattern: "direct" | "react" @@ -1212,9 +2917,11 @@ type CreateAgentRequest = { maxLength?: { ... } schemaFilter?: { ... } attributeTypeFilter?: { ... } + hidden?: { ... } }> required?: string[] } + knowledge_source_ids?: string // uuid[] } ``` @@ -1222,6 +2929,8 @@ type CreateAgentRequest = { ```ts type UpdateAgentRequest = { + domain?: "customer_service" | "sales" | "billing" | "metering_grid" | "other" + availability?: "flows" | "copilot" | "portals" | "website" | "all"[] name?: string description?: string category?: "message" | "entity" | "document" | "classification" | "custom" @@ -1232,6 +2941,8 @@ type UpdateAgentRequest = { model_id?: string temperature?: number max_tokens?: number + thinking?: boolean + thinking_budget?: number } max_iterations?: number execution_pattern?: "direct" | "react" @@ -1256,9 +2967,11 @@ type UpdateAgentRequest = { maxLength?: { ... } schemaFilter?: { ... } attributeTypeFilter?: { ... } + hidden?: { ... } }> required?: string[] } + knowledge_source_ids?: string // uuid[] } ``` @@ -1266,6 +2979,7 @@ type UpdateAgentRequest = { ```ts type AgentDefinition = { + domain?: "customer_service" | "sales" | "billing" | "metering_grid" | "other" agent_id?: string org_id?: string name?: string @@ -1273,7 +2987,7 @@ type AgentDefinition = { category?: "message" | "entity" | "document" | "classification" | "custom" icon?: string source?: "system" | "custom" - availability?: "flows" | "copilot" | "all"[] + availability?: "flows" | "copilot" | "portals" | "website" | "all"[] allowed_entity_schemas?: string[] system_prompt?: string tools?: string[] @@ -1281,6 +2995,8 @@ type AgentDefinition = { model_id?: string temperature?: number max_tokens?: number + thinking?: boolean + thinking_budget?: number } max_iterations?: number execution_pattern?: "direct" | "react" @@ -1305,9 +3021,11 @@ type AgentDefinition = { maxLength?: { ... } schemaFilter?: { ... } attributeTypeFilter?: { ... } + hidden?: { ... } }> required?: string[] } + knowledge_source_ids?: string // uuid[] version?: number created_at?: string // date-time updated_at?: string // date-time @@ -1320,6 +3038,7 @@ type AgentDefinition = { ```ts type ListAgentsResponse = { agents?: Array<{ + domain?: "customer_service" | "sales" | "billing" | "metering_grid" | "other" agent_id?: string org_id?: string name?: string @@ -1327,7 +3046,7 @@ type ListAgentsResponse = { category?: "message" | "entity" | "document" | "classification" | "custom" icon?: string source?: "system" | "custom" - availability?: "flows" | "copilot" | "all"[] + availability?: "flows" | "copilot" | "portals" | "website" | "all"[] allowed_entity_schemas?: string[] system_prompt?: string tools?: string[] @@ -1335,6 +3054,8 @@ type ListAgentsResponse = { model_id?: { ... } temperature?: { ... } max_tokens?: { ... } + thinking?: { ... } + thinking_budget?: { ... } } max_iterations?: number execution_pattern?: "direct" | "react" @@ -1345,6 +3066,7 @@ type ListAgentsResponse = { parameters: { ... } required?: { ... } } + knowledge_source_ids?: string // uuid[] version?: number created_at?: string // date-time updated_at?: string // date-time @@ -1363,9 +3085,9 @@ type ListExecutionsResponse = { agent_id?: string agent_source?: "system" | "custom" agent_name?: string - execution_context?: "flows" | "copilot" | "api" + execution_context?: "flows" | "copilot" | "api" | "sharing" org_id?: string - status?: "pending" | "running" | "waiting_approval" | "completed" | "failed" | "cancelled" + status?: "pending" | "queued" | "running" | "waiting_approval" | "completed" | "failed" | "cancelled" input?: object parameters?: object result?: { @@ -1393,6 +3115,12 @@ type ListExecutionsResponse = { } started_at?: string // date-time completed_at?: string // date-time + iterations?: Array<{ + index?: { ... } + tool?: { ... } + status?: { ... } + timestamp?: { ... } + }> }> next_cursor?: string } @@ -1403,6 +3131,8 @@ type ListExecutionsResponse = { ```ts type ApproveExecutionRequest = { reason?: string + approved_action_ids?: string[] + rejected_action_ids?: string[] } ``` @@ -1418,7 +3148,9 @@ type RejectExecutionRequest = { ```ts type ExecuteAgentRequest = { + mode?: "auto" | "stream" | "async" | "sync" input?: { + message?: string entity_id?: string entity_schema?: string workflow_id?: string @@ -1429,10 +3161,15 @@ type ExecuteAgentRequest = { entity_id: { ... } entity_schema: { ... } }> + attachment?: { + s3ref: { ... } + mime_type: { ... } + filename?: { ... } + } } parameters?: Record execution_mode_override?: "automatic" | "approval" | "draft" - execution_context?: "flows" | "copilot" | "api" + execution_context?: "flows" | "copilot" | "api" | "sharing" callback_url?: string // uri timeout_ms?: number } @@ -1446,9 +3183,9 @@ type ExecutionResponse = { agent_id?: string agent_source?: "system" | "custom" agent_name?: string - execution_context?: "flows" | "copilot" | "api" + execution_context?: "flows" | "copilot" | "api" | "sharing" org_id?: string - status?: "pending" | "running" | "waiting_approval" | "completed" | "failed" | "cancelled" + status?: "pending" | "queued" | "running" | "waiting_approval" | "completed" | "failed" | "cancelled" input?: object parameters?: object result?: { @@ -1483,6 +3220,56 @@ type ExecutionResponse = { } started_at?: string // date-time completed_at?: string // date-time + iterations?: Array<{ + index?: number + tool?: string + status?: "running" | "completed" + timestamp?: string // date-time + }> +} +``` + +### `ExecutionIterationProjection` + +```ts +type ExecutionIterationProjection = { + index?: number + tool?: string + status?: "running" | "completed" + timestamp?: string // date-time +} +``` + +### `ExecutionFeedback` + +```ts +type ExecutionFeedback = { + rating: "up" | "down" + comment?: string + user_id: string + submitted_at: string // date-time +} +``` + +### `ExecutionFeedbackResponse` + +```ts +type ExecutionFeedbackResponse = { + feedback: { + rating: "up" | "down" + comment?: string + user_id: string + submitted_at: string // date-time + } +} +``` + +### `PutExecutionFeedbackRequest` + +```ts +type PutExecutionFeedbackRequest = { + rating: "up" | "down" + comment?: string } ``` @@ -1597,6 +3384,111 @@ type ExecutionMetrics = { } ``` +### `AgentExecutionEventStatus` + +Lifecycle status carried on an agent execution event. + +Deliberately narrower than `ExecutionStatus`, which is the stored status of +the execution row: `pending` and `running` both surface as `started`, and +`cancelled` surfaces as `failed`. Consumers must not assume the two +vocabularies are interchang + +```ts +type AgentExecutionEventStatus = "started" | "queued" | "completed" | "failed" | "approval_required" +``` + +### `AgentExecutionEvent` + +Detail payload of the `agent-execution-status-update` event, published on +the AI Agents event bus with source `ai-agents`. + +`execution_context` and `input` are present on every status, so a consumer +can tell whether an execution is theirs, and what it belonged to, from the +terminal event alone — wit + +```ts +type AgentExecutionEvent = { + executionId: string + agentId: string + orgId: string + userId?: string + execution_status: "started" | "queued" | "completed" | "failed" | "approval_required" + execution_context?: "flows" | "copilot" | "api" | "sharing" + input?: Record + output?: Record + error?: { + message?: string + code?: string + stack?: string + } + duration?: number + iterations?: number + iteration?: number + message?: string + toolCalls?: Array<{ + name?: string + args?: Record + }> + timestamp?: string // date-time +} +``` + +### `KnowledgeSourceRegisteredEvent` + +Detail payload of the `knowledge-source-registered` event, published on +the AI Agents event bus with source `ai-agents` after the source record +exists in DynamoDB. Consumers must process `sourceId` idempotently. + + +```ts +type KnowledgeSourceRegisteredEvent = { + orgId: string + sourceId: string // uuid + type: "file" + bucket: string + key: string +} +``` + +### `KnowledgeFileSourceRegisteredEvent` + +```ts +type KnowledgeFileSourceRegisteredEvent = { + orgId: string + sourceId: string // uuid + type: "file" + bucket: string + key: string +} +``` + +### `KnowledgeSourceDeletedEvent` + +Published when a knowledge source is deleted. + +```ts +type KnowledgeSourceDeletedEvent = { + orgId: string + sourceId: string // uuid + type: "file" +} +``` + +### `KnowledgeSourceProcessingCompletedEvent` + +Published by a knowledge processing pipeline after all derived data for +the source has been stored and is available for agent retrieval. The +event uses source `knowledge-processing` and detail type +`knowledge-source-processing-completed` on the AI Agents event bus. + + +```ts +type KnowledgeSourceProcessingCompletedEvent = { + orgId: string + sourceId: string // uuid +} +``` + ### `ToolPreview` Structured preview data for approval UI. Provides a generic format that any tool can populate. @@ -1604,7 +3496,7 @@ Structured preview data for approval UI. Provides a generic format that any tool ```ts type ToolPreview = { action?: { - type: "move" | "create" | "update" | "delete" | "apply" | "send" | "link" | "unlink" + type: "move" | "create" | "update" | "delete" | "apply" | "send" | "link" | "unlink" | "batch_approval" verb: string } source?: { @@ -1663,7 +3555,7 @@ type ToolPreview = { Type of action being previewed ```ts -type PreviewActionType = "move" | "create" | "update" | "delete" | "apply" | "send" | "link" | "unlink" +type PreviewActionType = "move" | "create" | "update" | "delete" | "apply" | "send" | "link" | "unlink" | "batch_approval" ``` ### `PreviewEntity` @@ -1733,7 +3625,7 @@ type ToolDefinition = { tool_id?: string name?: string description?: string - category?: "entity" | "email" | "taxonomy" | "rag" | "workflow" + category?: "entity" | "message" | "taxonomy" | "rag" | "workflow" parameters?: object returns?: object requires_approval?: boolean @@ -1762,11 +3654,12 @@ type AgentSource = "system" | "custom" Where the skill/agent is available: - flows: Available in workflow automations - copilot: Available as a sub-agent in copilot -- all: Available everywhere - +- portals: Available in end-user self-service portals +- website: Website chat, explicitly selected; currently supports anonymous execution +- all: Available on the existing no ```ts -type SkillAvailability = "flows" | "copilot" | "all" +type SkillAvailability = "flows" | "copilot" | "portals" | "website" | "all" ``` ### `ExecutionContext` @@ -1775,10 +3668,11 @@ Where the execution was triggered from: - flows: Triggered from workflow automation - copilot: Triggered from copilot assistant - api: Direct API call +- sharing: Triggered by sharing-api auto-sharing rules ```ts -type ExecutionContext = "flows" | "copilot" | "api" +type ExecutionContext = "flows" | "copilot" | "api" | "sharing" ``` ### `ExecutionPattern` @@ -1805,7 +3699,7 @@ type ExecutionMode = "automatic" | "approval" | "draft" ### `ExecutionStatus` ```ts -type ExecutionStatus = "pending" | "running" | "waiting_approval" | "completed" | "failed" | "cancelled" +type ExecutionStatus = "pending" | "queued" | "running" | "waiting_approval" | "completed" | "failed" | "cancelled" ``` ### `ParameterType` @@ -1822,7 +3716,7 @@ Custom types (domain-specific): - entity-attribute ```ts -type ParameterType = "text" | "textarea" | "number" | "boolean" | "select" | "entity-schema" | "entity-attribute" | "entity-id" | "taxonomy" | "taxonomy-classification" | "shared-inbox" | "label" +type ParameterType = "text" | "textarea" | "number" | "boolean" | "select" | "entity-schema" | "entity-attribute" | "entity-id" | "taxonomy" | "taxonomy-classification" | "shared-inbox" | "label" | "matching-criteria" ``` ### `InputParameterDefinition` @@ -1831,7 +3725,7 @@ type ParameterType = "text" | "textarea" | "number" | "boolean" | "select" | "en type InputParameterDefinition = { name: string label: string - type: "text" | "textarea" | "number" | "boolean" | "select" | "entity-schema" | "entity-attribute" | "entity-id" | "taxonomy" | "taxonomy-classification" | "shared-inbox" | "label" + type: "text" | "textarea" | "number" | "boolean" | "select" | "entity-schema" | "entity-attribute" | "entity-id" | "taxonomy" | "taxonomy-classification" | "shared-inbox" | "label" | "matching-criteria" description?: string default?: unknown multi?: boolean @@ -1845,6 +3739,7 @@ type InputParameterDefinition = { maxLength?: number schemaFilter?: string[] attributeTypeFilter?: string[] + hidden?: boolean } ``` @@ -1856,7 +3751,7 @@ type InputParametersSchema = { parameters: Array<{ name: string label: string - type: "text" | "textarea" | "number" | "boolean" | "select" | "entity-schema" | "entity-attribute" | "entity-id" | "taxonomy" | "taxonomy-classification" | "shared-inbox" | "label" + type: "text" | "textarea" | "number" | "boolean" | "select" | "entity-schema" | "entity-attribute" | "entity-id" | "taxonomy" | "taxonomy-classification" | "shared-inbox" | "label" | "matching-criteria" description?: string default?: unknown multi?: boolean @@ -1870,6 +3765,7 @@ type InputParametersSchema = { maxLength?: number schemaFilter?: string[] attributeTypeFilter?: string[] + hidden?: boolean }> required?: string[] } @@ -1882,6 +3778,8 @@ type ModelConfig = { model_id?: string temperature?: number max_tokens?: number + thinking?: boolean + thinking_budget?: number } ``` @@ -1894,3 +3792,241 @@ type Error = { details?: object } ``` + +### `ChatRequest` + +```ts +type ChatRequest = { + agentId: string + message: string + conversationId?: string // uuid + clientHistory?: Array<{ + role: "user" | "assistant" | "tool" | "system" + content: string + tool_calls?: Array<{ + id?: { ... } + name?: { ... } + input?: { ... } + output?: { ... } + }> + }> + context?: { + entityId?: string + customData?: Record + } + streaming?: { + mode?: "updates" | "messages" + streamTokens?: boolean + includeMetadata?: boolean + } + preview_demo?: boolean +} +``` + +### `ChatMessage` + +```ts +type ChatMessage = { + role: "user" | "assistant" | "tool" | "system" + content: string + tool_calls?: Array<{ + id?: string + name?: string + input?: object + output?: string + }> +} +``` + +### `StreamingOptions` + +```ts +type StreamingOptions = { + mode?: "updates" | "messages" + streamTokens?: boolean + includeMetadata?: boolean +} +``` + +### `StreamEvent` + +Server-Sent Event for streaming responses + +```ts +type StreamEvent = { + type?: "token" | "agent_step" | "tool_call" | "tool_result" | "complete" | "error" | "metadata" | "needs_approval" + content?: string + index?: number + tool?: string + input?: object + output?: string + callId?: string + result?: { + response?: string + structured_output?: object + status?: "completed" | "failed" | "max_iterations" | "rejected" + metrics?: { + total_tokens?: { ... } + input_tokens?: { ... } + output_tokens?: { ... } + total_cost_usd?: { ... } + duration_ms?: { ... } + iteration_count?: { ... } + } + } + error?: { + code?: string + message?: string + } + conversationId?: string // uuid +} +``` + +### `ExecutionResult` + +```ts +type ExecutionResult = { + response?: string + structured_output?: object + status?: "completed" | "failed" | "max_iterations" | "rejected" + metrics?: { + total_tokens?: number + input_tokens?: number + output_tokens?: number + total_cost_usd?: number + duration_ms?: number + iteration_count?: number + } +} +``` + +### `ConversationItem` + +```ts +type ConversationItem = { + conversation_id?: string // uuid + user_id?: string + agent_id?: string + title?: string + message_count?: number + last_message?: string + last_message_at?: string // date-time + context?: { + entityId?: string + customData?: object + } + created_at?: string // date-time + updated_at?: string // date-time +} +``` + +### `MessageItem` + +```ts +type MessageItem = { + conversation_id?: string // uuid + role?: "user" | "assistant" | "tool" | "system" + content?: string + timestamp?: string // date-time + tool_calls?: Array<{ + id?: string + name?: string + input?: object + output?: string + }> + token_count?: number + trace_id?: string // uuid + feedback?: { + rating: "up" | "down" + comment?: string + user_id: string + submitted_at: string // date-time + } +} +``` + +### `MessageFeedback` + +```ts +type MessageFeedback = { + rating: "up" | "down" + comment?: string + user_id: string + submitted_at: string // date-time +} +``` + +### `SubmitFeedbackRequest` + +```ts +type SubmitFeedbackRequest = { + trace_id: string // uuid + rating: "up" | "down" + comment?: string +} +``` + +### `ListConversationsResponse` + +```ts +type ListConversationsResponse = { + conversations?: Array<{ + conversation_id?: string // uuid + user_id?: string + agent_id?: string + title?: string + message_count?: number + last_message?: string + last_message_at?: string // date-time + context?: { + entityId?: { ... } + customData?: { ... } + } + created_at?: string // date-time + updated_at?: string // date-time + }> + next_cursor?: string +} +``` + +### `ConversationWithMessages` + +```ts +type ConversationWithMessages = { + conversation?: { + conversation_id?: string // uuid + user_id?: string + agent_id?: string + title?: string + message_count?: number + last_message?: string + last_message_at?: string // date-time + context?: { + entityId?: { ... } + customData?: { ... } + } + created_at?: string // date-time + updated_at?: string // date-time + } + messages?: Array<{ + conversation_id?: string // uuid + role?: "user" | "assistant" | "tool" | "system" + content?: string + timestamp?: string // date-time + tool_calls?: Array<{ + id?: { ... } + name?: { ... } + input?: { ... } + output?: { ... } + }> + token_count?: number + trace_id?: string // uuid + feedback?: { + rating: { ... } + comment?: { ... } + user_id: { ... } + submitted_at: { ... } + } + }> +} +``` diff --git a/docs/sdk/clients/app.md b/docs/sdk/clients/app.md index a90e9ad5..9ef43ea6 100644 --- a/docs/sdk/clients/app.md +++ b/docs/sdk/clients/app.md @@ -37,6 +37,7 @@ const { data } = await appClient.getPublicFacingComponent(...) - [`patchInstallation`](#patchinstallation) - [`uninstall`](#uninstall) - [`promoteVersion`](#promoteversion) +- [`resolveOptions`](#resolveoptions) **App Configuration** - [`listConfigurations`](#listconfigurations) @@ -65,18 +66,29 @@ const { data } = await appClient.getPublicFacingComponent(...) - [`queryEvents`](#queryevents) - [`ingestEvent`](#ingestevent) +**App Proxy** +- [`publicProxyGet`](#publicproxyget) +- [`publicProxyPost`](#publicproxypost) +- [`publicProxyPut`](#publicproxyput) +- [`publicProxyPatch`](#publicproxypatch) +- [`publicProxyDelete`](#publicproxydelete) + **Schemas** - [`Role`](#role) - [`Options`](#options) +- [`ObjectField`](#objectfield) - [`Option`](#option) - [`OptionsRef`](#optionsref) - [`S3Reference`](#s3reference) - [`ComponentType`](#componenttype) +- [`FunctionDefinition`](#functiondefinition) - [`Author`](#author) - [`NotificationConfig`](#notificationconfig) - [`NotificationEvent`](#notificationevent) - [`BaseComponentCommon`](#basecomponentcommon) - [`BaseComponent`](#basecomponent) +- [`ApiProxyComponent`](#apiproxycomponent) +- [`ExternalValuesComponent`](#externalvaluescomponent) - [`CustomCapabilityComponent`](#customcapabilitycomponent) - [`CustomPageComponent`](#custompagecomponent) - [`CustomPageConfig`](#custompageconfig) @@ -86,7 +98,7 @@ const { data } = await appClient.getPublicFacingComponent(...) - [`CustomFlowActionComponent`](#customflowactioncomponent) - [`BaseCustomActionConfig`](#basecustomactionconfig) - [`ExternalIntegrationCustomActionConfig`](#externalintegrationcustomactionconfig) -- [`SandboxCustomActionConfig`](#sandboxcustomactionconfig) +- [`FunctionRefCustomActionConfig`](#functionrefcustomactionconfig) - [`CustomFlowConfig`](#customflowconfig) - [`ExternalProductCatalogComponent`](#externalproductcatalogcomponent) - [`ExternalProductCatalogConfig`](#externalproductcatalogconfig) @@ -99,9 +111,15 @@ const { data } = await appClient.getPublicFacingComponent(...) - [`PortalExtensionHookMeterReadingPlausibilityCheck`](#portalextensionhookmeterreadingplausibilitycheck) - [`PortalExtensionHookPriceDataRetrieval`](#portalextensionhookpricedataretrieval) - [`PortalExtensionHookConsumptionDataRetrieval`](#portalextensionhookconsumptiondataretrieval) +- [`PortalExtensionHookDataExport`](#portalextensionhookdataexport) +- [`PortalExtensionHookVisualizationMetadata`](#portalextensionhookvisualizationmetadata) - [`PortalExtensionHookCostDataRetrieval`](#portalextensionhookcostdataretrieval) +- [`PortalExtensionHookChangeEmail`](#portalextensionhookchangeemail) +- [`PortalExtensionHookChangePassword`](#portalextensionhookchangepassword) +- [`PortalExtensionHookDeleteAccount`](#portalextensionhookdeleteaccount) - [`PortalExtensionSeamlessLink`](#portalextensionseamlesslink) - [`PortalExtensionAuthBlock`](#portalextensionauthblock) +- [`PortalExtensionSecureProxy`](#portalextensionsecureproxy) - [`ExternalProductCatalogAuthBlock`](#externalproductcatalogauthblock) - [`OverrideDevMode`](#overridedevmode) - [`JourneyBlockConfig`](#journeyblockconfig) @@ -111,13 +129,22 @@ const { data } = await appClient.getPublicFacingComponent(...) - [`JourneyBlockComponentArgs`](#journeyblockcomponentargs) - [`TextArg`](#textarg) - [`BooleanArg`](#booleanarg) +- [`BlockReferenceArg`](#blockreferencearg) - [`EnumArg`](#enumarg) - [`BillingFrequency`](#billingfrequency) - [`Pricing`](#pricing) - [`Audit`](#audit) - [`Review`](#review) +- [`InternalReview`](#internalreview) - [`ConfigurationMetadata`](#configurationmetadata) - [`ConfigurationVersion`](#configurationversion) +- [`ApiProxyConfig`](#apiproxyconfig) +- [`ExternalValuesConfig`](#externalvaluesconfig) +- [`ExternalValuesHook`](#externalvalueshook) +- [`ContextRequirement`](#contextrequirement) +- [`EntityContextRequirement`](#entitycontextrequirement) +- [`ValueContextRequirement`](#valuecontextrequirement) +- [`ExternalValuesResult`](#externalvaluesresult) - [`Grants`](#grants) - [`BlueprintRef`](#blueprintref) - [`Installation`](#installation) @@ -392,6 +419,35 @@ const { data } = await client.getPublicConfiguration({ "configuration": {} } ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ], "is_beta": true, "deprecated_at": "string", "version": "string", @@ -403,7 +459,8 @@ const { data } = await client.getPublicConfiguration({ }, "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "latest_version": "string", "public": true, @@ -412,6 +469,8 @@ const { data } = await client.getPublicConfiguration({ "app_id": "string", "owner_org_id": "string", "components": [], + "functions": [], + "options": [], "visibility": "private", "public": false, "pending": false, @@ -488,20 +547,36 @@ const { data } = await client.getConfiguration({ "components": [ { "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } + "configuration": {} + } + ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" } ], "visibility": "private", @@ -515,15 +590,13 @@ const { data } = await client.getConfiguration({ "role": { "id": "string", "grants": [ - { - "action": "string", - "resource": "string" - } + {} ] }, "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "version_audit": { "created_at": "string", @@ -611,7 +684,8 @@ const { data } = await client.queryEvents( source: ['CUSTOM_JOURNEY_BLOCK'], component_id: ['string'], event_type: ['ERROR'], - correlation_id: 'string' + correlation_id: 'string', + search: 'string' }, aggregation: { group_by: ['source'], @@ -619,7 +693,8 @@ const { data } = await client.queryEvents( }, pagination: { page: 1, - page_size: 100 + page_size: 100, + before: '1970-01-01T00:00:00.000Z' }, sort: { field: 'timestamp', @@ -644,7 +719,8 @@ const { data } = await client.queryEvents( "source": ["CUSTOM_JOURNEY_BLOCK"], "component_id": ["string"], "event_type": ["ERROR"], - "correlation_id": "string" + "correlation_id": "string", + "search": "string" }, "aggregation": { "group_by": ["source"], @@ -652,7 +728,8 @@ const { data } = await client.queryEvents( }, "pagination": { "page": 1, - "page_size": 100 + "page_size": 100, + "before": "1970-01-01T00:00:00.000Z" }, "sort": { "field": "timestamp", @@ -843,25 +920,9 @@ const { data } = await client.listVersions({ { "app_id": "string", "owner_org_id": "string", - "components": [ - { - "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } - } - ], + "components": [], + "functions": [], + "options": [], "visibility": "private", "public": false, "pending": false, @@ -870,27 +931,9 @@ const { data } = await client.listVersions({ "deprecated_at": "string", "changelog": "string", "review_status": "approved", - "role": { - "id": "string", - "grants": [ - { - "action": "string", - "resource": "string" - } - ] - }, - "blueprint_ref": { - "manifest_id": "string", - "job_id": "string" - }, - "version_audit": { - "created_at": "string", - "created_by": "string", - "updated_at": "string", - "updated_by": "string", - "versioned_at": "string", - "versioned_by": "string" - } + "role": {}, + "blueprint_ref": {}, + "version_audit": {} } ], "pagination": { @@ -961,20 +1004,36 @@ const { data } = await client.getVersion({ "components": [ { "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } + "configuration": {} + } + ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": {}, + "description": {}, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" } ], "visibility": "private", @@ -988,15 +1047,13 @@ const { data } = await client.getVersion({ "role": { "id": "string", "grants": [ - { - "action": "string", - "resource": "string" - } + {} ] }, "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "version_audit": { "created_at": "string", @@ -1048,7 +1105,51 @@ const { data } = await client.patchVersion( action: 'string', resource: 'string' } - ] + ], + functions: [ + { + name: 'string', + type: 'workflow', + label: { + en: 'string', + de: 'string' + }, + description: { + en: 'string', + de: 'string' + }, + code: 'string', + schedule: 'rate(30 minutes)', + schedule_timezone: 'Europe/Berlin', + schedule_overlap: 'skip', + secrets: ['string'] + } + ], + options: [ + { + key: 'string', + label: 'string', + required: true, + description: 'string', + repeatable: true, + fields: [ + { + key: 'string', + label: 'string', + description: 'string', + required: true, + type: 'text' + } + ], + value: {}, + type: 'text', + sensitive: true, + configured: true, + lifted: true, + value_updated_at: 'string' + } + ], + changelog: 'string' }, ) ``` @@ -1249,11 +1350,16 @@ Clone an existing app version to create a new version `POST /v1/app-configurations/{appId}/versions/{sourceVersion}/clone-to/{targetVersion}` ```ts -const { data } = await client.cloneVersion({ - appId: 'example', - sourceVersion: 'example', - targetVersion: 'example', -}) +const { data } = await client.cloneVersion( + { + appId: 'example', + sourceVersion: 'example', + targetVersion: 'example', + }, + { + changelog: 'string' + }, +) ```
@@ -1298,48 +1404,15 @@ const { data } = await client.listInstallations({ "owner_org_id": "string", "enabled": true, "name": "string", - "option_values": [ - { - "component_id": "string", - "options": [ - { - "key": "string", - "value": {} - } - ] - } - ], - "components": [ - { - "component_type": "CUSTOM_JOURNEY_BLOCK", - "configuration": { - "override_dev_mode": { - "override_url": "http://localhost:3000" - }, - "component_url": "https://cdn.apps.com/123/v1.0.0/bundle.js", - "component_tag": "string", - "component_args": [ - { - "type": "text" - } - ], - "component_size": 0, - "component_mapping": {} - } - } - ], + "icon_url": "string", + "option_values": [], + "components": [], + "functions": [], + "options": [], "installed_version": "string", "role": "string", - "blueprint_ref": { - "manifest_id": "string", - "job_id": "string" - }, - "installation_audit": { - "created_at": "string", - "created_by": "string", - "updated_at": "string", - "updated_by": "string" - }, + "blueprint_ref": {}, + "installation_audit": {}, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } ], @@ -1377,6 +1450,7 @@ const { data } = await client.getInstallation({ "owner_org_id": "string", "enabled": true, "name": "string", + "icon_url": "string", "option_values": [ { "component_id": "string", @@ -1407,11 +1481,55 @@ const { data } = await client.getInstallation({ } } ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": { + "en": "string", + "de": "string" + }, + "description": { + "en": "string", + "de": "string" + }, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [ + { + "key": "string", + "label": "string", + "description": "string", + "required": true, + "type": "text" + } + ], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ], "installed_version": "string", "role": "string", "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "installation_audit": { "created_at": "string", @@ -1466,6 +1584,7 @@ const { data } = await client.install( "owner_org_id": "string", "enabled": true, "name": "string", + "icon_url": "string", "option_values": [ { "component_id": "string", @@ -1496,11 +1615,55 @@ const { data } = await client.install( } } ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": { + "en": "string", + "de": "string" + }, + "description": { + "en": "string", + "de": "string" + }, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [ + { + "key": "string", + "label": "string", + "description": "string", + "required": true, + "type": "text" + } + ], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ], "installed_version": "string", "role": "string", "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "installation_audit": { "created_at": "string", @@ -1584,6 +1747,7 @@ const { data } = await client.promoteVersion({ "owner_org_id": "string", "enabled": true, "name": "string", + "icon_url": "string", "option_values": [ { "component_id": "string", @@ -1614,11 +1778,55 @@ const { data } = await client.promoteVersion({ } } ], + "functions": [ + { + "name": "string", + "type": "workflow", + "label": { + "en": "string", + "de": "string" + }, + "description": { + "en": "string", + "de": "string" + }, + "code": "string", + "schedule": "rate(30 minutes)", + "schedule_timezone": "Europe/Berlin", + "schedule_overlap": "skip", + "secrets": ["string"] + } + ], + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [ + { + "key": "string", + "label": "string", + "description": "string", + "required": true, + "type": "text" + } + ], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ], "installed_version": "string", "role": "string", "blueprint_ref": { "manifest_id": "string", - "job_id": "string" + "job_id": "string", + "source_blueprint_file": "string" }, "installation_audit": { "created_at": "string", @@ -1634,6 +1842,59 @@ const { data } = await client.promoteVersion({ --- +### `resolveOptions` + +Resolve the effective app-level options of an installation, including decrypted sensitive values (secrets). This endpoint accepts epilot internal-auth tokens exclusively (internal service calls, e.g. + +`POST /v1/app/{appId}/options/resolve` + +```ts +const { data } = await client.resolveOptions( + { + appId: 'example', + }, + { + keys: ['string'] + }, +) +``` + +
+Response + +```json +{ + "options": [ + { + "key": "string", + "label": "string", + "required": true, + "description": "string", + "repeatable": true, + "fields": [ + { + "key": "string", + "label": "string", + "description": "string", + "required": true, + "type": "text" + } + ], + "value": {}, + "type": "text", + "sensitive": true, + "configured": true, + "lifted": true, + "value_updated_at": "string" + } + ] +} +``` + +
+ +--- + ### `ingestEvent` Internal endpoint for services to submit app events for analytic purposes @@ -1664,57 +1925,179 @@ const { data } = await client.ingestEvent( --- -## Schemas +### `publicProxyGet` -### `Role` +Forward a GET request to a registered proxy target from a public-facing component (e.g. journey blocks) + +`GET /v1/public/app/{appId}/proxy/{proxyName}/{path}` ```ts -type Role = { - id?: string - grants?: Array<{ - action: string - resource?: string - }> -} +const { data } = await client.publicProxyGet({ + appId: 'example', + proxyName: 'example', + path: 'example', + query: 'example', +}) ``` -### `Options` +--- -Options for the component configuration +### `publicProxyPost` -```ts -type Options = { - key: string - label?: string - required?: boolean - description?: string - value?: unknown - type: "text" | "number" | "boolean" | "secret" -} -``` +Forward a POST request to a registered proxy target from a public-facing component (e.g. journey blocks) -### `Option` +`POST /v1/public/app/{appId}/proxy/{proxyName}/{path}` ```ts -type Option = { - key: string - value: unknown -} +const { data } = await client.publicProxyPost( + { + appId: 'example', + proxyName: 'example', + path: 'example', + query: 'example', + }, + {}, +) ``` -### `OptionsRef` +--- + +### `publicProxyPut` + +Forward a PUT request to a registered proxy target from a public-facing component + +`PUT /v1/public/app/{appId}/proxy/{proxyName}/{path}` ```ts -type OptionsRef = { - component_id: string - options: Array<{ - key: string - value: unknown - }> -} +const { data } = await client.publicProxyPut( + { + appId: 'example', + proxyName: 'example', + path: 'example', + query: 'example', + }, + {}, +) ``` -### `S3Reference` +--- + +### `publicProxyPatch` + +Forward a PATCH request to a registered proxy target from a public-facing component + +`PATCH /v1/public/app/{appId}/proxy/{proxyName}/{path}` + +```ts +const { data } = await client.publicProxyPatch( + { + appId: 'example', + proxyName: 'example', + path: 'example', + query: 'example', + }, + {}, +) +``` + +--- + +### `publicProxyDelete` + +Forward a DELETE request to a registered proxy target from a public-facing component + +`DELETE /v1/public/app/{appId}/proxy/{proxyName}/{path}` + +```ts +const { data } = await client.publicProxyDelete({ + appId: 'example', + proxyName: 'example', + path: 'example', + query: 'example', +}) +``` + +--- + +## Schemas + +### `Role` + +```ts +type Role = { + id?: string + grants?: Array<{ + action: string + resource?: string + }> +} +``` + +### `Options` + +An option declaration — a setting the installing org fills in. Declared at app level. + +```ts +type Options = { + key: string + label?: string + required?: boolean + description?: string + repeatable?: boolean + fields?: Array<{ + key: string + label?: string + description?: string + required?: boolean + type: "text" | "number" | "boolean" | "secret" + }> + value?: unknown + type: "text" | "number" | "boolean" | "secret" | "object" + sensitive?: boolean + configured?: boolean + lifted?: boolean + value_updated_at?: string +} +``` + +### `ObjectField` + +One declared field inside a `type: object` option. Fields are primitives — object nesting +is not supported. + + +```ts +type ObjectField = { + key: string + label?: string + description?: string + required?: boolean + type: "text" | "number" | "boolean" | "secret" +} +``` + +### `Option` + +```ts +type Option = { + key: string + value: unknown +} +``` + +### `OptionsRef` + +```ts +type OptionsRef = { + component_id: string + options: Array<{ + key: string + value: unknown + }> +} +``` + +### `S3Reference` ```ts type S3Reference = { @@ -1728,7 +2111,32 @@ type S3Reference = { Type of app component ```ts -type ComponentType = "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" +type ComponentType = "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" | "API_PROXY" | "EXTERNAL_VALUES" | "APP_FUNCTION" +``` + +### `FunctionDefinition` + +A named server-side function belonging to the app. Runs in the epilot code-execution sandbox with an installation-scoped app token. Functions with a schedule are executed automatically once per installation. + + +```ts +type FunctionDefinition = { + name: string + type: "workflow" | "scheduled" + label?: { + en?: string + de: string + } + description?: { + en?: string + de: string + } + code: string + schedule?: string + schedule_timezone?: string + schedule_overlap?: "skip" + secrets?: string[] +} ``` ### `Author` @@ -1774,9 +2182,22 @@ type BaseComponentCommon = { label?: string required?: boolean description?: string + repeatable?: boolean + fields?: Array<{ + key: { ... } + label?: { ... } + description?: { ... } + required?: { ... } + type: { ... } + }> value?: unknown - type: "text" | "number" | "boolean" | "secret" + type: "text" | "number" | "boolean" | "secret" | "object" + sensitive?: boolean + configured?: boolean + lifted?: boolean + value_updated_at?: string }> + uses_options?: string[] surfaces?: object } ``` @@ -1799,20 +2220,77 @@ type BaseComponent = { label?: string required?: boolean description?: string + repeatable?: boolean + fields?: Array<{ + key: { ... } + label?: { ... } + description?: { ... } + required?: { ... } + type: { ... } + }> value?: unknown - type: "text" | "number" | "boolean" | "secret" + type: "text" | "number" | "boolean" | "secret" | "object" + sensitive?: boolean + configured?: boolean + lifted?: boolean + value_updated_at?: string }> + uses_options?: string[] surfaces?: object } ``` +### `ApiProxyComponent` + +```ts +type ApiProxyComponent = { + component_type: "API_PROXY" + configuration: { + name: string + target: string + auth_type: "header" | "bearer" | "basic" | "oauth2" | "none" + auth_header?: string + token_url?: string // uri + headers?: Record + } +} +``` + +### `ExternalValuesComponent` + +Exposes typed values resolved from an external system at runtime (e.g. a meter reading prediction). Consumers such as validation rules reference a hook and one of its results by id. Resolution is performed by the external-values-api on behalf of authenticated epilot 360 users and portal end customer + +```ts +type ExternalValuesComponent = { + component_type: "EXTERNAL_VALUES" + configuration: { + hooks: Array<{ + id: { ... } + name: { ... } + description?: { ... } + auth_type?: { ... } + auth_header?: { ... } + auth_secret?: { ... } + auth?: { ... } + call: { ... } + result: { ... } + timeout_ms?: { ... } + on_unavailable?: { ... } + contexts?: { ... } + cache?: { ... } + secure_proxy?: { ... } + }> + } +} +``` + ### `CustomCapabilityComponent` ```ts type CustomCapabilityComponent = { component_type: "CUSTOM_CAPABILITY" configuration: { - type?: "tab" | "group" + type?: "tab" | "group" | "widget" allowed_schemas?: string[] } surfaces?: { @@ -1892,7 +2370,7 @@ type PortalBlockComponent = { app_url?: { ... } zip_url?: { ... } override_url?: { ... } - section?: { ... } + supported_surfaces?: { ... } } } } @@ -1927,10 +2405,8 @@ type CustomFlowActionComponent = { name?: string description?: string wait_for_callback?: boolean - type: "sandbox" - sandbox_settings?: { - code?: { ... } - } + type: "function" + function_name: string } surfaces?: { flow_action_config?: { @@ -1967,22 +2443,23 @@ type ExternalIntegrationCustomActionConfig = { } ``` -### `SandboxCustomActionConfig` +### `FunctionRefCustomActionConfig` ```ts -type SandboxCustomActionConfig = { +type FunctionRefCustomActionConfig = { name?: string description?: string wait_for_callback?: boolean - type: "sandbox" - sandbox_settings?: { - code?: string - } + type: "function" + function_name: string } ``` ### `CustomFlowConfig` +Configuration of a flow action component. `external_integration` calls an external HTTP endpoint; `function` runs a workflow-type app function in the epilot sandbox. + + ```ts type CustomFlowConfig = { name?: string @@ -1997,10 +2474,8 @@ type CustomFlowConfig = { name?: string description?: string wait_for_callback?: boolean - type: "sandbox" - sandbox_settings?: { - code?: string - } + type: "function" + function_name: string } ``` @@ -2149,17 +2624,21 @@ type PortalExtensionComponent = { type: { ... } auth?: { ... } call: { ... } + resolved?: { ... } use_static_ips?: { ... } + secure_proxy?: { ... } } | { id: { ... } name?: { ... } type: { ... } auth?: { ... } call: { ... } + resolved?: { ... } assignment_mode?: { ... } contact_relation_attribute?: { ... } explanation?: { ... } use_static_ips?: { ... } + secure_proxy?: { ... } } | { id: { ... } name?: { ... } @@ -2169,6 +2648,7 @@ type PortalExtensionComponent = { call: { ... } resolved?: { ... } use_static_ips?: { ... } + secure_proxy?: { ... } } | { id: { ... } name?: { ... } @@ -2178,6 +2658,17 @@ type PortalExtensionComponent = { call: { ... } resolved?: { ... } use_static_ips?: { ... } + secure_proxy?: { ... } + } | { + id: { ... } + name?: { ... } + type: { ... } + block_types?: { ... } + auth?: { ... } + call: { ... } + resolved?: { ... } + use_static_ips?: { ... } + secure_proxy?: { ... } } | { id: { ... } name?: { ... } @@ -2187,6 +2678,7 @@ type PortalExtensionComponent = { call: { ... } resolved?: { ... } use_static_ips?: { ... } + secure_proxy?: { ... } } | { id: { ... } name?: { ... } @@ -2196,17 +2688,34 @@ type PortalExtensionComponent = { call: { ... } resolved: { ... } use_static_ips?: { ... } - }> - links?: Array<{ + secure_proxy?: { ... } + } | { id: { ... } - name: { ... } - description?: { ... } + name?: { ... } type: { ... } - condition?: { ... } auth?: { ... } - redirect: { ... } - }> - } + call: { ... } + resolved?: { ... } + use_static_ips?: { ... } + secure_proxy?: { ... } + } | { + id: { ... } + name?: { ... } + type: { ... } + change_mode?: { ... } + require_password_confirmation?: { ... } + explanation?: { ... } + auth?: { ... } + call: { ... } + resolved?: { ... } + secure_proxy?: { ... } + } | { + id: { ... } + name?: { ... } + type: { ... } + require_new_password?: { ... } + explanation?: { ... } + // ... } ``` @@ -2236,8 +2745,18 @@ type PortalExtensionConfig = { headers: { ... } body?: { ... } result: { ... } + result_correlation_id?: { ... } + } + resolved?: { + result?: { ... } + result_correlation_id?: { ... } + error_message_path?: { ... } } use_static_ips?: boolean + secure_proxy?: { + integration_id: { ... } + use_case_slug: { ... } + } } | { id: string name?: { @@ -2260,6 +2779,12 @@ type PortalExtensionConfig = { headers: { ... } body?: { ... } result?: { ... } + result_correlation_id?: { ... } + } + resolved?: { + result?: { ... } + result_correlation_id?: { ... } + error_message_path?: { ... } } assignment_mode?: "contracts" | "contact_to_contracts" | "contact_to_portal_user" contact_relation_attribute?: string @@ -2267,6 +2792,10 @@ type PortalExtensionConfig = { en: { ... } } use_static_ips?: boolean + secure_proxy?: { + integration_id: { ... } + use_case_slug: { ... } + } } | { id: string name?: { @@ -2274,7 +2803,7 @@ type PortalExtensionConfig = { de: { ... } } type: "priceDataRetrieval" - intervals?: "PT15M" | "PT1H" | "P1D" | "P1M"[] + intervals?: "PT15M" | "PT1H" | "P1D" | "P1M" | "P1Y" | "custom"[] auth?: { method?: { ... } url: { ... } @@ -2291,28 +2820,8 @@ type PortalExtensionConfig = { body?: { ... } } resolved?: { + data_path?: { ... } dataPath?: { ... } - } - use_static_ips?: boolean - } | { - id: string - name?: { - en?: { ... } - de: { ... } - } - type: "consumptionDataRetrieval" - intervals?: "PT15M" | "PT1H" | "P1D" | "P1M"[] - auth?: { - method?: { ... } - url: { ... } - params?: { ... } - headers?: { ... } - body?: { ... } - cache?: { ... } - } - call: { - method?: { ... } - url: { ... } // ... } ``` @@ -2349,8 +2858,18 @@ type PortalExtensionHookRegistrationIdentifiersCheck = { headers: Record body?: object result: string + result_correlation_id?: string + } + resolved?: { + result?: string + result_correlation_id?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -2389,6 +2908,12 @@ type PortalExtensionHookContractIdentification = { headers: Record body?: object result?: string + result_correlation_id?: string + } + resolved?: { + result?: string + result_correlation_id?: string + error_message_path?: string } assignment_mode?: "contracts" | "contact_to_contracts" | "contact_to_portal_user" contact_relation_attribute?: string @@ -2396,6 +2921,10 @@ type PortalExtensionHookContractIdentification = { en: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -2433,13 +2962,19 @@ type PortalExtensionHookMeterReadingPlausibilityCheck = { headers: Record } resolved: { + data_path?: string dataPath?: string counter_identifiers?: Record valid?: string upper_limit?: string lower_limit?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -2457,7 +2992,7 @@ type PortalExtensionHookPriceDataRetrieval = { de: string } type: "priceDataRetrieval" - intervals?: "PT15M" | "PT1H" | "P1D" | "P1M"[] + intervals?: "PT15M" | "PT1H" | "P1D" | "P1M" | "P1Y" | "custom"[] auth?: { method?: string url: string @@ -2477,9 +3012,15 @@ type PortalExtensionHookPriceDataRetrieval = { body?: Record } resolved?: { + data_path?: string dataPath?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -2497,7 +3038,7 @@ type PortalExtensionHookConsumptionDataRetrieval = { de: string } type: "consumptionDataRetrieval" - intervals?: "PT15M" | "PT1H" | "P1D" | "P1M"[] + intervals?: "PT15M" | "PT1H" | "P1D" | "P1M" | "P1Y" | "custom"[] auth?: { method?: string url: string @@ -2517,27 +3058,31 @@ type PortalExtensionHookConsumptionDataRetrieval = { body?: Record } resolved?: { + data_path?: string dataPath?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` -### `PortalExtensionHookCostDataRetrieval` - -Hook that will allow using the specified source as data for consumption visualizations. This hook is triggered to fetch the data. Format of the request and response has to follow the following specification: TBD. The expected response to the call is: - - 200 with the time series data +### `PortalExtensionHookDataExport` +Generic data export hook. When configured on blocks that support it, the portal delegates the export action (e.g. CSV/Excel/PDF download) to the configured external source instead of generating the file itself. Can be used by any block that supports export — consumption charts, dynamic tariff charts ```ts -type PortalExtensionHookCostDataRetrieval = { +type PortalExtensionHookDataExport = { id: string name?: { en?: string de: string } - type: "costDataRetrieval" - intervals?: "PT15M" | "PT1H" | "P1D" | "P1M"[] + type: "dataExport" + block_types?: string[] auth?: { method?: string url: string @@ -2557,27 +3102,28 @@ type PortalExtensionHookCostDataRetrieval = { body?: Record } resolved?: { - dataPath?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` -### `PortalExtensionSeamlessLink` +### `PortalExtensionHookVisualizationMetadata` + +Hook that returns runtime metadata describing how a visualization (consumption / price / cost chart) should be rendered for a given portal context (meter, contract, etc). It is invoked by the portal before fetching data, with the same context the data hook would receive, so that the discovery shape ```ts -type PortalExtensionSeamlessLink = { +type PortalExtensionHookVisualizationMetadata = { id: string - name: { - en?: string - de: string - } - description?: { + name?: { en?: string de: string } - type: "seamless" - condition?: string + type: "visualizationMetadata" auth?: { method?: string url: string @@ -2589,18 +3135,246 @@ type PortalExtensionSeamlessLink = { ttl: { ... } } } - redirect: { - url?: string + call: { + method?: string + url: string params?: Record + headers?: Record + body?: Record + } + resolved?: { + data_path?: string + dataPath?: string + error_message_path?: string + } + use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string } } ``` -### `PortalExtensionAuthBlock` +### `PortalExtensionHookCostDataRetrieval` -```ts -type PortalExtensionAuthBlock = { - method?: string +Hook that will allow using the specified source as data for consumption visualizations. This hook is triggered to fetch the data. Format of the request and response has to follow the following specification: TBD. The expected response to the call is: + - 200 with the time series data + + +```ts +type PortalExtensionHookCostDataRetrieval = { + id: string + name?: { + en?: string + de: string + } + type: "costDataRetrieval" + intervals?: "PT15M" | "PT1H" | "P1D" | "P1M" | "P1Y" | "custom"[] + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + } + resolved?: { + data_path?: string + dataPath?: string + error_message_path?: string + } + use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `PortalExtensionHookChangeEmail` + +Hook that replaces the built-in change email functionality for portal users. When configured, the portal does not run its own change email flow. Instead, this hook makes an HTTP call to the third-party system, which is expected to handle the email change. +The `change_mode` controls what the portal d + +```ts +type PortalExtensionHookChangeEmail = { + id: string + name?: { + en?: string + de: string + } + type: "changeEmail" + change_mode?: "synchronous" | "asynchronous" + require_password_confirmation?: boolean + explanation?: { + en: string + } + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers: Record + body?: object + } + resolved?: { + error_message_path?: string + } + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `PortalExtensionHookChangePassword` + +Hook that replaces the built-in change password functionality for portal users. When configured, the portal does not change the user's password itself. Instead, this hook makes an HTTP call to the third-party system, which is expected to handle the password change (most likely by sending the user in + +```ts +type PortalExtensionHookChangePassword = { + id: string + name?: { + en?: string + de: string + } + type: "changePassword" + require_new_password?: boolean + explanation?: { + en: string + } + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers: Record + body?: object + } + resolved?: { + error_message_path?: string + } + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `PortalExtensionHookDeleteAccount` + +Hook that replaces the built-in delete account functionality for portal users. When configured, the portal does not delete the user itself. Instead, this hook makes an HTTP call to the third-party system, which is expected to handle the deletion. +The `deletion_mode` controls what the portal does aft + +```ts +type PortalExtensionHookDeleteAccount = { + id: string + name?: { + en?: string + de: string + } + type: "deleteAccount" + deletion_mode?: "synchronous" | "asynchronous" + delete_contact?: "none" | "soft" | "hard" + explanation?: { + en: string + } + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers: Record + body?: object + } + resolved?: { + error_message_path?: string + } + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `PortalExtensionSeamlessLink` + +```ts +type PortalExtensionSeamlessLink = { + id: string + name: { + en?: string + de: string + } + description?: { + en?: string + de: string + } + type: "seamless" + condition?: string + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + redirect: { + url?: string + params?: Record + } +} +``` + +### `PortalExtensionAuthBlock` + +```ts +type PortalExtensionAuthBlock = { + method?: string url: string params?: Record headers?: Record @@ -2612,6 +3386,17 @@ type PortalExtensionAuthBlock = { } ``` +### `PortalExtensionSecureProxy` + +If set, requests are routed through the ERP Integration secure proxy. Mutually exclusive with use_static_ips. + +```ts +type PortalExtensionSecureProxy = { + integration_id: string // uuid + use_case_slug: string +} +``` + ### `ExternalProductCatalogAuthBlock` ```ts @@ -2645,7 +3430,7 @@ type JourneyBlockConfig = { component_tag: string component_args?: Array<{ key: string - type: "text" | "boolean" | "enum" + type: "text" | "boolean" | "enum" | "block_reference" required?: boolean description?: { en?: { ... } @@ -2684,7 +3469,7 @@ type PortalBlockSurfaceConfig = { app_url?: string zip_url?: string override_url?: string - section?: "main" | "footer" + supported_surfaces?: "main" | "footer_inline" | "footer_left_absolute" | "footer_right_absolute"[] } ``` @@ -2693,7 +3478,7 @@ type PortalBlockSurfaceConfig = { ```ts type JourneyBlockComponentArgs = { key: string - type: "text" | "boolean" | "enum" + type: "text" | "boolean" | "enum" | "block_reference" required?: boolean description?: { en?: string @@ -2722,6 +3507,21 @@ type BooleanArg = { } ``` +### `BlockReferenceArg` + +References another journey block by its ID. The configuring user picks +a block from the journey via a dropdown in the journey-builder; the +chosen block's ID is stored as the arg value (a string). The bundle can +then call `subscribe(blockId, cb)` / `getValue(blockId)` against that ID. + + +```ts +type BlockReferenceArg = { + type?: "block_reference" + allowed_types?: string[] +} +``` + ### `EnumArg` ```ts @@ -2780,6 +3580,26 @@ type Review = { } ``` +### `InternalReview` + +Review entry including app ownership info, used by internal admin endpoints + +```ts +type InternalReview = { + version?: string + review_status?: "approved" | "rejected" | "pending" + requested_at?: string + requested_by?: string + technical_contact?: string + marketing_contact?: string + demo_url?: string + app_id?: string + org_id?: string + reviewed_by?: string + reviewed_at?: string +} +``` + ### `ConfigurationMetadata` Basic metadata about your app configuration which does not get versioned @@ -2847,11 +3667,55 @@ type ConfigurationVersion = { label?: { ... } required?: { ... } description?: { ... } + repeatable?: { ... } + fields?: { ... } value?: { ... } type: { ... } + sensitive?: { ... } + configured?: { ... } + lifted?: { ... } + value_updated_at?: { ... } }> + uses_options?: string[] surfaces?: object }> + functions?: Array<{ + name: string + type: "workflow" | "scheduled" + label?: { + en?: { ... } + de: { ... } + } + description?: { + en?: { ... } + de: { ... } + } + code: string + schedule?: string + schedule_timezone?: string + schedule_overlap?: "skip" + secrets?: string[] + }> + options?: Array<{ + key: string + label?: string + required?: boolean + description?: string + repeatable?: boolean + fields?: Array<{ + key: { ... } + label?: { ... } + description?: { ... } + required?: { ... } + type: { ... } + }> + value?: unknown + type: "text" | "number" | "boolean" | "secret" | "object" + sensitive?: boolean + configured?: boolean + lifted?: boolean + value_updated_at?: string + }> visibility?: "public" | "private" public?: boolean pending?: boolean @@ -2870,6 +3734,7 @@ type ConfigurationVersion = { blueprint_ref?: { manifest_id?: string job_id?: string + source_blueprint_file?: string } version_audit: { created_at?: string @@ -2882,6 +3747,212 @@ type ConfigurationVersion = { } ``` +### `ApiProxyConfig` + +Configuration for an API proxy component + +```ts +type ApiProxyConfig = { + name: string + target: string + auth_type: "header" | "bearer" | "basic" | "oauth2" | "none" + auth_header?: string + token_url?: string // uri + headers?: Record +} +``` + +### `ExternalValuesConfig` + +Configuration for an EXTERNAL_VALUES component + +```ts +type ExternalValuesConfig = { + hooks: Array<{ + id: string + name: { + en?: { ... } + de: { ... } + } + description?: { + en?: { ... } + de: { ... } + } + auth_type?: "none" | "header" | "bearer" | "hmac" + auth_header?: string + auth_secret?: string + auth?: { + method?: { ... } + url: { ... } + params?: { ... } + headers?: { ... } + body?: { ... } + cache?: { ... } + } + call: { + method?: { ... } + url: { ... } + headers?: { ... } + params?: { ... } + body?: { ... } + } + result: Array<{ + id: { ... } + type: { ... } + name: { ... } + template?: { ... } + path?: { ... } + jsonata?: { ... } + }> + timeout_ms?: number + on_unavailable?: "skip" | "block" + contexts?: Array<{ + type: { ... } + schema: { ... } + } | { + type: { ... } + name: { ... } + value_type: { ... } + }> + cache?: { + ttl_seconds: { ... } + key?: { ... } + } + secure_proxy?: { + integration_id: { ... } + use_case_slug: { ... } + } + }> +} +``` + +### `ExternalValuesHook` + +One external call that returns one or more typed results. Interpolated templates (Liquid) have access to `Context`, `Consumer`, `Options`, `Env` and — for `result` templates — `Response` and `AuthResponse` (each is also available snake_case, e.g. `{{ context.contract }}`). + +`Context` is the name → v + +```ts +type ExternalValuesHook = { + id: string + name: { + en?: string + de: string + } + description?: { + en?: string + de: string + } + auth_type?: "none" | "header" | "bearer" | "hmac" + auth_header?: string + auth_secret?: string + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: "GET" | "POST" | "PUT" | "PATCH" + url: string + headers?: Record + params?: Record + body?: Record + } + result: Array<{ + id: string + type: "number" | "text" | "date" | "boolean" + name: { + en?: { ... } + de: { ... } + } + template?: string + path?: string + jsonata?: string + }> + timeout_ms?: number + on_unavailable?: "skip" | "block" + contexts?: Array<{ + type: "entity" + schema: string + } | { + type: "value" + name: string + value_type: "number" | "text" | "date" | "boolean" + }> + cache?: { + ttl_seconds: number + key?: string + } + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `ContextRequirement` + +A requirement a hook reads from `Context`, discriminated by `type`. More types will be added later; consumers must ignore types they do not know. + +```ts +type ContextRequirement = { + type: "entity" + schema: string +} | { + type: "value" + name: string + value_type: "number" | "text" | "date" | "boolean" +} +``` + +### `EntityContextRequirement` + +The consumer supplies the bound entities of `schema` under `Context.```. + +```ts +type EntityContextRequirement = { + type: "entity" + schema: string +} +``` + +### `ValueContextRequirement` + +The consumer supplies one scalar value under `Context.```, e.g. a date the customer entered in a journey block. A value input is optional: the consumer sends it when it has a value and omits it otherwise, so the hook's templates must cope with its absence, e.g. `{{ Context.reading_date | default + +```ts +type ValueContextRequirement = { + type: "value" + name: string + value_type: "number" | "text" | "date" | "boolean" +} +``` + +### `ExternalValuesResult` + +A single typed value extracted from the hook response. Exactly one of `template`, `path` or `jsonata` must be set. + + +```ts +type ExternalValuesResult = { + id: string + type: "number" | "text" | "date" | "boolean" + name: { + en?: string + de: string + } + template?: string + path?: string + jsonata?: string +} +``` + ### `Grants` Required grants for the app in order to call APIs for the installing tenant @@ -2899,6 +3970,7 @@ type Grants = Array<{ type BlueprintRef = { manifest_id?: string job_id?: string + source_blueprint_file?: string } ``` @@ -2913,6 +3985,7 @@ type Installation = { owner_org_id?: string enabled: boolean name: string + icon_url?: string option_values?: Array<{ component_id: string options: Array<{ @@ -2935,16 +4008,61 @@ type Installation = { label?: { ... } required?: { ... } description?: { ... } + repeatable?: { ... } + fields?: { ... } value?: { ... } type: { ... } + sensitive?: { ... } + configured?: { ... } + lifted?: { ... } + value_updated_at?: { ... } }> + uses_options?: string[] surfaces?: object }> + functions?: Array<{ + name: string + type: "workflow" | "scheduled" + label?: { + en?: { ... } + de: { ... } + } + description?: { + en?: { ... } + de: { ... } + } + code: string + schedule?: string + schedule_timezone?: string + schedule_overlap?: "skip" + secrets?: string[] + }> + options?: Array<{ + key: string + label?: string + required?: boolean + description?: string + repeatable?: boolean + fields?: Array<{ + key: { ... } + label?: { ... } + description?: { ... } + required?: { ... } + type: { ... } + }> + value?: unknown + type: "text" | "number" | "boolean" | "secret" | "object" + sensitive?: boolean + configured?: boolean + lifted?: boolean + value_updated_at?: string + }> installed_version: string role?: string blueprint_ref?: { manifest_id?: string job_id?: string + source_blueprint_file?: string } installation_audit?: { created_at?: string @@ -2998,11 +4116,55 @@ type PublicConfiguration = { label?: { ... } required?: { ... } description?: { ... } + repeatable?: { ... } + fields?: { ... } value?: { ... } type: { ... } + sensitive?: { ... } + configured?: { ... } + lifted?: { ... } + value_updated_at?: { ... } }> + uses_options?: string[] surfaces?: object }> + functions?: Array<{ + name: string + type: "workflow" | "scheduled" + label?: { + en?: { ... } + de: { ... } + } + description?: { + en?: { ... } + de: { ... } + } + code: string + schedule?: string + schedule_timezone?: string + schedule_overlap?: "skip" + secrets?: string[] + }> + options?: Array<{ + key: string + label?: string + required?: boolean + description?: string + repeatable?: boolean + fields?: Array<{ + key: { ... } + label?: { ... } + description?: { ... } + required?: { ... } + type: { ... } + }> + value?: unknown + type: "text" | "number" | "boolean" | "secret" | "object" + sensitive?: boolean + configured?: boolean + lifted?: boolean + value_updated_at?: string + }> is_beta?: boolean deprecated_at?: string version: string @@ -3016,44 +4178,8 @@ type PublicConfiguration = { blueprint_ref?: { manifest_id?: string job_id?: string - } - latest_version?: string - public?: boolean - versions?: Array<{ - app_id: string - owner_org_id: string - components: Array<{ - id: { ... } - name?: { ... } - description?: { ... } - options?: { ... } - surfaces?: { ... } - }> - visibility?: "public" | "private" - public?: boolean - pending?: boolean - version: string - is_beta?: boolean - deprecated_at?: string - changelog?: string - review_status?: "approved" | "rejected" | "pending" - role?: { - id?: { ... } - grants?: { ... } - } - blueprint_ref?: { - manifest_id?: { ... } - job_id?: { ... } - } - version_audit: { - created_at?: { ... } - created_by?: { ... } - updated_at?: { ... } - updated_by?: { ... } - versioned_at?: { ... } - versioned_by?: { ... } - } - }> + source_blueprint_file?: string + // ... } ``` @@ -3113,38 +4239,56 @@ type Configuration = { label?: { ... } required?: { ... } description?: { ... } + repeatable?: { ... } + fields?: { ... } value?: { ... } type: { ... } + sensitive?: { ... } + configured?: { ... } + lifted?: { ... } + value_updated_at?: { ... } }> + uses_options?: string[] surfaces?: object }> - visibility?: "public" | "private" - public?: boolean - pending?: boolean - version: string - is_beta?: boolean - deprecated_at?: string - changelog?: string - review_status?: "approved" | "rejected" | "pending" - role?: { - id?: string - grants?: Array<{ - action: { ... } - resource?: { ... } + functions?: Array<{ + name: string + type: "workflow" | "scheduled" + label?: { + en?: { ... } + de: { ... } + } + description?: { + en?: { ... } + de: { ... } + } + code: string + schedule?: string + schedule_timezone?: string + schedule_overlap?: "skip" + secrets?: string[] + }> + options?: Array<{ + key: string + label?: string + required?: boolean + description?: string + repeatable?: boolean + fields?: Array<{ + key: { ... } + label?: { ... } + description?: { ... } + required?: { ... } + type: { ... } }> - } - blueprint_ref?: { - manifest_id?: string - job_id?: string - } - version_audit: { - created_at?: string - created_by?: string - updated_at?: string - updated_by?: string - versioned_at?: string - versioned_by?: string - } + value?: unknown + type: "text" | "number" | "boolean" | "secret" | "object" + sensitive?: boolean + configured?: boolean + lifted?: boolean + value_updated_at?: string + }> + // ... } ``` @@ -3180,7 +4324,7 @@ type BatchEventRequest = { timestamp?: string correlation_id?: string event_type: "ERROR" | "WARNING" | "INFO" - source: "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" + source: "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" | "API_PROXY" | "EXTERNAL_VALUES" | "APP_FUNCTION" actor: { org_id?: { ... } user_id?: { ... } @@ -3212,7 +4356,7 @@ type AppEventData = { timestamp?: string correlation_id?: string event_type: "ERROR" | "WARNING" | "INFO" - source: "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" + source: "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" | "API_PROXY" | "EXTERNAL_VALUES" | "APP_FUNCTION" actor: { org_id?: string user_id?: string @@ -3232,10 +4376,11 @@ type EventsQuery = { preset?: "1h" | "6h" | "24h" | "7d" | "30d" } filters?: { - source?: "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE"[] + source?: "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" | "API_PROXY" | "EXTERNAL_VALUES" | "APP_FUNCTION"[] component_id?: string[] event_type?: "ERROR" | "WARNING" | "INFO"[] correlation_id?: string + search?: string } aggregation?: { group_by?: "source" | "component_id" | "event_type" | "hour" | "day"[] @@ -3244,6 +4389,7 @@ type EventsQuery = { pagination?: { page?: number page_size?: number + before?: string // date-time } sort?: { field?: "timestamp" | "event_type" | "component_id" @@ -3267,6 +4413,7 @@ type EventsQueryResponse = { component_id?: { ... } event_type?: { ... } correlation_id?: { ... } + search?: { ... } } aggregation?: { group_by?: { ... } @@ -3275,6 +4422,7 @@ type EventsQueryResponse = { pagination?: { page?: { ... } page_size?: { ... } + before?: { ... } } sort?: { field?: { ... } @@ -3324,7 +4472,7 @@ type RawEvents = { timestamp?: string correlation_id?: string event_type: "ERROR" | "WARNING" | "INFO" - source: "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" + source: "CUSTOM_JOURNEY_BLOCK" | "CUSTOM_PORTAL_BLOCK" | "PORTAL_EXTENSION" | "CUSTOM_FLOW_ACTION" | "ERP_INFORM_TOOLKIT" | "CUSTOM_CAPABILITY" | "EXTERNAL_PRODUCT_CATALOG" | "CUSTOM_PAGE" | "API_PROXY" | "EXTERNAL_VALUES" | "APP_FUNCTION" actor: { org_id?: { ... } user_id?: { ... } diff --git a/docs/sdk/clients/automation.md b/docs/sdk/clients/automation.md index 18d9a5ea..9237adcc 100644 --- a/docs/sdk/clients/automation.md +++ b/docs/sdk/clients/automation.md @@ -40,6 +40,7 @@ const { data } = await automationClient.searchFlows(...) **executions** - [`getExecutions`](#getexecutions) - [`startExecution`](#startexecution) +- [`searchExecutions`](#searchexecutions) - [`getExecution`](#getexecution) - [`cancelExecution`](#cancelexecution) - [`retriggerAction`](#retriggeraction) @@ -55,14 +56,18 @@ const { data } = await automationClient.searchFlows(...) - [`AutomationFlowId`](#automationflowid) - [`AutomationActionId`](#automationactionid) - [`AutomationFlow`](#automationflow) -- [`WorkflowContext`](#workflowcontext) - [`WorkflowContextRole`](#workflowcontextrole) - [`SearchAutomationsResp`](#searchautomationsresp) +- [`JourneyContextUsagesReq`](#journeycontextusagesreq) +- [`JourneyContextUsage`](#journeycontextusage) +- [`JourneyContextUsagesResp`](#journeycontextusagesresp) - [`AnyTrigger`](#anytrigger) - [`AnyAction`](#anyaction) - [`AnyActionConfig`](#anyactionconfig) - [`AutomationActionConfig`](#automationactionconfig) +- [`AutomationLoop`](#automationloop) - [`AutomationActionExecutionState`](#automationactionexecutionstate) +- [`AutomationActionIteration`](#automationactioniteration) - [`RetryStrategy`](#retrystrategy) - [`AutomationAction`](#automationaction) - [`ErrorOutput`](#erroroutput) @@ -74,6 +79,12 @@ const { data } = await automationClient.searchFlows(...) - [`MapEntityActionConfig`](#mapentityactionconfig) - [`MapEntityAction`](#mapentityaction) - [`MapEntityConfig`](#mapentityconfig) +- [`GraphContextEntry`](#graphcontextentry) +- [`GraphSeed`](#graphseed) +- [`GraphDefinition`](#graphdefinition) +- [`GraphNode`](#graphnode) +- [`GraphNodeFilter`](#graphnodefilter) +- [`GraphEdge`](#graphedge) - [`MappingConfigRef`](#mappingconfigref) - [`RelationAttribute`](#relationattribute) - [`MappingAttributeV2`](#mappingattributev2) @@ -87,10 +98,23 @@ const { data } = await automationClient.searchFlows(...) - [`AppendValueMapper`](#appendvaluemapper) - [`MoveThreadAction`](#movethreadaction) - [`AssignThreadAction`](#assignthreadaction) +- [`LabelEmailAction`](#labelemailaction) - [`MoveThreadConfig`](#movethreadconfig) +- [`LabelEmailConfig`](#labelemailconfig) - [`AssignThreadConfig`](#assignthreadconfig) +- [`EntityAssignee`](#entityassignee) +- [`EntityAssigneeVariable`](#entityassigneevariable) +- [`AssignEntityConfig`](#assignentityconfig) +- [`AssignEntityActionConfig`](#assignentityactionconfig) +- [`AssignEntityAction`](#assignentityaction) - [`SendEmailActionConfig`](#sendemailactionconfig) - [`SendEmailAction`](#sendemailaction) +- [`ForwardEmailActionConfig`](#forwardemailactionconfig) +- [`ForwardEmailAction`](#forwardemailaction) +- [`ForwardEmailConfig`](#forwardemailconfig) +- [`ReplyEmailActionConfig`](#replyemailactionconfig) +- [`ReplyEmailAction`](#replyemailaction) +- [`ReplyEmailConfig`](#replyemailconfig) - [`SendEmailConfig`](#sendemailconfig) - [`SendEmailCondition`](#sendemailcondition) - [`CreateDocumentActionConfig`](#createdocumentactionconfig) @@ -124,21 +148,31 @@ const { data } = await automationClient.searchFlows(...) - [`ActionSchedule`](#actionschedule) - [`AutomationExecutionId`](#automationexecutionid) - [`AutomationExecution`](#automationexecution) +- [`AutomationLoopState`](#automationloopstate) - [`WorkflowExecutionContext`](#workflowexecutioncontext) +- [`WorkflowWaitContext`](#workflowwaitcontext) - [`ExecutionChain`](#executionchain) - [`TriggerEventManual`](#triggereventmanual) - [`TriggerEventFlowAutomationTask`](#triggereventflowautomationtask) - [`TriggerEventEntityActivity`](#triggerevententityactivity) - [`TriggerEventMessaging`](#triggereventmessaging) - [`TriggerEventEntityOperation`](#triggerevententityoperation) +- [`TriggerEventEventCatalog`](#triggereventeventcatalog) +- [`TriggerEventPayloadRef`](#triggereventpayloadref) - [`ApiCallerContext`](#apicallercontext) - [`ExecutionStatus`](#executionstatus) - [`GetExecutionsResp`](#getexecutionsresp) +- [`SearchExecutionsReq`](#searchexecutionsreq) +- [`SearchExecutionsResp`](#searchexecutionsresp) - [`StartExecutionRequest`](#startexecutionrequest) +- [`ActionInputs`](#actioninputs) +- [`SendEmailInputs`](#sendemailinputs) +- [`FlowExecutionCancelInputs`](#flowexecutioncancelinputs) - [`PatchBulkJobRequest`](#patchbulkjobrequest) - [`BulkTriggerRequest`](#bulktriggerrequest) - [`EntityRef`](#entityref) - [`BulkTriggerJob`](#bulktriggerjob) +- [`ExecutionStats`](#executionstats) - [`ExecItem`](#execitem) - [`JobId`](#jobid) - [`EntityId`](#entityid) @@ -152,12 +186,14 @@ const { data } = await automationClient.searchFlows(...) - [`ApiSubmissionTrigger`](#apisubmissiontrigger) - [`NewEmailThreadTrigger`](#newemailthreadtrigger) - [`ReceivedEmailTrigger`](#receivedemailtrigger) +- [`SentEmailTrigger`](#sentemailtrigger) - [`EntityOperationTrigger`](#entityoperationtrigger) - [`ActivityTrigger`](#activitytrigger) - [`EntityOperation`](#entityoperation) - [`EntitySearchFilter`](#entitysearchfilter) - [`EntitySearchFilterValue`](#entitysearchfiltervalue) - [`EntityManualTrigger`](#entitymanualtrigger) +- [`EventCatalogTrigger`](#eventcatalogtrigger) - [`TriggerCondition`](#triggercondition) - [`Comparison`](#comparison) - [`FilterConditionOnEvent`](#filterconditiononevent) @@ -192,6 +228,8 @@ const { data } = await client.searchFlows({ size: 1, from: 1, trigger_source_id: 'example', + target_workflow: 'example', + trigger_event_name: 'example', include_flows: true, }) ``` @@ -306,11 +344,16 @@ const { data } = await client.getExecutions({ "conditions": [], "schedules": [], "actions": [], + "action_inputs": {}, "resume_token": "eyJraWQiOiJrZXkifQ==", "trigger_context": {}, "version": 2, "trigger_event": {}, - "workflow_context": {} + "workflow_context": {}, + "workflow_wait_context": {}, + "loops": [], + "loop_state": {}, + "chain": ["string"] } ] } @@ -340,10 +383,48 @@ const { data } = await client.startExecution( parent_execution_id: 'string', parent_task_id: 'string', depth: 0 + }, + _automation_chain: ['string'], + entity_contexts: [ + { + entity_id: 'string', + entity_schema: 'string', + is_primary: true + } + ], + resolved_input: { + with_relations: true, + also_pass: [ + { + entity_id: 'string', + entity_schema: 'string' + } + ] + }, + trigger_user_id: '10006129', + run_by: { + user_id: '10006129', + org_id: '739224' } }, flow_execution_id: 'string', - flow_automation_task_id: 'string' + flow_automation_task_id: 'string', + action_inputs: { + 'cancel-flow-execution': { + selected_reasons: [ + { + id: '_6kITMwkv_0Uo4i7fO7Ja', + title: 'Process completed successfully' + } + ], + extra_description: 'string' + }, + 'send-email': { + subject: 'string', + body: 'string', + attachment_entity_ids: ['string'] + } + } }, ) ``` @@ -376,7 +457,10 @@ const { data } = await client.startExecution( { "id": "string", "schedule_id": "string", + "evaluation_order": "AFTER_SCHEDULE", "evaluationResult": true, + "error_output": {}, + "allow_failure": true, "statements": [] } ], @@ -403,12 +487,14 @@ const { data } = await client.startExecution( "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] }, { "id": "9ec3711b-db63-449c-b894-54d5bb622a8f", @@ -422,14 +508,27 @@ const { data } = await client.startExecution( "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] } ], + "action_inputs": { + "cancel-flow-execution": { + "selected_reasons": [], + "extra_description": "string" + }, + "send-email": { + "subject": "string", + "body": "string", + "attachment_entity_ids": ["string"] + } + }, "resume_token": "eyJraWQiOiJrZXkifQ==", "trigger_context": { "entity_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" @@ -451,8 +550,100 @@ const { data } = await client.startExecution( "parent_execution_id": "string", "parent_task_id": "string", "depth": 0 + }, + "_automation_chain": ["string"], + "entity_contexts": [ + {} + ], + "resolved_input": { + "with_relations": true, + "also_pass": [] + }, + "trigger_user_id": "10006129", + "run_by": { + "user_id": "10006129", + "org_id": "739224" } - } + }, + "workflow_wait_context": { + "workflow_execution_id": "string", + "workflow_task_id": "string", + "source": "journey_submission" + }, + "loops": [ + { + "id": "loop_contracts", + "source_path": "submission.steps[0]['Contracts']", + "source_type": "journey-multi-select", + "filter_tags": ["_hidden_ 2a4b1c3d-0000-4000-8000-000000000000 - Dokumente"], + "length": 0 + } + ], + "loop_state": {}, + "chain": ["string"] +} +``` + +
+ +--- + +### `searchExecutions` + +Search automation executions of an entity with cursor-based pagination. +Returns pages of up to 100 executions, newest first. +Prefer this over GET /v1/automation/executions, which returns the full +exec + +`POST /v1/automation/executions:search` + +```ts +const { data } = await client.searchExecutions( + null, + { + entity_id: 'e3d3ebac-baab-4395-abf4-50b5bf1f8b74', + include_flows: false, + size: 25, + cursor: 'string' + }, +) +``` + +
+Response + +```json +{ + "total": 0, + "results": [ + { + "id": "9baf184f-bc81-4128-bca3-d974c90a12c4", + "execution_status": "pending", + "entity_id": "e3d3ebac-baab-4395-abf4-50b5bf1f8b74", + "activity_id": "e3d3ebac-baab-4395-abf4-50b5bf1f8b74", + "entity_snapshot": {}, + "org_id": "e3d3ebac-baab-4395-abf4-50b5bf1f8b74", + "flow_id": "7791b04a-16d2-44a2-9af9-2d59c25c512f", + "flow_name": "Handle contact form", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "current_action_id": "9ec3711b-db63-449c-b894-54d5bb622a8f", + "conditions": [], + "schedules": [], + "actions": [], + "action_inputs": {}, + "resume_token": "eyJraWQiOiJrZXkifQ==", + "trigger_context": {}, + "version": 2, + "trigger_event": {}, + "workflow_context": {}, + "workflow_wait_context": {}, + "loops": [], + "loop_state": {}, + "chain": ["string"] + } + ], + "next_cursor": "string" } ``` @@ -488,13 +679,14 @@ const { data } = await client.bulkTriggerExecutions( ### `getBulkJob` -Get the status of a bulk job that triggers multiple automation executions +Get the status of a bulk job that triggers multiple automation executions. `GET /v1/automation/executions/bulk-jobs/{job_id}` ```ts const { data } = await client.getBulkJob({ job_id: 'example', + include_execution_summary: true, }) ``` @@ -516,6 +708,9 @@ const { data } = await client.getBulkJob({ }, "task_token": "8c086140-f33e-4bb7-a993-50c0f2402c7b", "report_file_entity_id": "string", + "last_error": "ThrottlingException: Throughput exceeds the current capacity of your table or index.", + "restart_count": 1, + "restarted_at": "1970-01-01T00:00:00.000Z", "entity_query": { "type": "refs", "data": [ @@ -542,7 +737,21 @@ const { data } = await client.getBulkJob({ "timestamp": "2025-10-30T15:56:47.842Z", "error": "string" } - ] + ], + "execution_stats": { + "total": 60582, + "pending": 0, + "starting": 0, + "in_progress": 0, + "success": 0, + "failed": 0, + "cancelled": 0, + "skipped": 0, + "paused": 0, + "scheduled": 0, + "hot": 0 + }, + "execution_summary_truncated": true } ``` @@ -552,7 +761,7 @@ const { data } = await client.getBulkJob({ ### `patchBulkJob` -Approve / Cancel bulk job that triggers multiple automation executions +Approve / Cancel / Restart a bulk job that triggers multiple automation executions. `PATCH /v1/automation/executions/bulk-jobs/{job_id}` @@ -586,6 +795,9 @@ const { data } = await client.patchBulkJob( }, "task_token": "8c086140-f33e-4bb7-a993-50c0f2402c7b", "report_file_entity_id": "string", + "last_error": "ThrottlingException: Throughput exceeds the current capacity of your table or index.", + "restart_count": 1, + "restarted_at": "1970-01-01T00:00:00.000Z", "entity_query": { "type": "refs", "data": [ @@ -612,7 +824,21 @@ const { data } = await client.patchBulkJob( "timestamp": "2025-10-30T15:56:47.842Z", "error": "string" } - ] + ], + "execution_stats": { + "total": 60582, + "pending": 0, + "starting": 0, + "in_progress": 0, + "success": 0, + "failed": 0, + "cancelled": 0, + "skipped": 0, + "paused": 0, + "scheduled": 0, + "hot": 0 + }, + "execution_summary_truncated": true } ``` @@ -660,7 +886,10 @@ const { data } = await client.getExecution({ { "id": "string", "schedule_id": "string", + "evaluation_order": "AFTER_SCHEDULE", "evaluationResult": true, + "error_output": {}, + "allow_failure": true, "statements": [] } ], @@ -687,12 +916,14 @@ const { data } = await client.getExecution({ "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] }, { "id": "9ec3711b-db63-449c-b894-54d5bb622a8f", @@ -706,14 +937,27 @@ const { data } = await client.getExecution({ "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] } ], + "action_inputs": { + "cancel-flow-execution": { + "selected_reasons": [], + "extra_description": "string" + }, + "send-email": { + "subject": "string", + "body": "string", + "attachment_entity_ids": ["string"] + } + }, "resume_token": "eyJraWQiOiJrZXkifQ==", "trigger_context": { "entity_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" @@ -735,8 +979,37 @@ const { data } = await client.getExecution({ "parent_execution_id": "string", "parent_task_id": "string", "depth": 0 + }, + "_automation_chain": ["string"], + "entity_contexts": [ + {} + ], + "resolved_input": { + "with_relations": true, + "also_pass": [] + }, + "trigger_user_id": "10006129", + "run_by": { + "user_id": "10006129", + "org_id": "739224" } - } + }, + "workflow_wait_context": { + "workflow_execution_id": "string", + "workflow_task_id": "string", + "source": "journey_submission" + }, + "loops": [ + { + "id": "loop_contracts", + "source_path": "submission.steps[0]['Contracts']", + "source_type": "journey-multi-select", + "filter_tags": ["_hidden_ 2a4b1c3d-0000-4000-8000-000000000000 - Dokumente"], + "length": 0 + } + ], + "loop_state": {}, + "chain": ["string"] } ``` @@ -784,7 +1057,10 @@ const { data } = await client.cancelExecution({ { "id": "string", "schedule_id": "string", + "evaluation_order": "AFTER_SCHEDULE", "evaluationResult": true, + "error_output": {}, + "allow_failure": true, "statements": [] } ], @@ -811,12 +1087,14 @@ const { data } = await client.cancelExecution({ "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] }, { "id": "9ec3711b-db63-449c-b894-54d5bb622a8f", @@ -830,14 +1108,27 @@ const { data } = await client.cancelExecution({ "reason": {}, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", "outputs": {}, "error_output": {}, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [] } ], + "action_inputs": { + "cancel-flow-execution": { + "selected_reasons": [], + "extra_description": "string" + }, + "send-email": { + "subject": "string", + "body": "string", + "attachment_entity_ids": ["string"] + } + }, "resume_token": "eyJraWQiOiJrZXkifQ==", "trigger_context": { "entity_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" @@ -859,8 +1150,37 @@ const { data } = await client.cancelExecution({ "parent_execution_id": "string", "parent_task_id": "string", "depth": 0 + }, + "_automation_chain": ["string"], + "entity_contexts": [ + {} + ], + "resolved_input": { + "with_relations": true, + "also_pass": [] + }, + "trigger_user_id": "10006129", + "run_by": { + "user_id": "10006129", + "org_id": "739224" } - } + }, + "workflow_wait_context": { + "workflow_execution_id": "string", + "workflow_task_id": "string", + "source": "journey_submission" + }, + "loops": [ + { + "id": "loop_contracts", + "source_path": "submission.steps[0]['Contracts']", + "source_type": "journey-multi-select", + "filter_tags": ["_hidden_ 2a4b1c3d-0000-4000-8000-000000000000 - Dokumente"], + "length": 0 + } + ], + "loop_state": {}, + "chain": ["string"] } ``` @@ -939,6 +1259,10 @@ const { data } = await client.resumeExecutionWithToken( {}, {} ], + "action_inputs": { + "cancel-flow-execution": {}, + "send-email": {} + }, "resume_token": "eyJraWQiOiJrZXkifQ==", "trigger_context": { "entity_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef" @@ -954,8 +1278,23 @@ const { data } = await client.resumeExecutionWithToken( "workflow_exec_id": "string", "workflow_exec_task_id": "string", "workflow_role": "trigger_workflow", - "_execution_chain": {} - } + "_execution_chain": {}, + "_automation_chain": ["string"], + "entity_contexts": [], + "resolved_input": {}, + "trigger_user_id": "10006129", + "run_by": {} + }, + "workflow_wait_context": { + "workflow_execution_id": "string", + "workflow_task_id": "string", + "source": "journey_submission" + }, + "loops": [ + {} + ], + "loop_state": {}, + "chain": ["string"] }, "resumedAction": { "id": "9ec3711b-db63-449c-b894-54d5bb622a8f", @@ -965,11 +1304,13 @@ const { data } = await client.resumeExecutionWithToken( "config": { "mapping_config": {}, "target_schema": "string", + "use_uniqueness_criteria": true, "target_unique": ["string"], "mapping_attributes": [], "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] }, "allow_failure": true, "created_automatically": true, @@ -980,6 +1321,7 @@ const { data } = await client.resumeExecutionWithToken( }, "condition_id": "string", "schedule_id": "string", + "loop_id": "string", "execution_status": "pending", "started_at": "string", "updated_at": "string", @@ -989,7 +1331,10 @@ const { data } = await client.resumeExecutionWithToken( "error_reason": "string", "error_info": {} }, - "retry_strategy": "RETRY_AND_RESUME" + "retry_strategy": "RETRY_AND_RESUME", + "iterations": [ + {} + ] } } ``` @@ -1110,6 +1455,10 @@ type AutomationFlow = { configuration: { message_type?: { ... } } + } | { + id?: string // uuid + type: "sent_email" + configuration: object } | { id?: string // uuid type: "new_email_thread" @@ -1120,10 +1469,19 @@ type AutomationFlow = { } | { id?: string // uuid type: "flows_trigger" - configuration: { - source_id: { ... } + configuration?: { journey_id?: { ... } } + } | { + id?: string // uuid + type: "event_catalog" + configuration: { + event_name: { ... } + event_version: { ... } + entity_node_id: { ... } + entity_schema: { ... } + ignore_automation_triggered?: { ... } + } }> trigger_conditions?: Array<{ source: string @@ -1134,41 +1492,16 @@ type AutomationFlow = { conditions?: Array<{ id?: string schedule_id?: string + evaluation_order?: "AFTER_SCHEDULE" | "BEFORE_SCHEDULE" evaluationResult?: boolean - statements?: Array<{ - id?: { ... } - source?: { ... } - operation?: { ... } - values?: { ... } - }> - }> - schedules?: Array<{ - id: string - scheduleApiId?: string - numberOfUnits?: number - timePeriod?: "minutes" | "hours" | "days" | "weeks" | "months" - timeRelation?: "after" | "before" - source: { - id: { ... } - origin: { ... } - schema?: { ... } - attribute?: { ... } + error_output?: { + error_code: { ... } + error_reason: { ... } + error_info?: { ... } // ... } ``` -### `WorkflowContext` - -For automation that are connected to workflows V2, this field tracks various information about the workflow. - -```ts -type WorkflowContext = { - workflow_id: string // uuid - task_id?: string // uuid - workflow_role: "trigger_workflow" | "run_task_automation" -} -``` - ### `WorkflowContextRole` The role this automation plays in the workflow. @@ -1227,6 +1560,14 @@ type SearchAutomationsResp = { id?: { ... } type: { ... } configuration: { ... } + } | { + id?: { ... } + type: { ... } + configuration?: { ... } + } | { + id?: { ... } + type: { ... } + configuration: { ... } }> trigger_conditions?: Array<{ source: { ... } @@ -1237,7 +1578,10 @@ type SearchAutomationsResp = { conditions?: Array<{ id?: { ... } schedule_id?: { ... } + evaluation_order?: { ... } evaluationResult?: { ... } + error_output?: { ... } + allow_failure?: { ... } statements?: { ... } }> schedules?: Array<{ @@ -1248,6 +1592,13 @@ type SearchAutomationsResp = { timeRelation?: { ... } source: { ... } }> + loops?: Array<{ + id: { ... } + source_path: { ... } + source_type?: { ... } + filter_tags?: { ... } + length?: { ... } + }> actions: Array<{ type?: { ... } config?: { ... } @@ -1262,28 +1613,76 @@ type SearchAutomationsResp = { config?: { ... } } | { type?: { ... } - config?: { ... } - } | { - type?: { ... } - config?: { ... } - } | { - type?: { ... } - config?: { ... } - } | { - type?: { ... } - config?: { ... } - } | { - type?: { ... } - config?: { ... } - } | { - type?: { ... } - config?: { ... } - } | { - id?: { ... } // ... } ``` +### `JourneyContextUsagesReq` + +```ts +type JourneyContextUsagesReq = { + journey_id: string // uuid + param_keys: string[] + param_ids?: string[] +} +``` + +### `JourneyContextUsage` + +```ts +type JourneyContextUsage = { + kind: "automation" + resource: { + type: "automation_flow" + id: string + name?: string + } + location?: { + action_id?: string + action_type?: string + } + matched_as: { + dialect: "name" + token: string + at: string + } + link_hint: { + route: "automation-flow" + params: Record + } +} +``` + +### `JourneyContextUsagesResp` + +```ts +type JourneyContextUsagesResp = { + usages: Array<{ + kind: "automation" + resource: { + type: { ... } + id: { ... } + name?: { ... } + } + location?: { + action_id?: { ... } + action_type?: { ... } + } + matched_as: { + dialect: { ... } + token: { ... } + at: { ... } + } + link_hint: { + route: { ... } + params: { ... } + } + }> + status: "ok" | "partial" + scanned: number +} +``` + ### `AnyTrigger` ```ts @@ -1310,7 +1709,7 @@ type AnyTrigger = { type: "entity_operation" configuration: { schema?: string - operations?: "createEntity" | "updateEntity" | "deleteEntity" | "softDeleteEntity" | "restoreEntity"[] + operations?: "createEntity" | "updateEntity" | "deleteEntity" | "softDeleteEntity" | "restoreEntity" | "relationsAdded" | "relationsRemoved" | "relationsSoftDeleted" | "relationsRestored" | "relationsDeleted"[] include_activities?: string[] exclude_activities?: string[] filter_config?: { @@ -1342,6 +1741,10 @@ type AnyTrigger = { configuration: { message_type?: "RECEIVED" } +} | { + id?: string // uuid + type: "sent_email" + configuration: object } | { id?: string // uuid type: "new_email_thread" @@ -1352,10 +1755,19 @@ type AnyTrigger = { } | { id?: string // uuid type: "flows_trigger" - configuration: { - source_id: string // uuid + configuration?: { journey_id?: string // uuid } +} | { + id?: string // uuid + type: "event_catalog" + configuration: { + event_name: string + event_version: string + entity_node_id: string + entity_schema: string + ignore_automation_triggered?: boolean + } } ``` @@ -1371,6 +1783,7 @@ type AnyAction = { version?: { ... } } target_schema: string + use_uniqueness_criteria?: boolean target_unique?: string[] mapping_attributes?: Array<{ target?: { ... } @@ -1400,6 +1813,10 @@ type AnyAction = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> } } | { type?: "trigger-workflow" @@ -1422,6 +1839,8 @@ type AnyAction = { } | { type?: "trigger-share-entity" config?: { + operation?: "share" | "unshare" + unshare_all_partners?: boolean partner_org_ids?: string[] } } | { @@ -1455,13 +1874,6 @@ type AnyAction = { type?: "send-email" config?: { email_template_id?: string - language_code?: "de" | "en" - notify_portal_user_only?: boolean - skip_creating_entities?: boolean - wait_for_confirmation?: boolean - attachments?: Array<{ - source_filter?: { ... } - }> // ... } ``` @@ -1481,6 +1893,7 @@ type AnyActionConfig = { version?: { ... } } target_schema: string + use_uniqueness_criteria?: boolean target_unique?: string[] mapping_attributes?: Array<{ target?: { ... } @@ -1510,6 +1923,10 @@ type AnyActionConfig = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> } allow_failure?: boolean created_automatically?: boolean @@ -1520,6 +1937,7 @@ type AnyActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } | { id?: string flow_action_id?: string @@ -1550,25 +1968,19 @@ type AnyActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } | { id?: string flow_action_id?: string name?: string type?: "trigger-workflow" config?: { + operation?: "share" | "unshare" + unshare_all_partners?: boolean partner_org_ids?: string[] } allow_failure?: boolean created_automatically?: boolean - is_bulk_action?: boolean - reason?: { - message?: string - payload?: Record - } - condition_id?: string - schedule_id?: string -} | { - id?: string // ... } ``` @@ -1591,6 +2003,21 @@ type AutomationActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string +} +``` + +### `AutomationLoop` + +A loop scope on an automation flow. + +```ts +type AutomationLoop = { + id: string + source_path: string + source_type?: "journey-multi-select" | "journey-file-upload" | "previous-action-outputs" | "entity-relation" + filter_tags?: string[] + length?: number } ``` @@ -1610,6 +2037,39 @@ type AutomationActionExecutionState = { } } retry_strategy?: "RETRY_AND_RESUME" | "RETRY_AND_STOP" | "RETRY_ALL_PARENT_CONDITION_ACTIONS" + iterations?: Array<{ + index: number + execution_status: "pending" | "starting" | "in_progress" | "paused" | "success" | "failed" | "cancelled" | "skipped" | "scheduled" | "hot" + started_at?: string // date-time + ended_at?: string // date-time + outputs?: Record + error_output?: { + error_code: { ... } + error_reason: { ... } + error_info?: { ... } + } + }> +} +``` + +### `AutomationActionIteration` + +A snapshot of a single completed pass through a looped action. + +```ts +type AutomationActionIteration = { + index: number + execution_status: "pending" | "starting" | "in_progress" | "paused" | "success" | "failed" | "cancelled" | "skipped" | "scheduled" | "hot" + started_at?: string // date-time + ended_at?: string // date-time + outputs?: Record + error_output?: { + error_code: "MAPPING_ERROR" | "REFRESH_RELATIONS_ERROR" | "DUPLICATE_ENTITY_ERROR" | "TRIGGER_WORKFLOW_ERROR" | "TIMEOUT_ERROR" | "BAD_CONFIG" | "INTERNAL_ERROR" | "TRIGGER_WEBHOOK_ERROR" | "TEMPLATE_ERROR" | "INVALID_PAYLOAD" | "INVALID_SCHEDULE_CONFIG" | "CUSTOM_ACTION_ERROR" | "ORDER_CREATION_ERROR" | "DOCUMENT_GENERATION_ERROR" | "BULK_EMAIL_ERROR" | "SHARING_ERROR" | "CANCEL_FLOW_EXECUTION_ERROR" | "METER_READING_NOT_FOUND" | "ENTITY_NOT_FOUND" + error_reason: string + error_info?: { + details?: { ... } + } + } } ``` @@ -1639,6 +2099,7 @@ type AutomationAction = { } condition_id?: string schedule_id?: string + loop_id?: string execution_status?: "pending" | "starting" | "in_progress" | "paused" | "success" | "failed" | "cancelled" | "skipped" | "scheduled" | "hot" started_at?: string updated_at?: string @@ -1651,6 +2112,18 @@ type AutomationAction = { } } retry_strategy?: "RETRY_AND_RESUME" | "RETRY_AND_STOP" | "RETRY_ALL_PARENT_CONDITION_ACTIONS" + iterations?: Array<{ + index: number + execution_status: "pending" | "starting" | "in_progress" | "paused" | "success" | "failed" | "cancelled" | "skipped" | "scheduled" | "hot" + started_at?: string // date-time + ended_at?: string // date-time + outputs?: Record + error_output?: { + error_code: { ... } + error_reason: { ... } + error_info?: { ... } + } + }> } ``` @@ -1740,6 +2213,7 @@ type CartCheckoutActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -1857,6 +2331,7 @@ type MapEntityActionConfig = { version?: { ... } } target_schema: string + use_uniqueness_criteria?: boolean target_unique?: string[] mapping_attributes?: Array<{ target?: { ... } @@ -1886,6 +2361,10 @@ type MapEntityActionConfig = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> } allow_failure?: boolean created_automatically?: boolean @@ -1896,6 +2375,7 @@ type MapEntityActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -1911,6 +2391,7 @@ type MapEntityAction = { version?: { ... } } target_schema: string + use_uniqueness_criteria?: boolean target_unique?: string[] mapping_attributes?: Array<{ target?: { ... } @@ -1940,6 +2421,10 @@ type MapEntityAction = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> } } ``` @@ -1954,6 +2439,7 @@ type MapEntityConfig = { version?: number } target_schema: string + use_uniqueness_criteria?: boolean target_unique?: string[] mapping_attributes?: Array<{ target?: string @@ -1995,6 +2481,113 @@ type MapEntityConfig = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { + entity_id: { ... } + node_id: { ... } + } + graph: { + nodes: { ... } + edges: { ... } + } + }> +} +``` + +### `GraphContextEntry` + +One multi-hop graph query to run against entity-api's `POST /v1/entity:graph`. Every node +in `graph.nodes` is merged into the mapping's source context under its own `id`, so +listing multiple nodes here costs one entity-api call, not one per node. A node's value +overwrites any existing source-context + +```ts +type GraphContextEntry = { + seed: { + entity_id: string // uuid + node_id: string + } + graph: { + nodes: Array<{ + id: { ... } + schema: { ... } + cardinality?: { ... } + fields?: { ... } + filter?: { ... } + optional?: { ... } + }> + edges: Array<{ + from: { ... } + to: { ... } + }> + } +} +``` + +### `GraphSeed` + +```ts +type GraphSeed = { + entity_id: string // uuid + node_id: string +} +``` + +### `GraphDefinition` + +```ts +type GraphDefinition = { + nodes: Array<{ + id: string + schema: string + cardinality?: "one" | "many" + fields?: string[] + filter?: Array<{ + attribute: { ... } + value: { ... } + }> + optional?: boolean + }> + edges: Array<{ + from: string + to: string + }> +} +``` + +### `GraphNode` + +```ts +type GraphNode = { + id: string + schema: string + cardinality?: "one" | "many" + fields?: string[] + filter?: Array<{ + attribute: string + value: string | number | boolean + }> + optional?: boolean +} +``` + +### `GraphNodeFilter` + +Entities are included in this node's result only if `attribute` exactly equals the literal `value`. + +```ts +type GraphNodeFilter = { + attribute: string + value: string | number | boolean +} +``` + +### `GraphEdge` + +```ts +type GraphEdge = { + from: string + to: string } ``` @@ -2151,6 +2744,26 @@ type AssignThreadAction = { config?: { remove?: string[] add?: string[] + assignment_type?: "direct" | "even_distribution" | "sequential" + only_available_users?: boolean + hold_until_available?: boolean + match_user_skills?: boolean + required_skill_categories?: string[] + skill_match_mode?: "require_all" | "prefer" + fallback?: "leave_unassigned" | "assign_to_fallback" + fallback_assignees?: string[] + write_mode?: "append" | "replace" + } +} +``` + +### `LabelEmailAction` + +```ts +type LabelEmailAction = { + type?: "label-email" + config?: { + add: string[] } } ``` @@ -2163,12 +2776,273 @@ type MoveThreadConfig = { } ``` +### `LabelEmailConfig` + +```ts +type LabelEmailConfig = { + add: string[] +} +``` + ### `AssignThreadConfig` ```ts type AssignThreadConfig = { remove?: string[] add?: string[] + assignment_type?: "direct" | "even_distribution" | "sequential" + only_available_users?: boolean + hold_until_available?: boolean + match_user_skills?: boolean + required_skill_categories?: string[] + skill_match_mode?: "require_all" | "prefer" + fallback?: "leave_unassigned" | "assign_to_fallback" + fallback_assignees?: string[] + write_mode?: "append" | "replace" +} +``` + +### `EntityAssignee` + +A single assignee as stored in a user-relation attribute. Written through +verbatim by the assign-entity worker. Note this object encoding differs +deliberately from AssignThreadConfig, which stores bare id strings — +each matches what its own target accepts. + + +```ts +type EntityAssignee = { + type: "user" | "partner_user" | "partner_organization" | "group" + user_id?: string + group_id?: string + org_id?: string + partner_id?: string + display_name?: string + email?: string +} +``` + +### `EntityAssigneeVariable` + +An assignee resolved at execution time from a user-relation attribute of an +entity in the automation context, e.g. `{{submission._owners}}`. Resolves +against the entity being assigned or the triggering entity, whichever has +the given schema slug. The attribute may hold user ids, `{ org_id, user_id } + +```ts +type EntityAssigneeVariable = { + variable: string +} +``` + +### `AssignEntityConfig` + +```ts +type AssignEntityConfig = { + attribute?: string + assignees?: Array<{ + type: "user" | "partner_user" | "partner_organization" | "group" + user_id?: string + group_id?: string + org_id?: string + partner_id?: string + display_name?: string + email?: string + } | { + variable: string + }> + write_mode?: "replace" | "append" + assignment_type?: "direct" | "sequential" | "even_distribution" + candidate_pool?: Array<{ + type: "user" | "partner_user" | "partner_organization" | "group" + user_id?: string + group_id?: string + org_id?: string + partner_id?: string + display_name?: string + email?: string + }> + candidate_group?: { + type: "user" | "partner_user" | "partner_organization" | "group" + user_id?: string + group_id?: string + org_id?: string + partner_id?: string + display_name?: string + email?: string + } + reset_interval?: "daily" | "weekly" | "monthly" | "never" + workload_filter?: { + attribute?: string + values?: string[] + } + match_user_skills?: boolean + required_skill_categories?: string[] + required_skills?: string[] + required_skills_match_mode?: "require_all" | "prefer" + skill_match_mode?: "require_all" | "prefer" + fallback?: "leave_unassigned" | "assign_to_fallback" + fallback_assignees?: Array<{ + type: "user" | "partner_user" | "partner_organization" | "group" + user_id?: string + group_id?: string + org_id?: string + partner_id?: string + display_name?: string + email?: string + }> + source?: { + id?: string + origin?: "trigger" | "action" + schema?: string + } +} +``` + +### `AssignEntityActionConfig` + +```ts +type AssignEntityActionConfig = { + id?: string + flow_action_id?: string + name?: string + type?: "assign-entity" + config?: { + attribute?: string + assignees?: Array<{ + type: { ... } + user_id?: { ... } + group_id?: { ... } + org_id?: { ... } + partner_id?: { ... } + display_name?: { ... } + email?: { ... } + } | { + variable: { ... } + }> + write_mode?: "replace" | "append" + assignment_type?: "direct" | "sequential" | "even_distribution" + candidate_pool?: Array<{ + type: { ... } + user_id?: { ... } + group_id?: { ... } + org_id?: { ... } + partner_id?: { ... } + display_name?: { ... } + email?: { ... } + }> + candidate_group?: { + type: { ... } + user_id?: { ... } + group_id?: { ... } + org_id?: { ... } + partner_id?: { ... } + display_name?: { ... } + email?: { ... } + } + reset_interval?: "daily" | "weekly" | "monthly" | "never" + workload_filter?: { + attribute?: { ... } + values?: { ... } + } + match_user_skills?: boolean + required_skill_categories?: string[] + required_skills?: string[] + required_skills_match_mode?: "require_all" | "prefer" + skill_match_mode?: "require_all" | "prefer" + fallback?: "leave_unassigned" | "assign_to_fallback" + fallback_assignees?: Array<{ + type: { ... } + user_id?: { ... } + group_id?: { ... } + org_id?: { ... } + partner_id?: { ... } + display_name?: { ... } + email?: { ... } + }> + source?: { + id?: { ... } + origin?: { ... } + schema?: { ... } + } + } + allow_failure?: boolean + created_automatically?: boolean + is_bulk_action?: boolean + reason?: { + message?: string + payload?: Record + } + condition_id?: string + schedule_id?: string + loop_id?: string +} +``` + +### `AssignEntityAction` + +```ts +type AssignEntityAction = { + type?: "assign-entity" + config?: { + attribute?: string + assignees?: Array<{ + type: { ... } + user_id?: { ... } + group_id?: { ... } + org_id?: { ... } + partner_id?: { ... } + display_name?: { ... } + email?: { ... } + } | { + variable: { ... } + }> + write_mode?: "replace" | "append" + assignment_type?: "direct" | "sequential" | "even_distribution" + candidate_pool?: Array<{ + type: { ... } + user_id?: { ... } + group_id?: { ... } + org_id?: { ... } + partner_id?: { ... } + display_name?: { ... } + email?: { ... } + }> + candidate_group?: { + type: { ... } + user_id?: { ... } + group_id?: { ... } + org_id?: { ... } + partner_id?: { ... } + display_name?: { ... } + email?: { ... } + } + reset_interval?: "daily" | "weekly" | "monthly" | "never" + workload_filter?: { + attribute?: { ... } + values?: { ... } + } + match_user_skills?: boolean + required_skill_categories?: string[] + required_skills?: string[] + required_skills_match_mode?: "require_all" | "prefer" + skill_match_mode?: "require_all" | "prefer" + fallback?: "leave_unassigned" | "assign_to_fallback" + fallback_assignees?: Array<{ + type: { ... } + user_id?: { ... } + group_id?: { ... } + org_id?: { ... } + partner_id?: { ... } + display_name?: { ... } + email?: { ... } + }> + source?: { + id?: { ... } + origin?: { ... } + schema?: { ... } + } + } } ``` @@ -2182,10 +3056,16 @@ type SendEmailActionConfig = { type?: "send-email" config?: { email_template_id?: string - language_code?: "de" | "en" + language_code?: string notify_portal_user_only?: boolean skip_creating_entities?: boolean wait_for_confirmation?: boolean + wait_for_journey_submission?: boolean + journey_id?: string + reply_to_sender?: boolean + reply_mode?: "reply_in_thread" | "new_email" + mark_as_done?: boolean + mark_as_read?: boolean attachments?: Array<{ source_filter?: { ... } }> @@ -2202,6 +3082,7 @@ type SendEmailActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -2212,10 +3093,16 @@ type SendEmailAction = { type?: "send-email" config?: { email_template_id?: string - language_code?: "de" | "en" + language_code?: string notify_portal_user_only?: boolean skip_creating_entities?: boolean wait_for_confirmation?: boolean + wait_for_journey_submission?: boolean + journey_id?: string + reply_to_sender?: boolean + reply_mode?: "reply_in_thread" | "new_email" + mark_as_done?: boolean + mark_as_read?: boolean attachments?: Array<{ source_filter?: { ... } }> @@ -2226,19 +3113,149 @@ type SendEmailAction = { } ``` +### `ForwardEmailActionConfig` + +```ts +type ForwardEmailActionConfig = { + id?: string + flow_action_id?: string + name?: string + type?: "forward-email" + config?: { + forward_to: Array<{ + email: { ... } + name?: { ... } + }> + include_attachments?: boolean + subject_prefix?: string + language_code?: "de" | "en" + mark_as_done?: boolean + mark_as_read?: boolean + } + allow_failure?: boolean + created_automatically?: boolean + is_bulk_action?: boolean + reason?: { + message?: string + payload?: Record + } + condition_id?: string + schedule_id?: string + loop_id?: string +} +``` + +### `ForwardEmailAction` + +```ts +type ForwardEmailAction = { + type?: "forward-email" + config?: { + forward_to: Array<{ + email: { ... } + name?: { ... } + }> + include_attachments?: boolean + subject_prefix?: string + language_code?: "de" | "en" + mark_as_done?: boolean + mark_as_read?: boolean + } +} +``` + +### `ForwardEmailConfig` + +```ts +type ForwardEmailConfig = { + forward_to: Array<{ + email: string // email + name?: string + }> + include_attachments?: boolean + subject_prefix?: string + language_code?: "de" | "en" + mark_as_done?: boolean + mark_as_read?: boolean +} +``` + +### `ReplyEmailActionConfig` + +```ts +type ReplyEmailActionConfig = { + id?: string + flow_action_id?: string + name?: string + type?: "reply-email" + config?: { + email_template_id?: string + language_code?: string + reply_mode?: "reply_in_thread" | "new_email" + mark_as_done?: boolean + mark_as_read?: boolean + } + allow_failure?: boolean + created_automatically?: boolean + is_bulk_action?: boolean + reason?: { + message?: string + payload?: Record + } + condition_id?: string + schedule_id?: string + loop_id?: string +} +``` + +### `ReplyEmailAction` + +```ts +type ReplyEmailAction = { + type?: "reply-email" + config?: { + email_template_id?: string + language_code?: string + reply_mode?: "reply_in_thread" | "new_email" + mark_as_done?: boolean + mark_as_read?: boolean + } +} +``` + +### `ReplyEmailConfig` + +```ts +type ReplyEmailConfig = { + email_template_id?: string + language_code?: string + reply_mode?: "reply_in_thread" | "new_email" + mark_as_done?: boolean + mark_as_read?: boolean +} +``` + ### `SendEmailConfig` ```ts type SendEmailConfig = { email_template_id?: string - language_code?: "de" | "en" + language_code?: string notify_portal_user_only?: boolean skip_creating_entities?: boolean wait_for_confirmation?: boolean + wait_for_journey_submission?: boolean + journey_id?: string + reply_to_sender?: boolean + reply_mode?: "reply_in_thread" | "new_email" + mark_as_done?: boolean + mark_as_read?: boolean attachments?: Array<{ source_filter?: { limit?: { ... } filename_regex?: { ... } + filename?: { ... } + filename_pattern?: { ... } attribute?: { ... } relation_tag?: { ... } tag?: { ... } @@ -2287,6 +3304,7 @@ type CreateDocumentActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -2344,6 +3362,7 @@ type TriggerWorkflowActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -2412,6 +3431,8 @@ type TriggerShareEntityActionConfig = { name?: string type?: "trigger-workflow" config?: { + operation?: "share" | "unshare" + unshare_all_partners?: boolean partner_org_ids?: string[] } allow_failure?: boolean @@ -2423,6 +3444,7 @@ type TriggerShareEntityActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -2432,6 +3454,8 @@ type TriggerShareEntityActionConfig = { type TriggerShareEntityAction = { type?: "trigger-share-entity" config?: { + operation?: "share" | "unshare" + unshare_all_partners?: boolean partner_org_ids?: string[] } } @@ -2441,6 +3465,8 @@ type TriggerShareEntityAction = { ```ts type TriggerShareEntityConfig = { + operation?: "share" | "unshare" + unshare_all_partners?: boolean partner_org_ids?: string[] } ``` @@ -2493,6 +3519,7 @@ type TriggerWebhookActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -2543,6 +3570,7 @@ type InformERPActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -2590,6 +3618,7 @@ type TriggerEventActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -2640,6 +3669,7 @@ type FlowExecutionCancelActionConfig = { } condition_id?: string schedule_id?: string + loop_id?: string } ``` @@ -2660,7 +3690,7 @@ type FlowExecutionCancelAction = { ### `FlowExecutionCancelConfig` -Configuration for cancelling a flow execution with selected reasons +Configuration for cancelling a flow execution. The selected reasons are optional; a semi-automated step lets the person running it choose them when the execution starts. ```ts type FlowExecutionCancelConfig = { @@ -2691,7 +3721,7 @@ type ConditionStatement = { source?: { id?: string origin?: "trigger" | "action" - originType?: "entity" | "workflow" | "journey_block" + originType?: "entity" | "workflow" | "journey_block" | "event" schema?: string attribute?: string attributeType?: "string" | "text" | "number" | "boolean" | "date" | "datetime" | "tags" | "country" | "email" | "phone" | "product" | "price" | "status" | "relation" | "multiselect" | "select" | "radio" | "relation_user" | "purpose" | "label" | "payment" | "relation_payment_method" @@ -2710,7 +3740,16 @@ type ConditionStatement = { type ActionCondition = { id?: string schedule_id?: string + evaluation_order?: "AFTER_SCHEDULE" | "BEFORE_SCHEDULE" evaluationResult?: boolean + error_output?: { + error_code: "MAPPING_ERROR" | "REFRESH_RELATIONS_ERROR" | "DUPLICATE_ENTITY_ERROR" | "TRIGGER_WORKFLOW_ERROR" | "TIMEOUT_ERROR" | "BAD_CONFIG" | "INTERNAL_ERROR" | "TRIGGER_WEBHOOK_ERROR" | "TEMPLATE_ERROR" | "INVALID_PAYLOAD" | "INVALID_SCHEDULE_CONFIG" | "CUSTOM_ACTION_ERROR" | "ORDER_CREATION_ERROR" | "DOCUMENT_GENERATION_ERROR" | "BULK_EMAIL_ERROR" | "SHARING_ERROR" | "CANCEL_FLOW_EXECUTION_ERROR" | "METER_READING_NOT_FOUND" | "ENTITY_NOT_FOUND" + error_reason: string + error_info?: { + details?: { ... } + } + } + allow_failure?: boolean statements?: Array<{ id?: string // uuid source?: { @@ -2793,7 +3832,14 @@ type AutomationExecution = { conditions?: Array<{ id?: string schedule_id?: string + evaluation_order?: "AFTER_SCHEDULE" | "BEFORE_SCHEDULE" evaluationResult?: boolean + error_output?: { + error_code: { ... } + error_reason: { ... } + error_info?: { ... } + } + allow_failure?: boolean statements?: Array<{ id?: { ... } source?: { ... } @@ -2819,11 +3865,13 @@ type AutomationExecution = { config?: { mapping_config?: { ... } target_schema: { ... } + use_uniqueness_criteria?: { ... } target_unique?: { ... } mapping_attributes?: { ... } relation_attributes?: { ... } linkback_relation_attribute?: { ... } linkback_relation_tags?: { ... } + graph_context?: { ... } } } | { type?: "trigger-workflow" @@ -2837,6 +3885,8 @@ type AutomationExecution = { } | { type?: "trigger-share-entity" config?: { + operation?: { ... } + unshare_all_partners?: { ... } partner_org_ids?: { ... } } } | { @@ -2859,21 +3909,19 @@ type AutomationExecution = { config?: { event_name: { ... } event_inputs?: { ... } - } - } | { - type?: "create-document" - config?: { - template_id?: { ... } - filename?: { ... } - } - } | { - type?: "send-email" - config?: { - email_template_id?: { ... } // ... } ``` +### `AutomationLoopState` + +```ts +type AutomationLoopState = { + current_index: number + total: number +} +``` + ### `WorkflowExecutionContext` ```ts @@ -2886,6 +3934,37 @@ type WorkflowExecutionContext = { parent_task_id?: string depth?: number } + _automation_chain?: string[] + entity_contexts?: Array<{ + entity_id?: string + entity_schema?: string + is_primary?: boolean + }> + resolved_input?: { + with_relations: boolean + also_pass: Array<{ + entity_id: { ... } + entity_schema?: { ... } + }> + } + trigger_user_id?: string + run_by?: { + user_id: string + org_id?: string + } +} +``` + +### `WorkflowWaitContext` + +Correlation stamped when the triggering submission entity carried workflow wait claims from a journey link. Consumed by svc-workflows to resume a task waiting on this journey submission. + + +```ts +type WorkflowWaitContext = { + workflow_execution_id: string + workflow_task_id: string + source?: string } ``` @@ -2955,7 +4034,7 @@ type TriggerEventEntityActivity = { ```ts type TriggerEventMessaging = { - type?: "new_email_thread" + type?: "new_email_thread" | "sent_email" org_id: string thread_id: string message_id: string @@ -2971,7 +4050,43 @@ type TriggerEventEntityOperation = { entity_id: string org_id: string activity_id: string - operation_type: "createEntity" | "updateEntity" | "deleteEntity" | "softDeleteEntity" | "restoreEntity" + operation_type: "createEntity" | "updateEntity" | "deleteEntity" | "softDeleteEntity" | "restoreEntity" | "relationsAdded" | "relationsRemoved" | "relationsSoftDeleted" | "relationsRestored" | "relationsDeleted" +} +``` + +### `TriggerEventEventCatalog` + +Set on executions started by an Event Catalog event (see EventCatalogTrigger). The full event payload is not stored inline (it may be up to 256 KB) but by reference in `payload_ref`; automation workers hydrate it before every action. + + +```ts +type TriggerEventEventCatalog = { + type: "event_catalog" + org_id: string + entity_id: string + entity_node_id: string + event_id: string + event_name: string + event_version: string + published_version?: string + event_time?: string // date-time + trigger_source_type?: string + trigger_source?: string + payload_ref?: { + bucket: string + key: string + } +} +``` + +### `TriggerEventPayloadRef` + +S3 reference to the stored trigger event payload (`_downgrades` stripped, downgraded to the pinned version) + +```ts +type TriggerEventPayloadRef = { + bucket: string + key: string } ``` @@ -3028,7 +4143,10 @@ type GetExecutionsResp = { conditions?: Array<{ id?: { ... } schedule_id?: { ... } + evaluation_order?: { ... } evaluationResult?: { ... } + error_output?: { ... } + allow_failure?: { ... } statements?: { ... } }> schedules?: Array<{ @@ -3081,28 +4199,143 @@ type GetExecutionsResp = { reason?: { ... } condition_id?: { ... } schedule_id?: { ... } + loop_id?: { ... } execution_status?: { ... } started_at?: { ... } updated_at?: { ... } outputs?: { ... } error_output?: { ... } retry_strategy?: { ... } + iterations?: { ... } } | { type?: { ... } config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + // ... +} +``` + +### `SearchExecutionsReq` + +```ts +type SearchExecutionsReq = { + entity_id: string + include_flows?: boolean + size?: number + cursor?: string +} +``` + +### `SearchExecutionsResp` + +```ts +type SearchExecutionsResp = { + total: number + results: Array<{ + id: string + execution_status?: "pending" | "starting" | "in_progress" | "paused" | "success" | "failed" | "cancelled" | "skipped" | "scheduled" | "hot" + entity_id: string + activity_id?: string + entity_snapshot?: { + _id: { ... } + _title: { ... } + _org: { ... } + _schema: { ... } + _tags?: { ... } + _created_at: { ... } + _updated_at: { ... } + } + org_id: string + flow_id: string + flow_name?: string + created_at?: string // date-time + updated_at?: string // date-time + current_action_id?: string + conditions?: Array<{ + id?: { ... } + schedule_id?: { ... } + evaluation_order?: { ... } + evaluationResult?: { ... } + error_output?: { ... } + allow_failure?: { ... } + statements?: { ... } }> - resume_token?: string - trigger_context?: Record - version?: number - trigger_event?: { + schedules?: Array<{ + id: { ... } + scheduleApiId?: { ... } + numberOfUnits?: { ... } + timePeriod?: { ... } + timeRelation?: { ... } + source: { ... } + }> + actions: Array<{ type?: { ... } - org_id: { ... } - entity_id: { ... } - caller?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + id?: { ... } + flow_action_id?: { ... } + name?: { ... } + type?: { ... } + config?: { ... } + allow_failure?: { ... } + created_automatically?: { ... } + is_bulk_action?: { ... } + reason?: { ... } + condition_id?: { ... } + schedule_id?: { ... } + loop_id?: { ... } + execution_status?: { ... } + started_at?: { ... } + updated_at?: { ... } + outputs?: { ... } + error_output?: { ... } + retry_strategy?: { ... } + iterations?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } } | { type?: { ... } - org_id: { ... } - activity_id: { ... } // ... } ``` @@ -3122,9 +4355,89 @@ type StartExecutionRequest = { parent_task_id?: { ... } depth?: { ... } } + _automation_chain?: string[] + entity_contexts?: Array<{ + entity_id?: { ... } + entity_schema?: { ... } + is_primary?: { ... } + }> + resolved_input?: { + with_relations: { ... } + also_pass: { ... } + } + trigger_user_id?: string + run_by?: { + user_id: { ... } + org_id?: { ... } + } } flow_execution_id?: string flow_automation_task_id?: string + action_inputs?: { + cancel-flow-execution?: { + selected_reasons: { ... } + extra_description?: { ... } + } + send-email?: { + subject?: { ... } + body?: { ... } + attachment_entity_ids?: { ... } + } + } +} +``` + +### `ActionInputs` + +Internal. Run-time inputs for the actions of this execution, keyed by +action type. An action reads the entry for its own type and treats it +as replacing the matching configured values; an action whose type has +no entry runs entirely from its configuration. + +Only the workflows service may set this fi + +```ts +type ActionInputs = { + cancel-flow-execution?: { + selected_reasons: Array<{ + id: { ... } + title: { ... } + }> + extra_description?: string + } + send-email?: { + subject?: string + body?: string + attachment_entity_ids?: string[] + } +} +``` + +### `SendEmailInputs` + +Adjustments a person made to an email before sending it, replacing the rendered values the template produced. The template itself is untouched. + +`attachment_entity_ids` is a request, not an instruction: the worker keeps only the ids that are genuinely files of the entity this execution runs on, so a + +```ts +type SendEmailInputs = { + subject?: string + body?: string + attachment_entity_ids?: string[] +} +``` + +### `FlowExecutionCancelInputs` + +The cancellation reasons a person chose when running a semi-automated cancel step, replacing `selected_reasons` from the action's configuration. + +```ts +type FlowExecutionCancelInputs = { + selected_reasons: Array<{ + id: string + title: string + }> + extra_description?: string } ``` @@ -3132,8 +4445,8 @@ type StartExecutionRequest = { ```ts type PatchBulkJobRequest = { - action: "APPROVE" | "CANCEL" - task_token: string + action: "APPROVE" | "CANCEL" | "RESTART" + task_token?: string } ``` @@ -3171,36 +4484,9 @@ type BulkTriggerRequest = { exists?: { field: { ... } } - $and?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $or?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $not?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> + $and?: { ... } + $or?: { ... } + $not?: { ... } }> trigger_context?: Record } @@ -3230,6 +4516,9 @@ type BulkTriggerJob = { trigger_context?: Record task_token?: string report_file_entity_id?: string + last_error?: string + restart_count?: number + restarted_at?: string // date-time entity_query?: { type: "refs" | "query" | "filter" data: Array<{ @@ -3262,6 +4551,40 @@ type BulkTriggerJob = { timestamp?: string // date-time error?: string }> + execution_stats?: { + total: number + pending?: number + starting?: number + in_progress?: number + success?: number + failed?: number + cancelled?: number + skipped?: number + paused?: number + scheduled?: number + hot?: number + } + execution_summary_truncated?: boolean +} +``` + +### `ExecutionStats` + +Number of execution items of a bulk trigger job per execution status. Always complete. + +```ts +type ExecutionStats = { + total: number + pending?: number + starting?: number + in_progress?: number + success?: number + failed?: number + cancelled?: number + skipped?: number + paused?: number + scheduled?: number + hot?: number } ``` @@ -3328,8 +4651,7 @@ type AutomationTrigger = { type FlowsTrigger = { id?: string // uuid type: "flows_trigger" - configuration: { - source_id: string // uuid + configuration?: { journey_id?: string // uuid } } @@ -3373,6 +4695,12 @@ type ApiSubmissionTrigger = { ### `NewEmailThreadTrigger` +Starts the flow when an email starts a new thread. The thread is the execution's entity. + +For outbound threads, an email that failed to send or a bulk email does not start the flow, +and neither does an email whose automation chain already contains the flow. A flow that +sends emails itself (a send-em + ```ts type NewEmailThreadTrigger = { id?: string // uuid @@ -3396,6 +4724,23 @@ type ReceivedEmailTrigger = { } ``` +### `SentEmailTrigger` + +Starts the flow for every email sent from epilot: emails and replies sent from the inbox, +including replies sent from a draft, and emails sent by automations or Flows, except sends +that skip creating entities. The sent email is the execution's entity. The outgoing +counterpart of `received_email`. + +O + +```ts +type SentEmailTrigger = { + id?: string // uuid + type: "sent_email" + configuration: object +} +``` + ### `EntityOperationTrigger` - If provides filter_config, executes an automation based on the filtered configuration when an entity event occurs. @@ -3408,7 +4753,7 @@ type EntityOperationTrigger = { type: "entity_operation" configuration: { schema?: string - operations?: "createEntity" | "updateEntity" | "deleteEntity" | "softDeleteEntity" | "restoreEntity"[] + operations?: "createEntity" | "updateEntity" | "deleteEntity" | "softDeleteEntity" | "restoreEntity" | "relationsAdded" | "relationsRemoved" | "relationsSoftDeleted" | "relationsRestored" | "relationsDeleted"[] include_activities?: string[] exclude_activities?: string[] filter_config?: { @@ -3440,7 +4785,7 @@ type ActivityTrigger = { ### `EntityOperation` ```ts -type EntityOperation = "createEntity" | "updateEntity" | "deleteEntity" | "softDeleteEntity" | "restoreEntity" +type EntityOperation = "createEntity" | "updateEntity" | "deleteEntity" | "softDeleteEntity" | "restoreEntity" | "relationsAdded" | "relationsRemoved" | "relationsSoftDeleted" | "relationsRestored" | "relationsDeleted" ``` ### `EntitySearchFilter` @@ -3466,90 +4811,10 @@ type EntitySearchFilter = Array<{ exists?: { field: string } - $and?: Array<{ - term?: Record - terms?: Record - ids?: { - values?: { ... } - } - range?: Record - exists?: { - field: { ... } - } - $and?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $or?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $not?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - }> - $or?: Array<{ - term?: Record - terms?: Record - ids?: { - values?: { ... } - } - range?: Record - exists?: { - field: { ... } - } - $and?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $or?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - // ... -} + $and?: { ... } + $or?: { ... } + $not?: { ... } +}> ``` ### `EntitySearchFilterValue` @@ -3572,6 +4837,25 @@ type EntityManualTrigger = { } ``` +### `EventCatalogTrigger` + +Starts the flow when an Event Catalog event is published for the organization. The execution runs in the context of one entity from the event's entity graph (`entity_node_id`), and the event payload is available to conditions and actions as the `event` variable context. + + +```ts +type EventCatalogTrigger = { + id?: string // uuid + type: "event_catalog" + configuration: { + event_name: string + event_version: string + entity_node_id: string + entity_schema: string + ignore_automation_triggered?: boolean + } +} +``` + ### `TriggerCondition` ```ts @@ -3592,39 +4876,7 @@ type Comparison = "equals" | "any_of" | "not_empty" | "is_empty" ```ts type FilterConditionOnEvent = { - $or?: Array<{ - $or?: Array<{ - $or?: { ... } - } | Record>> - } | Record>> + $or?: { ... }[] } | Record>> - } | Record>> - } | Record>> + $or?: { ... }[] } | Record>> - } | Record>> + $or?: { ... }[] } | Record>> - } | Record>> + $or?: { ... }[] } | Record schedules?: Array<{ @@ -4027,29 +5168,26 @@ type ResumeResp = { reason?: { ... } condition_id?: { ... } schedule_id?: { ... } + loop_id?: { ... } execution_status?: { ... } started_at?: { ... } updated_at?: { ... } outputs?: { ... } error_output?: { ... } retry_strategy?: { ... } + iterations?: { ... } } | { type?: { ... } config?: { ... } - }> - resume_token?: string - trigger_context?: Record - version?: number - trigger_event?: { + } | { type?: { ... } - org_id: { ... } - entity_id: { ... } - caller?: { ... } + config?: { ... } + } | { + type?: { ... } + config?: { ... } } | { type?: { ... } - org_id: { ... } - activity_id: { ... } - activity_type: { ... } + config?: { ... } // ... } ``` diff --git a/docs/sdk/clients/billing.md b/docs/sdk/clients/billing.md index 9f2bcd9b..d41fe41c 100644 --- a/docs/sdk/clients/billing.md +++ b/docs/sdk/clients/billing.md @@ -42,26 +42,59 @@ const { data } = await billingClient.getBillingEvents(...) - [`updateContractEntity`](#updatecontractentity) - [`deleteContractEntity`](#deletecontractentity) +**Pricing Information** +- [`getContractPricingInformation`](#getcontractpricinginformation) +- [`getBillingAccountPricingInformation`](#getbillingaccountpricinginformation) + +**Configuration History** +- [`getContractConfigurationHistory`](#getcontractconfigurationhistory) +- [`getBillingAccountConfigurationHistory`](#getbillingaccountconfigurationhistory) + **Balance** - [`getCustomerBalance`](#getcustomerbalance) **Schemas** +- [`Error`](#error) - [`BaseEntity`](#baseentity) - [`EntityId`](#entityid) - [`EntitySlug`](#entityslug) - [`EntityRelationItem`](#entityrelationitem) - [`BaseBillingEvent`](#basebillingevent) +- [`BillingEvent`](#billingevent) +- [`BillingEventUpdate`](#billingeventupdate) - [`InstallmentEvent`](#installmentevent) +- [`PaymentEvent`](#paymentevent) - [`ReimbursementEvent`](#reimbursementevent) -- [`BillingEvent`](#billingevent) +- [`DunningFeeEvent`](#dunningfeeevent) +- [`InvoiceEvent`](#invoiceevent) +- [`FinalBillEvent`](#finalbillevent) +- [`BonusEvent`](#bonusevent) +- [`CorrectionEvent`](#correctionevent) +- [`CustomEvent`](#customevent) - [`Contract`](#contract) - [`ContractItem`](#contractitem) +- [`InstallmentAmountValue`](#installmentamountvalue) +- [`PriceContext`](#pricecontext) +- [`DynamicTariffPriceContext`](#dynamictariffpricecontext) +- [`ConfigurationHistoryContext`](#configurationhistorycontext) +- [`ContractTariffContext`](#contracttariffcontext) +- [`ContractPricingContext`](#contractpricingcontext) +- [`ConfigurationHistoryRowBase`](#configurationhistoryrowbase) +- [`InstallmentAmountChangedHistoryRow`](#installmentamountchangedhistoryrow) +- [`ContractPricingChangedHistoryRow`](#contractpricingchangedhistoryrow) +- [`ConfigurationHistoryRow`](#configurationhistoryrow) +- [`ConfigurationHistoryResponse`](#configurationhistoryresponse) +- [`PricingInformationBalance`](#pricinginformationbalance) +- [`ContractPricingSchedule`](#contractpricingschedule) +- [`ContractPricingInformation`](#contractpricinginformation) +- [`BillingAccountPricingInformation`](#billingaccountpricinginformation) - [`Balance`](#balance) - [`Currency`](#currency) ### `getBillingEvents` -Get and filter billing events such as installments and reimbursements. +Retrieve and filter billing events (Buchungssätze) such as installments (Abschlagszahlungen), +payments (Zahlungseingänge), and reimbursements (Rückerstattungen). `GET /v1/billing/events` @@ -70,6 +103,7 @@ const { data } = await client.getBillingEvents({ from: 1, size: 1, entity_id: ['...'], + contact_id: 'example', event_type: 'example', date_after: 'example', date_before: 'example', @@ -81,30 +115,18 @@ const { data } = await client.getBillingEvents({ ```json { - "hits": 0, + "hits": 42, "results": [ { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ] } @@ -116,7 +138,8 @@ const { data } = await client.getBillingEvents({ ### `createBillingEvent` -Create a new billing event. +Create a new billing event (Buchungssatz) such as an installment (Abschlagszahlung), +payment (Zahlungseingang), or reimbursement (Rückerstattung). `POST /v1/billing/events` @@ -124,27 +147,15 @@ Create a new billing event. const { data } = await client.createBillingEvent( null, { - billing_amount: 10050, - billing_amount_decimal: '100.50', - billing_currency: 'EUR', - external_id: 'd4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e', - contract: { - $relation: [ - { - entity_id: 'f589786b-3024-43cd-9cb3-5a3c953f2896' - } - ] - }, - _id: '5da0a718-c822-403d-9f5d-20d4584e0528', - _title: 'string', - _org: 'string', - _schema: 'contact', - _tags: ['string'], - _created_at: 'string', - _updated_at: 'string', type: 'installment', - due_date: '1970-01-01T00:00:00.000Z', - paid_date: '1970-01-01T00:00:00.000Z' + direction: 'debit', + note: 'July power & gas installment payment', + status: 'open', + booking_date: '2025-07-10', + due_date: '2025-07-10', + billing_amount: 5000, + billing_amount_decimal: '50.00', + billing_currency: 'EUR' }, ) ``` @@ -154,27 +165,15 @@ const { data } = await client.createBillingEvent( ```json { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ``` @@ -184,7 +183,7 @@ const { data } = await client.createBillingEvent( ### `getBillingEvent` -Get a single billing event by ID. +Retrieve a single billing event (Buchungssatz) by its unique ID. `GET /v1/billing/events/{id}` @@ -199,27 +198,15 @@ const { data } = await client.getBillingEvent({ ```json { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ``` @@ -229,7 +216,7 @@ const { data } = await client.getBillingEvent({ ### `updateBillingEvent` -Update an existing billing event. +Update an existing billing event (Buchungssatz). `PATCH /v1/billing/events/{id}` @@ -239,10 +226,12 @@ const { data } = await client.updateBillingEvent( id: '123e4567-e89b-12d3-a456-426614174000', }, { - billing_amount: 10050, - billing_amount_decimal: '100.50', + type: 'installment', + direction: 'debit', + billing_amount: 10000, + billing_amount_decimal: '100.00', billing_currency: 'EUR', - external_id: 'd4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e', + external_id: 'SAP-54321', contract: { $relation: [ { @@ -250,16 +239,24 @@ const { data } = await client.updateBillingEvent( } ] }, - _id: '5da0a718-c822-403d-9f5d-20d4584e0528', - _title: 'string', - _org: 'string', - _schema: 'contact', - _tags: ['string'], - _created_at: 'string', - _updated_at: 'string', - type: 'installment', - due_date: '1970-01-01T00:00:00.000Z', - paid_date: '1970-01-01T00:00:00.000Z' + booking_date: '2025-06-15', + due_date: '2025-06-30', + paid_date: '2025-06-15T10:00:00Z', + status: 'closed', + related_event: 'd4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e', + external_link: { + href: 'https://billing.example.com/invoices/12345', + title: 'Invoice 12345' + }, + attachments: { + $relation: [ + { + entity_id: 'f589786b-3024-43cd-9cb3-5a3c953f2896' + } + ] + }, + note: 'Teilzahlung für Abschlag Juni', + internal_note: 'Rückmeldung von SAP: Betrag aus Zahlungsavis 2025-06-14 übernommen' }, ) ``` @@ -269,27 +266,15 @@ const { data } = await client.updateBillingEvent( ```json { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ``` @@ -299,7 +284,7 @@ const { data } = await client.updateBillingEvent( ### `deleteBillingEvent` -Delete an existing billing event. +Delete an existing billing event (Buchungssatz). `DELETE /v1/billing/events/{id}` @@ -313,7 +298,7 @@ const { data } = await client.deleteBillingEvent({ ### `getBillingEventByExternalId` -Get a single billing event by External ID. +Retrieve a billing event (Buchungssatz) by its external system identifier. `GET /v1/billing/external/{external_id}` @@ -328,27 +313,15 @@ const { data } = await client.getBillingEventByExternalId({ ```json { - "billing_amount": 10050, - "billing_amount_decimal": "100.50", - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", "type": "installment", - "due_date": "1970-01-01T00:00:00.000Z", - "paid_date": "1970-01-01T00:00:00.000Z" + "direction": "debit", + "note": "July power & gas installment payment", + "status": "open", + "booking_date": "2025-07-10", + "due_date": "2025-07-10", + "billing_amount": 5000, + "billing_amount_decimal": "50.00", + "billing_currency": "EUR" } ``` @@ -358,7 +331,7 @@ const { data } = await client.getBillingEventByExternalId({ ### `createContractEntity` -Create a new contract entity. +Create a new contract entity (Vertrag) for billing purposes. `POST /v1/billing/contracts` @@ -367,32 +340,32 @@ const { data } = await client.createContractEntity( null, { _id: '5da0a718-c822-403d-9f5d-20d4584e0528', - _title: 'string', - _org: 'string', - _schema: 'contact', - _tags: ['string'], - _created_at: 'string', - _updated_at: 'string', - contract_name: 'Grid Contract', - contract_number: '12345', - status: 'approved', - description: 'This contract is for the supply of widgets.', - account_number: '67890', + _title: 'Abschlagszahlung Juli 2025', + _org: '123456', + _schema: 'billing_event', + _tags: ['billing', 'energy'], + _created_at: '2025-06-15T10:30:00Z', + _updated_at: '2025-06-15T14:45:00Z', + contract_name: 'Stromvertrag Haushalt', + contract_number: 'STR-2025-001234', + status: 'active', + description: 'Haushaltsstrom-Tarif mit 24 Monaten Preisgarantie', + account_number: 'KD-67890', branch: 'power', - billing_address: '123 Main St, Anytown', - delivery_address: '456 Elm St, Anytown', - additional_addresses: '789 Oak St, Anytown', - termination_date: '2022-01-01', - termination_reason: 'Non-payment', + billing_address: 'Musterstraße 123, 50667 Köln', + delivery_address: 'Musterstraße 123, 50667 Köln', + additional_addresses: 'Postfach 456, 50668 Köln', + termination_date: '2025-12-31', + termination_reason: 'Kundenkündigung', billing_period: 'monthly', billing_duration_amount: 30, - renewal_duration_amount: 365, - renewal_duration_unit: 'years', + renewal_duration_amount: 12, + renewal_duration_unit: 'months', notice_time_amount: 30, notice_time_unit: 'months', - start_date: '2021-01-01', - billing_due_day: 2, - installment_amount: 10050, + start_date: '2025-01-01', + billing_due_day: 15, + installment_amount: 8500, balance: 8990, balance_currency: 'EUR' }, @@ -405,32 +378,32 @@ const { data } = await client.createContractEntity( ```json { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", + "_title": "Abschlagszahlung Juli 2025", + "_org": "123456", + "_schema": "billing_event", + "_tags": ["billing", "energy"], + "_created_at": "2025-06-15T10:30:00Z", + "_updated_at": "2025-06-15T14:45:00Z", + "contract_name": "Stromvertrag Haushalt", + "contract_number": "STR-2025-001234", + "status": "active", + "description": "Haushaltsstrom-Tarif mit 24 Monaten Preisgarantie", + "account_number": "KD-67890", "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", + "billing_address": "Musterstraße 123, 50667 Köln", + "delivery_address": "Musterstraße 123, 50667 Köln", + "additional_addresses": "Postfach 456, 50668 Köln", + "termination_date": "2025-12-31", + "termination_reason": "Kundenkündigung", "billing_period": "monthly", "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", + "renewal_duration_amount": 12, + "renewal_duration_unit": "months", "notice_time_amount": 30, "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, + "start_date": "2025-01-01", + "billing_due_day": 15, + "installment_amount": 8500, "balance": 8990, "balance_currency": "EUR" } @@ -442,7 +415,7 @@ const { data } = await client.createContractEntity( ### `updateContractEntity` -Update an existing contract entity. +Update an existing contract entity (Vertrag). `PATCH /v1/billing/contracts/{id}` @@ -453,32 +426,32 @@ const { data } = await client.updateContractEntity( }, { _id: '5da0a718-c822-403d-9f5d-20d4584e0528', - _title: 'string', - _org: 'string', - _schema: 'contact', - _tags: ['string'], - _created_at: 'string', - _updated_at: 'string', - contract_name: 'Grid Contract', - contract_number: '12345', - status: 'approved', - description: 'This contract is for the supply of widgets.', - account_number: '67890', + _title: 'Abschlagszahlung Juli 2025', + _org: '123456', + _schema: 'billing_event', + _tags: ['billing', 'energy'], + _created_at: '2025-06-15T10:30:00Z', + _updated_at: '2025-06-15T14:45:00Z', + contract_name: 'Stromvertrag Haushalt', + contract_number: 'STR-2025-001234', + status: 'active', + description: 'Haushaltsstrom-Tarif mit 24 Monaten Preisgarantie', + account_number: 'KD-67890', branch: 'power', - billing_address: '123 Main St, Anytown', - delivery_address: '456 Elm St, Anytown', - additional_addresses: '789 Oak St, Anytown', - termination_date: '2022-01-01', - termination_reason: 'Non-payment', + billing_address: 'Musterstraße 123, 50667 Köln', + delivery_address: 'Musterstraße 123, 50667 Köln', + additional_addresses: 'Postfach 456, 50668 Köln', + termination_date: '2025-12-31', + termination_reason: 'Kundenkündigung', billing_period: 'monthly', billing_duration_amount: 30, - renewal_duration_amount: 365, - renewal_duration_unit: 'years', + renewal_duration_amount: 12, + renewal_duration_unit: 'months', notice_time_amount: 30, notice_time_unit: 'months', - start_date: '2021-01-01', - billing_due_day: 2, - installment_amount: 10050, + start_date: '2025-01-01', + billing_due_day: 15, + installment_amount: 8500, balance: 8990, balance_currency: 'EUR' }, @@ -491,32 +464,32 @@ const { data } = await client.updateContractEntity( ```json { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "string", - "_org": "string", - "_schema": "contact", - "_tags": ["string"], - "_created_at": "string", - "_updated_at": "string", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", + "_title": "Abschlagszahlung Juli 2025", + "_org": "123456", + "_schema": "billing_event", + "_tags": ["billing", "energy"], + "_created_at": "2025-06-15T10:30:00Z", + "_updated_at": "2025-06-15T14:45:00Z", + "contract_name": "Stromvertrag Haushalt", + "contract_number": "STR-2025-001234", + "status": "active", + "description": "Haushaltsstrom-Tarif mit 24 Monaten Preisgarantie", + "account_number": "KD-67890", "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", + "billing_address": "Musterstraße 123, 50667 Köln", + "delivery_address": "Musterstraße 123, 50667 Köln", + "additional_addresses": "Postfach 456, 50668 Köln", + "termination_date": "2025-12-31", + "termination_reason": "Kundenkündigung", "billing_period": "monthly", "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", + "renewal_duration_amount": 12, + "renewal_duration_unit": "months", "notice_time_amount": 30, "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, + "start_date": "2025-01-01", + "billing_due_day": 15, + "installment_amount": 8500, "balance": 8990, "balance_currency": "EUR" } @@ -528,7 +501,7 @@ const { data } = await client.updateContractEntity( ### `deleteContractEntity` -Delete an existing contract entity. +Delete an existing contract entity (Vertrag). `DELETE /v1/billing/contracts/{id}` @@ -540,9 +513,264 @@ const { data } = await client.deleteContractEntity({ --- +### `getContractPricingInformation` + +Get current pricing information and recent configuration history for a Contract. + +`GET /v1/billing/contracts/{id}/pricing_information` + +```ts +const { data } = await client.getContractPricingInformation({ + id: '123e4567-e89b-12d3-a456-426614174000', + history_change_types: 'example', + include_history: true, +}) +``` + +
+Response + +```json +{ + "entity_type": "contract", + "entity_id": "string", + "title": "string", + "current_installment_amount": { + "amount": 10050, + "amount_decimal": "100.50", + "currency": "EUR" + }, + "context": { + "base_price": { + "price_id": "string", + "price_title": "string", + "tariff_type": "string", + "pricing_model": "string", + "unit_amount_gross_decimal": "string", + "unit_amount_net_decimal": "string", + "before_discount_unit_amount_gross_decimal": "string", + "before_discount_unit_amount_net_decimal": "string", + "unit_discount_amount_decimal": "string", + "unit_discount_amount_net_decimal": "string", + "currency": "EUR", + "billing_period": "string", + "unit": "string", + "has_discount": true, + "is_dynamic_tariff": true, + "dynamic_tariff": {} + }, + "base_prices": [ + {} + ], + "working_price": { + "price_id": "string", + "price_title": "string", + "tariff_type": "string", + "pricing_model": "string", + "unit_amount_gross_decimal": "string", + "unit_amount_net_decimal": "string", + "before_discount_unit_amount_gross_decimal": "string", + "before_discount_unit_amount_net_decimal": "string", + "unit_discount_amount_decimal": "string", + "unit_discount_amount_net_decimal": "string", + "currency": "EUR", + "billing_period": "string", + "unit": "string", + "has_discount": true, + "is_dynamic_tariff": true, + "dynamic_tariff": {} + }, + "working_prices": [ + {} + ] + }, + "balance": { + "amount": 8990, + "amount_decimal": "89.90", + "currency": "EUR" + }, + "schedule": { + "billing_due_day": 0, + "billing_period": "weekly", + "installments_per_year": 0, + "inferred": true + }, + "pending_installment_change": true, + "history": [ + { + "event_id": "string", + "org_id": "string", + "entity_type": "contract", + "entity_id": "string", + "schema_version": 1, + "effective_at": "1970-01-01T00:00:00.000Z", + "changed_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "source": "portal", + "source_label": "string", + "source_system": "string", + "source_reference": "string", + "change_type": "installment_amount_changed", + "previous_value": {}, + "new_value": {}, + "context": {} + } + ] +} +``` + +
+ +--- + +### `getBillingAccountPricingInformation` + +Get current pricing information for the active Contracts linked to a Billing Account. + +`GET /v1/billing/billing_accounts/{id}/pricing_information` + +```ts +const { data } = await client.getBillingAccountPricingInformation({ + id: '123e4567-e89b-12d3-a456-426614174000', + history_change_types: 'example', + include_history: true, +}) +``` + +
+Response + +```json +{ + "entity_type": "billing_account", + "entity_id": "string", + "title": "string", + "balance": { + "amount": 8990, + "amount_decimal": "89.90", + "currency": "EUR" + }, + "contracts": [ + { + "entity_type": "contract", + "entity_id": "string", + "title": "string", + "current_installment_amount": {}, + "context": {}, + "balance": {}, + "schedule": {}, + "pending_installment_change": true, + "history": [] + } + ] +} +``` + +
+ +--- + +### `getContractConfigurationHistory` + +Get billing configuration history for a Contract. + +`GET /v1/billing/contracts/{id}/configuration_history` + +```ts +const { data } = await client.getContractConfigurationHistory({ + id: '123e4567-e89b-12d3-a456-426614174000', + change_type: 'example', + history_change_types: 'example', + from: 1, + size: 1, +}) +``` + +
+Response + +```json +{ + "history": [ + { + "event_id": "string", + "org_id": "string", + "entity_type": "contract", + "entity_id": "string", + "schema_version": 1, + "effective_at": "1970-01-01T00:00:00.000Z", + "changed_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "source": "portal", + "source_label": "string", + "source_system": "string", + "source_reference": "string", + "change_type": "installment_amount_changed", + "previous_value": {}, + "new_value": {}, + "context": {} + } + ], + "total": 0 +} +``` + +
+ +--- + +### `getBillingAccountConfigurationHistory` + +Get merged billing configuration history for active Contracts linked to a Billing Account. + +`GET /v1/billing/billing_accounts/{id}/configuration_history` + +```ts +const { data } = await client.getBillingAccountConfigurationHistory({ + id: '123e4567-e89b-12d3-a456-426614174000', + change_type: 'example', + history_change_types: 'example', + from: 1, + size: 1, +}) +``` + +
+Response + +```json +{ + "history": [ + { + "event_id": "string", + "org_id": "string", + "entity_type": "contract", + "entity_id": "string", + "schema_version": 1, + "effective_at": "1970-01-01T00:00:00.000Z", + "changed_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "source": "portal", + "source_label": "string", + "source_system": "string", + "source_reference": "string", + "change_type": "installment_amount_changed", + "previous_value": {}, + "new_value": {}, + "context": {} + } + ], + "total": 0 +} +``` + +
+ +--- + ### `getCustomerBalance` -Get total balance across all contracts and orders of a customer entity. +Retrieve the total balance (Kontostand) across all contracts and orders for a customer. `GET /v1/billing/customers/{id}/balance` @@ -569,23 +797,36 @@ const { data } = await client.getCustomerBalance({ ## Schemas +### `Error` + +Standard error response format + +```ts +type Error = { + error: string + message: string +} +``` + ### `BaseEntity` +Base schema for all epilot entities with common system fields + ```ts type BaseEntity = { _id?: string _title?: string _org?: string - _schema?: "contact" | "contract" | "file" | "order" | "opportunity" | "product" | "price" | "meter" | "meter_counter" | "billing_event" + _schema?: string _tags?: string[] - _created_at?: string - _updated_at?: string + _created_at?: string // date-time + _updated_at?: string // date-time } ``` ### `EntityId` -Entity ID +Unique entity identifier (UUID format) ```ts type EntityId = string @@ -593,14 +834,16 @@ type EntityId = string ### `EntitySlug` -URL-friendly identifier for the entity schema +URL-friendly identifier for the entity schema (Schema-Slug) ```ts -type EntitySlug = "contact" | "contract" | "file" | "order" | "opportunity" | "product" | "price" | "meter" | "meter_counter" | "billing_event" +type EntitySlug = string ``` ### `EntityRelationItem` +Reference to a related entity + ```ts type EntityRelationItem = { entity_id?: string @@ -609,26 +852,22 @@ type EntityRelationItem = { ### `BaseBillingEvent` -A base billing event to be inherited by all billing events. +Represents a single financial transaction entry (Buchungssatz) in the billing ledger. +Each entry is either a debit or a credit, following double-entry accounting principles. +Common types include Abschlagszahlung (installment), Zahlungseingang (payment), Rückerstattung (reimbursement), etc. + ```ts type BaseBillingEvent = { _id?: string _title?: string _org?: string - _schema?: "contact" | "contract" | "file" | "order" | "opportunity" | "product" | "price" | "meter" | "meter_counter" | "billing_event" + _schema?: string _tags?: string[] - _created_at?: string - _updated_at?: string -} -``` - -### `InstallmentEvent` - -An entity that describes an installment billing event. - -```ts -type InstallmentEvent = { + _created_at?: string // date-time + _updated_at?: string // date-time + type: string + direction?: "debit" | "credit" billing_amount: number billing_amount_decimal: string billing_currency: string @@ -638,76 +877,220 @@ type InstallmentEvent = { entity_id?: { ... } }> } - type: "installment" - due_date: string // date-time + booking_date: string // date + due_date?: string // date paid_date?: string // date-time -} -``` - -### `ReimbursementEvent` - -An entity that describes a reimbursement billing event. - -```ts -type ReimbursementEvent = { - billing_amount: number - billing_amount_decimal: string - billing_currency: string - external_id?: string - contract: { + status?: "closed" | "open" + related_event?: string + external_link?: { + href?: string // uri + title?: string + } + attachments?: { $relation?: Array<{ entity_id?: { ... } }> } - type: "reimbursement" - paid_date?: string // date-time + note?: string + internal_note?: string } ``` ### `BillingEvent` -An entity that describes a billing event such as a future installment or a reimbursement back to the customer. +Collection of supported billing event types (Buchungsarten). +Each type represents a different kind of financial transaction +that affects the customer's balance. + ```ts type BillingEvent = { - billing_amount: number - billing_amount_decimal: string - billing_currency: string + type?: "installment" +} | { + type?: "payment" +} | { + type?: "reimbursement" +} | { + type?: "dunning_fee" +} | { + type?: "invoice" +} | { + type?: "final_bill" +} | { + type?: "bonus" +} | { + type?: "correction" +} | { + type?: string +} +``` + +### `BillingEventUpdate` + +Fields to update on an existing billing event. + +```ts +type BillingEventUpdate = { + type?: string + direction?: "debit" | "credit" + billing_amount?: number + billing_amount_decimal?: string + billing_currency?: string external_id?: string - contract: { + contract?: { $relation?: Array<{ entity_id?: { ... } }> } - type: "installment" - due_date: string // date-time + booking_date?: string // date + due_date?: string // date paid_date?: string // date-time -} | { - billing_amount: number - billing_amount_decimal: string - billing_currency: string - external_id?: string - contract: { + status?: "closed" | "open" + related_event?: string + external_link?: { + href?: string // uri + title?: string + } + attachments?: { $relation?: Array<{ entity_id?: { ... } }> } - type: "reimbursement" - paid_date?: string // date-time + note?: string + internal_note?: string +} +``` + +### `InstallmentEvent` + +Installment billing event (Abschlagszahlung). +Represents a scheduled partial payment that the customer owes, +typically billed monthly for utilities like electricity or gas. + + +```ts +type InstallmentEvent = { + type?: "installment" +} +``` + +### `PaymentEvent` + +Payment received event (Zahlungseingang). +Represents money received from the customer, reducing their balance. +This is a credit transaction. + + +```ts +type PaymentEvent = { + type?: "payment" +} +``` + +### `ReimbursementEvent` + +Reimbursement event (Rückerstattung). +Represents a refund to the customer, typically after overpayment +or billing correction. This is a credit transaction. + + +```ts +type ReimbursementEvent = { + type?: "reimbursement" +} +``` + +### `DunningFeeEvent` + +Dunning fee event (Mahngebühr). +Represents a late payment fee charged to the customer +after a payment reminder has been sent. This is a debit transaction. + + +```ts +type DunningFeeEvent = { + type?: "dunning_fee" +} +``` + +### `InvoiceEvent` + +```ts +type InvoiceEvent = { + type?: "invoice" +} +``` + +### `FinalBillEvent` + +Final bill event (Endabrechnung/Schlussrechnung). +Represents the final settlement when a contract ends, +accounting for actual consumption vs. paid installments. +Can be either debit (customer owes more) or credit (customer overpaid). + + +```ts +type FinalBillEvent = { + type?: "final_bill" +} +``` + +### `BonusEvent` + +Bonus/credit event (Gutschrift/Bonus). +Represents a promotional credit or bonus applied to the customer's account, +such as welcome bonuses or loyalty rewards. This is a credit transaction. + + +```ts +type BonusEvent = { + type?: "bonus" +} +``` + +### `CorrectionEvent` + +Correction event (Korrekturbuchung). +Represents an adjustment to a previous billing entry, +such as correcting an overcharge or undercharge. +Can be either debit or credit depending on the correction. + + +```ts +type CorrectionEvent = { + type?: "correction" +} +``` + +### `CustomEvent` + +Custom billing event (Benutzerdefinierte Buchung). +Allows for organization-specific billing event types not covered +by the standard types. Use a descriptive type name. + + +```ts +type CustomEvent = { + type?: string } ``` ### `Contract` +Represents a customer contract (Vertrag) for billing purposes. +Contracts are the parent entities for billing events and contain +billing configuration such as installment amounts and billing cycles. + + ```ts type Contract = { _id?: string _title?: string _org?: string - _schema?: "contact" | "contract" | "file" | "order" | "opportunity" | "product" | "price" | "meter" | "meter_counter" | "billing_event" + _schema?: string _tags?: string[] - _created_at?: string - _updated_at?: string + _created_at?: string // date-time + _updated_at?: string // date-time contract_name?: string contract_number?: string status?: "draft" | "in_approval_process" | "approved" | "active" | "deactivated" | "revoked" | "terminated" | "expired" @@ -717,7 +1100,7 @@ type Contract = { billing_address?: string delivery_address?: string additional_addresses?: string - termination_date?: string + termination_date?: string // date termination_reason?: string billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" billing_duration_amount?: number @@ -725,7 +1108,7 @@ type Contract = { renewal_duration_unit?: "weeks" | "months" | "years" notice_time_amount?: number notice_time_unit?: "weeks" | "months" | "years" - start_date?: string + start_date?: string // date billing_due_day?: number installment_amount?: number balance?: number @@ -735,15 +1118,17 @@ type Contract = { ### `ContractItem` +Contract entity with all required system fields populated + ```ts type ContractItem = { _id?: string _title?: string _org?: string - _schema?: "contact" | "contract" | "file" | "order" | "opportunity" | "product" | "price" | "meter" | "meter_counter" | "billing_event" + _schema?: string _tags?: string[] - _created_at?: string - _updated_at?: string + _created_at?: string // date-time + _updated_at?: string // date-time contract_name?: string contract_number?: string status?: "draft" | "in_approval_process" | "approved" | "active" | "deactivated" | "revoked" | "terminated" | "expired" @@ -753,7 +1138,7 @@ type ContractItem = { billing_address?: string delivery_address?: string additional_addresses?: string - termination_date?: string + termination_date?: string // date termination_reason?: string billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" billing_duration_amount?: number @@ -761,7 +1146,7 @@ type ContractItem = { renewal_duration_unit?: "weeks" | "months" | "years" notice_time_amount?: number notice_time_unit?: "weeks" | "months" | "years" - start_date?: string + start_date?: string // date billing_due_day?: number installment_amount?: number balance?: number @@ -769,8 +1154,917 @@ type ContractItem = { } ``` +### `InstallmentAmountValue` + +```ts +type InstallmentAmountValue = { + amount?: number + amount_decimal?: string + currency?: string +} +``` + +### `PriceContext` + +```ts +type PriceContext = { + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + unit_discount_amount_decimal?: string + unit_discount_amount_net_decimal?: string + currency?: string + billing_period?: string + unit?: string + has_discount?: boolean + is_dynamic_tariff?: boolean + dynamic_tariff?: { + mode?: string + interval?: string + average_price_decimal?: string + markup_amount_decimal?: string + markup_amount_net_decimal?: string + markup_amount_gross_decimal?: string + market_price_decimal?: string + market_price_currency?: string + market?: string + bidding_zone?: string + timestamp?: string + } +} +``` + +### `DynamicTariffPriceContext` + +```ts +type DynamicTariffPriceContext = { + mode?: string + interval?: string + average_price_decimal?: string + markup_amount_decimal?: string + markup_amount_net_decimal?: string + markup_amount_gross_decimal?: string + market_price_decimal?: string + market_price_currency?: string + market?: string + bidding_zone?: string + timestamp?: string +} +``` + +### `ConfigurationHistoryContext` + +```ts +type ConfigurationHistoryContext = { + base_price?: { + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + unit_discount_amount_decimal?: string + unit_discount_amount_net_decimal?: string + currency?: string + billing_period?: string + unit?: string + has_discount?: boolean + is_dynamic_tariff?: boolean + dynamic_tariff?: { + mode?: { ... } + interval?: { ... } + average_price_decimal?: { ... } + markup_amount_decimal?: { ... } + markup_amount_net_decimal?: { ... } + markup_amount_gross_decimal?: { ... } + market_price_decimal?: { ... } + market_price_currency?: { ... } + market?: { ... } + bidding_zone?: { ... } + timestamp?: { ... } + } + } + base_prices?: Array<{ + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + unit_discount_amount_decimal?: string + unit_discount_amount_net_decimal?: string + currency?: string + billing_period?: string + unit?: string + has_discount?: boolean + is_dynamic_tariff?: boolean + dynamic_tariff?: { + mode?: { ... } + interval?: { ... } + average_price_decimal?: { ... } + markup_amount_decimal?: { ... } + markup_amount_net_decimal?: { ... } + markup_amount_gross_decimal?: { ... } + market_price_decimal?: { ... } + market_price_currency?: { ... } + market?: { ... } + bidding_zone?: { ... } + timestamp?: { ... } + } + }> + working_price?: { + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + unit_discount_amount_decimal?: string + unit_discount_amount_net_decimal?: string + currency?: string + billing_period?: string + unit?: string + has_discount?: boolean + is_dynamic_tariff?: boolean + dynamic_tariff?: { + mode?: { ... } + interval?: { ... } + average_price_decimal?: { ... } + markup_amount_decimal?: { ... } + markup_amount_net_decimal?: { ... } + markup_amount_gross_decimal?: { ... } + market_price_decimal?: { ... } + market_price_currency?: { ... } + market?: { ... } + bidding_zone?: { ... } + timestamp?: { ... } + } + } + working_prices?: Array<{ + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + // ... +} +``` + +### `ContractTariffContext` + +```ts +type ContractTariffContext = { + product_id?: string + product_title?: string +} +``` + +### `ContractPricingContext` + +```ts +type ContractPricingContext = { + base_price?: { + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + unit_discount_amount_decimal?: string + unit_discount_amount_net_decimal?: string + currency?: string + billing_period?: string + unit?: string + has_discount?: boolean + is_dynamic_tariff?: boolean + dynamic_tariff?: { + mode?: { ... } + interval?: { ... } + average_price_decimal?: { ... } + markup_amount_decimal?: { ... } + markup_amount_net_decimal?: { ... } + markup_amount_gross_decimal?: { ... } + market_price_decimal?: { ... } + market_price_currency?: { ... } + market?: { ... } + bidding_zone?: { ... } + timestamp?: { ... } + } + } + base_prices?: Array<{ + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + unit_discount_amount_decimal?: string + unit_discount_amount_net_decimal?: string + currency?: string + billing_period?: string + unit?: string + has_discount?: boolean + is_dynamic_tariff?: boolean + dynamic_tariff?: { + mode?: { ... } + interval?: { ... } + average_price_decimal?: { ... } + markup_amount_decimal?: { ... } + markup_amount_net_decimal?: { ... } + markup_amount_gross_decimal?: { ... } + market_price_decimal?: { ... } + market_price_currency?: { ... } + market?: { ... } + bidding_zone?: { ... } + timestamp?: { ... } + } + }> + working_price?: { + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + unit_discount_amount_decimal?: string + unit_discount_amount_net_decimal?: string + currency?: string + billing_period?: string + unit?: string + has_discount?: boolean + is_dynamic_tariff?: boolean + dynamic_tariff?: { + mode?: { ... } + interval?: { ... } + average_price_decimal?: { ... } + markup_amount_decimal?: { ... } + markup_amount_net_decimal?: { ... } + markup_amount_gross_decimal?: { ... } + market_price_decimal?: { ... } + market_price_currency?: { ... } + market?: { ... } + bidding_zone?: { ... } + timestamp?: { ... } + } + } + working_prices?: Array<{ + price_id?: string + price_title?: string + tariff_type?: string + pricing_model?: string + unit_amount_gross_decimal?: string + unit_amount_net_decimal?: string + before_discount_unit_amount_gross_decimal?: string + before_discount_unit_amount_net_decimal?: string + // ... +} +``` + +### `ConfigurationHistoryRowBase` + +```ts +type ConfigurationHistoryRowBase = { + event_id: string + org_id: string + entity_type: "contract" | "billing_account" + entity_id: string + schema_version: number + effective_at?: string // date-time + changed_at: string // date-time + created_at: string // date-time + source: "portal" | "epilot" | "erp" | "system" | "api" | "external" | "journey" | "automation" | "unknown" + source_label?: string + source_system?: string + source_reference?: string +} +``` + +### `InstallmentAmountChangedHistoryRow` + +```ts +type InstallmentAmountChangedHistoryRow = { + event_id: string + org_id: string + entity_type: "contract" | "billing_account" + entity_id: string + schema_version: number + effective_at?: string // date-time + changed_at: string // date-time + created_at: string // date-time + source: "portal" | "epilot" | "erp" | "system" | "api" | "external" | "journey" | "automation" | "unknown" + source_label?: string + source_system?: string + source_reference?: string + change_type: "installment_amount_changed" + previous_value?: { + amount?: number + amount_decimal?: string + currency?: string + } + new_value: { + amount?: number + amount_decimal?: string + currency?: string + } + context?: { + base_price?: { + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + } + base_prices?: Array<{ + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + }> + working_price?: { + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + } + working_prices?: Array<{ + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + }> + } +} +``` + +### `ContractPricingChangedHistoryRow` + +```ts +type ContractPricingChangedHistoryRow = { + event_id: string + org_id: string + entity_type: "contract" | "billing_account" + entity_id: string + schema_version: number + effective_at?: string // date-time + changed_at: string // date-time + created_at: string // date-time + source: "portal" | "epilot" | "erp" | "system" | "api" | "external" | "journey" | "automation" | "unknown" + source_label?: string + source_system?: string + source_reference?: string + change_type: "contract_pricing_changed" + previous_context: { + base_price?: { + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + } + base_prices?: Array<{ + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + }> + working_price?: { + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + } + working_prices?: Array<{ + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + }> + tariff?: { + product_id?: { ... } + product_title?: { ... } + } + tariffs?: Array<{ + product_id?: { ... } + product_title?: { ... } + }> + } + new_context: { + base_price?: { + price_id?: { ... } + price_title?: { ... } + // ... +} +``` + +### `ConfigurationHistoryRow` + +```ts +type ConfigurationHistoryRow = { + event_id: string + org_id: string + entity_type: "contract" | "billing_account" + entity_id: string + schema_version: number + effective_at?: string // date-time + changed_at: string // date-time + created_at: string // date-time + source: "portal" | "epilot" | "erp" | "system" | "api" | "external" | "journey" | "automation" | "unknown" + source_label?: string + source_system?: string + source_reference?: string + change_type: "installment_amount_changed" + previous_value?: { + amount?: number + amount_decimal?: string + currency?: string + } + new_value: { + amount?: number + amount_decimal?: string + currency?: string + } + context?: { + base_price?: { + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + } + base_prices?: Array<{ + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + }> + working_price?: { + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + } + working_prices?: Array<{ + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + }> + } +} | { + event_id: string + // ... +} +``` + +### `ConfigurationHistoryResponse` + +```ts +type ConfigurationHistoryResponse = { + history: Array<{ + event_id: string + org_id: string + entity_type: "contract" | "billing_account" + entity_id: string + schema_version: number + effective_at?: string // date-time + changed_at: string // date-time + created_at: string // date-time + source: "portal" | "epilot" | "erp" | "system" | "api" | "external" | "journey" | "automation" | "unknown" + source_label?: string + source_system?: string + source_reference?: string + change_type: "installment_amount_changed" + previous_value?: { + amount?: { ... } + amount_decimal?: { ... } + currency?: { ... } + } + new_value: { + amount?: { ... } + amount_decimal?: { ... } + currency?: { ... } + } + context?: { + base_price?: { ... } + base_prices?: { ... } + working_price?: { ... } + working_prices?: { ... } + } + } | { + event_id: string + org_id: string + entity_type: "contract" | "billing_account" + entity_id: string + schema_version: number + effective_at?: string // date-time + changed_at: string // date-time + created_at: string // date-time + source: "portal" | "epilot" | "erp" | "system" | "api" | "external" | "journey" | "automation" | "unknown" + source_label?: string + source_system?: string + source_reference?: string + change_type: "contract_pricing_changed" + previous_context: { + base_price?: { ... } + base_prices?: { ... } + working_price?: { ... } + working_prices?: { ... } + tariff?: { ... } + tariffs?: { ... } + } + new_context: { + base_price?: { ... } + base_prices?: { ... } + working_price?: { ... } + working_prices?: { ... } + tariff?: { ... } + tariffs?: { ... } + } + changed_fields: "tariff" | "base_price" | "working_price" | "discount" | "dynamic_tariff_configuration"[] + installment_amount?: { + amount?: { ... } + amount_decimal?: { ... } + currency?: { ... } + } + }> + total: number +} +``` + +### `PricingInformationBalance` + +```ts +type PricingInformationBalance = { + amount?: number + amount_decimal?: string + currency?: string +} +``` + +### `ContractPricingSchedule` + +```ts +type ContractPricingSchedule = { + billing_due_day?: number + billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" + installments_per_year?: number + inferred: boolean +} +``` + +### `ContractPricingInformation` + +```ts +type ContractPricingInformation = { + entity_type: "contract" + entity_id: string + title?: string + current_installment_amount?: { + amount?: number + amount_decimal?: string + currency?: string + } + context?: { + base_price?: { + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + } + base_prices?: Array<{ + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + }> + working_price?: { + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + } + working_prices?: Array<{ + price_id?: { ... } + price_title?: { ... } + tariff_type?: { ... } + pricing_model?: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net_decimal?: { ... } + before_discount_unit_amount_gross_decimal?: { ... } + before_discount_unit_amount_net_decimal?: { ... } + unit_discount_amount_decimal?: { ... } + unit_discount_amount_net_decimal?: { ... } + currency?: { ... } + billing_period?: { ... } + unit?: { ... } + has_discount?: { ... } + is_dynamic_tariff?: { ... } + dynamic_tariff?: { ... } + }> + } + balance?: { + amount?: number + amount_decimal?: string + currency?: string + } + schedule?: { + billing_due_day?: number + billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" + installments_per_year?: number + inferred: boolean + } + pending_installment_change?: boolean + history: Array<{ + event_id: string + org_id: string + entity_type: "contract" | "billing_account" + entity_id: string + // ... +} +``` + +### `BillingAccountPricingInformation` + +```ts +type BillingAccountPricingInformation = { + entity_type: "billing_account" + entity_id: string + title?: string + balance?: { + amount?: number + amount_decimal?: string + currency?: string + } + contracts: Array<{ + entity_type: "contract" + entity_id: string + title?: string + current_installment_amount?: { + amount?: { ... } + amount_decimal?: { ... } + currency?: { ... } + } + context?: { + base_price?: { ... } + base_prices?: { ... } + working_price?: { ... } + working_prices?: { ... } + } + balance?: { + amount?: { ... } + amount_decimal?: { ... } + currency?: { ... } + } + schedule?: { + billing_due_day?: { ... } + billing_period?: { ... } + installments_per_year?: { ... } + inferred: { ... } + } + pending_installment_change?: boolean + history: Array<{ + event_id: { ... } + org_id: { ... } + entity_type: { ... } + entity_id: { ... } + schema_version: { ... } + effective_at?: { ... } + changed_at: { ... } + created_at: { ... } + source: { ... } + source_label?: { ... } + source_system?: { ... } + source_reference?: { ... } + change_type: { ... } + previous_value?: { ... } + new_value: { ... } + context?: { ... } + } | { + event_id: { ... } + org_id: { ... } + entity_type: { ... } + entity_id: { ... } + schema_version: { ... } + effective_at?: { ... } + changed_at: { ... } + created_at: { ... } + source: { ... } + source_label?: { ... } + source_system?: { ... } + source_reference?: { ... } + change_type: { ... } + previous_context: { ... } + new_context: { ... } + changed_fields: { ... } + installment_amount?: { ... } + }> + }> +} +``` + ### `Balance` +Customer balance summary (Kontostandübersicht). +Represents the aggregated balance across all contracts and orders for a customer. + + ```ts type Balance = { balance?: number @@ -781,7 +2075,9 @@ type Balance = { ### `Currency` -Currency code in ISO 4217 format +Currency code in ISO 4217 format (Währungscode). +Common values: EUR (Euro), CHF (Swiss Franc) + ```ts type Currency = string diff --git a/docs/sdk/clients/blueprint-manifest.md b/docs/sdk/clients/blueprint-manifest.md index e5c027f2..d51f9901 100644 --- a/docs/sdk/clients/blueprint-manifest.md +++ b/docs/sdk/clients/blueprint-manifest.md @@ -38,13 +38,21 @@ const { data } = await blueprintManifestClient.getJob(...) - [`listInstalledMarketplaceBlueprints`](#listinstalledmarketplaceblueprints) - [`preInstallBlueprint`](#preinstallblueprint) - [`getBlueprintPreview`](#getblueprintpreview) -- [`installBlueprint`](#installblueprint) - [`getBlueprint`](#getblueprint) - [`updateBlueprint`](#updateblueprint) - [`deleteBlueprint`](#deleteblueprint) -- [`validateBlueprint`](#validateblueprint) -- [`exportBlueprint`](#exportblueprint) +- [`listBlueprintTestCases`](#listblueprinttestcases) +- [`createBlueprintTestCase`](#createblueprinttestcase) +- [`getBlueprintTestCase`](#getblueprinttestcase) +- [`updateBlueprintTestCase`](#updateblueprinttestcase) +- [`deleteBlueprintTestCase`](#deleteblueprinttestcase) +- [`addBlueprintNote`](#addblueprintnote) +- [`updateBlueprintNote`](#updateblueprintnote) +- [`deleteBlueprintNote`](#deleteblueprintnote) +- [`verifyBlueprint`](#verifyblueprint) +- [`listMarketplaceSlugs`](#listmarketplaceslugs) - [`formatBlueprintDescription`](#formatblueprintdescription) +- [`suggestBlueprintResources`](#suggestblueprintresources) - [`addBlueprintResource`](#addblueprintresource) - [`syncDependencies`](#syncdependencies) - [`bulkAddBlueprintResources`](#bulkaddblueprintresources) @@ -52,17 +60,145 @@ const { data } = await blueprintManifestClient.getJob(...) - [`bulkDeleteBlueprintResources`](#bulkdeleteblueprintresources) - [`updateBlueprintResource`](#updateblueprintresource) - [`deleteBlueprintResource`](#deleteblueprintresource) +- [`publishBlueprintV3`](#publishblueprintv3) +- [`sendBlueprintAssistantMessage`](#sendblueprintassistantmessage) +- [`listBlueprintAssistantConversations`](#listblueprintassistantconversations) +- [`getBlueprintAssistantConversation`](#getblueprintassistantconversation) +- [`listBlueprintAssistantSkills`](#listblueprintassistantskills) +- [`uploadBlueprintAssistantSkill`](#uploadblueprintassistantskill) +- [`getBlueprintAssistantSkill`](#getblueprintassistantskill) +- [`updateBlueprintAssistantSkill`](#updateblueprintassistantskill) +- [`deleteBlueprintAssistantSkill`](#deleteblueprintassistantskill) +- [`preInstallBlueprintV3`](#preinstallblueprintv3) +- [`installBlueprintV3`](#installblueprintv3) +- [`restoreBlueprintDeploymentV3`](#restoreblueprintdeploymentv3) +- [`getRestorePreview`](#getrestorepreview) +- [`triggerRestorePreview`](#triggerrestorepreview) +- [`getRestorePreviewReport`](#getrestorepreviewreport) +- [`triggerDeploymentHealthCheckV3`](#triggerdeploymenthealthcheckv3) +- [`getDeploymentHealthReportV3`](#getdeploymenthealthreportv3) +- [`getBlueprintLineageV3`](#getblueprintlineagev3) +- [`createBulkInstallV3`](#createbulkinstallv3) +- [`getBulkInstallV3`](#getbulkinstallv3) +- [`listBulkInstallTargetsV3`](#listbulkinstalltargetsv3) +- [`retryBulkInstallTargetV3`](#retrybulkinstalltargetv3) +- [`getSourceTestOperation`](#getsourcetestoperation) +- [`createSourceConfirmedRun`](#createsourceconfirmedrun) +- [`createBlueprintTestRun`](#createblueprinttestrun) +- [`listBlueprintTestRuns`](#listblueprinttestruns) +- [`getBlueprintTestRun`](#getblueprinttestrun) +- [`getBlueprintTestSuite`](#getblueprinttestsuite) +- [`createBlueprintTestSuiteRun`](#createblueprinttestsuiterun) +- [`getBlueprintTestSuiteRun`](#getblueprinttestsuiterun) +- [`createBlueprintGraphSuggestions`](#createblueprintgraphsuggestions) +- [`getBlueprintGraphSuggestions`](#getblueprintgraphsuggestions) +- [`acceptBlueprintGraphSuggestions`](#acceptblueprintgraphsuggestions) +- [`migrateBlueprintV1TestCases`](#migrateblueprintv1testcases) +- [`createBlueprintTestInterpretation`](#createblueprinttestinterpretation) +- [`getBlueprintTestInterpretation`](#getblueprinttestinterpretation) +- [`confirmBlueprintTestInterpretationV2`](#confirmblueprinttestinterpretationv2) **Jobs** - [`listBlueprintJobs`](#listblueprintjobs) - [`getBlueprintJob`](#getblueprintjob) - [`continueInstallationJob`](#continueinstallationjob) +- [`retryInstallationJob`](#retryinstallationjob) - [`cancelBlueprintJob`](#cancelblueprintjob) +**Marketplace Listings** +- [`createMarketplaceListing`](#createmarketplacelisting) +- [`getMarketplaceListing`](#getmarketplacelisting) +- [`listMarketplaceListings`](#listmarketplacelistings) +- [`getMarketplaceListingById`](#getmarketplacelistingbyid) +- [`updateMarketplaceListing`](#updatemarketplacelisting) +- [`deleteMarketplaceListing`](#deletemarketplacelisting) + +**Marketplace Listing Versions** +- [`createMarketplaceListingVersion`](#createmarketplacelistingversion) +- [`listMarketplaceListingVersions`](#listmarketplacelistingversions) +- [`updateMarketplaceListingVersion`](#updatemarketplacelistingversion) +- [`publishMarketplaceListingVersion`](#publishmarketplacelistingversion) + +**merge-plans** +- [`getBlueprintMergePlan`](#getblueprintmergeplan) +- [`listBlueprintMergePlanResources`](#listblueprintmergeplanresources) +- [`getBlueprintMergePlanResource`](#getblueprintmergeplanresource) +- [`updateBlueprintMergePlanResolutions`](#updateblueprintmergeplanresolutions) +- [`discardBlueprintMergePlan`](#discardblueprintmergeplan) +- [`replanBlueprintMergePlan`](#replanblueprintmergeplan) +- [`applyBlueprintMergePlan`](#applyblueprintmergeplan) +- [`previewBlueprintMergeRevert`](#previewblueprintmergerevert) +- [`applyBlueprintMergeRevert`](#applyblueprintmergerevert) + +**Uniqueness Criteria** +- [`listUniquenessCriteria`](#listuniquenesscriteria) +- [`getUniquenessCriteria`](#getuniquenesscriteria) +- [`putUniquenessCriteria`](#putuniquenesscriteria) +- [`deleteUniquenessCriteria`](#deleteuniquenesscriteria) + **Schemas** +- [`BlueprintTestSuiteError`](#blueprinttestsuiteerror) +- [`SentenceParamValue`](#sentenceparamvalue) +- [`Sentence`](#sentence) +- [`ClauseEvidenceView`](#clauseevidenceview) +- [`ClauseResultView`](#clauseresultview) +- [`BlueprintTestUnreadableResource`](#blueprinttestunreadableresource) +- [`SuiteRun`](#suiterun) +- [`CaseResultRow`](#caseresultrow) +- [`BlueprintTestSuiteSummary`](#blueprinttestsuitesummary) +- [`BlueprintTestSuite`](#blueprinttestsuite) +- [`BlueprintTestCaseShape`](#blueprinttestcaseshape) +- [`Suggestion`](#suggestion) +- [`BlueprintGraphSuggestionsStarted`](#blueprintgraphsuggestionsstarted) +- [`BlueprintTestInterpretationInput`](#blueprinttestinterpretationinput) +- [`BlueprintTestInterpretationStarted`](#blueprinttestinterpretationstarted) +- [`BlueprintInterpretedCheck`](#blueprintinterpretedcheck) +- [`BlueprintInterpretedPart`](#blueprintinterpretedpart) +- [`BlueprintInterpretationSpan`](#blueprintinterpretationspan) +- [`BlueprintTestInterpretationResult`](#blueprinttestinterpretationresult) +- [`BlueprintTestInterpretationConfirmInput`](#blueprinttestinterpretationconfirminput) +- [`BlueprintTestInterpretationConfirmation`](#blueprinttestinterpretationconfirmation) +- [`BlueprintTestCaseOrigin`](#blueprinttestcaseorigin) +- [`BlueprintGraphSuggestionPage`](#blueprintgraphsuggestionpage) +- [`BlueprintGraphSuggestionAcceptInput`](#blueprintgraphsuggestionacceptinput) +- [`BlueprintGraphSuggestionAcceptance`](#blueprintgraphsuggestionacceptance) +- [`BlueprintV1TestCaseMigration`](#blueprintv1testcasemigration) +- [`BlueprintTestCaseInput`](#blueprinttestcaseinput) +- [`BlueprintTestCaseUpdate`](#blueprinttestcaseupdate) +- [`BlueprintTestCase`](#blueprinttestcase) +- [`BlueprintTestPredicate`](#blueprinttestpredicate) +- [`BlueprintTestInterpretation`](#blueprinttestinterpretation) +- [`BlueprintTestCatalogEntry`](#blueprinttestcatalogentry) +- [`BlueprintTestInterpretationProposal`](#blueprinttestinterpretationproposal) +- [`BlueprintTestCaseConfirmation`](#blueprinttestcaseconfirmation) +- [`BlueprintTestResourceEvidence`](#blueprinttestresourceevidence) +- [`BlueprintTestCheckResult`](#blueprinttestcheckresult) +- [`BlueprintTestDependencyValidation`](#blueprinttestdependencyvalidation) +- [`BlueprintTestRunResult`](#blueprinttestrunresult) +- [`BlueprintSourceTestOperation`](#blueprintsourcetestoperation) +- [`BlueprintTestRun`](#blueprinttestrun) +- [`BlueprintTestRunPage`](#blueprinttestrunpage) +- [`BlueprintTestRunError`](#blueprinttestrunerror) +- [`BlueprintTestRunInput`](#blueprinttestruninput) +- [`BlueprintTestCasePage`](#blueprinttestcasepage) +- [`BlueprintAssistantMessageRequest`](#blueprintassistantmessagerequest) +- [`BlueprintAssistantConversation`](#blueprintassistantconversation) +- [`BlueprintAssistantSkill`](#blueprintassistantskill) +- [`BlueprintAssistantDefaultSkill`](#blueprintassistantdefaultskill) +- [`BlueprintAssistantSkillUpload`](#blueprintassistantskillupload) +- [`BlueprintAssistantConversationSummary`](#blueprintassistantconversationsummary) +- [`BlueprintAssistantMessage`](#blueprintassistantmessage) +- [`BlueprintAssistantPart`](#blueprintassistantpart) +- [`UniquenessCriteriaResourceType`](#uniquenesscriteriaresourcetype) +- [`UniquenessCriteria`](#uniquenesscriteria) +- [`LineageEntry`](#lineageentry) +- [`BlueprintNote`](#blueprintnote) - [`BlueprintID`](#blueprintid) - [`BlueprintResourceID`](#blueprintresourceid) - [`CommonBlueprintFields`](#commonblueprintfields) +- [`SuggestBlueprintResourcesRequest`](#suggestblueprintresourcesrequest) +- [`SuggestBlueprintResourcesResponse`](#suggestblueprintresourcesresponse) +- [`SkippedBlueprintResource`](#skippedblueprintresource) - [`BlueprintResource`](#blueprintresource) - [`BlueprintPreview`](#blueprintpreview) - [`CustomBlueprint`](#customblueprint) @@ -76,11 +212,33 @@ const { data } = await blueprintManifestClient.getJob(...) - [`CommonBlueprintJobFields`](#commonblueprintjobfields) - [`BlueprintExportJob`](#blueprintexportjob) - [`BlueprintInstallationJob`](#blueprintinstallationjob) +- [`BulkInstallStatus`](#bulkinstallstatus) +- [`BulkInstallCounts`](#bulkinstallcounts) +- [`BulkInstall`](#bulkinstall) +- [`BulkInstallTarget`](#bulkinstalltarget) +- [`BulkInstallTargetList`](#bulkinstalltargetlist) +- [`BulkInstallTargetInput`](#bulkinstalltargetinput) +- [`BulkInstallCreateRequest`](#bulkinstallcreaterequest) +- [`BlueprintRestoreJob`](#blueprintrestorejob) +- [`V3ResourceProgressEntry`](#v3resourceprogressentry) +- [`RestoreOutcomeItem`](#restoreoutcomeitem) +- [`HealthFinding`](#healthfinding) +- [`HealthCheckCoverage`](#healthcheckcoverage) +- [`HealthResourceTypeCoverage`](#healthresourcetypecoverage) +- [`HealthScanCoverage`](#healthscancoverage) +- [`DeploymentHealthReport`](#deploymenthealthreport) +- [`RestoreOutcome`](#restoreoutcome) +- [`RestorePreviewReport`](#restorepreviewreport) - [`BlueprintJob`](#blueprintjob) - [`BlueprintDependenciesSyncJob`](#blueprintdependenciessyncjob) -- [`BlueprintValidateJob`](#blueprintvalidatejob) +- [`BlueprintVerificationJob`](#blueprintverificationjob) +- [`LatestBlueprintVerification`](#latestblueprintverification) +- [`VerificationSummary`](#verificationsummary) +- [`ResourceVerificationResult`](#resourceverificationresult) +- [`FieldDiff`](#fielddiff) - [`BlueprintJobEvent`](#blueprintjobevent) - [`BlueprintInstallationJobOptions`](#blueprintinstallationjoboptions) +- [`ContinueInstallationJobRequest`](#continueinstallationjobrequest) - [`ManifestID`](#manifestid) - [`JobID`](#jobid) - [`ManifestSource`](#manifestsource) @@ -103,12 +261,47 @@ const { data } = await blueprintManifestClient.getJob(...) - [`PreInstallRequirements`](#preinstallrequirements) - [`BlueprintInstallStatus`](#blueprintinstallstatus) - [`FormattedErrorCodes`](#formattederrorcodes) +- [`V3SourceResource`](#v3sourceresource) +- [`V3MissingSourceResource`](#v3missingsourceresource) +- [`V3SourceDrift`](#v3sourcedrift) - [`FormattedErrorData`](#formattederrordata) - [`FormattedError`](#formattederror) - [`CallerIdentity`](#calleridentity) - [`SelectedResources`](#selectedresources) - [`ResourceReplacement`](#resourcereplacement) - [`PutManifestPayload`](#putmanifestpayload) +- [`MarketplaceListing`](#marketplacelisting) +- [`MarketplaceListingUpdate`](#marketplacelistingupdate) +- [`MarketplaceListingVersion`](#marketplacelistingversion) +- [`MergePlanState`](#mergeplanstate) +- [`MergeOptionId`](#mergeoptionid) +- [`MergeChoice`](#mergechoice) +- [`MergeChoiceInput`](#mergechoiceinput) +- [`MergeSectionRef`](#mergesectionref) +- [`MergeSectionValue`](#mergesectionvalue) +- [`MergeDecisionGroup`](#mergedecisiongroup) +- [`MergePlanWarning`](#mergeplanwarning) +- [`MergeBaseProvenance`](#mergebaseprovenance) +- [`MergeResourceStatus`](#mergeresourcestatus) +- [`MergeResourceEligibility`](#mergeresourceeligibility) +- [`MergeResourceAutoCounts`](#mergeresourceautocounts) +- [`MergePlanReview`](#mergeplanreview) +- [`MergePlanApplyCounts`](#mergeplanapplycounts) +- [`MergeResourceOutcome`](#mergeresourceoutcome) +- [`MergePlanResourceSummary`](#mergeplanresourcesummary) +- [`MergePlanResourcePage`](#mergeplanresourcepage) +- [`MergePlanResourceDetail`](#mergeplanresourcedetail) +- [`MergePlanResourceReview`](#mergeplanresourcereview) +- [`MergePlanResolutionsUpdate`](#mergeplanresolutionsupdate) +- [`MergePlanApplyRequest`](#mergeplanapplyrequest) +- [`MergePlanRevisionRequest`](#mergeplanrevisionrequest) +- [`MergePlanReplanResult`](#mergeplanreplanresult) +- [`MergeRevertEntry`](#mergerevertentry) +- [`MergeRevertPreview`](#mergerevertpreview) +- [`MergeRevertSelection`](#mergerevertselection) +- [`MergeRevertRequest`](#mergerevertrequest) +- [`MergeRevertResult`](#mergerevertresult) +- [`MergePlanError`](#mergeplanerror) ### `uploadManifest` @@ -162,67 +355,33 @@ const { data } = await client.listBlueprints({ "total": 1, "results": [ { + "source_drift": {}, "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "title": "string", "slug": "string", - "description": { - "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", - "postinstall": "This is the content of the postinstall.md file\n" - }, + "description": {}, + "notes": [], "version": "string", - "deployments": [ - { - "source_org_id": "string", - "source_blueprint_id": "string", - "destination_org_id": "string", - "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" - } - ], + "deployments": [], "is_verified": true, + "latest_verification": {}, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", - "created_by": { - "name": "manifest@epilot.cloud", - "org_id": "911690", - "user_id": "11001045", - "token_id": "api_5ZugdRXasLfWBypHi93Fk" - }, - "updated_by": { - "name": "manifest@epilot.cloud", - "org_id": "911690", - "user_id": "11001045", - "token_id": "api_5ZugdRXasLfWBypHi93Fk" - }, + "created_by": {}, + "updated_by": {}, "installation_job_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "archived": false, "docs_url": "string", "recommended_apps": ["string"], - "required_features": { - "enabled": ["string"], - "disabled": ["string"] - }, + "required_features": {}, "zip_file_name": "string", - "resources": [ - { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] - } - ], - "source_type": "string" + "resources": [], + "source_type": "custom" } ] } @@ -242,6 +401,15 @@ Create a Blueprint const { data } = await client.createBlueprint( null, { + source_drift: { + removed: [ + { /* ... */ } + ], + missing: [ + { /* ... */ } + ], + exclude_addresses: ['string'] + }, id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', title: 'string', slug: 'string', @@ -251,6 +419,15 @@ const { data } = await client.createBlueprint( postinstall: 'This is the content of the postinstall.md file ' }, + notes: [ + { + id: '3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40', + text: 'Adjusted the meter-reading journey for the §14a rollout.', + created_at: '1970-01-01T00:00:00.000Z', + updated_at: '1970-01-01T00:00:00.000Z', + created_by: { /* ... */ } + } + ], version: 'string', deployments: [ { @@ -258,11 +435,45 @@ const { data } = await client.createBlueprint( source_blueprint_id: 'string', destination_org_id: 'string', destination_blueprint_id: 'string', - triggered_at: '1970-01-01T00:00:00.000Z' + job_id: 'string', + triggered_at: '1970-01-01T00:00:00.000Z', + performed_by: { /* ... */ }, + note: 'string', + status: 'IN_PROGRESS', + merge_plan_id: 'string', + merge_snapshot_id: 'string', + snapshot_restore_available: true, + merge_plan_state: 'review_required', + revert_until: '1970-01-01T00:00:00.000Z', + restore_details: { /* ... */ }, + has_revertible_changes: true, + last_restore_job_id: 'string', + restore_status: 'available' } ], is_verified: true, + latest_verification: { + job_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + status: 'IN_PROGRESS', + triggered_at: '1970-01-01T00:00:00.000Z', + source_org_id: 'string', + source_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + destination_org_id: 'string', + destination_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + installation_job_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + sync_engine: 'terraform', + summary: { + total_resources: 0, + matched: 0, + mismatched: 0, + missing_in_destination: 0, + fetch_errors: 0 + } + }, + ignored_resource_addresses: ['string'], installation_status: 'IN_PROGRESS', + active_restore_job_id: 'string', + active_restore_started_at: '1970-01-01T00:00:00.000Z', created_at: '1970-01-01T00:00:00.000Z', updated_at: '1970-01-01T00:00:00.000Z', created_by: { @@ -301,10 +512,13 @@ const { data } = await client.createBlueprint( parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], depends_on_addresses: ['string'], impact_on_install: ['create'], - impact_on_install_reason: ['string'] + impact_on_install_reason: ['string'], + impact_on_install_changes: [ /* ... */ ], + impact_on_install_labels: {}, + impact_on_install_summary: ['string'] } ], - source_type: 'string' + source_type: 'custom' }, ) ``` @@ -314,6 +528,15 @@ const { data } = await client.createBlueprint( ```json { + "source_drift": { + "removed": [ + {} + ], + "missing": [ + {} + ], + "exclude_addresses": ["string"] + }, "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "title": "string", "slug": "string", @@ -321,6 +544,15 @@ const { data } = await client.createBlueprint( "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -328,11 +560,45 @@ const { data } = await client.createBlueprint( "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "merge_plan_id": "string", + "merge_snapshot_id": "string", + "snapshot_restore_available": true, + "merge_plan_state": "review_required", + "revert_until": "1970-01-01T00:00:00.000Z", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -371,10 +637,13 @@ const { data } = await client.createBlueprint( "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], "depends_on_addresses": ["string"], "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] } ], - "source_type": "string" + "source_type": "custom" } ``` @@ -432,7 +701,7 @@ const { data } = await client.listInstalledMarketplaceBlueprints() ### `preInstallBlueprint` -Pre-install a Blueprint based on a blueprint file +Pre-install a Blueprint based on a blueprint file. Format-agnostic: the engine is detected from the uploaded archive, so this endpoint accepts both Terraform exports and signed V3 packages. The return `POST /v2/blueprint-manifest/blueprints:pre-install` @@ -461,10 +730,15 @@ const { data } = await client.preInstallBlueprint( "version": "string", "slug": "string", "source_type": "marketplace", + "sync_engine": "terraform", "blueprint_file_s3_key": "string", "is_verified": true, "docs_url": "string", "recommended_apps": ["string"], + "required_features": { + "enabled": ["string"], + "disabled": ["string"] + }, "created_at": "1970-01-01T00:00:00.000Z", "created_by": { "name": "manifest@epilot.cloud", @@ -487,7 +761,17 @@ const { data } = await client.preInstallBlueprint( "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], "depends_on_addresses": ["string"], "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ + { + "path": "string", + "destination": {}, + "source": {}, + "added": true + } + ], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] } ] } @@ -523,10 +807,15 @@ const { data } = await client.getBlueprintPreview({ "version": "string", "slug": "string", "source_type": "marketplace", + "sync_engine": "terraform", "blueprint_file_s3_key": "string", "is_verified": true, "docs_url": "string", "recommended_apps": ["string"], + "required_features": { + "enabled": ["string"], + "disabled": ["string"] + }, "created_at": "1970-01-01T00:00:00.000Z", "created_by": { "name": "manifest@epilot.cloud", @@ -549,7 +838,17 @@ const { data } = await client.getBlueprintPreview({ "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], "depends_on_addresses": ["string"], "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ + { + "path": "string", + "destination": {}, + "source": {}, + "added": true + } + ], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] } ] } @@ -559,33 +858,6 @@ const { data } = await client.getBlueprintPreview({ --- -### `installBlueprint` - -Kick off a new blueprint installation job. Returns 202 Accepted with Location header pointing to the job resource - -`POST /v2/blueprint-manifest/blueprint:install` - -```ts -const { data } = await client.installBlueprint( - null, - { - source_org_id: 'string', - source_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', - source_blueprint_file: 'string', - destination_org_id: 'string', - destination_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', - options: { - resources_to_ignore: ['string'] - }, - mode: 'simple', - source_blueprint_type: 'marketplace', - slug: 'string' - }, -) -``` - ---- - ### `getBlueprint` Get Blueprint by ID @@ -603,6 +875,15 @@ const { data } = await client.getBlueprint({ ```json { + "source_drift": { + "removed": [ + {} + ], + "missing": [ + {} + ], + "exclude_addresses": ["string"] + }, "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "title": "string", "slug": "string", @@ -610,6 +891,15 @@ const { data } = await client.getBlueprint({ "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -617,11 +907,45 @@ const { data } = await client.getBlueprint({ "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "merge_plan_id": "string", + "merge_snapshot_id": "string", + "snapshot_restore_available": true, + "merge_plan_state": "review_required", + "revert_until": "1970-01-01T00:00:00.000Z", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -660,10 +984,13 @@ const { data } = await client.getBlueprint({ "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], "depends_on_addresses": ["string"], "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] } ], - "source_type": "string" + "source_type": "custom" } ``` @@ -683,6 +1010,15 @@ const { data } = await client.updateBlueprint( blueprint_id: 'example', }, { + source_drift: { + removed: [ + { /* ... */ } + ], + missing: [ + { /* ... */ } + ], + exclude_addresses: ['string'] + }, id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', title: 'string', slug: 'string', @@ -692,6 +1028,15 @@ const { data } = await client.updateBlueprint( postinstall: 'This is the content of the postinstall.md file ' }, + notes: [ + { + id: '3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40', + text: 'Adjusted the meter-reading journey for the §14a rollout.', + created_at: '1970-01-01T00:00:00.000Z', + updated_at: '1970-01-01T00:00:00.000Z', + created_by: { /* ... */ } + } + ], version: 'string', deployments: [ { @@ -699,11 +1044,45 @@ const { data } = await client.updateBlueprint( source_blueprint_id: 'string', destination_org_id: 'string', destination_blueprint_id: 'string', - triggered_at: '1970-01-01T00:00:00.000Z' + job_id: 'string', + triggered_at: '1970-01-01T00:00:00.000Z', + performed_by: { /* ... */ }, + note: 'string', + status: 'IN_PROGRESS', + merge_plan_id: 'string', + merge_snapshot_id: 'string', + snapshot_restore_available: true, + merge_plan_state: 'review_required', + revert_until: '1970-01-01T00:00:00.000Z', + restore_details: { /* ... */ }, + has_revertible_changes: true, + last_restore_job_id: 'string', + restore_status: 'available' } ], is_verified: true, + latest_verification: { + job_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + status: 'IN_PROGRESS', + triggered_at: '1970-01-01T00:00:00.000Z', + source_org_id: 'string', + source_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + destination_org_id: 'string', + destination_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + installation_job_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + sync_engine: 'terraform', + summary: { + total_resources: 0, + matched: 0, + mismatched: 0, + missing_in_destination: 0, + fetch_errors: 0 + } + }, + ignored_resource_addresses: ['string'], installation_status: 'IN_PROGRESS', + active_restore_job_id: 'string', + active_restore_started_at: '1970-01-01T00:00:00.000Z', created_at: '1970-01-01T00:00:00.000Z', updated_at: '1970-01-01T00:00:00.000Z', created_by: { @@ -742,10 +1121,13 @@ const { data } = await client.updateBlueprint( parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], depends_on_addresses: ['string'], impact_on_install: ['create'], - impact_on_install_reason: ['string'] + impact_on_install_reason: ['string'], + impact_on_install_changes: [ /* ... */ ], + impact_on_install_labels: {}, + impact_on_install_summary: ['string'] } ], - source_type: 'string' + source_type: 'custom' }, ) ``` @@ -755,6 +1137,15 @@ const { data } = await client.updateBlueprint( ```json { + "source_drift": { + "removed": [ + {} + ], + "missing": [ + {} + ], + "exclude_addresses": ["string"] + }, "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "title": "string", "slug": "string", @@ -762,6 +1153,15 @@ const { data } = await client.updateBlueprint( "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -769,11 +1169,45 @@ const { data } = await client.updateBlueprint( "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "merge_plan_id": "string", + "merge_snapshot_id": "string", + "snapshot_restore_available": true, + "merge_plan_state": "review_required", + "revert_until": "1970-01-01T00:00:00.000Z", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -812,10 +1246,13 @@ const { data } = await client.updateBlueprint( "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], "depends_on_addresses": ["string"], "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] } ], - "source_type": "string" + "source_type": "custom" } ``` @@ -840,6 +1277,15 @@ const { data } = await client.deleteBlueprint({ ```json { + "source_drift": { + "removed": [ + {} + ], + "missing": [ + {} + ], + "exclude_addresses": ["string"] + }, "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", "title": "string", "slug": "string", @@ -847,6 +1293,15 @@ const { data } = await client.deleteBlueprint({ "preinstall": "This is the content of the preinstall.md file which contains the blueprint description.\n", "postinstall": "This is the content of the postinstall.md file\n" }, + "notes": [ + { + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": {} + } + ], "version": "string", "deployments": [ { @@ -854,11 +1309,45 @@ const { data } = await client.deleteBlueprint({ "source_blueprint_id": "string", "destination_org_id": "string", "destination_blueprint_id": "string", - "triggered_at": "1970-01-01T00:00:00.000Z" + "job_id": "string", + "triggered_at": "1970-01-01T00:00:00.000Z", + "performed_by": {}, + "note": "string", + "status": "IN_PROGRESS", + "merge_plan_id": "string", + "merge_snapshot_id": "string", + "snapshot_restore_available": true, + "merge_plan_state": "review_required", + "revert_until": "1970-01-01T00:00:00.000Z", + "restore_details": {}, + "has_revertible_changes": true, + "last_restore_job_id": "string", + "restore_status": "available" } ], "is_verified": true, + "latest_verification": { + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "triggered_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "installation_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "sync_engine": "terraform", + "summary": { + "total_resources": 0, + "matched": 0, + "mismatched": 0, + "missing_in_destination": 0, + "fetch_errors": 0 + } + }, + "ignored_resource_addresses": ["string"], "installation_status": "IN_PROGRESS", + "active_restore_job_id": "string", + "active_restore_started_at": "1970-01-01T00:00:00.000Z", "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "created_by": { @@ -897,10 +1386,13 @@ const { data } = await client.deleteBlueprint({ "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], "depends_on_addresses": ["string"], "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] } ], - "source_type": "string" + "source_type": "custom" } ``` @@ -908,65 +1400,108 @@ const { data } = await client.deleteBlueprint({ --- -### `validateBlueprint` +### `listBlueprintTestCases` -Start a blueprint validation job. Validates Terraform for the blueprint (all types). -Returns 202 Accepted with job_id. Poll GET /jobs/{job_id} for status, valid, and errors. +Author versioned plain-language expectations. Requires the blueprint-test-cases organization feature flag. -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/validate` +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases` ```ts -const { data } = await client.validateBlueprint({ +const { data } = await client.listBlueprintTestCases({ blueprint_id: 'example', + limit: 1, + cursor: 'example', }) ``` ---- - -### `exportBlueprint` - -Kick off a new blueprint export job. Returns 202 Accepted with Location header pointing to the job resource. - -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}:export` - -```ts -const { data } = await client.exportBlueprint( - { - blueprint_id: 'example', - }, - { - destination_org_id: 'string', - destination_blueprint_id: 'string', - validate: true - }, -) -``` - ---- - -### `formatBlueprintDescription` - -Format a blueprint description as markdown using AI. - -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}:format-description` - -```ts -const { data } = await client.formatBlueprintDescription( - { - blueprint_id: 'example', - }, - { - text: 'string' - }, -) -``` -
Response ```json { - "markdown": "string" + "results": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "org_id": "string", + "schema_version": 1, + "revision": 1, + "title": "string", + "expectation": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "deleted_at": "1970-01-01T00:00:00.000Z", + "confirmation": { + "schema_version": "1", + "interpretation": { + "schema_version": "1", + "clauses": [ + { + "source_text": "string", + "status": "supported", + "assertions": [ + { + "operator": "resource_included", + "target_key": "string" + } + ], + "reason": "string" + } + ] + }, + "catalog": [ + { + "key": "string", + "type": "string", + "id": "string", + "label": "string", + "membership_state": "included", + "capabilities": ["resource_included"], + "tasks": [ + { + "key": "string", + "label": "string", + "capabilities": ["workflow_task_required"] + } + ] + } + ], + "proposal_hash": "string", + "expectation_sha256": "string", + "interpreter_version": "string", + "confirmed_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "confirmed_at": "1970-01-01T00:00:00.000Z", + "interpreter_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "clauses": [ + {} + ], + "clauses_hash": "string", + "title_key": {}, + "origin": {}, + "needs_reinterpretation": { + "reason": "string" + } + } + ], + "next_cursor": "string" } ``` @@ -974,32 +1509,20 @@ const { data } = await client.formatBlueprintDescription( --- -### `addBlueprintResource` +### `createBlueprintTestCase` -Add a resource to a Blueprint +Author versioned plain-language expectations. Requires the blueprint-test-cases organization feature flag. -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/resources` +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases` ```ts -const { data } = await client.addBlueprintResource( +const { data } = await client.createBlueprintTestCase( { blueprint_id: 'example', - add_dependencies: true, }, { - id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', - name: 'string', - type: 'designbuilder', - address: 'string', - is_root: true, - is_ready: true, - is_hidden: true, - is_disabled: false, - hard_dependencies: ['designbuilder'], - parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], - depends_on_addresses: ['string'], - impact_on_install: ['create'], - impact_on_install_reason: ['string'] + title: 'string', + expectation: 'string' }, ) ``` @@ -1009,23 +1532,84 @@ const { data } = await client.addBlueprintResource( ```json { - "resources": [ - { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] - } - ] + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "org_id": "string", + "schema_version": 1, + "revision": 1, + "title": "string", + "expectation": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "deleted_at": "1970-01-01T00:00:00.000Z", + "confirmation": { + "schema_version": "1", + "interpretation": { + "schema_version": "1", + "clauses": [ + { + "source_text": "string", + "status": "supported", + "assertions": [ + { + "operator": "resource_included", + "target_key": "string" + } + ], + "reason": "string" + } + ] + }, + "catalog": [ + { + "key": "string", + "type": "string", + "id": "string", + "label": "string", + "membership_state": "included", + "capabilities": ["resource_included"], + "tasks": [ + { + "key": "string", + "label": "string", + "capabilities": ["workflow_task_required"] + } + ] + } + ], + "proposal_hash": "string", + "expectation_sha256": "string", + "interpreter_version": "string", + "confirmed_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "confirmed_at": "1970-01-01T00:00:00.000Z", + "interpreter_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "clauses": [ + {} + ], + "clauses_hash": "string", + "title_key": {}, + "origin": {}, + "needs_reinterpretation": { + "reason": "string" + } } ``` @@ -1033,74 +1617,103 @@ const { data } = await client.addBlueprintResource( --- -### `syncDependencies` +### `getBlueprintTestCase` -Sync dependencies of all root resources in a Blueprint +Author versioned plain-language expectations. Requires the blueprint-test-cases organization feature flag. -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/resources:syncDependencies` +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases/{test_case_id}` ```ts -const { data } = await client.syncDependencies({ +const { data } = await client.getBlueprintTestCase({ blueprint_id: 'example', + test_case_id: 'example', + revision: 1, }) ``` ---- - -### `bulkAddBlueprintResources` - -Bulk Add resources in a Blueprint - -`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/bulk` - -```ts -const { data } = await client.bulkAddBlueprintResources( - { - blueprint_id: 'example', - add_dependencies: true, - }, - [ - { - id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', - name: 'string', - type: 'designbuilder', - address: 'string', - is_root: true, - is_ready: true, - is_hidden: true, - is_disabled: false, - hard_dependencies: ['designbuilder'], - parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], - depends_on_addresses: ['string'], - impact_on_install: ['create'], - impact_on_install_reason: ['string'] - } - ], -) -``` - -
-Response +
+Response ```json { - "resources": [ - { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] - } - ] + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "org_id": "string", + "schema_version": 1, + "revision": 1, + "title": "string", + "expectation": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "deleted_at": "1970-01-01T00:00:00.000Z", + "confirmation": { + "schema_version": "1", + "interpretation": { + "schema_version": "1", + "clauses": [ + { + "source_text": "string", + "status": "supported", + "assertions": [ + { + "operator": "resource_included", + "target_key": "string" + } + ], + "reason": "string" + } + ] + }, + "catalog": [ + { + "key": "string", + "type": "string", + "id": "string", + "label": "string", + "membership_state": "included", + "capabilities": ["resource_included"], + "tasks": [ + { + "key": "string", + "label": "string", + "capabilities": ["workflow_task_required"] + } + ] + } + ], + "proposal_hash": "string", + "expectation_sha256": "string", + "interpreter_version": "string", + "confirmed_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "confirmed_at": "1970-01-01T00:00:00.000Z", + "interpreter_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "clauses": [ + {} + ], + "clauses_hash": "string", + "title_key": {}, + "origin": {}, + "needs_reinterpretation": { + "reason": "string" + } } ``` @@ -1108,34 +1721,23 @@ const { data } = await client.bulkAddBlueprintResources( --- -### `bulkUpdateBlueprintResources` +### `updateBlueprintTestCase` -Bulk update resources in a Blueprint +Author versioned plain-language expectations. Requires the blueprint-test-cases organization feature flag. -`PUT /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/bulk` +`PUT /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases/{test_case_id}` ```ts -const { data } = await client.bulkUpdateBlueprintResources( +const { data } = await client.updateBlueprintTestCase( { blueprint_id: 'example', + test_case_id: 'example', + }, + { + title: 'string', + expectation: 'string', + expected_revision: 1 }, - [ - { - id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', - name: 'string', - type: 'designbuilder', - address: 'string', - is_root: true, - is_ready: true, - is_hidden: true, - is_disabled: false, - hard_dependencies: ['designbuilder'], - parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], - depends_on_addresses: ['string'], - impact_on_install: ['create'], - impact_on_install_reason: ['string'] - } - ], ) ``` @@ -1144,23 +1746,84 @@ const { data } = await client.bulkUpdateBlueprintResources( ```json { - "resources": [ - { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] - } - ] + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "org_id": "string", + "schema_version": 1, + "revision": 1, + "title": "string", + "expectation": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "deleted_at": "1970-01-01T00:00:00.000Z", + "confirmation": { + "schema_version": "1", + "interpretation": { + "schema_version": "1", + "clauses": [ + { + "source_text": "string", + "status": "supported", + "assertions": [ + { + "operator": "resource_included", + "target_key": "string" + } + ], + "reason": "string" + } + ] + }, + "catalog": [ + { + "key": "string", + "type": "string", + "id": "string", + "label": "string", + "membership_state": "included", + "capabilities": ["resource_included"], + "tasks": [ + { + "key": "string", + "label": "string", + "capabilities": ["workflow_task_required"] + } + ] + } + ], + "proposal_hash": "string", + "expectation_sha256": "string", + "interpreter_version": "string", + "confirmed_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "confirmed_at": "1970-01-01T00:00:00.000Z", + "interpreter_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "clauses": [ + {} + ], + "clauses_hash": "string", + "title_key": {}, + "origin": {}, + "needs_reinterpretation": { + "reason": "string" + } } ``` @@ -1168,18 +1831,38 @@ const { data } = await client.bulkUpdateBlueprintResources( --- -### `bulkDeleteBlueprintResources` +### `deleteBlueprintTestCase` -Bulk delete resources in a Blueprint +Author versioned plain-language expectations. Requires the blueprint-test-cases organization feature flag. -`DELETE /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/bulk` +`DELETE /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases/{test_case_id}` ```ts -const { data } = await client.bulkDeleteBlueprintResources( +const { data } = await client.deleteBlueprintTestCase({ + blueprint_id: 'example', + test_case_id: 'example', + expected_revision: 1, +}) +``` + +--- + +### `addBlueprintNote` + +Append an internal note to a blueprint. `id`, `created_at` and `created_by` +are stamped server-side from the caller, so notes cannot be backdated or +attributed to someone else. Existing notes are neve + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/notes` + +```ts +const { data } = await client.addBlueprintNote( { blueprint_id: 'example', }, - ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], + { + text: 'string' + }, ) ``` @@ -1188,23 +1871,16 @@ const { data } = await client.bulkDeleteBlueprintResources( ```json { - "resources": [ - { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] - } - ] + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + } } ``` @@ -1212,32 +1888,22 @@ const { data } = await client.bulkDeleteBlueprintResources( --- -### `updateBlueprintResource` +### `updateBlueprintNote` -Update a resource in a Blueprint +Rewrite the text of an existing internal note. The note keeps its position in +the list along with `created_at` and `created_by`, so an edit cannot reassign +authorship; `updated_at` is stamped server-s -`PUT /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/{resource_id}` +`PATCH /v2/blueprint-manifest/blueprints/{blueprint_id}/notes/{note_id}` ```ts -const { data } = await client.updateBlueprintResource( +const { data } = await client.updateBlueprintNote( { blueprint_id: 'example', - resource_id: 'example', + note_id: 'example', }, { - id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', - name: 'string', - type: 'designbuilder', - address: 'string', - is_root: true, - is_ready: true, - is_hidden: true, - is_disabled: false, - hard_dependencies: ['designbuilder'], - parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], - depends_on_addresses: ['string'], - impact_on_install: ['create'], - impact_on_install_reason: ['string'] + text: 'string' }, ) ``` @@ -1247,23 +1913,16 @@ const { data } = await client.updateBlueprintResource( ```json { - "resources": [ - { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] - } - ] + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + } } ``` @@ -1271,16 +1930,16 @@ const { data } = await client.updateBlueprintResource( --- -### `deleteBlueprintResource` +### `deleteBlueprintNote` -Delete a resource from a Blueprint +Remove a single internal note from a blueprint. -`DELETE /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/{resource_id}` +`DELETE /v2/blueprint-manifest/blueprints/{blueprint_id}/notes/{note_id}` ```ts -const { data } = await client.deleteBlueprintResource({ +const { data } = await client.deleteBlueprintNote({ blueprint_id: 'example', - resource_id: 'example', + note_id: 'example', }) ``` @@ -1289,21 +1948,18 @@ const { data } = await client.deleteBlueprintResource({ ```json { - "resources": [ + "notes": [ { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "name": "string", - "type": "designbuilder", - "address": "string", - "is_root": true, - "is_ready": true, - "is_hidden": true, - "is_disabled": false, - "hard_dependencies": ["designbuilder"], - "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], - "depends_on_addresses": ["string"], - "impact_on_install": ["create"], - "impact_on_install_reason": ["string"] + "id": "3f1c9b0e-2f3a-4a1f-9a3e-6f2b8c7d1e40", + "text": "Adjusted the meter-reading journey for the §14a rollout.", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + } } ] } @@ -1313,14 +1969,43 @@ const { data } = await client.deleteBlueprintResource({ --- -### `listBlueprintJobs` +### `verifyBlueprint` -List Blueprint Jobs +Start a blueprint verification job. Compares resource configurations between a source org +and a destination org to verify that a sync/install was successful. +Returns 202 Accepted with job_id. Poll GET -`GET /v2/blueprint-manifest/jobs` +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}:verify` ```ts -const { data } = await client.listBlueprintJobs() +const { data } = await client.verifyBlueprint( + { + blueprint_id: 'example', + }, + { + source_org_id: 'string', + source_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + destination_org_id: 'string', + destination_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + source_auth_token: 'string', + destination_auth_token: 'string', + installation_job_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + sync_engine: 'terraform' + }, +) +``` + +--- + +### `listMarketplaceSlugs` + +List all available marketplace blueprint slugs from Webflow CMS. +Returns cached results when available. + +`GET /v2/blueprint-manifest/marketplace/slugs` + +```ts +const { data } = await client.listMarketplaceSlugs() ```
@@ -1328,55 +2013,103 @@ const { data } = await client.listBlueprintJobs() ```json { - "total": 1, "results": [ + { + "slug": "wallbox_b2c", + "marketplace_slug": "wallbox-b2c", + "version": "v1.0.0", + "name": "Wallbox B2C", + "installation_link": "https://portal.epilot.cloud/app/blueprints/install/marketplace/wallbox_b2c?s3Ref=https://example.com/blueprint.zip" + } + ] +} +``` + +
+ +--- + +### `formatBlueprintDescription` + +Format a blueprint description as markdown using AI. + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}:format-description` + +```ts +const { data } = await client.formatBlueprintDescription( + { + blueprint_id: 'example', + }, + { + text: 'string' + }, +) +``` + +
+Response + +```json +{ + "markdown": "string" +} +``` + +
+ +--- + +### `suggestBlueprintResources` + +Suggest resources to add to a blueprint based on a natural-language prompt. + +`POST /v2/blueprint-manifest/blueprints:suggest-resources` + +```ts +const { data } = await client.suggestBlueprintResources( + null, + { + prompt: 'everything for the hausanschluss use case', + blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341' + }, +) +``` + +
+Response + +```json +{ + "resources": [ { "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "events": [ + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ { - "timestamp": "1970-01-01T00:00:00.000Z", - "message": "string", - "errors": [ - { - "error": "string", - "code": "dependency_extraction", - "data": { - "formattedResource": { - "id": "string", - "name": "string", - "type": "string" - }, - "resource": "string", - "resourceDependency": "string", - "resources": ["string"], - "addresses": ["string"], - "originalError": "string" - } - } - ], - "level": "info", - "data": { - "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "resources": 0 - } + "path": "string", + "destination": {}, + "source": {}, + "added": true } ], - "triggered_at": "1970-01-01T00:00:00.000Z", - "created_by": { - "name": "manifest@epilot.cloud", - "org_id": "911690", - "user_id": "11001045", - "token_id": "api_5ZugdRXasLfWBypHi93Fk" - }, - "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "status": "IN_PROGRESS", - "download_file": { - "bucket": "blueprint-manifest-prod-blueprintsv2bucket-sybpsryropzw", - "key": "templates/main.tf" - } + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] } - ] + ], + "suggested_blueprint_name": "Hausanschluss", + "explanation": "string", + "add_dependencies_recommended": true } ``` @@ -1384,16 +2117,44 @@ const { data } = await client.listBlueprintJobs() --- -### `getBlueprintJob` +### `addBlueprintResource` -Get Job +Add a resource to a Blueprint -`GET /v2/blueprint-manifest/jobs/{job_id}` +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/resources` ```ts -const { data } = await client.getBlueprintJob({ - job_id: 'example', -}) +const { data } = await client.addBlueprintResource( + { + blueprint_id: 'example', + add_dependencies: true, + }, + { + id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + name: 'string', + type: 'designbuilder', + address: 'string', + is_root: true, + is_ready: true, + is_hidden: true, + is_disabled: false, + hard_dependencies: ['designbuilder'], + parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], + depends_on_addresses: ['string'], + impact_on_install: ['create'], + impact_on_install_reason: ['string'], + impact_on_install_changes: [ + { + path: 'string', + destination: {}, + source: {}, + added: true + } + ], + impact_on_install_labels: {}, + impact_on_install_summary: ['string'] + }, +) ```
@@ -1401,201 +2162,5352 @@ const { data } = await client.getBlueprintJob({ ```json { - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "events": [ + "resources": [ { - "timestamp": "1970-01-01T00:00:00.000Z", - "message": "string", - "errors": [ + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ { - "error": "string", - "code": "dependency_extraction", - "data": { - "formattedResource": { - "id": "string", - "name": "string", - "type": "string" - }, - "resource": "string", - "resourceDependency": "string", - "resources": ["string"], - "addresses": ["string"], - "originalError": "string" - } + "path": "string", + "destination": {}, + "source": {}, + "added": true } ], - "level": "info", + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] + } + ], + "skipped": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "type": "designbuilder", + "reason": "not_found" + } + ], + "errors": [ + { + "error": "string", + "code": "dependency_extraction", "data": { - "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "resources": 0 + "missing_count": 0, + "exclude_count": 0, + "source_drift_s3_key": "string", + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string", + "current": 0, + "max_allowed": 0, + "planned": 0 } } ], - "triggered_at": "1970-01-01T00:00:00.000Z", - "created_by": { - "name": "manifest@epilot.cloud", - "org_id": "911690", - "user_id": "11001045", - "token_id": "api_5ZugdRXasLfWBypHi93Fk" + "total_errors": 0, + "errors_truncated": true +} +``` + +
+ +--- + +### `syncDependencies` + +Sync dependencies of all root resources in a Blueprint + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/resources:syncDependencies` + +```ts +const { data } = await client.syncDependencies({ + blueprint_id: 'example', + trigger: 'example', +}) +``` + +--- + +### `bulkAddBlueprintResources` + +Bulk Add resources in a Blueprint + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/bulk` + +```ts +const { data } = await client.bulkAddBlueprintResources( + { + blueprint_id: 'example', + add_dependencies: true, }, - "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "status": "IN_PROGRESS", - "download_file": { - "bucket": "blueprint-manifest-prod-blueprintsv2bucket-sybpsryropzw", - "key": "templates/main.tf" + [ + { + id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + name: 'string', + type: 'designbuilder', + address: 'string', + is_root: true, + is_ready: true, + is_hidden: true, + is_disabled: false, + hard_dependencies: ['designbuilder'], + parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], + depends_on_addresses: ['string'], + impact_on_install: ['create'], + impact_on_install_reason: ['string'], + impact_on_install_changes: [ + { + path: 'string', + destination: {}, + source: {}, + added: true + } + ], + impact_on_install_labels: {}, + impact_on_install_summary: ['string'] + } + ], +) +``` + +
+Response + +```json +{ + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ + { + "path": "string", + "destination": {}, + "source": {}, + "added": true + } + ], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] + } + ], + "skipped": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "type": "designbuilder", + "reason": "not_found" + } + ], + "errors": [ + { + "error": "string", + "code": "dependency_extraction", + "data": { + "missing_count": 0, + "exclude_count": 0, + "source_drift_s3_key": "string", + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string", + "current": 0, + "max_allowed": 0, + "planned": 0 + } + } + ], + "total_errors": 0, + "errors_truncated": true +} +``` + +
+ +--- + +### `bulkUpdateBlueprintResources` + +Bulk update resources in a Blueprint + +`PUT /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/bulk` + +```ts +const { data } = await client.bulkUpdateBlueprintResources( + { + blueprint_id: 'example', + }, + [ + { + id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + name: 'string', + type: 'designbuilder', + address: 'string', + is_root: true, + is_ready: true, + is_hidden: true, + is_disabled: false, + hard_dependencies: ['designbuilder'], + parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], + depends_on_addresses: ['string'], + impact_on_install: ['create'], + impact_on_install_reason: ['string'], + impact_on_install_changes: [ + { + path: 'string', + destination: {}, + source: {}, + added: true + } + ], + impact_on_install_labels: {}, + impact_on_install_summary: ['string'] + } + ], +) +``` + +
+Response + +```json +{ + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ + { + "path": "string", + "destination": {}, + "source": {}, + "added": true + } + ], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] + } + ] +} +``` + +
+ +--- + +### `bulkDeleteBlueprintResources` + +Bulk delete resources in a Blueprint + +`DELETE /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/bulk` + +```ts +const { data } = await client.bulkDeleteBlueprintResources( + { + blueprint_id: 'example', + }, + ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], +) +``` + +
+Response + +```json +{ + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ + { + "path": "string", + "destination": {}, + "source": {}, + "added": true + } + ], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] + } + ] +} +``` + +
+ +--- + +### `updateBlueprintResource` + +Update a resource in a Blueprint + +`PUT /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/{resource_id}` + +```ts +const { data } = await client.updateBlueprintResource( + { + blueprint_id: 'example', + resource_id: 'example', + }, + { + id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + name: 'string', + type: 'designbuilder', + address: 'string', + is_root: true, + is_ready: true, + is_hidden: true, + is_disabled: false, + hard_dependencies: ['designbuilder'], + parent_resource_ids: ['c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341'], + depends_on_addresses: ['string'], + impact_on_install: ['create'], + impact_on_install_reason: ['string'], + impact_on_install_changes: [ + { + path: 'string', + destination: {}, + source: {}, + added: true + } + ], + impact_on_install_labels: {}, + impact_on_install_summary: ['string'] + }, +) +``` + +
+Response + +```json +{ + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ + { + "path": "string", + "destination": {}, + "source": {}, + "added": true + } + ], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] + } + ] +} +``` + +
+ +--- + +### `deleteBlueprintResource` + +Delete a resource from a Blueprint + +`DELETE /v2/blueprint-manifest/blueprints/{blueprint_id}/resources/{resource_id}` + +```ts +const { data } = await client.deleteBlueprintResource({ + blueprint_id: 'example', + resource_id: 'example', +}) +``` + +
+Response + +```json +{ + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ + { + "path": "string", + "destination": {}, + "source": {}, + "added": true + } + ], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] + } + ] +} +``` + +
+ +--- + +### `listBlueprintJobs` + +List all blueprint jobs + +`GET /v2/blueprint-manifest/jobs` + +```ts +const { data } = await client.listBlueprintJobs() +``` + +
+Response + +```json +{ + "total": 1, + "results": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "events": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "message": "string", + "errors": [ + { + "error": "string", + "code": "dependency_extraction", + "data": { + "missing_count": 0, + "exclude_count": 0, + "source_drift_s3_key": "string", + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string", + "current": 0, + "max_allowed": 0, + "planned": 0 + } + } + ], + "level": "info", + "data": { + "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "resources": 0 + } + } + ], + "triggered_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "job_type": "export", + "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "download_file": { + "bucket": "blueprint-manifest-prod-blueprintsv2bucket-sybpsryropzw", + "key": "templates/main.tf" + } + } + ] +} +``` + +
+ +--- + +### `getBlueprintJob` + +Poll the current state of a job. Serves both Terraform (v2) and V3-engine jobs — +check `sync_engine` (`terraform` | `v3`) to tell them apart. V3 jobs additionally +expose live `resource_progress[]`. V3 + +`GET /v2/blueprint-manifest/jobs/{job_id}` + +```ts +const { data } = await client.getBlueprintJob({ + job_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "events": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "message": "string", + "errors": [ + { + "error": "string", + "code": "dependency_extraction", + "data": { + "missing_count": 0, + "exclude_count": 0, + "source_drift_s3_key": "string", + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string", + "current": 0, + "max_allowed": 0, + "planned": 0 + } + } + ], + "level": "info", + "data": { + "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "resources": 0 + } + } + ], + "triggered_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "job_type": "export", + "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "download_file": { + "bucket": "blueprint-manifest-prod-blueprintsv2bucket-sybpsryropzw", + "key": "templates/main.tf" + } +} +``` + +
+ +--- + +### `continueInstallationJob` + +Resume an installation job that is paused at `status: "WAITING_USER_ACTION"` after +planning. Works for both Terraform and V3 jobs. Not needed for V3 installs created +with `auto_apply: true` (including + +`POST /v2/blueprint-manifest/jobs/{job_id}:continue` + +```ts +const { data } = await client.continueInstallationJob( + { + job_id: 'example', + }, + { + resources_to_ignore: ['string'], + sync_notes: false, + include_field_diffs: false, + source_auth_token: 'string' + }, +) +``` + +
+Response + +```json +{ + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "events": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "message": "string", + "errors": [ + { + "error": "string", + "code": "dependency_extraction", + "data": { + "missing_count": 0, + "exclude_count": 0, + "source_drift_s3_key": "string", + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string", + "current": 0, + "max_allowed": 0, + "planned": 0 + } + } + ], + "level": "info", + "data": { + "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "resources": 0 + } + } + ], + "triggered_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "source_drift": { + "removed": [ + { + "address": "string", + "type": "designbuilder", + "name": "string", + "id": "string" + } + ], + "missing": [ + { + "address": "string", + "type": "designbuilder", + "name": "string", + "id": "string", + "referenced_by": ["string"] + } + ], + "exclude_addresses": ["string"] + }, + "job_type": "install", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "source_blueprint_type": "custom", + "source_org_id": "string", + "source_blueprint_file": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "slug": "string", + "sync_engine": "terraform", + "resource_progress": [ + { + "lineage_id": "string", + "type": "string", + "address": "string", + "name": "string", + "status": "pending", + "target_id": "string", + "error_message": "string", + "error_code": "string", + "error_data": {} + } + ], + "options": { + "resources_to_ignore": ["string"], + "sync_notes": false, + "include_field_diffs": false + }, + "merge_plan_id": "string", + "wait_kind": "plan", + "prefill_from_merge_plan_id": "string", + "assigned_merge_plan_id": "string", + "status": "IN_PROGRESS" +} +``` + +
+ +--- + +### `retryInstallationJob` + +Retry a finished V3 installation job whose status is `FAILED` or +`PARTIAL_SUCCESS`. Starts a fresh install job (new `job_id`) with the same +source/destination and `auto_apply: true` — no `:continue` c + +`POST /v2/blueprint-manifest/jobs/{job_id}:retry` + +```ts +const { data } = await client.retryInstallationJob({ + job_id: 'example', +}) +``` + +--- + +### `cancelBlueprintJob` + +Cancel a blueprint job if it is still running. + +`POST /v2/blueprint-manifest/jobs/{job_id}:cancel` + +```ts +const { data } = await client.cancelBlueprintJob({ + job_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "events": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "message": "string", + "errors": [ + { + "error": "string", + "code": "dependency_extraction", + "data": { + "missing_count": 0, + "exclude_count": 0, + "source_drift_s3_key": "string", + "formattedResource": { + "id": "string", + "name": "string", + "type": "string" + }, + "resource": "string", + "resourceDependency": "string", + "resources": ["string"], + "addresses": ["string"], + "originalError": "string", + "current": 0, + "max_allowed": 0, + "planned": 0 + } + } + ], + "level": "info", + "data": { + "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "resources": 0 + } + } + ], + "triggered_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "job_type": "export", + "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "IN_PROGRESS", + "download_file": { + "bucket": "blueprint-manifest-prod-blueprintsv2bucket-sybpsryropzw", + "key": "templates/main.tf" + } +} +``` + +
+ +--- + +### `createMarketplaceListing` + +Create a marketplace listing for a blueprint. Returns 409 if one already exists. + +`POST /v1/blueprints/{blueprint_id}/marketplace-listing` + +```ts +const { data } = await client.createMarketplaceListing( + { + blueprint_id: 'example', + }, + { + name: 'string', + slug: 'string' + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getMarketplaceListing` + +Get marketplace listing for a blueprint including all versions + +`GET /v1/blueprints/{blueprint_id}/marketplace-listing` + +```ts +const { data } = await client.getMarketplaceListing({ + blueprint_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "versions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" + } + ], + "has_publishable_draft": true +} +``` + +
+ +--- + +### `listMarketplaceListings` + +List all marketplace listings for the authenticated organization + +`GET /v1/marketplace-listings` + +```ts +const { data } = await client.listMarketplaceListings() +``` + +
+Response + +```json +{ + "listings": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `getMarketplaceListingById` + +Get marketplace listing by listing ID including all versions + +`GET /v1/marketplace-listings/{listing_id}` + +```ts +const { data } = await client.getMarketplaceListingById({ + listing_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "versions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" + } + ], + "has_publishable_draft": true +} +``` + +
+ +--- + +### `updateMarketplaceListing` + +Update listing-level fields + +`PATCH /v1/marketplace-listings/{listing_id}` + +```ts +const { data } = await client.updateMarketplaceListing( + { + listing_id: 'example', + }, + { + name: 'string', + slug: 'string', + logo: 'string', + documentation_url: 'string', + pricing_type: 'free', + support_email: 'string', + portal_description: 'string', + teaser_name: 'string', + teaser_short_description: 'string', + teaser_thumbnail: 'string', + details_page_title: 'string', + details_page_description: 'string', + details_page_hero_image: 'string', + details_page_carousel: ['string'], + resources_section_description: 'string', + resources_section_benefits_title: 'string', + resources_section_benefits_list: 'string', + resources_section_process_details: 'string', + partner: 'string', + partner_subtext: 'string', + partner_logo: 'string', + partner_website_link: 'string', + last_updated_on: 'string', + requires_customer_portal: true, + process_details_section_title: 'string', + is_new_blueprint: true, + available_in: 'string', + testimonials: ['string'], + installation_link: 'string', + installation_slug: 'string', + demo_form_link: 'string', + order: 0, + categories: ['string'], + main_category: ['string'] + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "name": "string", + "slug": "string", + "logo": "string", + "documentation_url": "string", + "pricing_type": "free", + "support_email": "string", + "portal_description": "string", + "teaser_name": "string", + "teaser_short_description": "string", + "teaser_thumbnail": "string", + "details_page_title": "string", + "details_page_description": "string", + "details_page_hero_image": "string", + "details_page_carousel": ["string"], + "resources_section_description": "string", + "resources_section_benefits_title": "string", + "resources_section_benefits_list": "string", + "resources_section_process_details": "string", + "partner": "string", + "partner_subtext": "string", + "partner_logo": "string", + "partner_website_link": "string", + "last_updated_on": "string", + "requires_customer_portal": true, + "process_details_section_title": "string", + "is_new_blueprint": true, + "available_in": "string", + "testimonials": ["string"], + "installation_link": "string", + "installation_slug": "string", + "demo_form_link": "string", + "order": 0, + "categories": ["string"], + "main_category": ["string"], + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteMarketplaceListing` + +Delete listing and all versions + +`DELETE /v1/marketplace-listings/{listing_id}` + +```ts +const { data } = await client.deleteMarketplaceListing({ + listing_id: 'example', +}) +``` + +--- + +### `createMarketplaceListingVersion` + +Create a draft version; auto-snapshots resources, requiredFeatures, recommendedApps from current blueprint + +`POST /v1/marketplace-listings/{listing_id}/versions` + +```ts +const { data } = await client.createMarketplaceListingVersion({ + listing_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listMarketplaceListingVersions` + +List all versions for a listing, newest first + +`GET /v1/marketplace-listings/{listing_id}/versions` + +```ts +const { data } = await client.listMarketplaceListingVersions({ + listing_id: 'example', +}) +``` + +
+Response + +```json +{ + "versions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `updateMarketplaceListingVersion` + +Update updateNote, requiredFeatures, or recommendedApps on a draft version + +`PATCH /v1/marketplace-listings/{listing_id}/versions/{version_id}` + +```ts +const { data } = await client.updateMarketplaceListingVersion( + { + listing_id: 'example', + version_id: 'example', + }, + { + update_note: 'string', + required_features: ['string'], + recommended_apps: ['string'] + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `publishMarketplaceListingVersion` + +Publish a draft version; archives the previous live version + +`POST /v1/marketplace-listings/{listing_id}/versions/{version_id}/publish` + +```ts +const { data } = await client.publishMarketplaceListingVersion( + { + listing_id: 'example', + version_id: 'example', + }, + { + version_name: 'string', + update_note: 'string' + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "listing_id": "string", + "status": "draft", + "version_name": "string", + "draft_label": "string", + "update_note": "string", + "resources": [ + {} + ], + "required_features": ["string"], + "recommended_apps": ["string"], + "created_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `publishBlueprintV3` + +Starts an asynchronous V3 publication. The result is a signed, portable package; poll the existing blueprint job endpoint for completion. + +`POST /v3/blueprint-manifest/blueprints/{blueprint_id}:publish` + +```ts +const { data } = await client.publishBlueprintV3( + { + blueprint_id: 'example', + }, + { + publish_to_marketplace: false, + slug: 'string', + version: 'string', + name: 'string' + }, +) +``` + +--- + +### `sendBlueprintAssistantMessage` + +Sends a message to the blueprint assistant for a custom blueprint, starting a conversation when +`conversation_id` is omitted. The answer is produced asynchronously: poll +`getBlueprintAssistantConversa + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/assistant/messages` + +```ts +const { data } = await client.sendBlueprintAssistantMessage( + { + blueprint_id: 'example', + }, + { + conversation_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + message: 'string', + retry: true, + proposal_update: { + proposal_id: 'string', + status: 'applied', + note: 'string' + } + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "blueprint_id": "string", + "status": "IN_PROGRESS", + "error": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "created_by_name": "string", + "messages": [ + { + "id": "string", + "role": "user", + "created_at": "1970-01-01T00:00:00.000Z", + "parts": [ + { + "type": "text", + "text": "string", + "tool_use_id": "string", + "tool": "string", + "title": "string", + "status": "running", + "result": { + "kind": "string" + } + } + ] + } + ] +} +``` + +
+ +--- + +### `listBlueprintAssistantConversations` + +The blueprint's blueprint assistant conversations in this organization, most recently updated first +(at most 20). Conversations expire 30 days after their last update. + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/assistant/conversations` + +```ts +const { data } = await client.listBlueprintAssistantConversations({ + blueprint_id: 'example', + mine: true, +}) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "string", + "title": "string", + "status": "IN_PROGRESS", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "created_by_name": "string", + "message_count": 0 + } + ] +} +``` + +
+ +--- + +### `getBlueprintAssistantConversation` + +A blueprint assistant conversation, including the answer in progress. + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/assistant/conversations/{conversation_id}` + +```ts +const { data } = await client.getBlueprintAssistantConversation({ + blueprint_id: 'example', + conversation_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "string", + "blueprint_id": "string", + "status": "IN_PROGRESS", + "error": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "created_by_name": "string", + "messages": [ + { + "id": "string", + "role": "user", + "created_at": "1970-01-01T00:00:00.000Z", + "parts": [ + { + "type": "text", + "text": "string", + "tool_use_id": "string", + "tool": "string", + "title": "string", + "status": "running", + "result": { + "kind": "string" + } + } + ] + } + ] +} +``` + +
+ +--- + +### `listBlueprintAssistantSkills` + +The organization's blueprint assistant skills, the skills epilot ships (`defaults`; an organization +skill with the same name replaces one), and the upload limits. Available when `blueprint-ai-assistan + +`GET /v2/blueprint-manifest/assistant/skills` + +```ts +const { data } = await client.listBlueprintAssistantSkills() +``` + +
+Response + +```json +{ + "results": [ + { + "name": "string", + "description": "string", + "enabled": true, + "files": ["string"], + "size": 0, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "updated_by_name": "string" + } + ], + "defaults": [ + { + "name": "string", + "description": "string", + "audience": "publishers" + } + ], + "limits": {} +} +``` + +
+ +--- + +### `uploadBlueprintAssistantSkill` + +Uploads a skill for the organization's blueprint assistant, replacing the skill of the same name. +The file is a `SKILL.md` or a zip with `SKILL.md` and `references/*.md` (the format claude.ai exports; + +`POST /v2/blueprint-manifest/assistant/skills` + +```ts +const { data } = await client.uploadBlueprintAssistantSkill( + null, + { + file_name: 'string', + content_base64: 'string' + }, +) +``` + +
+Response + +```json +{ + "name": "string", + "description": "string", + "enabled": true, + "files": ["string"], + "size": 0, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "updated_by_name": "string", + "ignored": ["string"] +} +``` + +
+ +--- + +### `getBlueprintAssistantSkill` + +A skill of the organization with the text of its files. + +`GET /v2/blueprint-manifest/assistant/skills/{skill_name}` + +```ts +const { data } = await client.getBlueprintAssistantSkill({ + skill_name: 'example', +}) +``` + +
+Response + +```json +{ + "name": "string", + "description": "string", + "enabled": true, + "files": ["string"], + "size": 0, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "updated_by_name": "string", + "contents": {} +} +``` + +
+ +--- + +### `updateBlueprintAssistantSkill` + +Enables or disables a skill. Conversations keep the skills they started with. + +`PATCH /v2/blueprint-manifest/assistant/skills/{skill_name}` + +```ts +const { data } = await client.updateBlueprintAssistantSkill( + { + skill_name: 'example', + }, + { + enabled: true + }, +) +``` + +
+Response + +```json +{ + "name": "string", + "description": "string", + "enabled": true, + "files": ["string"], + "size": 0, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "updated_by_name": "string" +} +``` + +
+ +--- + +### `deleteBlueprintAssistantSkill` + +Deletes a skill. Running conversations that offered it answer that it was removed. + +`DELETE /v2/blueprint-manifest/assistant/skills/{skill_name}` + +```ts +const { data } = await client.deleteBlueprintAssistantSkill({ + skill_name: 'example', +}) +``` + +--- + +### `preInstallBlueprintV3` + +Validates a signed V3 package and returns the destination-specific resource plan used by the install UI. + +`POST /v3/blueprint-manifest/blueprints:pre-install` + +```ts +const { data } = await client.preInstallBlueprintV3( + null, + { + blueprint_file: 'string', + source_blueprint_type: 'marketplace', + slug: 'string' + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "org_id": "string", + "title": "string", + "description": { + "preinstall": "string" + }, + "version": "string", + "slug": "string", + "source_type": "marketplace", + "sync_engine": "terraform", + "blueprint_file_s3_key": "string", + "is_verified": true, + "docs_url": "string", + "recommended_apps": ["string"], + "required_features": { + "enabled": ["string"], + "disabled": ["string"] + }, + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "is_updating": true, + "resources": [ + { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "name": "string", + "type": "designbuilder", + "address": "string", + "is_root": true, + "is_ready": true, + "is_hidden": true, + "is_disabled": false, + "hard_dependencies": ["designbuilder"], + "parent_resource_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "depends_on_addresses": ["string"], + "impact_on_install": ["create"], + "impact_on_install_reason": ["string"], + "impact_on_install_changes": [ + { + "path": "string", + "destination": {}, + "source": {}, + "added": true + } + ], + "impact_on_install_labels": {}, + "impact_on_install_summary": ["string"] + } + ] +} +``` + +
+ +--- + +### `getBlueprintMergePlan` + +Summary of an update merge plan, with counts, warnings and the revision to send back. + +`GET /v3/blueprint-manifest/merge-plans/{merge_plan_id}` + +```ts +const { data } = await client.getBlueprintMergePlan({ + merge_plan_id: 'example', +}) +``` + +
+Response + +```json +{ + "merge_plan_id": "string", + "plan_revision": 0, + "expected_plan_revision": 0, + "warnings": [ + { + "code": "string", + "resource_key": "string", + "target": "string", + "message": "string" + } + ], + "blocked_reasons": ["string"], + "apply_counts": { + "updated": 0, + "kept": 0, + "removed": 0, + "restored": 0 + }, + "apply_counts_unknown": true, + "state": "review_required", + "job_id": "string", + "destination_blueprint_id": "string", + "source": { + "blueprint_id": "string", + "version": "string" + }, + "resource_counts": { + "automatic": 0, + "decisions_required": 0, + "ready": 0, + "blocked": 0 + }, + "group_counts": { + "conflict": 0, + "confirm": 0, + "mandatory": 0, + "unresolved": 0 + }, + "warning_count": 0, + "auto_counts": { + "kept_customizations": 0, + "applied_updates": 0 + }, + "other_resource_count": 0, + "created_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "revert_until": "1970-01-01T00:00:00.000Z", + "supersedes": "string", + "superseded_by": "string", + "successor_failed": true +} +``` + +
+ +--- + +### `listBlueprintMergePlanResources` + +Journeys of the plan, one page at a time. A cursor is valid only for the revision it was issued for. + +`GET /v3/blueprint-manifest/merge-plans/{merge_plan_id}/resources` + +```ts +const { data } = await client.listBlueprintMergePlanResources({ + merge_plan_id: 'example', + cursor: 'example', + limit: 1, +}) +``` + +
+Response + +```json +{ + "merge_plan_id": "string", + "plan_revision": 0, + "resources": [ + { + "resource_key": "string", + "label": "string", + "status": "automatic", + "eligibility": "merge", + "blocking_reasons": ["string"], + "auto_counts": { + "from_current": 0, + "from_incoming": 0 + }, + "unresolved": 0, + "warning_count": 0, + "outcome": "applied" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `getBlueprintMergePlanResource` + +One journey of the plan with its decision groups and warnings. + +`GET /v3/blueprint-manifest/merge-plans/{merge_plan_id}/resources/{resource_key}` + +```ts +const { data } = await client.getBlueprintMergePlanResource({ + merge_plan_id: 'example', + resource_key: 'example', +}) +``` + +
+Response + +```json +{ + "merge_plan_id": "string", + "plan_revision": 0, + "resource": { + "resource_key": "string", + "resource_type": "journey", + "lineage_id": "string", + "target_id": "string", + "label": "string", + "model_version": "string", + "base_provenance": { + "rung": "apply_evidence", + "job_id": "string", + "manifest_version": "string", + "reason": "no_evidence" + }, + "eligibility": "merge", + "fast_path": true, + "auto_counts": { + "from_current": 0, + "from_incoming": 0 + }, + "decision_groups": [ + {} + ], + "warnings": [ + {} + ], + "status": "automatic", + "blocking_reasons": ["string"], + "outcome": "applied" + } +} +``` + +
+ +--- + +### `updateBlueprintMergePlanResolutions` + +Saves choices for decision groups. Each submitted choice replaces the saved choice of the same group. Allowed while the plan waits for review. + +`PUT /v3/blueprint-manifest/merge-plans/{merge_plan_id}/resolutions` + +```ts +const { data } = await client.updateBlueprintMergePlanResolutions( + { + merge_plan_id: 'example', + }, + { + expected_plan_revision: 0, + resolutions: [ + { + group_id: 'string', + group_signature: 'string', + option_id: 'string' + } + ] + }, +) +``` + +
+Response + +```json +{ + "merge_plan_id": "string", + "plan_revision": 0, + "expected_plan_revision": 0, + "warnings": [ + { + "code": "string", + "resource_key": "string", + "target": "string", + "message": "string" + } + ], + "blocked_reasons": ["string"], + "apply_counts": { + "updated": 0, + "kept": 0, + "removed": 0, + "restored": 0 + }, + "apply_counts_unknown": true, + "state": "review_required", + "job_id": "string", + "destination_blueprint_id": "string", + "source": { + "blueprint_id": "string", + "version": "string" + }, + "resource_counts": { + "automatic": 0, + "decisions_required": 0, + "ready": 0, + "blocked": 0 + }, + "group_counts": { + "conflict": 0, + "confirm": 0, + "mandatory": 0, + "unresolved": 0 + }, + "warning_count": 0, + "auto_counts": { + "kept_customizations": 0, + "applied_updates": 0 + }, + "other_resource_count": 0, + "created_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "revert_until": "1970-01-01T00:00:00.000Z", + "supersedes": "string", + "superseded_by": "string", + "successor_failed": true +} +``` + +
+ +--- + +### `discardBlueprintMergePlan` + +Discards a plan waiting for review and ends its job. Nothing is written. + +`POST /v3/blueprint-manifest/merge-plans/{merge_plan_id}:discard` + +```ts +const { data } = await client.discardBlueprintMergePlan( + { + merge_plan_id: 'example', + }, + { + expected_plan_revision: 0 + }, +) +``` + +
+Response + +```json +{ + "merge_plan_id": "string", + "plan_revision": 0, + "expected_plan_revision": 0, + "warnings": [ + { + "code": "string", + "resource_key": "string", + "target": "string", + "message": "string" + } + ], + "blocked_reasons": ["string"], + "apply_counts": { + "updated": 0, + "kept": 0, + "removed": 0, + "restored": 0 + }, + "apply_counts_unknown": true, + "state": "review_required", + "job_id": "string", + "destination_blueprint_id": "string", + "source": { + "blueprint_id": "string", + "version": "string" + }, + "resource_counts": { + "automatic": 0, + "decisions_required": 0, + "ready": 0, + "blocked": 0 + }, + "group_counts": { + "conflict": 0, + "confirm": 0, + "mandatory": 0, + "unresolved": 0 + }, + "warning_count": 0, + "auto_counts": { + "kept_customizations": 0, + "applied_updates": 0 + }, + "other_resource_count": 0, + "created_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "revert_until": "1970-01-01T00:00:00.000Z", + "supersedes": "string", + "superseded_by": "string", + "successor_failed": true +} +``` + +
+ +--- + +### `replanBlueprintMergePlan` + +Starts a new update job whose plan is prefilled with this plan's saved choices. A plan still waiting for review, or expired, becomes `superseded`. + +`POST /v3/blueprint-manifest/merge-plans/{merge_plan_id}:replan` + +```ts +const { data } = await client.replanBlueprintMergePlan( + { + merge_plan_id: 'example', + }, + { + expected_plan_revision: 0 + }, +) +``` + +--- + +### `applyBlueprintMergePlan` + +Approves the plan at `expected_plan_revision` with its current choices and resumes the parked update job with the caller's token. Only a `ready` plan whose job waits for this review can be applied. Re + +`POST /v3/blueprint-manifest/merge-plans/{merge_plan_id}:apply` + +```ts +const { data } = await client.applyBlueprintMergePlan( + { + merge_plan_id: 'example', + }, + { + expected_plan_revision: 0, + idempotency_key: 'string' + }, +) +``` + +--- + +### `previewBlueprintMergeRevert` + +Lists what the update wrote, from its own journal, and what reverting each resource would do. Resources changed since the update need an explicit choice (`requires_choice`); `not_restorable` ones can + +`POST /v3/blueprint-manifest/merge-plans/{merge_plan_id}:preview-revert` + +```ts +const { data } = await client.previewBlueprintMergeRevert( + { + merge_plan_id: 'example', + }, + {}, +) +``` + +
+Response + +```json +{ + "revert_preview_id": "string", + "preview_revision": 0, + "merge_plan_id": "string", + "entries": [ + { + "resource_key": "string", + "lineage_id": "string", + "label": "string", + "resource_type": "string", + "category": "unchanged", + "default_action": "restore", + "requires_choice": true + } + ] +} +``` + +
+ +--- + +### `applyBlueprintMergeRevert` + +Reverts the update as the preview describes it, with an explicit `action` for every preview entry. Starts a `restore` job and moves the plan to `reverting`; the job ends it `reverted`, or `revert_part + +`POST /v3/blueprint-manifest/merge-plans/{merge_plan_id}:revert` + +```ts +const { data } = await client.applyBlueprintMergeRevert( + { + merge_plan_id: 'example', + }, + { + revert_preview_id: 'string', + expected_preview_revision: 0, + idempotency_key: 'string', + selections: [ + { + resource_key: 'string', + action: 'restore' + } + ], + session_credentials: { + refresh_token: 'string', + client_id: 'string', + pipeline_id: 'string' + } + }, +) +``` + +--- + +### `installBlueprintV3` + +Install a blueprint into a single destination org using the V3 engine (direct API +calls, no Terraform). Creates resources in topological order with global ID +replacement and supports checkpoint-based + +`POST /v3/blueprint-manifest/blueprint:install` + +```ts +const { data } = await client.installBlueprintV3( + null, + {}, +) +``` + +--- + +### `restoreBlueprintDeploymentV3` + +Roll a deployment back to its pre-install state. Two phases: + +`POST /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}:restore` + +```ts +const { data } = await client.restoreBlueprintDeploymentV3({ + blueprint_id: 'example', + job_id: 'example', +}) +``` + +--- + +### `getRestorePreview` + +Computes what would happen if the user triggered a restore on this +deployment, without performing any writes. The forecast uses the +snapshot's captured resources (when present) plus the current lineag + +`GET /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}/restore-preview` + +```ts +const { data } = await client.getRestorePreview({ + blueprint_id: 'example', + job_id: 'example', +}) +``` + +
+Response + +```json +{ + "snapshot_id": "string", + "resources": [ + { + "lineage_id": "string", + "type": "string", + "name": "string", + "target_id": "string", + "action": "restore", + "reason": "modified", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "current_updated_at": "1970-01-01T00:00:00.000Z", + "error_message": "string", + "is_hidden": true, + "co_owned_by": [ + { + "blueprint_id": "string", + "title": "string" + } + ], + "protected_by": [ + { + "lineage_id": "string", + "type": "string", + "target_id": "string" + } + ] + } + ], + "has_effective_changes": true +} +``` + +
+ +--- + +### `triggerRestorePreview` + +Starts computing the same forecast as `getRestorePreview` in the +background. Large deployments take longer than the API Gateway +timeout to forecast inline, so clients should prefer this endpoint. + +`POST /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}:restore-preview` + +```ts +const { data } = await client.triggerRestorePreview({ + blueprint_id: 'example', + job_id: 'example', +}) +``` + +--- + +### `getRestorePreviewReport` + +Returns a restore preview started by `triggerRestorePreview`. The +`outcome` is present once `status` is `completed`. A preview whose +worker stopped without reporting is returned as `failed`. + +`GET /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}/restore-preview/{preview_id}` + +```ts +const { data } = await client.getRestorePreviewReport({ + blueprint_id: 'example', + job_id: 'example', + preview_id: 'example', +}) +``` + +
+Response + +```json +{ + "preview_id": "string", + "job_id": "string", + "status": "running", + "requested_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "outcome": { + "snapshot_id": "string", + "resources": [ + { + "lineage_id": "string", + "type": "string", + "name": "string", + "target_id": "string", + "action": "restore", + "reason": "modified", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "current_updated_at": "1970-01-01T00:00:00.000Z", + "error_message": "string", + "is_hidden": true, + "co_owned_by": [ + { + "blueprint_id": "string", + "title": "string" + } + ], + "protected_by": [ + { + "lineage_id": "string", + "type": "string", + "target_id": "string" + } + ] + } + ], + "has_effective_changes": true + }, + "error": "string" +} +``` + +
+ +--- + +### `triggerDeploymentHealthCheckV3` + +Starts a read-only health scan of the resources this deployment's +blueprint instance tracks in the destination org (see +docs/rfcs/RFC-org-health-check.md, Phase 0). Checks: + +`POST /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}:health-check` + +```ts +const { data } = await client.triggerDeploymentHealthCheckV3( + { + blueprint_id: 'example', + job_id: 'example', + }, + { + source_org_id: 'string', + source_auth_token: 'string' + }, +) +``` + +--- + +### `getDeploymentHealthReportV3` + +Returns the most recent health report produced for this deployment +by the `:health-check` endpoint. Idempotent and side-effect free. + +`GET /v3/blueprint-manifest/blueprints/{blueprint_id}/deployments/{job_id}/health-report` + +```ts +const { data } = await client.getDeploymentHealthReportV3({ + blueprint_id: 'example', + job_id: 'example', +}) +``` + +
+Response + +```json +{ + "status": "running", + "job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "blueprint_instance_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "generated_at": "1970-01-01T00:00:00.000Z", + "html_url": "string", + "summary": { + "resources_scanned": 0, + "unchecked": 0, + "errors": 0, + "warnings": 0, + "infos": 0 + }, + "findings": [ + { + "check_id": "live_readability", + "code": "missing_in_destination", + "severity": "error", + "resource_type": "string", + "lineage_id": "string", + "target_id": "string", + "resource_name": "string", + "message": "string", + "verdict": "string", + "evidence": { + "path": "string", + "referenced_id": "string", + "referenced_type": "string", + "referenced_name": "string", + "referenced_lineage_id": "string", + "expected_target_id": "string", + "reference_kind": "string", + "operation": "string", + "rejection_reason": "string", + "error_message": "string", + "response_status": 0 + } + } + ], + "coverage": { + "checks": [ + { + "check_id": "live_readability", + "status": "completed", + "scope": "tracked_resources", + "resources_considered": 0, + "details": ["string"] + } + ], + "resource_types": [ + { + "resource_type": "string", + "tracked": 0, + "readable_by_lineage": 0, + "missing_by_lineage": 0, + "read_errors": 0, + "unchecked": 0, + "specialized_checks": ["live_readability"], + "known_blind_spots": ["string"] + } + ] + }, + "error": "string" +} +``` + +
+ +--- + +### `getBlueprintLineageV3` + +Returns the lineage registry entries for a blueprint's resources in the current org. +Shows the mapping between source lineage IDs and target resource IDs. + +`GET /v3/blueprint-manifest/blueprints/{blueprint_id}/lineage` + +```ts +const { data } = await client.getBlueprintLineageV3({ + blueprint_id: 'example', +}) +``` + +
+Response + +```json +{ + "total": 0, + "entries": [ + { + "lineage_id": "string", + "target_id": "string", + "resource_type": "designbuilder", + "blueprint_instance_ids": ["string"], + "fidelity": "full", + "last_synced_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `createBulkInstallV3` + +Install one source blueprint into many destination organizations in a single +request. The server schedules child V3 installs with `auto_apply=true` and caps +active installs at `max_concurrency`. Not a + +`POST /v3/blueprint-manifest/bulk-installs` + +```ts +const { data } = await client.createBulkInstallV3( + null, + { + source_org_id: 'string', + source_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + max_concurrency: 2, + slug: 'string', + options: { + resources_to_ignore: ['string'], + sync_notes: false, + include_field_diffs: false + }, + targets: [ + { + destination_org_id: 'string', + destination_blueprint_id: 'c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341', + destination_auth_token: 'string' + } + ] + }, +) +``` + +--- + +### `getBulkInstallV3` + +Returns the bulk install parent with aggregate status and counts. Scoped by the +caller org as `source_org_id`. Target rows are not included — use the targets +endpoint to page through them. + +`GET /v3/blueprint-manifest/bulk-installs/{bulk_job_id}` + +```ts +const { data } = await client.getBulkInstallV3({ + bulk_job_id: 'example', +}) +``` + +
+Response + +```json +{ + "bulk_job_id": "string", + "source_org_id": "string", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "QUEUED", + "target_count": 0, + "max_concurrency": 0, + "counts": { + "queued": 0, + "in_progress": 0, + "success": 0, + "partial_success": 0, + "failed": 0, + "review_required": 0 + }, + "slug": "string", + "options": { + "resources_to_ignore": ["string"], + "sync_notes": false, + "include_field_diffs": false + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listBulkInstallTargetsV3` + +Pages through the bulk install's target rows. Each row hydrates its latest child +install job (`job_ids.at(-1)`) with the standard V3 job shape (`events[]`, +`resource_progress[]`) so callers can inspec + +`GET /v3/blueprint-manifest/bulk-installs/{bulk_job_id}/targets` + +```ts +const { data } = await client.listBulkInstallTargetsV3({ + bulk_job_id: 'example', + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "bulk_job_id": "string", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "QUEUED", + "job_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "merge_plan_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "job": {} + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `retryBulkInstallTargetV3` + +Retries a single failed target. Allowed only for `FAILED` and `PARTIAL_SUCCESS` +targets. Starts a new child install with `auto_apply=true`, appends its job id to +`job_ids`, and reuses the same target + +`POST /v3/blueprint-manifest/bulk-installs/{bulk_job_id}/targets/{destination_org_id}:retry` + +```ts +const { data } = await client.retryBulkInstallTargetV3( + { + bulk_job_id: 'example', + destination_org_id: 'example', + }, + { + destination_auth_token: 'string' + }, +) +``` + +
+Response + +```json +{ + "bulk_job_id": "string", + "destination_org_id": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "status": "QUEUED", + "job_ids": ["c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341"], + "merge_plan_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "job": { + "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "events": [ + {} + ], + "triggered_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "source_drift": { + "removed": [], + "missing": [], + "exclude_addresses": ["string"] + }, + "job_type": "install", + "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "source_blueprint_type": "custom", + "source_org_id": "string", + "source_blueprint_file": "string", + "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", + "destination_org_id": "string", + "slug": "string", + "sync_engine": "terraform", + "resource_progress": [ + {} + ], + "options": { + "resources_to_ignore": ["string"], + "sync_notes": false, + "include_field_diffs": false + }, + "merge_plan_id": "string", + "wait_kind": "plan", + "prefill_from_merge_plan_id": "string", + "assigned_merge_plan_id": "string", + "status": "IN_PROGRESS" + } +} +``` + +
+ +--- + +### `listUniquenessCriteria` + +List all custom uniqueness criteria configured for the caller's organization. +These overrides are applied during install (V2 and V3) when matching incoming +resources against existing ones in the desti + +`GET /v1/blueprint-manifest/uniqueness-criteria` + +```ts +const { data } = await client.listUniquenessCriteria() +``` + +
+Response + +```json +{ + "results": [ + { + "org_id": "string", + "resource_type": "emailtemplate", + "fields": ["string"], + "propagated_to": ["string"], + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string" + } + ], + "defaults": {}, + "readonly_types": ["string"] +} +``` + +
+ +--- + +### `getUniquenessCriteria` + +Get the configured uniqueness criteria for a specific resource type, if any. + +`GET /v1/blueprint-manifest/uniqueness-criteria/{resource_type}` + +```ts +const { data } = await client.getUniquenessCriteria({ + resource_type: 'example', +}) +``` + +
+Response + +```json +{ + "org_id": "string", + "resource_type": "emailtemplate", + "fields": ["string"], + "propagated_to": ["string"], + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string" +} +``` + +
+ +--- + +### `putUniquenessCriteria` + +Set or replace the uniqueness criteria for a resource type. The provided fields +must be valid attributes on the resource's schema (the UI typically loads the +schema to populate options). All listed fi + +`PUT /v1/blueprint-manifest/uniqueness-criteria/{resource_type}` + +```ts +const { data } = await client.putUniquenessCriteria( + { + resource_type: 'example', + }, + { + fields: ['string'], + propagated_to: ['string'] + }, +) +``` + +
+Response + +```json +{ + "org_id": "string", + "resource_type": "emailtemplate", + "fields": ["string"], + "propagated_to": ["string"], + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string" +} +``` + +
+ +--- + +### `deleteUniquenessCriteria` + +Remove the custom criteria for a resource type, reverting to the default fields. + +`DELETE /v1/blueprint-manifest/uniqueness-criteria/{resource_type}` + +```ts +const { data } = await client.deleteUniquenessCriteria({ + resource_type: 'example', +}) +``` + +--- + +### `getSourceTestOperation` + +Read a source-only generation or manual run. Requires the blueprint-test-cases organization feature flag and the original caller's organization. + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases/{test_case_id}/source-operations/{run_id}` + +```ts +const { data } = await client.getSourceTestOperation({ + blueprint_id: 'example', + test_case_id: 'example', + run_id: 'example', +}) +``` + +
+Response + +```json +{ + "operation_kind": "generate", + "run": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "blueprint_id": "string", + "incarnation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "test_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "test_revision": 1, + "expectation": "string", + "title": "string", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "status": "queued", + "confirmation_hash": "string", + "membership_fingerprint": "string", + "result": { + "verdict": "PASSED", + "checks": [], + "coverage": {}, + "fingerprints": {}, + "evaluator_version": "1", + "checked_at": "1970-01-01T00:00:00.000Z", + "evidence": [], + "evidence_omitted_count": 0, + "dependency_validation": {}, + "interpretation_proposal": {}, + "requires_confirmation": true + }, + "error": { + "code": "expired" + }, + "superseded": true, + "stale": true + } +} +``` + +
+ +--- + +### `createSourceConfirmedRun` + +Evaluate previously confirmed checks against the source Blueprint only. Requires the blueprint-test-cases organization feature flag and the original caller's organization. + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases/{test_case_id}/source-confirmed-runs` + +```ts +const { data } = await client.createSourceConfirmedRun( + { + blueprint_id: 'example', + test_case_id: 'example', + }, + { + expected_revision: 1 + }, +) +``` + +--- + +### `createBlueprintTestRun` + +Run read-only configuration acceptance checks or review their interpretation. Requires the blueprint-test-cases organization feature flag and the original caller's organization. + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases/{test_case_id}/runs` + +```ts +const { data } = await client.createBlueprintTestRun( + { + blueprint_id: 'example', + test_case_id: 'example', + }, + { + expected_revision: 1 + }, +) +``` + +--- + +### `listBlueprintTestRuns` + +Run read-only configuration acceptance checks or review their interpretation. Requires the blueprint-test-cases organization feature flag and the original caller's organization. + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases/{test_case_id}/runs` + +```ts +const { data } = await client.listBlueprintTestRuns({ + blueprint_id: 'example', + test_case_id: 'example', + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "blueprint_id": "string", + "incarnation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "test_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "test_revision": 1, + "expectation": "string", + "title": "string", + "created_by": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "status": "queued", + "confirmation_hash": "string", + "membership_fingerprint": "string", + "result": {}, + "error": {}, + "superseded": true, + "stale": true + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `getBlueprintTestRun` + +Run read-only configuration acceptance checks or review their interpretation. Requires the blueprint-test-cases organization feature flag and the original caller's organization. + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-cases/{test_case_id}/runs/{run_id}` + +```ts +const { data } = await client.getBlueprintTestRun({ + blueprint_id: 'example', + test_case_id: 'example', + run_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "blueprint_id": "string", + "incarnation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "test_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "test_revision": 1, + "expectation": "string", + "title": "string", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "status": "queued", + "confirmation_hash": "string", + "membership_fingerprint": "string", + "result": { + "verdict": "PASSED", + "checks": [ + {} + ], + "coverage": { + "complete": true, + "boundaries": [], + "supported_clauses": 0, + "total_clauses": 1 + }, + "fingerprints": {}, + "evaluator_version": "1", + "checked_at": "1970-01-01T00:00:00.000Z", + "evidence": [ + {} + ], + "evidence_omitted_count": 0, + "dependency_validation": { + "scope": "related_resources", + "verdict": "PASSED", + "checks": [], + "boundaries": [], + "omitted_count": 0 + }, + "interpretation_proposal": { + "schema_version": "1", + "interpretation": {}, + "catalog": [], + "proposal_hash": "string", + "expectation_sha256": "string", + "interpreter_version": "string", + "interpreter_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "requires_confirmation": true + }, + "error": { + "code": "expired" + }, + "superseded": true, + "stale": true +} +``` + +
+ +--- + +### `getBlueprintTestSuite` + +The v2 test cases of the blueprint with their current latest suite result (stale results never count as passed) and a summary over all cases. Requires the blueprint-test-cases organization feature fla + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite` + +```ts +const { data } = await client.getBlueprintTestSuite({ + blueprint_id: 'example', + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "cases": [ + { + "case": {}, + "latest": {} + } + ], + "summary": { + "passed": 0, + "failed": 0, + "cannot_verify": 0, + "never_run": 0, + "stale": 0, + "needs_reinterpretation": 0 + }, + "active_run": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "queued", + "created_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "digest": "string", + "unreadable": [ + {} + ], + "counts": { + "passed": 0, + "failed": 0, + "cannot_verify": 0, + "superseded": 0 + }, + "skipped_v1": 0, + "membership_fingerprint": "string", + "error": "string" + }, + "next_cursor": "string" +} +``` + +
+ +--- + +### `createBlueprintTestSuiteRun` + +Run every v2 test case of the blueprint against one configuration snapshot. Requires the blueprint-test-cases organization feature flag. + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite/runs` + +```ts +const { data } = await client.createBlueprintTestSuiteRun( + { + blueprint_id: 'example', + }, + {}, +) +``` + +--- + +### `getBlueprintTestSuiteRun` + +Read a suite run. Requires the blueprint-test-cases organization feature flag. + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite/runs/{run_id}` + +```ts +const { data } = await client.getBlueprintTestSuiteRun({ + blueprint_id: 'example', + run_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "queued", + "created_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "digest": "string", + "unreadable": [ + { + "type": "string", + "id": "string", + "reason": "string" + } + ], + "counts": { + "passed": 0, + "failed": 0, + "cannot_verify": 0, + "superseded": 0 + }, + "skipped_v1": 0, + "membership_fingerprint": "string", + "error": "string" +} +``` + +
+ +--- + +### `createBlueprintGraphSuggestions` + +Generate engine-verified test suggestions from the blueprint configuration graph. Requires the blueprint-test-cases organization feature flag. + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite/suggestions` + +```ts +const { data } = await client.createBlueprintGraphSuggestions( + { + blueprint_id: 'example', + }, + {}, +) +``` + +--- + +### `getBlueprintGraphSuggestions` + +Read a graph suggestion generation and a page of its suggestions. Requires the blueprint-test-cases organization feature flag. + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite/suggestions/{generation_id}` + +```ts +const { data } = await client.getBlueprintGraphSuggestions({ + blueprint_id: 'example', + generation_id: 'example', + shape: 'example', + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "pending", + "created_at": "1970-01-01T00:00:00.000Z", + "error": { + "code": "string", + "retriable": true + }, + "prompt_version": "string", + "model": "string", + "digest": "string", + "total": 0, + "counts_by_shape": { + "journey_starts_workflow": 0, + "event_sends_email": 0, + "step_logic": 0, + "answer_options": 0, + "process_order": 0, + "catalog_structure": 0 + }, + "excluded": [ + { + "reason": "invalid", + "count": 0 + } + ], + "unreadable": [ + { + "type": "string", + "id": "string", + "reason": "string" + } + ], + "incomplete_subjects": [ + { + "node_id": "string", + "resource_id": "string", + "resource_type": "string", + "reason": "step_cap" + } + ], + "items": [ + { + "id": "string", + "shape": "journey_starts_workflow", + "subject": { + "node_id": "string", + "resource_id": "string", + "resource_type": "string", + "label": "string" + }, + "clauses": [ + {} + ], + "sentences": [ + { + "key": "string", + "params": {} + } + ] + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `acceptBlueprintGraphSuggestions` + +Accept suggestions as v2 test cases. Idempotent per suggestion id. Requires the blueprint-test-cases organization feature flag. + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite/suggestions/{generation_id}/accept` + +```ts +const { data } = await client.acceptBlueprintGraphSuggestions( + { + blueprint_id: 'example', + generation_id: 'example', + }, + { + suggestion_ids: ['string'] + }, +) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "org_id": "string", + "schema_version": 1, + "revision": 1, + "title": "string", + "expectation": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "deleted_at": "1970-01-01T00:00:00.000Z", + "confirmation": { + "schema_version": "1", + "interpretation": { + "schema_version": "1", + "clauses": [ + { + "source_text": "string", + "status": "supported", + "assertions": [ + { + "operator": "resource_included", + "target_key": "string" + } + ], + "reason": "string" + } + ] + }, + "catalog": [ + { + "key": "string", + "type": "string", + "id": "string", + "label": "string", + "membership_state": "included", + "capabilities": ["resource_included"], + "tasks": [ + { + "key": "string", + "label": "string", + "capabilities": ["workflow_task_required"] + } + ] + } + ], + "proposal_hash": "string", + "expectation_sha256": "string", + "interpreter_version": "string", + "confirmed_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "confirmed_at": "1970-01-01T00:00:00.000Z", + "interpreter_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "clauses": [ + {} + ], + "clauses_hash": "string", + "title_key": {}, + "origin": {}, + "needs_reinterpretation": { + "reason": "string" + } + } + ], + "accepted_ids": ["string"] +} +``` + +
+ +--- + +### `migrateBlueprintV1TestCases` + +Migrate v1 test cases to v2 clauses; cases that cannot be mapped are flagged needs_reinterpretation. Requires the blueprint-test-cases organization feature flag. + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite:migrate-v1` + +```ts +const { data } = await client.migrateBlueprintV1TestCases( + { + blueprint_id: 'example', + }, + {}, +) +``` + +
+Response + +```json +{ + "migrated": 0, + "needs_reinterpretation": 0, + "cases": [ + { + "case_id": "string", + "result": "migrated", + "clauses": [ + {} + ] + } + ] +} +``` + +
+ +--- + +### `createBlueprintTestInterpretation` + +Start interpreting an author's plain-language test against the blueprint configuration. With test_case_id the result rewrites that case. One active interpretation per author and blueprint. Requires th + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite/interpretations` + +```ts +const { data } = await client.createBlueprintTestInterpretation( + { + blueprint_id: 'example', + }, + { + text: 'string', + test_case_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + }, +) +``` + +--- + +### `getBlueprintTestInterpretation` + +Read the caller's own text interpretation. Requires the blueprint-test-cases organization feature flag. + +`GET /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite/interpretations/{interpretation_id}` + +```ts +const { data } = await client.getBlueprintTestInterpretation({ + blueprint_id: 'example', + interpretation_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "pending", + "created_at": "1970-01-01T00:00:00.000Z", + "text": "string", + "test_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "parts": [ + { + "index": 0, + "span": [0, 0], + "state": "supported", + "check": { + "id": "string", + "hash": "string", + "clause": {}, + "sentence": { + "key": "string", + "params": {} + }, + "result": { + "clause_id": "string", + "verdict": "PASSED", + "reason": "string", + "sentence": { + "key": "string", + "params": {} + }, + "evidence": [ + { + "node_id": "string", + "resource_id": "string", + "resource_type": "string", + "label": "string", + "path": "string", + "expected": {}, + "actual": {} + } + ], + "evidence_truncated": true, + "candidates": ["string"] + } + } + } + ], + "dropped": 0, + "unchanged": true, + "unreadable": [ + { + "type": "string", + "id": "string", + "reason": "string" + } + ], + "prompt_version": "string", + "model": "string", + "error": { + "code": "interpretation_too_complex", + "retriable": true + }, + "accepted_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" +} +``` + +
+ +--- + +### `confirmBlueprintTestInterpretationV2` + +Save the author's confirmed selection of a completed interpretation as a v2 test case (201), or as a new revision of the case it rewrites (200, needs expected_revision). Ambiguous parts need a chosen + +`POST /v2/blueprint-manifest/blueprints/{blueprint_id}/test-suite/interpretations/{interpretation_id}/confirm` + +```ts +const { data } = await client.confirmBlueprintTestInterpretationV2( + { + blueprint_id: 'example', + interpretation_id: 'example', + }, + { + choices: [ + { + part_index: 0, + candidate_id: 'string' + } + ], + omit_parts: [0], + confirmed: true, + expected_revision: 1 + }, +) +``` + +
+Response + +```json +{ + "test_case": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "blueprint_id": "string", + "org_id": "string", + "schema_version": 1, + "revision": 1, + "title": "string", + "expectation": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "deleted_at": "1970-01-01T00:00:00.000Z", + "confirmation": { + "schema_version": "1", + "interpretation": { + "schema_version": "1", + "clauses": [ + { + "source_text": "string", + "status": "supported", + "assertions": [ + { + "operator": "resource_included", + "target_key": "string" + } + ], + "reason": "string" + } + ] + }, + "catalog": [ + { + "key": "string", + "type": "string", + "id": "string", + "label": "string", + "membership_state": "included", + "capabilities": ["resource_included"], + "tasks": [ + { + "key": "string", + "label": "string", + "capabilities": ["workflow_task_required"] + } + ] + } + ], + "proposal_hash": "string", + "expectation_sha256": "string", + "interpreter_version": "string", + "confirmed_by": { + "name": "manifest@epilot.cloud", + "org_id": "911690", + "user_id": "11001045", + "token_id": "api_5ZugdRXasLfWBypHi93Fk" + }, + "confirmed_at": "1970-01-01T00:00:00.000Z", + "interpreter_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "clauses": [ + {} + ], + "clauses_hash": "string", + "title_key": {}, + "origin": {}, + "needs_reinterpretation": { + "reason": "string" + } + }, + "confirmation_kept": true +} +``` + +
+ +--- + +## Schemas + +### `BlueprintTestSuiteError` + +```ts +type BlueprintTestSuiteError = { + status: number + code: "invalid_request" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "credential_invalid" | "permissions_unavailable" | "permission_denied" | "feature_unavailable" | "session_expiring" | "storage_conflict" | "suite_unavailable" | "v2_case" | "active_generation" | "active_suite_run" | "org_run_limit" | "suggestions_stale" | "unknown_suggestion" | "suggestion_acceptance_changed" | "suggestion_input_too_large" | "invalid_clauses" | "not_implemented" | "interpretation_input_too_large" | "interpretation_incomplete" | "interpretation_not_ready" | "interpretation_used" | "confirmation_required" + retriable: boolean + active_run_id?: string // uuid + generation_id?: string // uuid + retry_after_seconds?: number + accepted_ids?: string[] + count?: number +} +``` + +### `SentenceParamValue` + +A sentence parameter. Strings, lists and objects of parameters; never prose. + +```ts +type SentenceParamValue = string | { ... }[] | Record +``` + +### `Sentence` + +A translation key and its parameters. The UI renders the text; the server never returns sentences. + +```ts +type Sentence = { + key: string + params: Record> +} +``` + +### `ClauseEvidenceView` + +```ts +type ClauseEvidenceView = { + node_id: string + resource_id: string + resource_type: string + label: string + path?: string + expected?: unknown + actual?: unknown +} +``` + +### `ClauseResultView` + +```ts +type ClauseResultView = { + clause_id: string + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + reason?: string + sentence: { + key: string + params: Record> + } + evidence: Array<{ + node_id: string + resource_id: string + resource_type: string + label: string + path?: string + expected?: unknown + actual?: unknown + }> + evidence_truncated?: boolean + candidates?: string[] +} +``` + +### `BlueprintTestUnreadableResource` + +```ts +type BlueprintTestUnreadableResource = { + type: string + id: string + reason: string +} +``` + +### `SuiteRun` + +```ts +type SuiteRun = { + id: string // uuid + status: "queued" | "running" | "completed" | "failed" + created_at: string // date-time + finished_at?: string // date-time + digest?: string + unreadable?: Array<{ + type: string + id: string + reason: string + }> + counts?: { + passed: number + failed: number + cannot_verify: number + superseded: number + } + skipped_v1?: number + membership_fingerprint?: string + error?: string +} +``` + +### `CaseResultRow` + +```ts +type CaseResultRow = { + case_id: string // uuid + case_revision: number + clauses_hash: string + membership_fingerprint: string + status: "PASSED" | "FAILED" | "CANNOT_VERIFY" | "stale" + reason?: "no_clauses" + results: Array<{ + clause_id: string + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + reason?: string + sentence: { + key: { ... } + params: { ... } + } + evidence: Array<{ + node_id: { ... } + resource_id: { ... } + resource_type: { ... } + label: { ... } + path?: { ... } + expected?: { ... } + actual?: { ... } + }> + evidence_truncated?: boolean + candidates?: string[] + }> + run_id?: string // uuid + finished_at?: string // date-time +} +``` + +### `BlueprintTestSuiteSummary` + +Over all cases of the blueprint, not only the page. v1 cases count as needs_reinterpretation when migration flagged them, otherwise as never_run. + +```ts +type BlueprintTestSuiteSummary = { + passed: number + failed: number + cannot_verify: number + never_run: number + stale: number + needs_reinterpretation: number +} +``` + +### `BlueprintTestSuite` + +```ts +type BlueprintTestSuite = { + cases: Array<{ + case: { + id: { ... } + blueprint_id: { ... } + org_id: { ... } + schema_version: { ... } + revision: { ... } + title?: { ... } + expectation?: { ... } + created_at: { ... } + created_by: { ... } + updated_at: { ... } + updated_by: { ... } + deleted_at?: { ... } + confirmation?: { ... } + clauses?: { ... } + clauses_hash?: { ... } + title_key?: { ... } + origin?: { ... } + needs_reinterpretation?: { ... } + } + latest?: { + case_id: { ... } + case_revision: { ... } + clauses_hash: { ... } + membership_fingerprint: { ... } + status: { ... } + reason?: { ... } + results: { ... } + run_id?: { ... } + finished_at?: { ... } + } + }> + summary: { + passed: number + failed: number + cannot_verify: number + never_run: number + stale: number + needs_reinterpretation: number + } + active_run?: { + id: string // uuid + status: "queued" | "running" | "completed" | "failed" + created_at: string // date-time + finished_at?: string // date-time + digest?: string + unreadable?: Array<{ + type: { ... } + id: { ... } + reason: { ... } + }> + counts?: { + passed: { ... } + failed: { ... } + cannot_verify: { ... } + superseded: { ... } + } + skipped_v1?: number + membership_fingerprint?: string + error?: string + } + next_cursor?: string +} +``` + +### `BlueprintTestCaseShape` + +```ts +type BlueprintTestCaseShape = "journey_starts_workflow" | "event_sends_email" | "step_logic" | "answer_options" | "process_order" | "catalog_structure" +``` + +### `Suggestion` + +```ts +type Suggestion = { + id: string + shape: "journey_starts_workflow" | "event_sends_email" | "step_logic" | "answer_options" | "process_order" | "catalog_structure" + subject: { + node_id: string + resource_id: string + resource_type: string + label: string + } + clauses: Record[] + sentences: Array<{ + key: string + params: Record> + }> +} +``` + +### `BlueprintGraphSuggestionsStarted` + +```ts +type BlueprintGraphSuggestionsStarted = { + generation_id: string // uuid + status: "pending" +} +``` + +### `BlueprintTestInterpretationInput` + +```ts +type BlueprintTestInterpretationInput = { + text: string + test_case_id?: string // uuid +} +``` + +### `BlueprintTestInterpretationStarted` + +```ts +type BlueprintTestInterpretationStarted = { + interpretation_id: string // uuid + status: "pending" +} +``` + +### `BlueprintInterpretedCheck` + +An engine-verified check. Code-assigned id (p or pc``); the sentence is a key, never model text. + +```ts +type BlueprintInterpretedCheck = { + id: string + hash: string + clause: Record + sentence: { + key: string + params: Record> + } + result: { + clause_id: string + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + reason?: string + sentence: { + key: { ... } + params: { ... } + } + evidence: Array<{ + node_id: { ... } + resource_id: { ... } + resource_type: { ... } + label: { ... } + path?: { ... } + expected?: { ... } + actual?: { ... } + }> + evidence_truncated?: boolean + candidates?: string[] + } +} +``` + +### `BlueprintInterpretedPart` + +One part of the author's text in one of three states. span is an integer offset pair into the author's own text. + +```ts +type BlueprintInterpretedPart = { + index: number + span?: number[] + state: "supported" + check: { + id: string + hash: string + clause: Record + sentence: { + key: { ... } + params: { ... } + } + result: { + clause_id: { ... } + verdict: { ... } + reason?: { ... } + sentence: { ... } + evidence: { ... } + evidence_truncated?: { ... } + candidates?: { ... } + } + } +} | { + index: number + span?: number[] + state: "ambiguous" + candidates: Array<{ + id: string + hash: string + clause: Record + sentence: { + key: { ... } + params: { ... } + } + result: { + clause_id: { ... } + verdict: { ... } + reason?: { ... } + sentence: { ... } + evidence: { ... } + evidence_truncated?: { ... } + candidates?: { ... } + } + }> +} | { + index: number + span?: number[] + state: "unsupported" + reason: "runtime_behaviour" | "document_content" | "external_system" | "legal_judgement" | "generic_integrity" | "no_matching_resource" | "no_matching_field" | "no_matching_value" | "not_expressible" | "cannot_bind" | "too_vague" + hint: { + code: "name_the_resource" | "name_the_field" | "name_the_value" | "split_statement" | "describe_configuration" | "use_health_check" | "rephrase_as_check" + params: { + type?: { ... } + } + } +} +``` + +### `BlueprintInterpretationSpan` + +[start, end) character offsets into the author's text. + +```ts +type BlueprintInterpretationSpan = number[] +``` + +### `BlueprintTestInterpretationResult` + +```ts +type BlueprintTestInterpretationResult = { + id: string // uuid + status: "pending" | "running" | "completed" | "failed" + created_at: string // date-time + text: string + test_case_id?: string // uuid + parts: Array<{ + index: number + span?: number[] + state: "supported" + check: { + id: { ... } + hash: { ... } + clause: { ... } + sentence: { ... } + result: { ... } + } + } | { + index: number + span?: number[] + state: "ambiguous" + candidates: Array<{ + id: { ... } + hash: { ... } + clause: { ... } + sentence: { ... } + result: { ... } + }> + } | { + index: number + span?: number[] + state: "unsupported" + reason: "runtime_behaviour" | "document_content" | "external_system" | "legal_judgement" | "generic_integrity" | "no_matching_resource" | "no_matching_field" | "no_matching_value" | "not_expressible" | "cannot_bind" | "too_vague" + hint: { + code: { ... } + params: { ... } + } + }> + dropped: number + unchanged?: boolean + unreadable: Array<{ + type: string + id: string + reason: string + }> + prompt_version?: string + model?: string + error?: { + code: "interpretation_too_complex" | "model_unavailable" | "timeout" | "expired" | "worker_failed" | "not_authorized" | "invoke_failed" + retriable: boolean + } + accepted_case_id?: string // uuid +} +``` + +### `BlueprintTestInterpretationConfirmInput` + +```ts +type BlueprintTestInterpretationConfirmInput = { + choices: Array<{ + part_index: number + candidate_id: string + }> + omit_parts: number[] + confirmed: boolean + expected_revision?: number +} +``` + +### `BlueprintTestInterpretationConfirmation` + +```ts +type BlueprintTestInterpretationConfirmation = { + test_case: { + id: string // uuid + blueprint_id: string + org_id: string + schema_version: 1 | 2 + revision: number + title?: string + expectation?: string + created_at: string // date-time + created_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + updated_at: string // date-time + updated_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + deleted_at?: string // date-time + confirmation?: { + schema_version: { ... } + interpretation: { ... } + catalog: { ... } + proposal_hash: { ... } + expectation_sha256: { ... } + interpreter_version: { ... } + confirmed_by: { ... } + confirmed_at: { ... } + interpreter_execution_id?: { ... } + } + clauses?: Record[] + clauses_hash?: string + title_key?: Record + origin?: Record + needs_reinterpretation?: { + reason: { ... } + } + } + confirmation_kept: boolean +} +``` + +### `BlueprintTestCaseOrigin` + +Where a v2 case came from (BlueprintTestCase.origin). + +```ts +type BlueprintTestCaseOrigin = { + kind: "suggestion" + source: "ai" + shape: "journey_starts_workflow" | "event_sends_email" | "step_logic" | "answer_options" | "process_order" | "catalog_structure" + suggestion_id: string + generation_id: string + prompt_version: string + model: string +} | { + kind: "migrated_v1" + from_revision: number +} | { + kind: "interpretation" + source: "ai" + interpretation_id: string // uuid + prompt_version: string + model: string + confirmed_clauses_hash: string + confirmed_at: string // date-time + confirmed_by: { + name?: unknown + org_id: string + user_id?: string + token_id?: string + } +} +``` + +### `BlueprintGraphSuggestionPage` + +```ts +type BlueprintGraphSuggestionPage = { + id: string // uuid + status: "pending" | "running" | "completed" | "failed" + created_at: string // date-time + error?: { + code: string + retriable: boolean + } + prompt_version?: string + model?: string + digest?: string + total: number + counts_by_shape: { + journey_starts_workflow?: number + event_sends_email?: number + step_logic?: number + answer_options?: number + process_order?: number + catalog_structure?: number + } + excluded: Array<{ + reason: "invalid" | "unknown_subject" | "shape_unknown" | "not_passing" | "cannot_verify" | "trivial" | "duplicate" + count: number + }> + unreadable: Array<{ + type: string + id: string + reason: string + }> + incomplete_subjects: Array<{ + node_id: string + resource_id: string + resource_type: string + reason: "step_cap" | "input_cap" | "deadline" | "model_error" + }> + items: Array<{ + id: string + shape: "journey_starts_workflow" | "event_sends_email" | "step_logic" | "answer_options" | "process_order" | "catalog_structure" + subject: { + node_id: { ... } + resource_id: { ... } + resource_type: { ... } + label: { ... } + } + clauses: Record[] + sentences: Array<{ + key: { ... } + params: { ... } + }> + }> + next_cursor?: string +} +``` + +### `BlueprintGraphSuggestionAcceptInput` + +```ts +type BlueprintGraphSuggestionAcceptInput = { + suggestion_ids: string[] +} +``` + +### `BlueprintGraphSuggestionAcceptance` + +```ts +type BlueprintGraphSuggestionAcceptance = { + results: Array<{ + id: string // uuid + blueprint_id: string + org_id: string + schema_version: 1 | 2 + revision: number + title?: string + expectation?: string + created_at: string // date-time + created_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + updated_at: string // date-time + updated_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + deleted_at?: string // date-time + confirmation?: { + schema_version: { ... } + interpretation: { ... } + catalog: { ... } + proposal_hash: { ... } + expectation_sha256: { ... } + interpreter_version: { ... } + confirmed_by: { ... } + confirmed_at: { ... } + interpreter_execution_id?: { ... } + } + clauses?: Record[] + clauses_hash?: string + title_key?: Record + origin?: Record + needs_reinterpretation?: { + reason: { ... } + } + }> + accepted_ids: string[] +} +``` + +### `BlueprintV1TestCaseMigration` + +```ts +type BlueprintV1TestCaseMigration = { + migrated: number + needs_reinterpretation: number + cases: Array<{ + case_id: string + result: "migrated" + clauses: Record[] + } | { + case_id: string + result: "needs_reinterpretation" + reason: string + }> +} +``` + +### `BlueprintTestCaseInput` + +```ts +type BlueprintTestCaseInput = { + title: string + expectation: string +} +``` + +### `BlueprintTestCaseUpdate` + +```ts +type BlueprintTestCaseUpdate = { + title: string + expectation: string + expected_revision: number +} +``` + +### `BlueprintTestCase` + +```ts +type BlueprintTestCase = { + id: string // uuid + blueprint_id: string + org_id: string + schema_version: 1 | 2 + revision: number + title?: string + expectation?: string + created_at: string // date-time + created_by: { + name?: unknown + org_id: string + user_id?: string + token_id?: string + } + updated_at: string // date-time + updated_by: { + name?: unknown + org_id: string + user_id?: string + token_id?: string + } + deleted_at?: string // date-time + confirmation?: { + schema_version: "1" + interpretation: { + schema_version: { ... } + clauses: { ... } + } + catalog: Array<{ + key: { ... } + type: { ... } + id: { ... } + label: { ... } + membership_state: { ... } + capabilities: { ... } + tasks?: { ... } + }> + proposal_hash: string + expectation_sha256: string + interpreter_version: string + confirmed_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + confirmed_at: string // date-time + interpreter_execution_id?: string // uuid + } + clauses?: Record[] + clauses_hash?: string + title_key?: Record + origin?: Record + needs_reinterpretation?: { + reason: string + } +} +``` + +### `BlueprintTestPredicate` + +```ts +type BlueprintTestPredicate = { + operator: "resource_included" + target_key: string +} | { + operator: "resource_references" + target_key: string + expected_target_key: string +} | { + operator: "config_enabled" + target_key: string +} | { + operator: "workflow_task_required" + target_key: string + task_key: string +} +``` + +### `BlueprintTestInterpretation` + +```ts +type BlueprintTestInterpretation = { + schema_version: "1" + clauses: Array<{ + source_text: string + status: "supported" + assertions: Array<{ + operator: { ... } + target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + expected_target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + task_key: { ... } + }> + reason: string + } | { + source_text: string + status: "unsupported" | "ambiguous" + assertions: Array<{ + operator: { ... } + target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + expected_target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + task_key: { ... } + }> + reason: string + }> +} +``` + +### `BlueprintTestCatalogEntry` + +```ts +type BlueprintTestCatalogEntry = { + key: string + type: string + id: string + label: string + membership_state: "included" | "excluded" | "absent" + capabilities: "resource_included" | "resource_references" | "config_enabled" | "workflow_task_required"[] + tasks?: Array<{ + key: string + label: string + capabilities: "workflow_task_required"[] + }> +} +``` + +### `BlueprintTestInterpretationProposal` + +```ts +type BlueprintTestInterpretationProposal = { + schema_version: "1" + interpretation: { + schema_version: "1" + clauses: Array<{ + source_text: { ... } + status: { ... } + assertions: { ... } + reason: { ... } + } | { + source_text: { ... } + status: { ... } + assertions: { ... } + reason: { ... } + }> + } + catalog: Array<{ + key: string + type: string + id: string + label: string + membership_state: "included" | "excluded" | "absent" + capabilities: "resource_included" | "resource_references" | "config_enabled" | "workflow_task_required"[] + tasks?: Array<{ + key: { ... } + label: { ... } + capabilities: { ... } + }> + }> + proposal_hash: string + expectation_sha256: string + interpreter_version: string + interpreter_execution_id?: string // uuid +} +``` + +### `BlueprintTestCaseConfirmation` + +```ts +type BlueprintTestCaseConfirmation = { + schema_version: "1" + interpretation: { + schema_version: "1" + clauses: Array<{ + source_text: { ... } + status: { ... } + assertions: { ... } + reason: { ... } + } | { + source_text: { ... } + status: { ... } + assertions: { ... } + reason: { ... } + }> + } + catalog: Array<{ + key: string + type: string + id: string + label: string + membership_state: "included" | "excluded" | "absent" + capabilities: "resource_included" | "resource_references" | "config_enabled" | "workflow_task_required"[] + tasks?: Array<{ + key: { ... } + label: { ... } + capabilities: { ... } + }> + }> + proposal_hash: string + expectation_sha256: string + interpreter_version: string + confirmed_by: { + name?: unknown + org_id: string + user_id?: string + token_id?: string + } + confirmed_at: string // date-time + interpreter_execution_id?: string // uuid +} +``` + +### `BlueprintTestResourceEvidence` + +```ts +type BlueprintTestResourceEvidence = { + type: string + id: string + key: string + membership_state: "included" | "excluded" | "absent" + source_state: "read" | "source_unreadable" | "unsupported" | "not_read" + checked_at?: string // date-time + fingerprint?: string + references: Array<{ + target_key: string + path: string + candidate_target_keys?: string[] + }> + dependency_coverage: "complete" | "incomplete" + enabled?: { + path: string + value: boolean + } + tasks_complete?: boolean + tasks: Array<{ + key: string + path: string + required?: boolean + manual: boolean + task_type?: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" + }> +} +``` + +### `BlueprintTestCheckResult` + +```ts +type BlueprintTestCheckResult = { + predicate?: { + operator: "resource_included" + target_key: string + } | { + operator: "resource_references" + target_key: string + expected_target_key: string + } | { + operator: "config_enabled" + target_key: string + } | { + operator: "workflow_task_required" + target_key: string + task_key: string + } + resource_key?: string + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + reason: string + path?: string + actual?: boolean | string +} +``` + +### `BlueprintTestDependencyValidation` + +```ts +type BlueprintTestDependencyValidation = { + scope: "related_resources" + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + checks: Array<{ + predicate?: { + operator: { ... } + target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + expected_target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + task_key: { ... } + } + resource_key?: string + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + reason: string + path?: string + actual?: boolean | string + }> + boundaries: Array<{ + key?: string + path?: string + reason: string + }> + omitted_count: number +} +``` + +### `BlueprintTestRunResult` + +```ts +type BlueprintTestRunResult = { + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + checks: Array<{ + predicate?: { + operator: { ... } + target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + expected_target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + } | { + operator: { ... } + target_key: { ... } + task_key: { ... } + } + resource_key?: string + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + reason: string + path?: string + actual?: boolean | string + }> + coverage: { + complete: boolean + boundaries: Array<{ + key?: { ... } + path?: { ... } + reason: { ... } + }> + supported_clauses: number + total_clauses: number + } + fingerprints: Record + evaluator_version: "1" + checked_at: string // date-time + evidence?: Array<{ + type: string + id: string + key: string + membership_state: "included" | "excluded" | "absent" + source_state: "read" | "source_unreadable" | "unsupported" | "not_read" + checked_at?: string // date-time + fingerprint?: string + references: Array<{ + target_key: { ... } + path: { ... } + candidate_target_keys?: { ... } + }> + dependency_coverage: "complete" | "incomplete" + enabled?: { + path: { ... } + value: { ... } + } + tasks_complete?: boolean + tasks: Array<{ + key: { ... } + path: { ... } + required?: { ... } + manual: { ... } + task_type?: { ... } + }> + }> + evidence_omitted_count: number + dependency_validation?: { + scope: "related_resources" + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + checks: Array<{ + predicate?: { ... } + resource_key?: { ... } + verdict: { ... } + reason: { ... } + path?: { ... } + actual?: { ... } + }> + boundaries: Array<{ + key?: { ... } + path?: { ... } + reason: { ... } + }> + omitted_count: number + } + interpretation_proposal?: { + schema_version: "1" + interpretation: { + schema_version: { ... } + clauses: { ... } + } + catalog: Array<{ + key: { ... } + type: { ... } + id: { ... } + label: { ... } + membership_state: { ... } + capabilities: { ... } + tasks?: { ... } + }> + proposal_hash: string + expectation_sha256: string + // ... +} +``` + +### `BlueprintSourceTestOperation` + +```ts +type BlueprintSourceTestOperation = { + operation_kind: "generate" | "execute" + run: { + id: string // uuid + org_id: string + blueprint_id: string + incarnation_id: string // uuid + test_case_id: string // uuid + test_revision: number + expectation: string + title: string + created_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + created_at: string // date-time + expires_at: string // date-time + status: "queued" | "running" | "completed" | "failed" + confirmation_hash?: string + membership_fingerprint?: string + result?: { + verdict: { ... } + checks: { ... } + coverage: { ... } + fingerprints: { ... } + evaluator_version: { ... } + checked_at: { ... } + evidence?: { ... } + evidence_omitted_count: { ... } + dependency_validation?: { ... } + interpretation_proposal?: { ... } + requires_confirmation?: { ... } + } + error?: { + code: { ... } + } + superseded?: boolean + stale: boolean + } +} +``` + +### `BlueprintTestRun` + +```ts +type BlueprintTestRun = { + id: string // uuid + org_id: string + blueprint_id: string + incarnation_id: string // uuid + test_case_id: string // uuid + test_revision: number + expectation: string + title: string + created_by: { + name?: unknown + org_id: string + user_id?: string + token_id?: string + } + created_at: string // date-time + expires_at: string // date-time + status: "queued" | "running" | "completed" | "failed" + confirmation_hash?: string + membership_fingerprint?: string + result?: { + verdict: "PASSED" | "FAILED" | "CANNOT_VERIFY" + checks: Array<{ + predicate?: { ... } + resource_key?: { ... } + verdict: { ... } + reason: { ... } + path?: { ... } + actual?: { ... } + }> + coverage: { + complete: { ... } + boundaries: { ... } + supported_clauses: { ... } + total_clauses: { ... } + } + fingerprints: Record + evaluator_version: "1" + checked_at: string // date-time + evidence?: Array<{ + type: { ... } + id: { ... } + key: { ... } + membership_state: { ... } + source_state: { ... } + checked_at?: { ... } + fingerprint?: { ... } + references: { ... } + dependency_coverage: { ... } + enabled?: { ... } + tasks_complete?: { ... } + tasks: { ... } + }> + evidence_omitted_count: number + dependency_validation?: { + scope: { ... } + verdict: { ... } + checks: { ... } + boundaries: { ... } + omitted_count: { ... } + } + interpretation_proposal?: { + schema_version: { ... } + interpretation: { ... } + catalog: { ... } + proposal_hash: { ... } + expectation_sha256: { ... } + interpreter_version: { ... } + interpreter_execution_id?: { ... } + } + requires_confirmation?: true + } + error?: { + code: "expired" | "timeout" | "invoke_failed" | "worker_failed" + } + superseded?: boolean + stale: boolean +} +``` + +### `BlueprintTestRunPage` + +```ts +type BlueprintTestRunPage = { + results: Array<{ + id: string // uuid + org_id: string + blueprint_id: string + incarnation_id: string // uuid + test_case_id: string // uuid + test_revision: number + expectation: string + title: string + created_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + created_at: string // date-time + expires_at: string // date-time + status: "queued" | "running" | "completed" | "failed" + confirmation_hash?: string + membership_fingerprint?: string + result?: { + verdict: { ... } + checks: { ... } + coverage: { ... } + fingerprints: { ... } + evaluator_version: { ... } + checked_at: { ... } + evidence?: { ... } + evidence_omitted_count: { ... } + dependency_validation?: { ... } + interpretation_proposal?: { ... } + requires_confirmation?: { ... } + } + error?: { + code: { ... } + } + superseded?: boolean + stale: boolean + }> + next_cursor?: string +} +``` + +### `BlueprintTestRunError` + +```ts +type BlueprintTestRunError = { + status: number + code: "invalid_request" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "checks_already_confirmed" | "confirmation_required" | "portable_test_unavailable" | "active_run" | "org_run_limit" | "session_expiring" | "credential_invalid" | "permissions_unavailable" | "permission_denied" | "feature_unavailable" | "run_unavailable" | "storage_conflict" | "v2_case" + retriable?: boolean + active_run_id?: string // uuid + retry_after_seconds?: number +} +``` + +### `BlueprintTestRunInput` + +```ts +type BlueprintTestRunInput = { + expected_revision: number +} +``` + +### `BlueprintTestCasePage` + +```ts +type BlueprintTestCasePage = { + results: Array<{ + id: string // uuid + blueprint_id: string + org_id: string + schema_version: 1 | 2 + revision: number + title?: string + expectation?: string + created_at: string // date-time + created_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + updated_at: string // date-time + updated_by: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + deleted_at?: string // date-time + confirmation?: { + schema_version: { ... } + interpretation: { ... } + catalog: { ... } + proposal_hash: { ... } + expectation_sha256: { ... } + interpreter_version: { ... } + confirmed_by: { ... } + confirmed_at: { ... } + interpreter_execution_id?: { ... } + } + clauses?: Record[] + clauses_hash?: string + title_key?: Record + origin?: Record + needs_reinterpretation?: { + reason: { ... } + } + }> + next_cursor?: string +} +``` + +### `BlueprintAssistantMessageRequest` + +```ts +type BlueprintAssistantMessageRequest = { + conversation_id?: string // uuid + message?: string + retry?: boolean + proposal_update?: { + proposal_id: string + status: "applied" | "dismissed" + note?: string } } ``` -
+### `BlueprintAssistantConversation` ---- +```ts +type BlueprintAssistantConversation = { + id: string + blueprint_id: string + status: "IN_PROGRESS" | "IDLE" | "FAILED" + error?: string + created_at: string // date-time + updated_at: string // date-time + created_by?: string + created_by_name?: string + messages: Array<{ + id: string + role: "user" | "assistant" + created_at: string // date-time + parts: Array<{ + type: { ... } + text?: { ... } + tool_use_id?: { ... } + tool?: { ... } + title?: { ... } + status?: { ... } + result?: { ... } + }> + }> +} +``` -### `continueInstallationJob` +### `BlueprintAssistantSkill` -Continue Installation Job +```ts +type BlueprintAssistantSkill = { + name: string + description: string + enabled: boolean + files: string[] + size: number + updated_at: string // date-time + updated_by?: string + updated_by_name?: string +} +``` -`POST /v2/blueprint-manifest/jobs/{job_id}:continue` +### `BlueprintAssistantDefaultSkill` ```ts -const { data } = await client.continueInstallationJob( - { - job_id: 'example', - }, - { - resources_to_ignore: ['string'] - }, -) +type BlueprintAssistantDefaultSkill = { + name: string + description: string + audience?: "publishers" +} ``` -
-Response +### `BlueprintAssistantSkillUpload` -```json -{ - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "events": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "message": "string", - "errors": [ - { - "error": "string", - "code": "dependency_extraction", - "data": { - "formattedResource": { - "id": "string", - "name": "string", - "type": "string" - }, - "resource": "string", - "resourceDependency": "string", - "resources": ["string"], - "addresses": ["string"], - "originalError": "string" - } - } - ], - "level": "info", - "data": { - "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "resources": 0 - } +```ts +type BlueprintAssistantSkillUpload = { + file_name: string + content_base64: string +} +``` + +### `BlueprintAssistantConversationSummary` + +```ts +type BlueprintAssistantConversationSummary = { + id: string + title: string + status: "IN_PROGRESS" | "IDLE" | "FAILED" + created_at: string // date-time + updated_at: string // date-time + created_by?: string + created_by_name?: string + message_count: number +} +``` + +### `BlueprintAssistantMessage` + +```ts +type BlueprintAssistantMessage = { + id: string + role: "user" | "assistant" + created_at: string // date-time + parts: Array<{ + type: "text" | "tool" + text?: string + tool_use_id?: string + tool?: string + title?: string + status?: "running" | "done" | "error" + result?: { + kind?: { ... } } - ], - "triggered_at": "1970-01-01T00:00:00.000Z", - "created_by": { - "name": "manifest@epilot.cloud", - "org_id": "911690", - "user_id": "11001045", - "token_id": "api_5ZugdRXasLfWBypHi93Fk" - }, - "source_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "source_blueprint_type": "custom", - "source_org_id": "string", - "source_blueprint_file": "string", - "destination_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "destination_org_id": "string", - "slug": "string", - "status": "IN_PROGRESS" + }> } ``` -
+### `BlueprintAssistantPart` ---- +`text` parts carry `text`. `tool` parts carry the tool call and, once finished, its structured +`result`, discriminated by `result.kind`: `overview`, `resources`, `inclusion`, `resource_content`, +`audit`, `proposal_changes`, `proposal_add`, `proposal_blueprint`, `proposal_publish`, `skill` or `error` -### `cancelBlueprintJob` +```ts +type BlueprintAssistantPart = { + type: "text" | "tool" + text?: string + tool_use_id?: string + tool?: string + title?: string + status?: "running" | "done" | "error" + result?: { + kind?: string + } +} +``` -Cancel Blueprint Job +### `UniquenessCriteriaResourceType` -`POST /v2/blueprint-manifest/jobs/{job_id}:cancel` +Resource type for which custom uniqueness criteria can be configured. ```ts -const { data } = await client.cancelBlueprintJob({ - job_id: 'example', -}) +type UniquenessCriteriaResourceType = "emailtemplate" | "product" | "price" | "tax" | "coupon" | "product_recommendation" | "file" | "document_template" | "notification_template" | "journey" ``` -
-Response +### `UniquenessCriteria` -```json -{ - "id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "events": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "message": "string", - "errors": [ - { - "error": "string", - "code": "dependency_extraction", - "data": { - "formattedResource": { - "id": "string", - "name": "string", - "type": "string" - }, - "resource": "string", - "resourceDependency": "string", - "resources": ["string"], - "addresses": ["string"], - "originalError": "string" - } - } - ], - "level": "info", - "data": { - "installed_blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "export_job_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "resources": 0 - } - } - ], - "triggered_at": "1970-01-01T00:00:00.000Z", - "created_by": { - "name": "manifest@epilot.cloud", - "org_id": "911690", - "user_id": "11001045", - "token_id": "api_5ZugdRXasLfWBypHi93Fk" - }, - "blueprint_id": "c2d6cac8-bdd5-4ea2-8a6c-1cbdbe77b341", - "status": "IN_PROGRESS", - "download_file": { - "bucket": "blueprint-manifest-prod-blueprintsv2bucket-sybpsryropzw", - "key": "templates/main.tf" - } +```ts +type UniquenessCriteria = { + org_id: string + resource_type: "emailtemplate" | "product" | "price" | "tax" | "coupon" | "product_recommendation" | "file" | "document_template" | "notification_template" | "journey" + fields: string[] + propagated_to?: string[] + updated_at: string // date-time + updated_by?: string } ``` -
+### `LineageEntry` ---- +```ts +type LineageEntry = { + lineage_id?: string + target_id?: string + resource_type?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + blueprint_instance_ids?: string[] + fidelity?: "full" | "partial" + last_synced_at?: string // date-time +} +``` -## Schemas +### `BlueprintNote` + +A single internal note on a blueprint. + +```ts +type BlueprintNote = { + id: string + text: string + created_at: string // date-time + updated_at?: string // date-time + created_by?: { + name?: unknown + org_id: string + user_id?: string + token_id?: string + } +} +``` ### `BlueprintID` @@ -1617,6 +7529,22 @@ type BlueprintResourceID = string ```ts type CommonBlueprintFields = { + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] + } id?: string title: string slug?: string @@ -1624,16 +7552,74 @@ type CommonBlueprintFields = { preinstall?: string postinstall?: string } + notes?: Array<{ + id: string + text: string + created_at: string // date-time + updated_at?: string // date-time + created_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + }> version?: string deployments?: Array<{ source_org_id?: string source_blueprint_id?: string destination_org_id?: string destination_blueprint_id?: string + job_id?: string triggered_at?: string // date-time + performed_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + note?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + merge_plan_id?: string + merge_snapshot_id?: string + snapshot_restore_available?: boolean + merge_plan_state?: "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" + revert_until?: string // date-time + restore_details?: { + has_revertible_changes?: { ... } + resource_impact_summary?: { ... } + last_restore_job_id?: { ... } + last_restore_at?: { ... } + last_restored_by?: { ... } + status?: { ... } + } + has_revertible_changes?: boolean + last_restore_job_id?: string + restore_status?: "available" | "in_progress" | "restored" | "partially_restored" | "restore_failed" | "unavailable" }> is_verified?: boolean + latest_verification?: { + job_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + triggered_at?: string // date-time + source_org_id?: string + source_blueprint_id?: string + destination_org_id?: string + destination_blueprint_id?: string + installation_job_id?: string + sync_engine?: "terraform" | "v3" + summary?: { + total_resources?: { ... } + matched?: { ... } + mismatched?: { ... } + missing_in_destination?: { ... } + fetch_errors?: { ... } + } + } + ignored_resource_addresses?: string[] installation_status?: "IN_PROGRESS" | "CANCELED" | "PARTIAL" | "SUCCESS" | "FAILED" + active_restore_job_id?: string + active_restore_started_at?: string // date-time created_at?: string // date-time updated_at?: string // date-time created_by?: { @@ -1642,22 +7628,63 @@ type CommonBlueprintFields = { user_id?: string token_id?: string } - updated_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - installation_job_ids?: string[] - source_blueprint_id?: string - archived?: boolean - docs_url?: string - recommended_apps?: string[] - required_features?: { - enabled?: string[] - disabled?: string[] - } - zip_file_name?: string + // ... +} +``` + +### `SuggestBlueprintResourcesRequest` + +```ts +type SuggestBlueprintResourcesRequest = { + prompt: string + blueprint_id?: string +} +``` + +### `SuggestBlueprintResourcesResponse` + +```ts +type SuggestBlueprintResourcesResponse = { + resources: Array<{ + id: string + name?: string + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + address?: string + is_root?: boolean + is_ready?: boolean + is_hidden?: boolean + is_disabled?: boolean + hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event"[] + parent_resource_ids?: string[] + depends_on_addresses?: string[] + impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored" | "error"[] + impact_on_install_reason?: string[] + impact_on_install_changes?: Array<{ + path: { ... } + destination?: { ... } + source?: { ... } + added: { ... } + }> + impact_on_install_labels?: Record + impact_on_install_summary?: string[] + }> + suggested_blueprint_name?: string + explanation?: string + add_dependencies_recommended?: boolean +} +``` + +### `SkippedBlueprintResource` + +A resource that was requested (or discovered as a dependency) but was not +added to the Blueprint. Reasons are stable machine-readable codes. + + +```ts +type SkippedBlueprintResource = { + id: string + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + reason: "not_found" | "source_validation_failed" | "enrichment_failed" } ``` @@ -1667,17 +7694,25 @@ type CommonBlueprintFields = { type BlueprintResource = { id: string name?: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" address?: string is_root?: boolean is_ready?: boolean is_hidden?: boolean is_disabled?: boolean - hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template"[] + hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event"[] parent_resource_ids?: string[] depends_on_addresses?: string[] - impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] + impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored" | "error"[] impact_on_install_reason?: string[] + impact_on_install_changes?: Array<{ + path: string + destination?: unknown + source?: unknown + added: boolean + }> + impact_on_install_labels?: Record + impact_on_install_summary?: string[] } ``` @@ -1696,10 +7731,15 @@ type BlueprintPreview = { version?: string slug?: string source_type: "marketplace" | "file" + sync_engine?: "terraform" | "v3" blueprint_file_s3_key: string is_verified: boolean docs_url?: string recommended_apps?: string[] + required_features?: { + enabled?: string[] + disabled?: string[] + } created_at: string // date-time created_by: { name?: unknown @@ -1711,17 +7751,25 @@ type BlueprintPreview = { resources: Array<{ id: string name?: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" address?: string is_root?: boolean is_ready?: boolean is_hidden?: boolean is_disabled?: boolean - hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template"[] + hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event"[] parent_resource_ids?: string[] depends_on_addresses?: string[] - impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] + impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored" | "error"[] impact_on_install_reason?: string[] + impact_on_install_changes?: Array<{ + path: { ... } + destination?: { ... } + source?: { ... } + added: { ... } + }> + impact_on_install_labels?: Record + impact_on_install_summary?: string[] }> } ``` @@ -1730,6 +7778,22 @@ type BlueprintPreview = { ```ts type CustomBlueprint = { + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] + } id?: string title: string slug?: string @@ -1737,16 +7801,74 @@ type CustomBlueprint = { preinstall?: string postinstall?: string } + notes?: Array<{ + id: string + text: string + created_at: string // date-time + updated_at?: string // date-time + created_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + }> version?: string deployments?: Array<{ source_org_id?: string source_blueprint_id?: string destination_org_id?: string destination_blueprint_id?: string + job_id?: string triggered_at?: string // date-time + performed_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + note?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + merge_plan_id?: string + merge_snapshot_id?: string + snapshot_restore_available?: boolean + merge_plan_state?: "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" + revert_until?: string // date-time + restore_details?: { + has_revertible_changes?: { ... } + resource_impact_summary?: { ... } + last_restore_job_id?: { ... } + last_restore_at?: { ... } + last_restored_by?: { ... } + status?: { ... } + } + has_revertible_changes?: boolean + last_restore_job_id?: string + restore_status?: "available" | "in_progress" | "restored" | "partially_restored" | "restore_failed" | "unavailable" }> is_verified?: boolean + latest_verification?: { + job_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + triggered_at?: string // date-time + source_org_id?: string + source_blueprint_id?: string + destination_org_id?: string + destination_blueprint_id?: string + installation_job_id?: string + sync_engine?: "terraform" | "v3" + summary?: { + total_resources?: { ... } + matched?: { ... } + mismatched?: { ... } + missing_in_destination?: { ... } + fetch_errors?: { ... } + } + } + ignored_resource_addresses?: string[] installation_status?: "IN_PROGRESS" | "CANCELED" | "PARTIAL" | "SUCCESS" | "FAILED" + active_restore_job_id?: string + active_restore_started_at?: string // date-time created_at?: string // date-time updated_at?: string // date-time created_by?: { @@ -1755,38 +7877,7 @@ type CustomBlueprint = { user_id?: string token_id?: string } - updated_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - installation_job_ids?: string[] - source_blueprint_id?: string - archived?: boolean - docs_url?: string - recommended_apps?: string[] - required_features?: { - enabled?: string[] - disabled?: string[] - } - zip_file_name?: string - resources?: Array<{ - id: string - name?: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" - address?: string - is_root?: boolean - is_ready?: boolean - is_hidden?: boolean - is_disabled?: boolean - hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template"[] - parent_resource_ids?: string[] - depends_on_addresses?: string[] - impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] - impact_on_install_reason?: string[] - }> - source_type?: string + // ... } ``` @@ -1794,6 +7885,22 @@ type CustomBlueprint = { ```ts type FileBlueprint = { + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] + } id?: string title: string slug?: string @@ -1801,16 +7908,74 @@ type FileBlueprint = { preinstall?: string postinstall?: string } + notes?: Array<{ + id: string + text: string + created_at: string // date-time + updated_at?: string // date-time + created_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + }> version?: string deployments?: Array<{ source_org_id?: string source_blueprint_id?: string destination_org_id?: string destination_blueprint_id?: string + job_id?: string triggered_at?: string // date-time + performed_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + note?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + merge_plan_id?: string + merge_snapshot_id?: string + snapshot_restore_available?: boolean + merge_plan_state?: "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" + revert_until?: string // date-time + restore_details?: { + has_revertible_changes?: { ... } + resource_impact_summary?: { ... } + last_restore_job_id?: { ... } + last_restore_at?: { ... } + last_restored_by?: { ... } + status?: { ... } + } + has_revertible_changes?: boolean + last_restore_job_id?: string + restore_status?: "available" | "in_progress" | "restored" | "partially_restored" | "restore_failed" | "unavailable" }> is_verified?: boolean + latest_verification?: { + job_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + triggered_at?: string // date-time + source_org_id?: string + source_blueprint_id?: string + destination_org_id?: string + destination_blueprint_id?: string + installation_job_id?: string + sync_engine?: "terraform" | "v3" + summary?: { + total_resources?: { ... } + matched?: { ... } + mismatched?: { ... } + missing_in_destination?: { ... } + fetch_errors?: { ... } + } + } + ignored_resource_addresses?: string[] installation_status?: "IN_PROGRESS" | "CANCELED" | "PARTIAL" | "SUCCESS" | "FAILED" + active_restore_job_id?: string + active_restore_started_at?: string // date-time created_at?: string // date-time updated_at?: string // date-time created_by?: { @@ -1819,38 +7984,7 @@ type FileBlueprint = { user_id?: string token_id?: string } - updated_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - installation_job_ids?: string[] - source_blueprint_id?: string - archived?: boolean - docs_url?: string - recommended_apps?: string[] - required_features?: { - enabled?: string[] - disabled?: string[] - } - zip_file_name?: string - source_type?: string - resources?: Array<{ - id: string - name?: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" - address?: string - is_root?: boolean - is_ready?: boolean - is_hidden?: boolean - is_disabled?: boolean - hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template"[] - parent_resource_ids?: string[] - depends_on_addresses?: string[] - impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] - impact_on_install_reason?: string[] - }> + // ... } ``` @@ -1858,6 +7992,22 @@ type FileBlueprint = { ```ts type MarketplaceBlueprint = { + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] + } id?: string title: string slug?: string @@ -1865,16 +8015,74 @@ type MarketplaceBlueprint = { preinstall?: string postinstall?: string } + notes?: Array<{ + id: string + text: string + created_at: string // date-time + updated_at?: string // date-time + created_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + }> version?: string deployments?: Array<{ source_org_id?: string source_blueprint_id?: string destination_org_id?: string destination_blueprint_id?: string + job_id?: string triggered_at?: string // date-time + performed_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + note?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + merge_plan_id?: string + merge_snapshot_id?: string + snapshot_restore_available?: boolean + merge_plan_state?: "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" + revert_until?: string // date-time + restore_details?: { + has_revertible_changes?: { ... } + resource_impact_summary?: { ... } + last_restore_job_id?: { ... } + last_restore_at?: { ... } + last_restored_by?: { ... } + status?: { ... } + } + has_revertible_changes?: boolean + last_restore_job_id?: string + restore_status?: "available" | "in_progress" | "restored" | "partially_restored" | "restore_failed" | "unavailable" }> is_verified?: boolean + latest_verification?: { + job_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + triggered_at?: string // date-time + source_org_id?: string + source_blueprint_id?: string + destination_org_id?: string + destination_blueprint_id?: string + installation_job_id?: string + sync_engine?: "terraform" | "v3" + summary?: { + total_resources?: { ... } + matched?: { ... } + mismatched?: { ... } + missing_in_destination?: { ... } + fetch_errors?: { ... } + } + } + ignored_resource_addresses?: string[] installation_status?: "IN_PROGRESS" | "CANCELED" | "PARTIAL" | "SUCCESS" | "FAILED" + active_restore_job_id?: string + active_restore_started_at?: string // date-time created_at?: string // date-time updated_at?: string // date-time created_by?: { @@ -1883,41 +8091,7 @@ type MarketplaceBlueprint = { user_id?: string token_id?: string } - updated_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - installation_job_ids?: string[] - source_blueprint_id?: string - archived?: boolean - docs_url?: string - recommended_apps?: string[] - required_features?: { - enabled?: string[] - disabled?: string[] - } - zip_file_name?: string - source_type?: string - resources?: Array<{ - id: string - name?: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" - address?: string - is_root?: boolean - is_ready?: boolean - is_hidden?: boolean - is_disabled?: boolean - hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template"[] - parent_resource_ids?: string[] - depends_on_addresses?: string[] - impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] - impact_on_install_reason?: string[] - }> - has_update_available?: boolean - latest_marketplace_version?: string - installation_link?: string + // ... } ``` @@ -1954,6 +8128,22 @@ type InstalledMarketplaceBlueprintItem = { ```ts type DeployedBlueprint = { + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] + } id?: string title: string slug?: string @@ -1961,127 +8151,106 @@ type DeployedBlueprint = { preinstall?: string postinstall?: string } + notes?: Array<{ + id: string + text: string + created_at: string // date-time + updated_at?: string // date-time + created_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + }> version?: string deployments?: Array<{ source_org_id?: string source_blueprint_id?: string destination_org_id?: string destination_blueprint_id?: string + job_id?: string triggered_at?: string // date-time + performed_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + note?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + merge_plan_id?: string + merge_snapshot_id?: string + snapshot_restore_available?: boolean + merge_plan_state?: "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" + revert_until?: string // date-time + restore_details?: { + has_revertible_changes?: { ... } + resource_impact_summary?: { ... } + last_restore_job_id?: { ... } + last_restore_at?: { ... } + last_restored_by?: { ... } + status?: { ... } + } + has_revertible_changes?: boolean + last_restore_job_id?: string + restore_status?: "available" | "in_progress" | "restored" | "partially_restored" | "restore_failed" | "unavailable" }> is_verified?: boolean - installation_status?: "IN_PROGRESS" | "CANCELED" | "PARTIAL" | "SUCCESS" | "FAILED" - created_at?: string // date-time - updated_at?: string // date-time - created_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - updated_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - installation_job_ids?: string[] - source_blueprint_id?: string - archived?: boolean - docs_url?: string - recommended_apps?: string[] - required_features?: { - enabled?: string[] - disabled?: string[] - } - zip_file_name?: string - source_type?: string - resources?: Array<{ - id: string - name?: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" - address?: string - is_root?: boolean - is_ready?: boolean - is_hidden?: boolean - is_disabled?: boolean - hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template"[] - parent_resource_ids?: string[] - depends_on_addresses?: string[] - impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] - impact_on_install_reason?: string[] - }> -} -``` - -### `AppBlueprint` - -```ts -type AppBlueprint = { - id?: string - title: string - slug?: string - description?: { - preinstall?: string - postinstall?: string - } - version?: string - deployments?: Array<{ + latest_verification?: { + job_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + triggered_at?: string // date-time source_org_id?: string source_blueprint_id?: string destination_org_id?: string destination_blueprint_id?: string - triggered_at?: string // date-time - }> - is_verified?: boolean + installation_job_id?: string + sync_engine?: "terraform" | "v3" + summary?: { + total_resources?: { ... } + matched?: { ... } + mismatched?: { ... } + missing_in_destination?: { ... } + fetch_errors?: { ... } + } + } + ignored_resource_addresses?: string[] installation_status?: "IN_PROGRESS" | "CANCELED" | "PARTIAL" | "SUCCESS" | "FAILED" + active_restore_job_id?: string + active_restore_started_at?: string // date-time created_at?: string // date-time updated_at?: string // date-time created_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - updated_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - installation_job_ids?: string[] - source_blueprint_id?: string - archived?: boolean - docs_url?: string - recommended_apps?: string[] - required_features?: { - enabled?: string[] - disabled?: string[] - } - zip_file_name?: string - source_type?: string - resources?: Array<{ - id: string - name?: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" - address?: string - is_root?: boolean - is_ready?: boolean - is_hidden?: boolean - is_disabled?: boolean - hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template"[] - parent_resource_ids?: string[] - depends_on_addresses?: string[] - impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] - impact_on_install_reason?: string[] - }> + name?: unknown + org_id: string + user_id?: string + token_id?: string + } + // ... } ``` -### `Blueprint` +### `AppBlueprint` ```ts -type Blueprint = { +type AppBlueprint = { + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] + } id?: string title: string slug?: string @@ -2089,16 +8258,74 @@ type Blueprint = { preinstall?: string postinstall?: string } + notes?: Array<{ + id: string + text: string + created_at: string // date-time + updated_at?: string // date-time + created_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + }> version?: string deployments?: Array<{ source_org_id?: string source_blueprint_id?: string destination_org_id?: string destination_blueprint_id?: string + job_id?: string triggered_at?: string // date-time + performed_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + note?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + merge_plan_id?: string + merge_snapshot_id?: string + snapshot_restore_available?: boolean + merge_plan_state?: "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" + revert_until?: string // date-time + restore_details?: { + has_revertible_changes?: { ... } + resource_impact_summary?: { ... } + last_restore_job_id?: { ... } + last_restore_at?: { ... } + last_restored_by?: { ... } + status?: { ... } + } + has_revertible_changes?: boolean + last_restore_job_id?: string + restore_status?: "available" | "in_progress" | "restored" | "partially_restored" | "restore_failed" | "unavailable" }> is_verified?: boolean + latest_verification?: { + job_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + triggered_at?: string // date-time + source_org_id?: string + source_blueprint_id?: string + destination_org_id?: string + destination_blueprint_id?: string + installation_job_id?: string + sync_engine?: "terraform" | "v3" + summary?: { + total_resources?: { ... } + matched?: { ... } + mismatched?: { ... } + missing_in_destination?: { ... } + fetch_errors?: { ... } + } + } + ignored_resource_addresses?: string[] installation_status?: "IN_PROGRESS" | "CANCELED" | "PARTIAL" | "SUCCESS" | "FAILED" + active_restore_job_id?: string + active_restore_started_at?: string // date-time created_at?: string // date-time updated_at?: string // date-time created_by?: { @@ -2107,39 +8334,30 @@ type Blueprint = { user_id?: string token_id?: string } - updated_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - installation_job_ids?: string[] - source_blueprint_id?: string - archived?: boolean - docs_url?: string - recommended_apps?: string[] - required_features?: { - enabled?: string[] - disabled?: string[] + // ... +} +``` + +### `Blueprint` + +```ts +type Blueprint = { + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] } - zip_file_name?: string - resources?: Array<{ - id: string - name?: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" - address?: string - is_root?: boolean - is_ready?: boolean - is_hidden?: boolean - is_disabled?: boolean - hard_dependencies?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template"[] - parent_resource_ids?: string[] - depends_on_addresses?: string[] - impact_on_install?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] - impact_on_install_reason?: string[] - }> - source_type?: string -} | { id?: string title: string slug?: string @@ -2147,16 +8365,74 @@ type Blueprint = { preinstall?: string postinstall?: string } + notes?: Array<{ + id: string + text: string + created_at: string // date-time + updated_at?: string // date-time + created_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + }> version?: string deployments?: Array<{ source_org_id?: string source_blueprint_id?: string destination_org_id?: string destination_blueprint_id?: string + job_id?: string triggered_at?: string // date-time + performed_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + note?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + merge_plan_id?: string + merge_snapshot_id?: string + snapshot_restore_available?: boolean + merge_plan_state?: "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" + revert_until?: string // date-time + restore_details?: { + has_revertible_changes?: { ... } + resource_impact_summary?: { ... } + last_restore_job_id?: { ... } + last_restore_at?: { ... } + last_restored_by?: { ... } + status?: { ... } + } + has_revertible_changes?: boolean + last_restore_job_id?: string + restore_status?: "available" | "in_progress" | "restored" | "partially_restored" | "restore_failed" | "unavailable" }> is_verified?: boolean + latest_verification?: { + job_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + triggered_at?: string // date-time + source_org_id?: string + source_blueprint_id?: string + destination_org_id?: string + destination_blueprint_id?: string + installation_job_id?: string + sync_engine?: "terraform" | "v3" + summary?: { + total_resources?: { ... } + matched?: { ... } + mismatched?: { ... } + missing_in_destination?: { ... } + fetch_errors?: { ... } + } + } + ignored_resource_addresses?: string[] installation_status?: "IN_PROGRESS" | "CANCELED" | "PARTIAL" | "SUCCESS" | "FAILED" + active_restore_job_id?: string + active_restore_started_at?: string // date-time created_at?: string // date-time updated_at?: string // date-time created_by?: { @@ -2165,22 +8441,6 @@ type Blueprint = { user_id?: string token_id?: string } - updated_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string - } - installation_job_ids?: string[] - source_blueprint_id?: string - archived?: boolean - docs_url?: string - recommended_apps?: string[] - required_features?: { - enabled?: string[] - disabled?: string[] - } - zip_file_name?: string // ... } ``` @@ -2223,10 +8483,325 @@ type CommonBlueprintJobFields = { } ``` -### `BlueprintExportJob` +### `BlueprintExportJob` + +```ts +type BlueprintExportJob = { + id?: string + events?: Array<{ + timestamp?: string // date-time + message?: string + errors?: Array<{ + error?: { ... } + code?: { ... } + data?: { ... } + }> + level?: "info" | "warning" | "error" + data?: { + installed_blueprint_id?: { ... } + export_job_id?: { ... } + resources?: { ... } + } + }> + triggered_at?: string // date-time + created_by?: { + name?: unknown + org_id: string + user_id?: string + token_id?: string + } + job_type?: "export" + blueprint_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "FAILED" | "CANCELED" + download_file?: { + bucket: string + key: string + } +} +``` + +### `BlueprintInstallationJob` + +```ts +type BlueprintInstallationJob = { + id?: string + events?: Array<{ + timestamp?: string // date-time + message?: string + errors?: Array<{ + error?: { ... } + code?: { ... } + data?: { ... } + }> + level?: "info" | "warning" | "error" + data?: { + installed_blueprint_id?: { ... } + export_job_id?: { ... } + resources?: { ... } + } + }> + triggered_at?: string // date-time + created_by?: { + name?: unknown + org_id: string + user_id?: string + token_id?: string + } + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] + } + job_type?: "install" + source_blueprint_id?: string + source_blueprint_type?: "custom" | "file" | "marketplace" | "deploy" | "app" + source_org_id?: string + source_blueprint_file?: string + destination_blueprint_id?: string + destination_org_id?: string + slug?: string + sync_engine?: "terraform" | "v3" + resource_progress?: Array<{ + lineage_id: string + type: string + address: string + name?: string + status: "pending" | "in_progress" | "done" | "failed" | "skipped" + target_id?: string + error_message?: string + error_code?: string + error_data?: Record + }> + options?: { + resources_to_ignore?: string[] + sync_notes?: boolean + include_field_diffs?: boolean + } + merge_plan_id?: string + wait_kind?: "plan" | "reauth" | "merge_review" + prefill_from_merge_plan_id?: string + assigned_merge_plan_id?: string + status?: "IN_PROGRESS" | "WAITING_USER_ACTION" | "REAUTH_REQUIRED" | "CANCELED" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" +} +``` + +### `BulkInstallStatus` + +Aggregate status for a bulk install or one of its targets. +- `QUEUED`: not started yet +- `IN_PROGRESS`: at least one target queued/in-progress, not all done +- `SUCCESS`: all targets succeeded +- `PARTIAL_SUCCESS`: all targets terminal with a mix of success/partial/failure +- `FAILED`: all targets term + +```ts +type BulkInstallStatus = "QUEUED" | "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" | "REVIEW_REQUIRED" +``` + +### `BulkInstallCounts` + +Tally of target rows by status. Recomputed from target rows on each transition. + +```ts +type BulkInstallCounts = { + queued?: number + in_progress?: number + success?: number + partial_success?: number + failed?: number + review_required?: number +} +``` + +### `BulkInstall` + +Bulk install parent. Never carries target auth tokens. + +```ts +type BulkInstall = { + bulk_job_id?: string + source_org_id?: string + source_blueprint_id?: string + status?: "QUEUED" | "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" | "REVIEW_REQUIRED" + target_count?: number + max_concurrency?: number + counts?: { + queued?: number + in_progress?: number + success?: number + partial_success?: number + failed?: number + review_required?: number + } + slug?: string + options?: { + resources_to_ignore?: string[] + sync_notes?: boolean + include_field_diffs?: boolean + } + created_at?: string // date-time + updated_at?: string // date-time +} +``` + +### `BulkInstallTarget` + +A single destination of a bulk install. `job` is the hydrated latest child +install job derived from `job_ids.at(-1)`. Auth tokens are never stored or returned. + + +```ts +type BulkInstallTarget = { + bulk_job_id?: string + destination_org_id?: string + destination_blueprint_id?: string + status?: "QUEUED" | "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" | "REVIEW_REQUIRED" + job_ids?: string[] + merge_plan_id?: string + created_at?: string // date-time + updated_at?: string // date-time + job?: { + id?: string + events?: Array<{ + timestamp?: { ... } + message?: { ... } + errors?: { ... } + level?: { ... } + data?: { ... } + }> + triggered_at?: string // date-time + created_by?: { + name?: { ... } + org_id: { ... } + user_id?: { ... } + token_id?: { ... } + } + source_drift?: { + removed: { ... } + missing?: { ... } + exclude_addresses?: { ... } + } + job_type?: "install" + source_blueprint_id?: string + source_blueprint_type?: "custom" | "file" | "marketplace" | "deploy" | "app" + source_org_id?: string + source_blueprint_file?: string + destination_blueprint_id?: string + destination_org_id?: string + slug?: string + sync_engine?: "terraform" | "v3" + resource_progress?: Array<{ + lineage_id: { ... } + type: { ... } + address: { ... } + name?: { ... } + status: { ... } + target_id?: { ... } + error_message?: { ... } + error_code?: { ... } + error_data?: { ... } + }> + options?: { + resources_to_ignore?: { ... } + sync_notes?: { ... } + include_field_diffs?: { ... } + } + merge_plan_id?: string + wait_kind?: "plan" | "reauth" | "merge_review" + prefill_from_merge_plan_id?: string + assigned_merge_plan_id?: string + status?: "IN_PROGRESS" | "WAITING_USER_ACTION" | "REAUTH_REQUIRED" | "CANCELED" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + } +} +``` + +### `BulkInstallTargetList` + +```ts +type BulkInstallTargetList = { + results?: Array<{ + bulk_job_id?: string + destination_org_id?: string + destination_blueprint_id?: string + status?: "QUEUED" | "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" | "REVIEW_REQUIRED" + job_ids?: string[] + merge_plan_id?: string + created_at?: string // date-time + updated_at?: string // date-time + job?: { + id?: { ... } + events?: { ... } + triggered_at?: { ... } + created_by?: { ... } + source_drift?: { ... } + job_type?: { ... } + source_blueprint_id?: { ... } + source_blueprint_type?: { ... } + source_org_id?: { ... } + source_blueprint_file?: { ... } + destination_blueprint_id?: { ... } + destination_org_id?: { ... } + slug?: { ... } + sync_engine?: { ... } + resource_progress?: { ... } + options?: { ... } + merge_plan_id?: { ... } + wait_kind?: { ... } + prefill_from_merge_plan_id?: { ... } + assigned_merge_plan_id?: { ... } + status?: { ... } + } + }> + next_cursor?: string +} +``` + +### `BulkInstallTargetInput` + +```ts +type BulkInstallTargetInput = { + destination_org_id: string + destination_blueprint_id?: string + destination_auth_token: string +} +``` + +### `BulkInstallCreateRequest` + +```ts +type BulkInstallCreateRequest = { + source_org_id?: string + source_blueprint_id: string + max_concurrency?: number + slug?: string + options?: { + resources_to_ignore?: string[] + sync_notes?: boolean + include_field_diffs?: boolean + } + targets: Array<{ + destination_org_id: string + destination_blueprint_id?: string + destination_auth_token: string + }> +} +``` + +### `BlueprintRestoreJob` ```ts -type BlueprintExportJob = { +type BlueprintRestoreJob = { id?: string events?: Array<{ timestamp?: string // date-time @@ -2250,50 +8825,279 @@ type BlueprintExportJob = { user_id?: string token_id?: string } - blueprint_id?: string - status?: "IN_PROGRESS" | "SUCCESS" | "FAILED" | "CANCELED" - download_file?: { - bucket: string - key: string + job_type?: "restore" + destination_blueprint_id?: string + destination_org_id?: string + install_job_id?: string + merge_plan_id?: string + snapshot_id?: string + sync_engine?: "v3" + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + restore_result?: { + snapshot_id?: string + resources?: Array<{ + lineage_id: { ... } + type: { ... } + name?: { ... } + target_id?: { ... } + action: { ... } + reason?: { ... } + last_synced_at?: { ... } + current_updated_at?: { ... } + error_message?: { ... } + is_hidden?: { ... } + co_owned_by?: { ... } + protected_by?: { ... } + }> + has_effective_changes?: boolean } } ``` -### `BlueprintInstallationJob` +### `V3ResourceProgressEntry` ```ts -type BlueprintInstallationJob = { - id?: string - events?: Array<{ - timestamp?: string // date-time - message?: string - errors?: Array<{ - error?: { ... } - code?: { ... } - data?: { ... } - }> - level?: "info" | "warning" | "error" - data?: { - installed_blueprint_id?: { ... } - export_job_id?: { ... } - resources?: { ... } +type V3ResourceProgressEntry = { + lineage_id: string + type: string + address: string + name?: string + status: "pending" | "in_progress" | "done" | "failed" | "skipped" + target_id?: string + error_message?: string + error_code?: string + error_data?: Record +} +``` + +### `RestoreOutcomeItem` + +```ts +type RestoreOutcomeItem = { + lineage_id: string + type: string + name?: string + target_id?: string + action: "restore" | "delete" | "skip" | "failed" + reason?: "modified" | "delete_unsupported" | "heuristic_match" | "co_owned" | "dependency_protected" | "already_deleted" | "non_revertible" | "not_created_by_install" | "unconfirmed" | "unknown_provenance" + last_synced_at?: string // date-time + current_updated_at?: string // date-time + error_message?: string + is_hidden?: boolean + co_owned_by?: Array<{ + blueprint_id: string + title?: string + }> + protected_by?: Array<{ + lineage_id: string + type: string + target_id?: string + }> +} +``` + +### `HealthFinding` + +```ts +type HealthFinding = { + check_id: "live_readability" | "referential_integrity" | "install_completeness" | "schema_consistency" | "mapping_integrity" | "execution_readiness" | "catalog_hygiene" | "spec_conformance" + code: "missing_in_destination" | "fetch_error" | "no_readback" | "unreplaced_source_reference" | "broken_internal_reference" | "dropped_at_install" | "orphaned_group_reference" | "uuid_group_label" | "unreachable_attribute_purpose" | "duplicate_attribute_name" | "duplicate_headline" | "broken_mapping_reference" | "stale_mapping_version" | "mapping_slot_mismatch" | "mapping_parity_mismatch" | "stale_lineage" | "broken_trigger_reference" | "broken_action_reference" | "broken_workflow_step" | "invalid_mapping_target" | "invalid_mapping_source" | "invalid_mapping_version" | "unknown_mapping_attribute" | "workflow_edge_limit" | "dead_purpose_reference" | "broken_portal_reference" | "orphaned_portal_block" | "broken_closing_reason" | "broken_journey_settings" | "unresolved_assignee" | "current_write_invalid" | "duplicate_live_resource" | "missing_file_content" | "file_etag_mismatch" | "incomplete_webhook" | "broken_template_reference" | "orphaned_price" | "duplicate_price" | "inactive_price_in_use" | "cross_org_reference" + severity: "error" | "warning" | "info" + resource_type: string + lineage_id: string + target_id?: string + resource_name?: string + message: string + verdict?: string + evidence?: { + path?: string + referenced_id?: string + referenced_type?: string + referenced_name?: string + referenced_lineage_id?: string + expected_target_id?: string + reference_kind?: string + operation?: string + rejection_reason?: string + error_message?: string + response_status?: number + } +} +``` + +### `HealthCheckCoverage` + +```ts +type HealthCheckCoverage = { + check_id: "live_readability" | "referential_integrity" | "install_completeness" | "schema_consistency" | "mapping_integrity" | "execution_readiness" | "spec_conformance" + status: "completed" | "partial" | "skipped" | "not_applicable" + scope: "tracked_resources" | "org_wide" | "source_comparison" + resources_considered: number + details: string[] +} +``` + +### `HealthResourceTypeCoverage` + +```ts +type HealthResourceTypeCoverage = { + resource_type: string + tracked: number + readable_by_lineage: number + missing_by_lineage: number + read_errors: number + unchecked: number + specialized_checks: "live_readability" | "referential_integrity" | "install_completeness" | "schema_consistency" | "mapping_integrity" | "execution_readiness" | "spec_conformance"[] + known_blind_spots: string[] +} +``` + +### `HealthScanCoverage` + +```ts +type HealthScanCoverage = { + checks: Array<{ + check_id: "live_readability" | "referential_integrity" | "install_completeness" | "schema_consistency" | "mapping_integrity" | "execution_readiness" | "spec_conformance" + status: "completed" | "partial" | "skipped" | "not_applicable" + scope: "tracked_resources" | "org_wide" | "source_comparison" + resources_considered: number + details: string[] + }> + resource_types: Array<{ + resource_type: string + tracked: number + readable_by_lineage: number + missing_by_lineage: number + read_errors: number + unchecked: number + specialized_checks: "live_readability" | "referential_integrity" | "install_completeness" | "schema_consistency" | "mapping_integrity" | "execution_readiness" | "spec_conformance"[] + known_blind_spots: string[] + }> +} +``` + +### `DeploymentHealthReport` + +```ts +type DeploymentHealthReport = { + status: "running" | "completed" | "failed" + job_id: string + blueprint_instance_id: string + destination_org_id: string + generated_at: string // date-time + html_url?: string + summary?: { + resources_scanned?: number + unchecked?: number + errors?: number + warnings?: number + infos?: number + } + findings?: Array<{ + check_id: "live_readability" | "referential_integrity" | "install_completeness" | "schema_consistency" | "mapping_integrity" | "execution_readiness" | "catalog_hygiene" | "spec_conformance" + code: "missing_in_destination" | "fetch_error" | "no_readback" | "unreplaced_source_reference" | "broken_internal_reference" | "dropped_at_install" | "orphaned_group_reference" | "uuid_group_label" | "unreachable_attribute_purpose" | "duplicate_attribute_name" | "duplicate_headline" | "broken_mapping_reference" | "stale_mapping_version" | "mapping_slot_mismatch" | "mapping_parity_mismatch" | "stale_lineage" | "broken_trigger_reference" | "broken_action_reference" | "broken_workflow_step" | "invalid_mapping_target" | "invalid_mapping_source" | "invalid_mapping_version" | "unknown_mapping_attribute" | "workflow_edge_limit" | "dead_purpose_reference" | "broken_portal_reference" | "orphaned_portal_block" | "broken_closing_reason" | "broken_journey_settings" | "unresolved_assignee" | "current_write_invalid" | "duplicate_live_resource" | "missing_file_content" | "file_etag_mismatch" | "incomplete_webhook" | "broken_template_reference" | "orphaned_price" | "duplicate_price" | "inactive_price_in_use" | "cross_org_reference" + severity: "error" | "warning" | "info" + resource_type: string + lineage_id: string + target_id?: string + resource_name?: string + message: string + verdict?: string + evidence?: { + path?: { ... } + referenced_id?: { ... } + referenced_type?: { ... } + referenced_name?: { ... } + referenced_lineage_id?: { ... } + expected_target_id?: { ... } + reference_kind?: { ... } + operation?: { ... } + rejection_reason?: { ... } + error_message?: { ... } + response_status?: { ... } } }> - triggered_at?: string // date-time - created_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string + coverage?: { + checks: Array<{ + check_id: { ... } + status: { ... } + scope: { ... } + resources_considered: { ... } + details: { ... } + }> + resource_types: Array<{ + resource_type: { ... } + tracked: { ... } + readable_by_lineage: { ... } + missing_by_lineage: { ... } + read_errors: { ... } + unchecked: { ... } + specialized_checks: { ... } + known_blind_spots: { ... } + }> } - source_blueprint_id?: string - source_blueprint_type?: "custom" | "file" | "marketplace" | "deploy" | "app" - source_org_id?: string - source_blueprint_file?: string - destination_blueprint_id?: string - destination_org_id?: string - slug?: string - status?: "IN_PROGRESS" | "WAITING_USER_ACTION" | "CANCELED" | "SUCCESS" | "FAILED" + error?: string +} +``` + +### `RestoreOutcome` + +```ts +type RestoreOutcome = { + snapshot_id?: string + resources?: Array<{ + lineage_id: string + type: string + name?: string + target_id?: string + action: "restore" | "delete" | "skip" | "failed" + reason?: "modified" | "delete_unsupported" | "heuristic_match" | "co_owned" | "dependency_protected" | "already_deleted" | "non_revertible" | "not_created_by_install" | "unconfirmed" | "unknown_provenance" + last_synced_at?: string // date-time + current_updated_at?: string // date-time + error_message?: string + is_hidden?: boolean + co_owned_by?: Array<{ + blueprint_id: { ... } + title?: { ... } + }> + protected_by?: Array<{ + lineage_id: { ... } + type: { ... } + target_id?: { ... } + }> + }> + has_effective_changes?: boolean +} +``` + +### `RestorePreviewReport` + +```ts +type RestorePreviewReport = { + preview_id: string + job_id: string + status: "running" | "completed" | "failed" + requested_at: string // date-time + completed_at?: string // date-time + outcome?: { + snapshot_id?: string + resources?: Array<{ + lineage_id: { ... } + type: { ... } + name?: { ... } + target_id?: { ... } + action: { ... } + reason?: { ... } + last_synced_at?: { ... } + current_updated_at?: { ... } + error_message?: { ... } + is_hidden?: { ... } + co_owned_by?: { ... } + protected_by?: { ... } + }> + has_effective_changes?: boolean + } + error?: string } ``` @@ -2324,6 +9128,7 @@ type BlueprintJob = { user_id?: string token_id?: string } + job_type?: "export" blueprint_id?: string status?: "IN_PROGRESS" | "SUCCESS" | "FAILED" | "CANCELED" download_file?: { @@ -2354,6 +9159,23 @@ type BlueprintJob = { user_id?: string token_id?: string } + source_drift?: { + removed: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + }> + missing?: Array<{ + address: { ... } + type: { ... } + name: { ... } + id: { ... } + referenced_by: { ... } + }> + exclude_addresses?: string[] + } + job_type?: "install" source_blueprint_id?: string source_blueprint_type?: "custom" | "file" | "marketplace" | "deploy" | "app" source_org_id?: string @@ -2361,45 +9183,27 @@ type BlueprintJob = { destination_blueprint_id?: string destination_org_id?: string slug?: string - status?: "IN_PROGRESS" | "WAITING_USER_ACTION" | "CANCELED" | "SUCCESS" | "FAILED" -} | { - id?: string - events?: Array<{ - timestamp?: string // date-time - message?: string - errors?: Array<{ - error?: { ... } - code?: { ... } - data?: { ... } - }> - level?: "info" | "warning" | "error" - data?: { - installed_blueprint_id?: { ... } - export_job_id?: { ... } - resources?: { ... } - } + sync_engine?: "terraform" | "v3" + resource_progress?: Array<{ + lineage_id: string + type: string + address: string + name?: string + status: "pending" | "in_progress" | "done" | "failed" | "skipped" + target_id?: string + error_message?: string + error_code?: string + error_data?: Record }> - triggered_at?: string // date-time - created_by?: { - name?: unknown - org_id: string - user_id?: string - token_id?: string + options?: { + resources_to_ignore?: string[] + sync_notes?: boolean + include_field_diffs?: boolean } - blueprint_id?: string - status?: "IN_PROGRESS" | "SUCCESS" | "FAILED" | "CANCELED" -} | { - id?: string - events?: Array<{ - timestamp?: string // date-time - message?: string - errors?: Array<{ - error?: { ... } - code?: { ... } - data?: { ... } - }> - level?: "info" | "warning" | "error" - data?: { + merge_plan_id?: string + wait_kind?: "plan" | "reauth" | "merge_review" + prefill_from_merge_plan_id?: string + assigned_merge_plan_id?: string // ... } ``` @@ -2431,15 +9235,16 @@ type BlueprintDependenciesSyncJob = { user_id?: string token_id?: string } + job_type?: "dependencies_sync" blueprint_id?: string status?: "IN_PROGRESS" | "SUCCESS" | "FAILED" | "CANCELED" } ``` -### `BlueprintValidateJob` +### `BlueprintVerificationJob` ```ts -type BlueprintValidateJob = { +type BlueprintVerificationJob = { id?: string events?: Array<{ timestamp?: string // date-time @@ -2463,21 +9268,113 @@ type BlueprintValidateJob = { user_id?: string token_id?: string } - blueprint_id?: string - status?: "IN_PROGRESS" | "SUCCESS" | "FAILED" - valid?: boolean - errors?: Array<{ - error?: string | object - code?: "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" - data?: { - formattedResource?: { ... } - resource?: { ... } - resourceDependency?: { ... } - resources?: { ... } - addresses?: { ... } - originalError?: { ... } - } + job_type?: "verification" + source_org_id?: string + source_blueprint_id?: string + destination_org_id?: string + destination_blueprint_id?: string + installation_job_id?: string + sync_engine?: "terraform" | "v3" + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + summary?: { + total_resources?: number + matched?: number + mismatched?: number + missing_in_destination?: number + fetch_errors?: number + } + resource_results?: Array<{ + resource_type?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + resource_name?: string + source_resource_id?: string + source_resource_address?: string + destination_resource_id?: string + destination_resource_address?: string + status?: "matched" | "mismatched" | "missing_in_destination" | "fetch_error" + failure_context?: "depends_on_failed_resource" | "may_be_caused_by_failed_dependency" + failed_dependency_resource_ids?: string[] + failed_dependency_resource_names?: string[] + failed_dependency_addresses?: string[] + field_diffs?: Array<{ + path?: { ... } + source_value?: { ... } + destination_value?: { ... } + diff_type?: { ... } + }> + error?: string + }> + resource_results_s3_key?: string +} +``` + +### `LatestBlueprintVerification` + +```ts +type LatestBlueprintVerification = { + job_id?: string + status?: "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" + triggered_at?: string // date-time + source_org_id?: string + source_blueprint_id?: string + destination_org_id?: string + destination_blueprint_id?: string + installation_job_id?: string + sync_engine?: "terraform" | "v3" + summary?: { + total_resources?: number + matched?: number + mismatched?: number + missing_in_destination?: number + fetch_errors?: number + } +} +``` + +### `VerificationSummary` + +```ts +type VerificationSummary = { + total_resources?: number + matched?: number + mismatched?: number + missing_in_destination?: number + fetch_errors?: number +} +``` + +### `ResourceVerificationResult` + +```ts +type ResourceVerificationResult = { + resource_type?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + resource_name?: string + source_resource_id?: string + source_resource_address?: string + destination_resource_id?: string + destination_resource_address?: string + status?: "matched" | "mismatched" | "missing_in_destination" | "fetch_error" + failure_context?: "depends_on_failed_resource" | "may_be_caused_by_failed_dependency" + failed_dependency_resource_ids?: string[] + failed_dependency_resource_names?: string[] + failed_dependency_addresses?: string[] + field_diffs?: Array<{ + path?: string + source_value?: unknown + destination_value?: unknown + diff_type?: "value_changed" | "field_missing_in_destination" | "field_missing_in_source" | "type_mismatch" }> + error?: string +} +``` + +### `FieldDiff` + +```ts +type FieldDiff = { + path?: string + source_value?: unknown + destination_value?: unknown + diff_type?: "value_changed" | "field_missing_in_destination" | "field_missing_in_source" | "type_mismatch" } ``` @@ -2489,14 +9386,20 @@ type BlueprintJobEvent = { message?: string errors?: Array<{ error?: string | object - code?: "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" + code?: "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" | "workflow_quota_reached" | "entity_mapping_journey_not_in_blueprint" | "missing_required_reference" | "source_resources_missing" data?: { + missing_count?: { ... } + exclude_count?: { ... } + source_drift_s3_key?: { ... } formattedResource?: { ... } resource?: { ... } resourceDependency?: { ... } resources?: { ... } addresses?: { ... } originalError?: { ... } + current?: { ... } + max_allowed?: { ... } + planned?: { ... } } }> level?: "info" | "warning" | "error" @@ -2513,6 +9416,19 @@ type BlueprintJobEvent = { ```ts type BlueprintInstallationJobOptions = { resources_to_ignore?: string[] + sync_notes?: boolean + include_field_diffs?: boolean +} +``` + +### `ContinueInstallationJobRequest` + +```ts +type ContinueInstallationJobRequest = { + resources_to_ignore?: string[] + sync_notes?: boolean + include_field_diffs?: boolean + source_auth_token?: string // password } ``` @@ -2546,7 +9462,7 @@ type Manifest = { previous_jobs_ids?: string[] previous_jobs?: Array<{ job_id?: string - job_status?: "PENDING" | "STARTED" | "WAITING_USER_ACTION" | "CANCELED" | "IN_PROGRESS" | "SUCCESS" | "FAILED" + job_status?: "PENDING" | "STARTED" | "WAITING_USER_ACTION" | "REAUTH_REQUIRED" | "CANCELED" | "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" manifest_file_path?: string message?: string timestamp?: string // date-time @@ -2699,7 +9615,7 @@ type ManifestItem = { ### `JobStatus` ```ts -type JobStatus = "PENDING" | "STARTED" | "WAITING_USER_ACTION" | "CANCELED" | "IN_PROGRESS" | "SUCCESS" | "FAILED" +type JobStatus = "PENDING" | "STARTED" | "WAITING_USER_ACTION" | "REAUTH_REQUIRED" | "CANCELED" | "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" ``` ### `ResourceNodeType` @@ -2707,7 +9623,7 @@ type JobStatus = "PENDING" | "STARTED" | "WAITING_USER_ACTION" | "CANCELED" | "I Type of the resource ```ts -type ResourceNodeType = "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" +type ResourceNodeType = "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" ``` ### `PlanChanges` @@ -2721,7 +9637,7 @@ type PlanChanges = "create" | "update" | "internal-update" | "no-op" | "delete" ```ts type CommonResourceNode = { id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: boolean @@ -2733,14 +9649,14 @@ type CommonResourceNode = { ```ts type RootResourceNode = { id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: boolean address?: string dependencies?: Array<{ id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: true @@ -2767,68 +9683,18 @@ type RootResourceNode = { ```ts type VirtualResourceNodeGroup = { id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: true dependencies?: Array<{ id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" - name?: string - source_id?: string - is_virtual?: boolean - address?: string - dependencies?: Array<{ - id: { ... } - type: { ... } - name?: { ... } - source_id?: { ... } - is_virtual?: { ... } - address?: { ... } - dependencies?: { ... } - parents?: { ... } - changes?: { ... } - changes_reason?: { ... } - }> - parents?: Array<{ - id?: { ... } - type?: { ... } - }> - changes?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] - changes_reason?: string[] - }> -} -``` - -### `ResourceNode` - -```ts -type ResourceNode = { - id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" - name?: string - source_id?: string - is_virtual?: boolean - address?: string - dependencies?: Array<{ - id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string - source_id?: string - is_virtual?: boolean - address?: string - dependencies?: Array<{ - id: { ... } - type: { ... } - name?: { ... } - source_id?: { ... } - is_virtual?: { ... } - address?: { ... } - dependencies?: { ... } - parents?: { ... } - changes?: { ... } - changes_reason?: { ... } - }> + source_id?: string + is_virtual?: boolean + address?: string + dependencies?: { ... }[] parents?: Array<{ id?: { ... } type?: { ... } @@ -2836,9 +9702,23 @@ type ResourceNode = { changes?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] changes_reason?: string[] }> +} +``` + +### `ResourceNode` + +```ts +type ResourceNode = { + id: string + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + name?: string + source_id?: string + is_virtual?: boolean + address?: string + dependencies?: { ... }[] parents?: Array<{ id?: string - type?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type?: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" }> changes?: "create" | "update" | "internal-update" | "no-op" | "delete" | "ignored"[] changes_reason?: string[] @@ -2850,14 +9730,14 @@ type ResourceNode = { ```ts type Job = { job_id?: string - job_status?: "PENDING" | "STARTED" | "WAITING_USER_ACTION" | "CANCELED" | "IN_PROGRESS" | "SUCCESS" | "FAILED" + job_status?: "PENDING" | "STARTED" | "WAITING_USER_ACTION" | "REAUTH_REQUIRED" | "CANCELED" | "IN_PROGRESS" | "SUCCESS" | "PARTIAL_SUCCESS" | "FAILED" manifest_file_path?: string message?: string timestamp?: string // date-time plan_file_content?: string resources_to_export?: Array<{ id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: boolean @@ -2874,7 +9754,7 @@ type Job = { changes_reason?: string[] }> | { id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: boolean @@ -2893,7 +9773,7 @@ type Job = { large_resources_to_export_url?: string resources_to_import?: Array<{ id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: boolean @@ -2910,7 +9790,7 @@ type Job = { changes_reason?: string[] }> | { id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: boolean @@ -2935,19 +9815,19 @@ type Job = { is_verified?: boolean errors?: Array<{ error?: string | object - code?: "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" + code?: "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" | "workflow_quota_reached" | "entity_mapping_journey_not_in_blueprint" | "missing_required_reference" | "source_resources_missing" data?: { + missing_count?: { ... } + exclude_count?: { ... } + source_drift_s3_key?: { ... } formattedResource?: { ... } resource?: { ... } resourceDependency?: { ... } resources?: { ... } addresses?: { ... } originalError?: { ... } - } - }> - source_type?: "file" | "marketplace" | "sandbox" - imported_resources?: Array<{ - id: string + current?: { ... } + max_allowed?: { ... } // ... } ``` @@ -3034,7 +9914,7 @@ type CommonImportFields = { source_type?: "file" | "marketplace" | "sandbox" imported_resources?: Array<{ id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: boolean @@ -3051,7 +9931,7 @@ type CommonImportFields = { changes_reason?: string[] }> | { id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" name?: string source_id?: string is_virtual?: boolean @@ -3100,7 +9980,56 @@ type BlueprintInstallStatus = "SUCCESS" | "PARTIAL" | "FAILED" ### `FormattedErrorCodes` ```ts -type FormattedErrorCodes = "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" +type FormattedErrorCodes = "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" | "workflow_quota_reached" | "entity_mapping_journey_not_in_blueprint" | "missing_required_reference" | "source_resources_missing" +``` + +### `V3SourceResource` + +```ts +type V3SourceResource = { + address: string + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + name: string + id: string +} +``` + +### `V3MissingSourceResource` + +```ts +type V3MissingSourceResource = { + address: string + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + name: string + id: string + referenced_by: string[] +} +``` + +### `V3SourceDrift` + +V3 live-source plan capture only. Available on the install job and destination +blueprint plan. Only confirmed owning-API NotFound/404 reads may be auto-skipped; null, permission, +transport, server errors and missing ids remain strict capture failures. +Complete details are hydrated from durable stora + +```ts +type V3SourceDrift = { + removed: Array<{ + address: string + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + name: string + id: string + }> + missing?: Array<{ + address: string + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" + name: string + id: string + referenced_by: string[] + }> + exclude_addresses?: string[] +} ``` ### `FormattedErrorData` @@ -3118,8 +10047,11 @@ type FormattedErrorData = { ```ts type FormattedError = { error?: string | object - code?: "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" + code?: "dependency_extraction" | "resource_not_found" | "resource_fetch_api_error" | "resource_fetch_unknown_error" | "terraform_cli_process_error" | "terraform_import_block_process_error" | "terraform_init_error" | "terraform_validate_error" | "terraform_plan_error" | "terraform_apply_error" | "terraform_show_error" | "generic_error" | "bad_request" | "forbidden" | "conflict" | "not_found" | "undeclared_resource" | "invalid_readonly_attribute" | "invalid_attribute_value" | "unsupported_attribute" | "self_referential_block" | "circular_dependency" | "state_mismatch" | "import_nonexistent_object" | "provider_install_error" | "stale_blueprint" | "workflow_quota_reached" | "entity_mapping_journey_not_in_blueprint" | "missing_required_reference" | "source_resources_missing" data?: { + missing_count?: number + exclude_count?: number + source_drift_s3_key?: string formattedResource?: { id?: { ... } name?: { ... } @@ -3130,6 +10062,9 @@ type FormattedError = { resources?: string[] addresses?: string[] originalError?: string + current?: number + max_allowed?: number + planned?: number } } ``` @@ -3151,7 +10086,7 @@ type CallerIdentity = { type SelectedResources = { exported_root_resources: Array<{ id: string - type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" + type: "designbuilder" | "journey" | "product" | "price" | "product_recommendation" | "coupon" | "tax" | "automation_flow" | "entity_mapping" | "file" | "emailtemplate" | "schema" | "schema_attribute" | "schema_capability" | "schema_group" | "schema_group_headline" | "workflow_definition" | "closing_reason" | "taxonomy_classification" | "webhook" | "integration" | "dashboard" | "insight" | "custom_variable" | "usergroup" | "saved_view" | "app" | "role" | "portal_config" | "target" | "kanban" | "validation_rule" | "flow_template" | "taxonomy" | "notification_template" | "environment_variable" | "datasource" | "family" | "permission" | "email_signature" | "shared_inbox" | "event_catalog_event" address?: string }> selected_resources: string[] @@ -3184,3 +10119,640 @@ type PutManifestPayload = { }> } ``` + +### `MarketplaceListing` + +```ts +type MarketplaceListing = { + id: string // uuid + blueprint_id: string + name: string + slug: string + logo?: string + documentation_url?: string + pricing_type?: "free" | "paid" | "freemium" | "contact_us" + support_email?: string + portal_description?: string + teaser_name?: string + teaser_short_description?: string + teaser_thumbnail?: string + details_page_title?: string + details_page_description?: string + details_page_hero_image?: string + details_page_carousel?: string[] + resources_section_description?: string + resources_section_benefits_title?: string + resources_section_benefits_list?: string + resources_section_process_details?: string + partner?: string + partner_subtext?: string + partner_logo?: string + partner_website_link?: string + last_updated_on?: string + requires_customer_portal?: boolean + process_details_section_title?: string + is_new_blueprint?: boolean + available_in?: string + testimonials?: string[] + installation_link?: string + installation_slug?: string + demo_form_link?: string + order?: number + categories?: string[] + main_category?: string[] + status: "draft" | "live" | "archived" + created_at?: string // date-time + updated_at?: string // date-time +} +``` + +### `MarketplaceListingUpdate` + +```ts +type MarketplaceListingUpdate = { + name?: string + slug?: string + logo?: string + documentation_url?: string + pricing_type?: "free" | "paid" | "freemium" | "contact_us" + support_email?: string + portal_description?: string + teaser_name?: string + teaser_short_description?: string + teaser_thumbnail?: string + details_page_title?: string + details_page_description?: string + details_page_hero_image?: string + details_page_carousel?: string[] + resources_section_description?: string + resources_section_benefits_title?: string + resources_section_benefits_list?: string + resources_section_process_details?: string + partner?: string + partner_subtext?: string + partner_logo?: string + partner_website_link?: string + last_updated_on?: string + requires_customer_portal?: boolean + process_details_section_title?: string + is_new_blueprint?: boolean + available_in?: string + testimonials?: string[] + installation_link?: string + installation_slug?: string + demo_form_link?: string + order?: number + categories?: string[] + main_category?: string[] +} +``` + +### `MarketplaceListingVersion` + +```ts +type MarketplaceListingVersion = { + id: string // uuid + listing_id: string + status: "draft" | "published" | "archived" + version_name?: string + draft_label: string + update_note?: string + resources?: object[] + required_features?: string[] + recommended_apps?: string[] + created_at: string // date-time + published_at?: string // date-time +} +``` + +### `MergePlanState` + +Lifecycle state of an update merge plan. + +```ts +type MergePlanState = "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" +``` + +### `MergeOptionId` + +```ts +type MergeOptionId = "keep_current" | "take_incoming" | "keep_absent" | "restore_incoming" +``` + +### `MergeChoice` + +The reviewer's choice for one decision group. Valid only while `group_signature` matches. + +```ts +type MergeChoice = { + group_id: string + group_signature: string + option_id: "keep_current" | "take_incoming" | "keep_absent" | "restore_incoming" +} +``` + +### `MergeChoiceInput` + +A submitted choice. `option_id` is not an enum here, so an option the group does not offer is answered with 422 `merge_plan_choice_invalid` and its `group_ids`, like every other invalid choice. + +```ts +type MergeChoiceInput = { + group_id: string + group_signature: string + option_id: string +} +``` + +### `MergeSectionRef` + +```ts +type MergeSectionRef = { + resource_lineage_id: string + section_id: string + item_path?: Array<{ + section_id: string + item_key: string + }> +} +``` + +### `MergeSectionValue` + +A unit value in builder terms. `present` false means the unit does not exist on that side. + +```ts +type MergeSectionValue = { + present: boolean + value?: unknown +} +``` + +### `MergeDecisionGroup` + +```ts +type MergeDecisionGroup = { + group_id: string + group_signature: string + kind: "conflict" | "mandatory" | "confirm" + scope: "units" | "order" | "resource" + section_refs: Array<{ + resource_lineage_id: string + section_id: string + item_path?: Array<{ + section_id: { ... } + item_key: { ... } + }> + }> + ui_concept: string + label_key: string + values: Array<{ + section_ref: { + resource_lineage_id: { ... } + section_id: { ... } + item_path?: { ... } + } + label: string + base: { + present: { ... } + value?: { ... } + } + current: { + present: { ... } + value?: { ... } + } + incoming: { + present: { ... } + value?: { ... } + } + }> + options: Array<{ + option_id: "keep_current" | "take_incoming" | "keep_absent" | "restore_incoming" + label_key: string + description_key: string + }> + selection_required: boolean + selected_option_id?: "keep_current" | "take_incoming" | "keep_absent" | "restore_incoming" + mandatory_declaration_ids: string[] + batch_key?: string + sequence_labels?: { + base?: string[] + current: string[] + incoming: string[] + } +} +``` + +### `MergePlanWarning` + +A finding of the merged result that does not block the update. + +```ts +type MergePlanWarning = { + code: string + target: string + unit_key?: string + level?: "warning" + message: string +} +``` + +### `MergeBaseProvenance` + +```ts +type MergeBaseProvenance = { + rung: "apply_evidence" | "none" + job_id?: string + manifest_version?: string + reason?: "no_evidence" | "unreconciled" | "no_manifest" | "not_in_manifest" | "translation_gap" +} +``` + +### `MergeResourceStatus` + +```ts +type MergeResourceStatus = "automatic" | "decisions_required" | "ready" | "blocked" +``` + +### `MergeResourceEligibility` + +```ts +type MergeResourceEligibility = "merge" | "two_way" | "blocked" | "automatic_keep_absent" | "absence_decision" +``` + +### `MergeResourceAutoCounts` + +```ts +type MergeResourceAutoCounts = { + from_current: number + from_incoming: number +} +``` + +### `MergePlanReview` + +Summary of an update merge plan. + +```ts +type MergePlanReview = { + merge_plan_id: string + plan_revision: number + expected_plan_revision: number + warnings: Array<{ + code: string + resource_key: string + target: string + message: string + }> + blocked_reasons: string[] + apply_counts: { + updated: number + kept: number + removed: number + restored: number + } + apply_counts_unknown?: boolean + state: "review_required" | "ready" | "approved" | "applying" | "applied" | "partially_applied" | "failed" | "discarded" | "expired" | "superseded" | "reverting" | "reverted" | "revert_partial" + job_id: string + destination_blueprint_id: string + source: { + blueprint_id?: string + version?: string + } + resource_counts: { + automatic: number + decisions_required: number + ready: number + blocked: number + } + group_counts: { + conflict: number + confirm: number + mandatory: number + unresolved: number + } + warning_count: number + auto_counts: { + kept_customizations: number + applied_updates: number + } + other_resource_count: number + created_at: string // date-time + expires_at: string // date-time + revert_until: string // date-time + supersedes?: string + superseded_by?: string + successor_failed?: boolean +} +``` + +### `MergePlanApplyCounts` + +Journeys by what apply does with the current choices: `updated` (written), `kept` (blocked, left as they are), `removed` (stay removed), `restored` (created again). + +```ts +type MergePlanApplyCounts = { + updated: number + kept: number + removed: number + restored: number +} +``` + +### `MergeResourceOutcome` + +Result of one journey after apply. + +```ts +type MergeResourceOutcome = "applied" | "kept_removed" | "restored" | "merge_stale" | "failed" +``` + +### `MergePlanResourceSummary` + +```ts +type MergePlanResourceSummary = { + resource_key: string + label: string + status: "automatic" | "decisions_required" | "ready" | "blocked" + eligibility: "merge" | "two_way" | "blocked" | "automatic_keep_absent" | "absence_decision" + blocking_reasons: string[] + auto_counts: { + from_current: number + from_incoming: number + } + unresolved: number + warning_count: number + outcome?: "applied" | "kept_removed" | "restored" | "merge_stale" | "failed" +} +``` + +### `MergePlanResourcePage` + +```ts +type MergePlanResourcePage = { + merge_plan_id: string + plan_revision: number + resources: Array<{ + resource_key: string + label: string + status: "automatic" | "decisions_required" | "ready" | "blocked" + eligibility: "merge" | "two_way" | "blocked" | "automatic_keep_absent" | "absence_decision" + blocking_reasons: string[] + auto_counts: { + from_current: { ... } + from_incoming: { ... } + } + unresolved: number + warning_count: number + outcome?: "applied" | "kept_removed" | "restored" | "merge_stale" | "failed" + }> + next_cursor?: string +} +``` + +### `MergePlanResourceDetail` + +```ts +type MergePlanResourceDetail = { + resource_key: string + resource_type: "journey" + lineage_id: string + target_id: string + label: string + model_version: string + base_provenance: { + rung: "apply_evidence" | "none" + job_id?: string + manifest_version?: string + reason?: "no_evidence" | "unreconciled" | "no_manifest" | "not_in_manifest" | "translation_gap" + } + eligibility: "merge" | "two_way" | "blocked" | "automatic_keep_absent" | "absence_decision" + fast_path: boolean + auto_counts: { + from_current: number + from_incoming: number + } + decision_groups: Array<{ + group_id: string + group_signature: string + kind: "conflict" | "mandatory" | "confirm" + scope: "units" | "order" | "resource" + section_refs: Array<{ + resource_lineage_id: { ... } + section_id: { ... } + item_path?: { ... } + }> + ui_concept: string + label_key: string + values: Array<{ + section_ref: { ... } + label: { ... } + base: { ... } + current: { ... } + incoming: { ... } + }> + options: Array<{ + option_id: { ... } + label_key: { ... } + description_key: { ... } + }> + selection_required: boolean + selected_option_id?: "keep_current" | "take_incoming" | "keep_absent" | "restore_incoming" + mandatory_declaration_ids: string[] + batch_key?: string + sequence_labels?: { + base?: { ... } + current: { ... } + incoming: { ... } + } + }> + warnings: Array<{ + code: string + target: string + unit_key?: string + level?: "warning" + message: string + }> + status: "automatic" | "decisions_required" | "ready" | "blocked" + blocking_reasons: string[] + outcome?: "applied" | "kept_removed" | "restored" | "merge_stale" | "failed" +} +``` + +### `MergePlanResourceReview` + +```ts +type MergePlanResourceReview = { + merge_plan_id: string + plan_revision: number + resource: { + resource_key: string + resource_type: "journey" + lineage_id: string + target_id: string + label: string + model_version: string + base_provenance: { + rung: { ... } + job_id?: { ... } + manifest_version?: { ... } + reason?: { ... } + } + eligibility: "merge" | "two_way" | "blocked" | "automatic_keep_absent" | "absence_decision" + fast_path: boolean + auto_counts: { + from_current: { ... } + from_incoming: { ... } + } + decision_groups: Array<{ + group_id: { ... } + group_signature: { ... } + kind: { ... } + scope: { ... } + section_refs: { ... } + ui_concept: { ... } + label_key: { ... } + values: { ... } + options: { ... } + selection_required: { ... } + selected_option_id?: { ... } + mandatory_declaration_ids: { ... } + batch_key?: { ... } + sequence_labels?: { ... } + }> + warnings: Array<{ + code: { ... } + target: { ... } + unit_key?: { ... } + level?: { ... } + message: { ... } + }> + status: "automatic" | "decisions_required" | "ready" | "blocked" + blocking_reasons: string[] + outcome?: "applied" | "kept_removed" | "restored" | "merge_stale" | "failed" + } +} +``` + +### `MergePlanResolutionsUpdate` + +```ts +type MergePlanResolutionsUpdate = { + expected_plan_revision: number + resolutions: Array<{ + group_id: string + group_signature: string + option_id: string + }> +} +``` + +### `MergePlanApplyRequest` + +```ts +type MergePlanApplyRequest = { + expected_plan_revision: number + idempotency_key: string +} +``` + +### `MergePlanRevisionRequest` + +Body of discard and refresh requests. + +```ts +type MergePlanRevisionRequest = { + expected_plan_revision: number +} +``` + +### `MergePlanReplanResult` + +```ts +type MergePlanReplanResult = { + merge_plan_id: string + job_id: string +} +``` + +### `MergeRevertEntry` + +```ts +type MergeRevertEntry = { + resource_key: string + lineage_id: string + label: string + resource_type: string + category: "unchanged" | "changed_since_update" | "created_by_update" | "metadata_only" | "not_restorable" + default_action: "restore" | "keep" + requires_choice: boolean +} +``` + +### `MergeRevertPreview` + +```ts +type MergeRevertPreview = { + revert_preview_id: string + preview_revision: number + merge_plan_id: string + entries: Array<{ + resource_key: string + lineage_id: string + label: string + resource_type: string + category: "unchanged" | "changed_since_update" | "created_by_update" | "metadata_only" | "not_restorable" + default_action: "restore" | "keep" + requires_choice: boolean + }> +} +``` + +### `MergeRevertSelection` + +```ts +type MergeRevertSelection = { + resource_key: string + action: "restore" | "keep" +} +``` + +### `MergeRevertRequest` + +```ts +type MergeRevertRequest = { + revert_preview_id: string + expected_preview_revision: number + idempotency_key: string + selections: Array<{ + resource_key: string + action: "restore" | "keep" + }> + session_credentials?: { + refresh_token: string // password + client_id: string + pipeline_id?: string + } +} +``` + +### `MergeRevertResult` + +```ts +type MergeRevertResult = { + job_id: string +} +``` + +### `MergePlanError` + +```ts +type MergePlanError = { + status: number + error: string + group_ids?: string[] + action?: "replan" + merge_plan_id?: string + retry_after?: number + resource_keys?: string[] +} +``` diff --git a/docs/sdk/clients/calendar.md b/docs/sdk/clients/calendar.md new file mode 100644 index 00000000..be7c0843 --- /dev/null +++ b/docs/sdk/clients/calendar.md @@ -0,0 +1,1786 @@ +--- +title: "Calendar API" +description: "TypeScript SDK client for the epilot Calendar API: usage with @epilot/sdk, all operations and schemas." +--- + +# Calendar API + +- **Base URL:** `https://calendar.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/calendar](https://docs.epilot.io/api/calendar) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.calendar.listUsersAbsence(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/calendar' + +const calendarClient = getClient() +authorize(calendarClient, () => '') +const { data } = await calendarClient.listUsersAbsence(...) +``` + +## Operations + +**Absence** +- [`listUsersAbsence`](#listusersabsence) +- [`searchAbsence`](#searchabsence) +- [`searchNowAbsence`](#searchnowabsence) +- [`listAbsenceAdjustments`](#listabsenceadjustments) +- [`createAbsenceAdjustment`](#createabsenceadjustment) +- [`getAbsenceAdjustment`](#getabsenceadjustment) +- [`patchAbsenceAdjustment`](#patchabsenceadjustment) +- [`deleteAbsenceAdjustment`](#deleteabsenceadjustment) +- [`getUserAbsence`](#getuserabsence) + +**Working Hours** +- [`getWorkingHours`](#getworkinghours) +- [`putWorkingHours`](#putworkinghours) +- [`deleteWorkingHours`](#deleteworkinghours) + +**Calendars** +- [`listCalendars`](#listcalendars) +- [`createCalendar`](#createcalendar) +- [`addOutlookCalendar`](#addoutlookcalendar) +- [`listOutlookCalendars`](#listoutlookcalendars) +- [`deleteOutlookCalendar`](#deleteoutlookcalendar) +- [`outlookWebhook`](#outlookwebhook) +- [`getCalendar`](#getcalendar) +- [`updateCalendar`](#updatecalendar) +- [`deleteCalendar`](#deletecalendar) + +**Calendar Events** +- [`listEvents`](#listevents) +- [`createEvent`](#createevent) +- [`getEvent`](#getevent) +- [`updateEvent`](#updateevent) +- [`deleteEvent`](#deleteevent) +- [`shareEvent`](#shareevent) +- [`unshareEvent`](#unshareevent) + +**Schemas** +- [`AbsenceInterval`](#absenceinterval) +- [`AbsenceIntervalSource`](#absenceintervalsource) +- [`Error`](#error) +- [`SearchAbsenceBody`](#searchabsencebody) +- [`SearchNowAbsenceBody`](#searchnowabsencebody) +- [`AbsenceAdjustment`](#absenceadjustment) +- [`AbsenceStatus`](#absencestatus) +- [`AbsenceType`](#absencetype) +- [`CreateAbsenceAdjustmentBody`](#createabsenceadjustmentbody) +- [`PatchAbsenceAdjustmentBody`](#patchabsenceadjustmentbody) +- [`ExternalCalendar`](#externalcalendar) +- [`WorkingHours`](#workinghours) +- [`UpsertWorkingHoursBody`](#upsertworkinghoursbody) +- [`TimeWindow`](#timewindow) +- [`Calendar`](#calendar) +- [`CalendarSource`](#calendarsource) +- [`Provider`](#provider) +- [`CalendarCreateBody`](#calendarcreatebody) +- [`AddOutlookCalendarRequest`](#addoutlookcalendarrequest) +- [`AvailableOutlookCalendar`](#availableoutlookcalendar) +- [`CalendarPatchBody`](#calendarpatchbody) +- [`CalendarEvent`](#calendarevent) +- [`EventType`](#eventtype) +- [`EventStatus`](#eventstatus) +- [`Sensitivity`](#sensitivity) +- [`Importance`](#importance) +- [`ResponseStatus`](#responsestatus) +- [`Attendee`](#attendee) +- [`EventSource`](#eventsource) +- [`CalendarEventCreateBody`](#calendareventcreatebody) +- [`CalendarEventPatchBody`](#calendareventpatchbody) +- [`ShareEventBody`](#shareeventbody) + +### `listUsersAbsence` + +List organization users with known absence metadata in the requested time window. + +`GET /v1/calendar/absence/users` + +```ts +const { data } = await client.listUsersAbsence({ + from: 'example', + to: 'example', + include_busy: true, + working_hours_granularity: 'example', + query: 'example', + limit: 1, + offset: 1, +}) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "hits": 0, + "results": [ + { + "absent": true, + "absence_intervals": [ + { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "original_from": "1970-01-01T00:00:00.000Z", + "original_to": "1970-01-01T00:00:00.000Z", + "absent": true, + "source": "calendar_event", + "calendar_event_id": "string", + "absence_adjustment_id": "string", + "reason": "string" + } + ], + "user_id": "string", + "display_name": "string", + "email": "user@example.com", + "status": "string" + } + ] +} +``` + +
+ +--- + +### `searchAbsence` + +Search known absence for candidate users in the requested time window. + +`POST /v1/calendar/absence:search` + +```ts +const { data } = await client.searchAbsence( + null, + { + from: '1970-01-01T00:00:00.000Z', + to: '1970-01-01T00:00:00.000Z', + user_ids: ['string'], + include_busy: false, + working_hours_granularity: 'time' + }, +) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "users": {} +} +``` + +
+ +--- + +### `searchNowAbsence` + +Search known absence for candidate users at the current server time. + +`POST /v1/calendar/absence:search-now` + +```ts +const { data } = await client.searchNowAbsence( + null, + { + user_ids: ['string'], + include_busy: false, + working_hours_granularity: 'time' + }, +) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "users": {} +} +``` + +
+ +--- + +### `listAbsenceAdjustments` + +List absence adjustments for a user in a time window. + +`GET /v1/calendar/absence/users/{user_id}/adjustments` + +```ts +const { data } = await client.listAbsenceAdjustments({ + user_id: 'example', + from: 'example', + to: 'example', +}) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "results": [ + { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string", + "adjustment_id": "string", + "user_id": "string", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `createAbsenceAdjustment` + +Create a time-bound absence adjustment for a user in the caller organization. + +`POST /v1/calendar/absence/users/{user_id}/adjustments` + +```ts +const { data } = await client.createAbsenceAdjustment( + { + user_id: 'example', + }, + { + from: '1970-01-01T00:00:00.000Z', + to: '1970-01-01T00:00:00.000Z', + absent: true, + status: 'oof', + type: 'string', + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string", + "adjustment_id": "string", + "user_id": "string", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getAbsenceAdjustment` + +Get an absence adjustment by ID. + +`GET /v1/calendar/absence/users/{user_id}/adjustments/{adjustment_id}` + +```ts +const { data } = await client.getAbsenceAdjustment({ + user_id: 'example', + adjustment_id: 'example', +}) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string", + "adjustment_id": "string", + "user_id": "string", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `patchAbsenceAdjustment` + +Update an absence adjustment in the caller organization. + +`PATCH /v1/calendar/absence/users/{user_id}/adjustments/{adjustment_id}` + +```ts +const { data } = await client.patchAbsenceAdjustment( + { + user_id: 'example', + adjustment_id: 'example', + }, + { + from: '1970-01-01T00:00:00.000Z', + to: '1970-01-01T00:00:00.000Z', + absent: true, + status: 'oof', + type: 'string', + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "absent": true, + "status": "oof", + "type": "string", + "reason": "string", + "adjustment_id": "string", + "user_id": "string", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteAbsenceAdjustment` + +Delete an absence adjustment. + +`DELETE /v1/calendar/absence/users/{user_id}/adjustments/{adjustment_id}` + +```ts +const { data } = await client.deleteAbsenceAdjustment({ + user_id: 'example', + adjustment_id: 'example', +}) +``` + +--- + +### `getUserAbsence` + +Get known absence for a user in a time window. absent=false means no known absence, not guaranteed availability. + +`GET /v1/calendar/absence/users/{user_id}` + +```ts +const { data } = await client.getUserAbsence({ + user_id: 'example', + from: 'example', + to: 'example', + include_busy: true, + working_hours_granularity: 'example', +}) +``` + +
+Response + +```json +{ + "absent": true, + "absence_intervals": [ + { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "original_from": "1970-01-01T00:00:00.000Z", + "original_to": "1970-01-01T00:00:00.000Z", + "absent": true, + "source": "calendar_event", + "calendar_event_id": "string", + "absence_adjustment_id": "string", + "reason": "string" + } + ], + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "user_id": "string", + "external_calendars": [ + { + "provider": "outlook", + "last_synced_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `getWorkingHours` + +Get the recurring weekly working hours of a user. 404 means no record exists and the user is treated as always available. + +`GET /v1/calendar/working-hours/users/{user_id}` + +```ts +const { data } = await client.getWorkingHours({ + user_id: 'example', +}) +``` + +
+Response + +```json +{ + "monday": [ + { + "start": "string", + "end": "string" + } + ], + "tuesday": [ + { + "start": "string", + "end": "string" + } + ], + "wednesday": [ + { + "start": "string", + "end": "string" + } + ], + "thursday": [ + { + "start": "string", + "end": "string" + } + ], + "friday": [ + { + "start": "string", + "end": "string" + } + ], + "saturday": [ + { + "start": "string", + "end": "string" + } + ], + "sunday": [ + { + "start": "string", + "end": "string" + } + ], + "timezone": "string", + "user_id": "string", + "updated_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `putWorkingHours` + +Create or fully replace the working hours of a user in the caller organization. This is a full replace, not a merge. + +`PUT /v1/calendar/working-hours/users/{user_id}` + +```ts +const { data } = await client.putWorkingHours( + { + user_id: 'example', + }, + { + monday: [ + { + start: 'string', + end: 'string' + } + ], + tuesday: [ + { + start: 'string', + end: 'string' + } + ], + wednesday: [ + { + start: 'string', + end: 'string' + } + ], + thursday: [ + { + start: 'string', + end: 'string' + } + ], + friday: [ + { + start: 'string', + end: 'string' + } + ], + saturday: [ + { + start: 'string', + end: 'string' + } + ], + sunday: [ + { + start: 'string', + end: 'string' + } + ], + timezone: 'Europe/Berlin' + }, +) +``` + +
+Response + +```json +{ + "monday": [ + { + "start": "string", + "end": "string" + } + ], + "tuesday": [ + { + "start": "string", + "end": "string" + } + ], + "wednesday": [ + { + "start": "string", + "end": "string" + } + ], + "thursday": [ + { + "start": "string", + "end": "string" + } + ], + "friday": [ + { + "start": "string", + "end": "string" + } + ], + "saturday": [ + { + "start": "string", + "end": "string" + } + ], + "sunday": [ + { + "start": "string", + "end": "string" + } + ], + "timezone": "string", + "user_id": "string", + "updated_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteWorkingHours` + +Delete the working hours of a user. The user is then treated as always available again. + +`DELETE /v1/calendar/working-hours/users/{user_id}` + +```ts +const { data } = await client.deleteWorkingHours({ + user_id: 'example', +}) +``` + +--- + +### `listCalendars` + +List calendars visible to the caller. + +`GET /v1/calendar` + +```ts +const { data } = await client.listCalendars({ + size: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createCalendar` + +Create a native epilot calendar. + +`POST /v1/calendar` + +```ts +const { data } = await client.createCalendar( + null, + { + name: 'string', + description: 'string', + color: 'string' + }, +) +``` + +
+Response + +```json +{ + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `addOutlookCalendar` + +Registers one of the caller's Outlook calendars as an epilot calendar. + +`POST /v1/calendar/sources/outlook` + +```ts +const { data } = await client.addOutlookCalendar( + null, + { + provider_calendar_id: 'string', + name: 'string' + }, +) +``` + +
+Response + +```json +{ + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listOutlookCalendars` + +Lists the calling user's Outlook calendars available to import as epilot calendars. + +`GET /v1/calendar/sources/outlook/available` + +```ts +const { data } = await client.listOutlookCalendars() +``` + +
+Response + +```json +{ + "calendars": [ + { + "provider_calendar_id": "string", + "name": "string", + "color": "string", + "is_default": true, + "can_edit": true, + "owner": "string" + } + ] +} +``` + +
+ +--- + +### `deleteOutlookCalendar` + +Disconnects a previously registered Outlook calendar. + +`DELETE /v1/calendar/sources/outlook/{calendar_id}` + +```ts +const { data } = await client.deleteOutlookCalendar({ + calendar_id: 'example', +}) +``` + +--- + +### `outlookWebhook` + +Public Microsoft Graph webhook receiver for per-user Outlook calendar +subscriptions. Unauthenticated by design (API Gateway `Authorizer: NONE`): +Graph calls it with no epilot token. + +`POST /v1/calendar/outlook/webhook` + +```ts +const { data } = await client.outlookWebhook({ + validationToken: 'example', +}) +``` + +--- + +### `getCalendar` + +Get a single calendar by its epilot ID. + +`GET /v1/calendar/{calendar_id}` + +```ts +const { data } = await client.getCalendar({ + calendar_id: 'example', +}) +``` + +
+Response + +```json +{ + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateCalendar` + +Update local calendar details. Changes to synced calendars do not modify the provider calendar. + +`PATCH /v1/calendar/{calendar_id}` + +```ts +const { data } = await client.updateCalendar( + { + calendar_id: 'example', + }, + { + name: 'string', + description: 'string', + color: 'string' + }, +) +``` + +
+Response + +```json +{ + "_id": "string", + "_schema": "calendar", + "_org": "string", + "_title": "string", + "name": "string", + "description": "string", + "color": "string", + "is_default": true, + "is_epilot_default": true, + "read_only": true, + "owner_email": "user@example.com", + "source": { + "type": "native", + "provider": "outlook", + "provider_calendar_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteCalendar` + +Delete a native epilot calendar or disconnect a synced calendar, including its locally stored events. + +`DELETE /v1/calendar/{calendar_id}` + +```ts +const { data } = await client.deleteCalendar({ + calendar_id: 'example', +}) +``` + +--- + +### `listEvents` + +List events in a time window. Recurring events are returned as expanded occurrences – each instance appears as its own event. + +`GET /v1/calendar/events` + +```ts +const { data } = await client.listEvents({ + from: 'example', + to: 'example', + calendar_id: 'example', + size: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "_id": "string", + "_schema": "calendar_event", + "_org": "string", + "_title": "string", + "_tags": ["string"], + "calendar_id": "string", + "event_type": "singleInstance", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "busy": true, + "is_cancelled": true, + "is_draft": true, + "sensitivity": "normal", + "importance": "low", + "is_online_meeting": true, + "online_meeting_url": "https://example.com/path", + "web_link": "https://example.com/path", + "response_status": "none", + "organizer_email": "user@example.com", + "attendees": [ + { + "email": "user@example.com", + "name": "string", + "response": "none", + "type": "required" + } + ], + "metadata": {}, + "is_recurring": true, + "series_master_id": "string", + "source": { + "type": "native", + "provider": "outlook", + "provider_event_id": "string", + "provider_event_url": "https://example.com/path", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "etag": "string" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createEvent` + +Create a native epilot calendar event. Omit `calendar_id` to use the caller’s epilot default calendar. + +`POST /v1/calendar/events` + +```ts +const { data } = await client.createEvent( + null, + { + calendar_id: 'string', + description: 'string', + start_time: '1970-01-01T00:00:00.000Z', + end_time: '1970-01-01T00:00:00.000Z', + timezone: 'string', + is_all_day: true, + location: 'string', + status: 'free', + sensitivity: 'normal', + metadata: {}, + _title: 'string' + }, +) +``` + +
+Response + +```json +{ + "_id": "string", + "_schema": "calendar_event", + "_org": "string", + "_title": "string", + "_tags": ["string"], + "calendar_id": "string", + "event_type": "singleInstance", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "busy": true, + "is_cancelled": true, + "is_draft": true, + "sensitivity": "normal", + "importance": "low", + "is_online_meeting": true, + "online_meeting_url": "https://example.com/path", + "web_link": "https://example.com/path", + "response_status": "none", + "organizer_email": "user@example.com", + "attendees": [ + { + "email": "user@example.com", + "name": "string", + "response": "none", + "type": "required" + } + ], + "metadata": {}, + "is_recurring": true, + "series_master_id": "string", + "source": { + "type": "native", + "provider": "outlook", + "provider_event_id": "string", + "provider_event_url": "https://example.com/path", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "etag": "string" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getEvent` + +Get a single event by its epilot ID. + +`GET /v1/calendar/events/{event_id}` + +```ts +const { data } = await client.getEvent({ + event_id: 'example', +}) +``` + +
+Response + +```json +{ + "_id": "string", + "_schema": "calendar_event", + "_org": "string", + "_title": "string", + "_tags": ["string"], + "calendar_id": "string", + "event_type": "singleInstance", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "busy": true, + "is_cancelled": true, + "is_draft": true, + "sensitivity": "normal", + "importance": "low", + "is_online_meeting": true, + "online_meeting_url": "https://example.com/path", + "web_link": "https://example.com/path", + "response_status": "none", + "organizer_email": "user@example.com", + "attendees": [ + { + "email": "user@example.com", + "name": "string", + "response": "none", + "type": "required" + } + ], + "metadata": {}, + "is_recurring": true, + "series_master_id": "string", + "source": { + "type": "native", + "provider": "outlook", + "provider_event_id": "string", + "provider_event_url": "https://example.com/path", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "etag": "string" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateEvent` + +Update a native epilot calendar event. + +`PATCH /v1/calendar/events/{event_id}` + +```ts +const { data } = await client.updateEvent( + { + event_id: 'example', + }, + { + description: 'string', + start_time: '1970-01-01T00:00:00.000Z', + end_time: '1970-01-01T00:00:00.000Z', + timezone: 'string', + is_all_day: true, + location: 'string', + status: 'free', + is_cancelled: true, + sensitivity: 'normal', + _title: 'string' + }, +) +``` + +
+Response + +```json +{ + "_id": "string", + "_schema": "calendar_event", + "_org": "string", + "_title": "string", + "_tags": ["string"], + "calendar_id": "string", + "event_type": "singleInstance", + "description": "string", + "start_time": "1970-01-01T00:00:00.000Z", + "end_time": "1970-01-01T00:00:00.000Z", + "timezone": "string", + "is_all_day": true, + "location": "string", + "status": "free", + "busy": true, + "is_cancelled": true, + "is_draft": true, + "sensitivity": "normal", + "importance": "low", + "is_online_meeting": true, + "online_meeting_url": "https://example.com/path", + "web_link": "https://example.com/path", + "response_status": "none", + "organizer_email": "user@example.com", + "attendees": [ + { + "email": "user@example.com", + "name": "string", + "response": "none", + "type": "required" + } + ], + "metadata": {}, + "is_recurring": true, + "series_master_id": "string", + "source": { + "type": "native", + "provider": "outlook", + "provider_event_id": "string", + "provider_event_url": "https://example.com/path", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "etag": "string" + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteEvent` + +Delete a native epilot calendar event. + +`DELETE /v1/calendar/events/{event_id}` + +```ts +const { data } = await client.deleteEvent({ + event_id: 'example', +}) +``` + +--- + +### `shareEvent` + +Share a calendar event with another user of the same organization, view-only. Owner-only: recipients of a share cannot re-share. Sharing an already-shared event is a no-op. + +`POST /v1/calendar/events/{event_id}/share` + +```ts +const { data } = await client.shareEvent( + { + event_id: 'example', + }, + { + user_id: 'string' + }, +) +``` + +--- + +### `unshareEvent` + +Revoke a per-event share. The recipient loses access immediately. Owner-only. + +`DELETE /v1/calendar/events/{event_id}/share/{user_id}` + +```ts +const { data } = await client.unshareEvent({ + event_id: 'example', + user_id: 'example', +}) +``` + +--- + +## Schemas + +### `AbsenceInterval` + +```ts +type AbsenceInterval = { + from: string // date-time + to: string // date-time + original_from: string // date-time + original_to: string // date-time + absent: boolean + source: "calendar_event" | "absence_adjustment" | "working_hours" + calendar_event_id?: string + absence_adjustment_id?: string + reason?: string +} +``` + +### `AbsenceIntervalSource` + +```ts +type AbsenceIntervalSource = "calendar_event" | "absence_adjustment" | "working_hours" +``` + +### `Error` + +```ts +type Error = { + status: number + error: string | unknown[] +} +``` + +### `SearchAbsenceBody` + +```ts +type SearchAbsenceBody = { + from: string // date-time + to: string // date-time + user_ids: string[] + include_busy?: boolean + working_hours_granularity?: "time" | "day" +} +``` + +### `SearchNowAbsenceBody` + +```ts +type SearchNowAbsenceBody = { + user_ids: string[] + include_busy?: boolean + working_hours_granularity?: "time" | "day" +} +``` + +### `AbsenceAdjustment` + +```ts +type AbsenceAdjustment = { + from: string // date-time + to: string // date-time + absent: boolean + status: "oof" | "busy" + type?: string + reason?: string + adjustment_id: string + user_id: string + created_by: string + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `AbsenceStatus` + +Calendar status targeted by the absence adjustment. + +```ts +type AbsenceStatus = "oof" | "busy" +``` + +### `AbsenceType` + +Optional producer-defined reference stored with an absence adjustment. + +```ts +type AbsenceType = string +``` + +### `CreateAbsenceAdjustmentBody` + +```ts +type CreateAbsenceAdjustmentBody = { + from: string // date-time + to: string // date-time + absent: boolean + status: "oof" | "busy" + type?: string + reason?: string +} +``` + +### `PatchAbsenceAdjustmentBody` + +```ts +type PatchAbsenceAdjustmentBody = { + from?: string // date-time + to?: string // date-time + absent?: boolean + status?: "oof" | "busy" + type?: string + reason?: string +} +``` + +### `ExternalCalendar` + +```ts +type ExternalCalendar = { + provider: "outlook" | "google" + last_synced_at: string // date-time +} +``` + +### `WorkingHours` + +Recurring weekly working hours of a user. The absence of a record means the user is treated as always available. + +```ts +type WorkingHours = { + monday: Array<{ + start: string + end: string + }> + tuesday: Array<{ + start: string + end: string + }> + wednesday: Array<{ + start: string + end: string + }> + thursday: Array<{ + start: string + end: string + }> + friday: Array<{ + start: string + end: string + }> + saturday: Array<{ + start: string + end: string + }> + sunday: Array<{ + start: string + end: string + }> + timezone: string + user_id: string + updated_by: string + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `UpsertWorkingHoursBody` + +Full replacement of the working-hours record. All weekdays are required; an empty array means a day off. Users without a working-hours record are treated as always available. + +```ts +type UpsertWorkingHoursBody = { + monday: Array<{ + start: string + end: string + }> + tuesday: Array<{ + start: string + end: string + }> + wednesday: Array<{ + start: string + end: string + }> + thursday: Array<{ + start: string + end: string + }> + friday: Array<{ + start: string + end: string + }> + saturday: Array<{ + start: string + end: string + }> + sunday: Array<{ + start: string + end: string + }> + timezone?: string +} +``` + +### `TimeWindow` + +A wall-clock working window within a single day. + +```ts +type TimeWindow = { + start: string + end: string +} +``` + +### `Calendar` + +```ts +type Calendar = { + _id: string + _schema: "calendar" + _org: string + _title?: string + name: string + description?: string + color?: string + is_default: boolean + is_epilot_default: boolean + read_only: boolean + owner_email?: string // email + source: { + type: "native" | "synced" + provider?: "outlook" | "google" | null + provider_calendar_id?: string + last_synced_at?: string // date-time + } + _created_at?: string // date-time + _updated_at?: string // date-time +} +``` + +### `CalendarSource` + +```ts +type CalendarSource = { + type: "native" | "synced" + provider?: "outlook" | "google" | null + provider_calendar_id?: string + last_synced_at?: string // date-time +} +``` + +### `Provider` + +Null for native epilot calendars + +```ts +type Provider = "outlook" | "google" | null +``` + +### `CalendarCreateBody` + +```ts +type CalendarCreateBody = { + name: string + description?: string + color?: string +} +``` + +### `AddOutlookCalendarRequest` + +```ts +type AddOutlookCalendarRequest = { + provider_calendar_id: string + name?: string +} +``` + +### `AvailableOutlookCalendar` + +```ts +type AvailableOutlookCalendar = { + provider_calendar_id: string + name: string + color?: string + is_default?: boolean + can_edit?: boolean + owner?: string +} +``` + +### `CalendarPatchBody` + +```ts +type CalendarPatchBody = { + name?: string + description?: string + color?: string +} +``` + +### `CalendarEvent` + +```ts +type CalendarEvent = { + _id: string + _schema: "calendar_event" + _org: string + _title?: string + _tags?: string[] + calendar_id: string + event_type: "singleInstance" | "occurrence" | "exception" | "seriesMaster" + description?: string + start_time: string // date-time + end_time: string // date-time + timezone: string + is_all_day: boolean + location?: string + status: "free" | "tentative" | "busy" | "oof" | "workingElsewhere" | "unknown" + busy: boolean + is_cancelled: boolean + is_draft: boolean + sensitivity: "normal" | "personal" | "private" | "confidential" + importance: "low" | "normal" | "high" + is_online_meeting: boolean + online_meeting_url?: string // uri + web_link?: string // uri + response_status: "none" | "organizer" | "tentativelyAccepted" | "accepted" | "declined" | "notResponded" + organizer_email?: string // email + attendees?: Array<{ + email: string // email + name?: string + response: "none" | "organizer" | "tentativelyAccepted" | "accepted" | "declined" | "notResponded" + type: "required" | "optional" | "resource" + }> + metadata?: Record + is_recurring: boolean + series_master_id?: string + source: { + type: "native" | "synced" + provider?: "outlook" | "google" | null + provider_event_id?: string + provider_event_url?: string // uri + last_synced_at?: string // date-time + etag?: string + } + _created_at?: string // date-time + _updated_at?: string // date-time +} +``` + +### `EventType` + +```ts +type EventType = "singleInstance" | "occurrence" | "exception" | "seriesMaster" +``` + +### `EventStatus` + +Free/busy state derived from provider `showAs` + +```ts +type EventStatus = "free" | "tentative" | "busy" | "oof" | "workingElsewhere" | "unknown" +``` + +### `Sensitivity` + +```ts +type Sensitivity = "normal" | "personal" | "private" | "confidential" +``` + +### `Importance` + +```ts +type Importance = "low" | "normal" | "high" +``` + +### `ResponseStatus` + +Caller's response to the invite + +```ts +type ResponseStatus = "none" | "organizer" | "tentativelyAccepted" | "accepted" | "declined" | "notResponded" +``` + +### `Attendee` + +```ts +type Attendee = { + email: string // email + name?: string + response: "none" | "organizer" | "tentativelyAccepted" | "accepted" | "declined" | "notResponded" + type: "required" | "optional" | "resource" +} +``` + +### `EventSource` + +```ts +type EventSource = { + type: "native" | "synced" + provider?: "outlook" | "google" | null + provider_event_id?: string + provider_event_url?: string // uri + last_synced_at?: string // date-time + etag?: string +} +``` + +### `CalendarEventCreateBody` + +```ts +type CalendarEventCreateBody = { + calendar_id?: string + description?: string + start_time: string // date-time + end_time: string // date-time + timezone: string + is_all_day: boolean + location?: string + status: "free" | "tentative" | "busy" | "oof" | "workingElsewhere" | "unknown" + sensitivity: "normal" | "personal" | "private" | "confidential" + metadata?: Record + _title: string +} +``` + +### `CalendarEventPatchBody` + +```ts +type CalendarEventPatchBody = { + description?: string + start_time?: string // date-time + end_time?: string // date-time + timezone?: string + is_all_day?: boolean + location?: string + status?: "free" | "tentative" | "busy" | "oof" | "workingElsewhere" | "unknown" + is_cancelled?: boolean + sensitivity?: "normal" | "personal" | "private" | "confidential" + _title?: string +} +``` + +### `ShareEventBody` + +```ts +type ShareEventBody = { + user_id: string +} +``` diff --git a/docs/sdk/clients/chat.md b/docs/sdk/clients/chat.md new file mode 100644 index 00000000..0f8092d7 --- /dev/null +++ b/docs/sdk/clients/chat.md @@ -0,0 +1,1821 @@ +--- +title: "epilot Chat API" +description: "TypeScript SDK client for the epilot epilot Chat API: usage with @epilot/sdk, all operations and schemas." +--- + +# epilot Chat API + +- **Base URL:** `https://chat.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/chat](https://docs.epilot.io/api/chat) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.chat.listWebsiteChats(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/chat' + +const chatClient = getClient() +authorize(chatClient, () => '') +const { data } = await chatClient.listWebsiteChats(...) +``` + +## Operations + +**Website Chats** +- [`listWebsiteChats`](#listwebsitechats) +- [`createWebsiteChat`](#createwebsitechat) +- [`getWebsiteChat`](#getwebsitechat) +- [`updateWebsiteChat`](#updatewebsitechat) +- [`deleteWebsiteChat`](#deletewebsitechat) +- [`createWebsiteChatPreviewGrant`](#createwebsitechatpreviewgrant) + +**Other** +- [`getPublicWebsiteChat`](#getpublicwebsitechat) +- [`createPublicChatGrant`](#createpublicchatgrant) +- [`createAnonymousChatSession`](#createanonymouschatsession) +- [`sendAnonymousChatMessage`](#sendanonymouschatmessage) +- [`getChatVerification`](#getchatverification) +- [`startChatEmailVerification`](#startchatemailverification) +- [`verifyChatEmailCode`](#verifychatemailcode) +- [`cancelChatVerification`](#cancelchatverification) +- [`getChatPortalLogin`](#getchatportallogin) +- [`getChatPortalJourneyToken`](#getchatportaljourneytoken) +- [`startChatPortalLogin`](#startchatportallogin) +- [`verifyChatPortalLogin`](#verifychatportallogin) +- [`cancelChatPortalLogin`](#cancelchatportallogin) +- [`signOutChatCustomer`](#signoutchatcustomer) +- [`getChatAction`](#getchataction) +- [`startChatAction`](#startchataction) +- [`reportChatActionEvent`](#reportchatactionevent) +- [`submitChatAction`](#submitchataction) +- [`confirmChatAction`](#confirmchataction) +- [`cancelChatAction`](#cancelchataction) + +**Schemas** +- [`ListWebsiteChatsResponse`](#listwebsitechatsresponse) +- [`WebsiteChat`](#websitechat) +- [`WebsiteChatSettings`](#websitechatsettings) +- [`SelfServiceSettings`](#selfservicesettings) +- [`SelfServiceAction`](#selfserviceaction) +- [`WebsiteChatPreviewGrantRequest`](#websitechatpreviewgrantrequest) +- [`WebsiteChatPreviewGrant`](#websitechatpreviewgrant) +- [`Error`](#error) +- [`CreateWebsiteChatRequest`](#createwebsitechatrequest) +- [`UpdateWebsiteChatRequest`](#updatewebsitechatrequest) +- [`ActionRevision`](#actionrevision) +- [`ActionState`](#actionstate) +- [`VerificationState`](#verificationstate) +- [`PortalLoginState`](#portalloginstate) +- [`LoginMethod`](#loginmethod) +- [`AccessMethod`](#accessmethod) +- [`AccessTier`](#accesstier) +- [`CustomerAccess`](#customeraccess) +- [`StarterQuestions`](#starterquestions) +- [`PublicWebsiteChat`](#publicwebsitechat) +- [`WebsiteChatDesign`](#websitechatdesign) +- [`PublicEvent`](#publicevent) +- [`SelfServiceDirective`](#selfservicedirective) +- [`PublicChatError`](#publicchaterror) + +### `listWebsiteChats` + +`GET /v1/website-chats` + +```ts +const { data } = await client.listWebsiteChats({ + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "website_chats": [ + { + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "settings": { + "allowed_origins": ["string"], + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "portal": { + "portal_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + }, + "self_service": { + "actions": [ + { + "action": "submit_meter_reading", + "enabled": true, + "fulfilment": "in_chat", + "journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "url": "string", + "access": "anonymous", + "guidance": "string" + } + ] + } + }, + "website_chat_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "binding_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "version": 1, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "embed": { + "script_url": "https://example.com/path", + "chat_api_origin": "https://example.com/path", + "demo_url": "https://example.com/path" + } + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createWebsiteChat` + +`POST /v1/website-chats` + +```ts +const { data } = await client.createWebsiteChat( + null, + { + agent_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + settings: { + allowed_origins: ['string'], + default_locale: 'en', + design_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + authentication: { + email_code: { + email_template_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + }, + portal: { + portal_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + } + }, + self_service: { + actions: [ + { + action: 'submit_meter_reading', + enabled: true, + fulfilment: 'in_chat', + journey_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + url: 'string', + access: 'anonymous', + guidance: 'string' + } + ] + } + } + }, +) +``` + +
+Response + +```json +{ + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "settings": { + "allowed_origins": ["string"], + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "portal": { + "portal_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + }, + "self_service": { + "actions": [ + { + "action": "submit_meter_reading", + "enabled": true, + "fulfilment": "in_chat", + "journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "url": "string", + "access": "anonymous", + "guidance": "string" + } + ] + } + }, + "website_chat_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "binding_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "version": 1, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "embed": { + "script_url": "https://example.com/path", + "chat_api_origin": "https://example.com/path", + "demo_url": "https://example.com/path" + } +} +``` + +
+ +--- + +### `getWebsiteChat` + +`GET /v1/website-chats/{website_chat_id}` + +```ts +const { data } = await client.getWebsiteChat({ + website_chat_id: 'example', +}) +``` + +
+Response + +```json +{ + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "settings": { + "allowed_origins": ["string"], + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "portal": { + "portal_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + }, + "self_service": { + "actions": [ + { + "action": "submit_meter_reading", + "enabled": true, + "fulfilment": "in_chat", + "journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "url": "string", + "access": "anonymous", + "guidance": "string" + } + ] + } + }, + "website_chat_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "binding_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "version": 1, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "embed": { + "script_url": "https://example.com/path", + "chat_api_origin": "https://example.com/path", + "demo_url": "https://example.com/path" + } +} +``` + +
+ +--- + +### `updateWebsiteChat` + +`PUT /v1/website-chats/{website_chat_id}` + +```ts +const { data } = await client.updateWebsiteChat( + { + website_chat_id: 'example', + }, + { + agent_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + settings: { + allowed_origins: ['string'], + default_locale: 'en', + design_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + authentication: { + email_code: { + email_template_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + }, + portal: { + portal_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + } + }, + self_service: { + actions: [ + { + action: 'submit_meter_reading', + enabled: true, + fulfilment: 'in_chat', + journey_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + url: 'string', + access: 'anonymous', + guidance: 'string' + } + ] + } + }, + version: 1 + }, +) +``` + +
+Response + +```json +{ + "agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "settings": { + "allowed_origins": ["string"], + "default_locale": "en", + "design_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "authentication": { + "email_code": { + "email_template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "portal": { + "portal_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + } + }, + "self_service": { + "actions": [ + { + "action": "submit_meter_reading", + "enabled": true, + "fulfilment": "in_chat", + "journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "url": "string", + "access": "anonymous", + "guidance": "string" + } + ] + } + }, + "website_chat_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "binding_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "version": 1, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "embed": { + "script_url": "https://example.com/path", + "chat_api_origin": "https://example.com/path", + "demo_url": "https://example.com/path" + } +} +``` + +
+ +--- + +### `deleteWebsiteChat` + +`DELETE /v1/website-chats/{website_chat_id}` + +```ts +const { data } = await client.deleteWebsiteChat({ + website_chat_id: 'example', + version: 1, +}) +``` + +--- + +### `createWebsiteChatPreviewGrant` + +`POST /v1/website-chats/{website_chat_id}/preview-grant` + +```ts +const { data } = await client.createWebsiteChatPreviewGrant( + { + website_chat_id: 'example', + }, + { + design_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + demo_customer: false + }, +) +``` + +
+Response + +```json +{ + "grant": "string", + "expires_in": 0, + "frame_origin": "https://example.com/path", + "website_chat": { + "key": "string", + "assistant_name": { + "de": "string", + "en": "string" + }, + "greeting": { + "de": "string", + "en": "string" + }, + "defaultLocale": "en", + "login_methods": ["email_code"], + "starters": { + "de": ["string"], + "en": ["string"] + }, + "actions": { + "meter_reading": true, + "meter_reading_journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "design": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "last_modified_at": "string", + "style": { + "palette": { + "primary": "string", + "background": "string" + }, + "typography": { + "font": { + "font_family": "string" + } + }, + "shape": { + "border_radius": 0 + } + }, + "spark_theme": { + "accentColor": "string", + "backgroundColor": "string", + "fontBody": "string", + "fontHeading": "string", + "radius": "string", + "scaling": "string", + "spacing": "string", + "appearance": "string", + "neutralColor": "string", + "styleVariant": "string", + "labelPosition": "string", + "inputStyle": "string", + "inputColor": "string", + "cardVariant": "string", + "cardColor": "string", + "highContrast": true + } + }, + "locales": ["en"] + } +} +``` + +
+ +--- + +### `getPublicWebsiteChat` + +`GET /v1/website-chats/{website_chat_id}/configuration` + +```ts +const { data } = await client.getPublicWebsiteChat({ + website_chat_id: 'example', +}) +``` + +
+Response + +```json +{ + "key": "string", + "assistant_name": { + "de": "string", + "en": "string" + }, + "greeting": { + "de": "string", + "en": "string" + }, + "defaultLocale": "en", + "login_methods": ["email_code"], + "starters": { + "de": ["string"], + "en": ["string"] + }, + "actions": { + "meter_reading": true, + "meter_reading_journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "design": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "last_modified_at": "string", + "style": { + "palette": { + "primary": "string", + "background": "string" + }, + "typography": { + "font": { + "font_family": "string" + } + }, + "shape": { + "border_radius": 0 + } + }, + "spark_theme": { + "accentColor": "string", + "backgroundColor": "string", + "fontBody": "string", + "fontHeading": "string", + "radius": "string", + "scaling": "string", + "spacing": "string", + "appearance": "string", + "neutralColor": "string", + "styleVariant": "string", + "labelPosition": "string", + "inputStyle": "string", + "inputColor": "string", + "cardVariant": "string", + "cardColor": "string", + "highContrast": true + } + }, + "locales": ["en"] +} +``` + +
+ +--- + +### `createPublicChatGrant` + +`POST /v1/bootstrap` + +```ts +const { data } = await client.createPublicChatGrant( + null, + { + website_chat_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "grant": "string", + "expires_in": 60, + "frame_origin": "https://example.com/path" +} +``` + +
+ +--- + +### `createAnonymousChatSession` + +`POST /v1/sessions` + +```ts +const { data } = await client.createAnonymousChatSession( + null, + { + grant: 'string' + }, +) +``` + +
+Response + +```json +{ + "token": "string", + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "expires_at": 0, + "website_chat": { + "key": "string", + "assistant_name": { + "de": "string", + "en": "string" + }, + "greeting": { + "de": "string", + "en": "string" + }, + "defaultLocale": "en", + "login_methods": ["email_code"], + "starters": { + "de": ["string"], + "en": ["string"] + }, + "actions": { + "meter_reading": true, + "meter_reading_journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "design": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "last_modified_at": "string", + "style": { + "palette": { + "primary": "string", + "background": "string" + }, + "typography": { + "font": { + "font_family": "string" + } + }, + "shape": { + "border_radius": 0 + } + }, + "spark_theme": { + "accentColor": "string", + "backgroundColor": "string", + "fontBody": "string", + "fontHeading": "string", + "radius": "string", + "scaling": "string", + "spacing": "string", + "appearance": "string", + "neutralColor": "string", + "styleVariant": "string", + "labelPosition": "string", + "inputStyle": "string", + "inputColor": "string", + "cardVariant": "string", + "cardColor": "string", + "highContrast": true + } + }, + "locales": ["en"] + }, + "preview": true, + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `sendAnonymousChatMessage` + +`POST /v1/messages` + +```ts +const { data } = await client.sendAnonymousChatMessage( + null, + { + request_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + message: 'string', + locale: 'en', + simple_language: true + }, +) +``` + +--- + +### `getChatVerification` + +`GET /v1/verification` + +```ts +const { data } = await client.getChatVerification() +``` + +
+Response + +```json +{ + "available": true, + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "anonymous", + "challenge_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "code_expires_at": 0, + "resend_after": 0, + "email": "user@example.com", + "contact_resolution": "matched", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `startChatEmailVerification` + +`POST /v1/verification/email` + +```ts +const { data } = await client.startChatEmailVerification( + null, + { + request_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + email: 'user@example.com', + locale: 'en' + }, +) +``` + +
+Response + +```json +{ + "available": true, + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "anonymous", + "challenge_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "code_expires_at": 0, + "resend_after": 0, + "email": "user@example.com", + "contact_resolution": "matched", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `verifyChatEmailCode` + +`POST /v1/verification/code` + +```ts +const { data } = await client.verifyChatEmailCode( + null, + { + challenge_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + code: 'string' + }, +) +``` + +
+Response + +```json +{ + "available": true, + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "anonymous", + "challenge_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "code_expires_at": 0, + "resend_after": 0, + "email": "user@example.com", + "contact_resolution": "matched", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `cancelChatVerification` + +`POST /v1/verification/cancel` + +```ts +const { data } = await client.cancelChatVerification() +``` + +
+Response + +```json +{ + "available": true, + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "anonymous", + "challenge_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "code_expires_at": 0, + "resend_after": 0, + "email": "user@example.com", + "contact_resolution": "matched", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `getChatPortalLogin` + +`GET /v1/login/portal` + +```ts +const { data } = await client.getChatPortalLogin() +``` + +
+Response + +```json +{ + "available": true, + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "anonymous", + "challenge_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "code_expires_at": 0, + "attempts_left": 0, + "email": "user@example.com", + "contact_resolution": "matched", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `getChatPortalJourneyToken` + +`GET /v1/login/portal/journey-token` + +```ts +const { data } = await client.getChatPortalJourneyToken() +``` + +
+Response + +```json +{ + "id_token": "string", + "expires_at": 0 +} +``` + +
+ +--- + +### `startChatPortalLogin` + +`POST /v1/login/portal/start` + +```ts +const { data } = await client.startChatPortalLogin( + null, + { + request_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + email: 'user@example.com' + }, +) +``` + +
+Response + +```json +{ + "available": true, + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "anonymous", + "challenge_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "code_expires_at": 0, + "attempts_left": 0, + "email": "user@example.com", + "contact_resolution": "matched", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `verifyChatPortalLogin` + +`POST /v1/login/portal/verify` + +```ts +const { data } = await client.verifyChatPortalLogin( + null, + { + challenge_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + code: 'string' + }, +) +``` + +
+Response + +```json +{ + "available": true, + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "anonymous", + "challenge_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "code_expires_at": 0, + "attempts_left": 0, + "email": "user@example.com", + "contact_resolution": "matched", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `cancelChatPortalLogin` + +`POST /v1/login/portal/cancel` + +```ts +const { data } = await client.cancelChatPortalLogin() +``` + +
+Response + +```json +{ + "available": true, + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "anonymous", + "challenge_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "code_expires_at": 0, + "attempts_left": 0, + "email": "user@example.com", + "contact_resolution": "matched", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `signOutChatCustomer` + +`POST /v1/login/sign-out` + +```ts +const { data } = await client.signOutChatCustomer() +``` + +
+Response + +```json +{ + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "access": { + "tier": "anonymous", + "method": "email_code" + } +} +``` + +
+ +--- + +### `getChatAction` + +`GET /v1/actions` + +```ts +const { data } = await client.getChatAction() +``` + +
+Response + +```json +{ + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "none", + "action_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "revision": 0, + "options": [ + { + "meter_id": "string", + "counter_id": "string", + "meter_number": "string", + "label": "string", + "unit": "string", + "min_value": 0, + "max_value": 0 + } + ], + "values": { + "meter_id": "string", + "counter_id": "string", + "value": 0 + }, + "field_error": "VALUE_INVALID", + "receipt": { + "reference": "string", + "meter_number": "string", + "value": 0, + "unit": "string", + "submitted_at": "string" + }, + "reason": "NO_METERS" +} +``` + +
+ +--- + +### `startChatAction` + +`POST /v1/actions` + +```ts +const { data } = await client.startChatAction( + null, + { + request_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + action_type: 'submit_meter_reading' + }, +) +``` + +
+Response + +```json +{ + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "none", + "action_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "revision": 0, + "options": [ + { + "meter_id": "string", + "counter_id": "string", + "meter_number": "string", + "label": "string", + "unit": "string", + "min_value": 0, + "max_value": 0 + } + ], + "values": { + "meter_id": "string", + "counter_id": "string", + "value": 0 + }, + "field_error": "VALUE_INVALID", + "receipt": { + "reference": "string", + "meter_number": "string", + "value": 0, + "unit": "string", + "submitted_at": "string" + }, + "reason": "NO_METERS" +} +``` + +
+ +--- + +### `reportChatActionEvent` + +`POST /v1/actions/events` + +```ts +const { data } = await client.reportChatActionEvent( + null, + { + action: 'string', + event: 'journey_submitted' + }, +) +``` + +--- + +### `submitChatAction` + +`POST /v1/actions/{action_id}/submit` + +```ts +const { data } = await client.submitChatAction( + { + action_id: 'example', + }, + { + expected_revision: 1, + meter_id: 'string', + counter_id: 'string', + value: 0 + }, +) +``` + +
+Response + +```json +{ + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "none", + "action_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "revision": 0, + "options": [ + { + "meter_id": "string", + "counter_id": "string", + "meter_number": "string", + "label": "string", + "unit": "string", + "min_value": 0, + "max_value": 0 + } + ], + "values": { + "meter_id": "string", + "counter_id": "string", + "value": 0 + }, + "field_error": "VALUE_INVALID", + "receipt": { + "reference": "string", + "meter_number": "string", + "value": 0, + "unit": "string", + "submitted_at": "string" + }, + "reason": "NO_METERS" +} +``` + +
+ +--- + +### `confirmChatAction` + +`POST /v1/actions/{action_id}/confirm` + +```ts +const { data } = await client.confirmChatAction( + { + action_id: 'example', + }, + { + expected_revision: 1 + }, +) +``` + +
+Response + +```json +{ + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "none", + "action_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "revision": 0, + "options": [ + { + "meter_id": "string", + "counter_id": "string", + "meter_number": "string", + "label": "string", + "unit": "string", + "min_value": 0, + "max_value": 0 + } + ], + "values": { + "meter_id": "string", + "counter_id": "string", + "value": 0 + }, + "field_error": "VALUE_INVALID", + "receipt": { + "reference": "string", + "meter_number": "string", + "value": 0, + "unit": "string", + "submitted_at": "string" + }, + "reason": "NO_METERS" +} +``` + +
+ +--- + +### `cancelChatAction` + +`POST /v1/actions/{action_id}/cancel` + +```ts +const { data } = await client.cancelChatAction( + { + action_id: 'example', + }, + { + expected_revision: 1 + }, +) +``` + +
+Response + +```json +{ + "conversation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "none", + "action_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "revision": 0, + "options": [ + { + "meter_id": "string", + "counter_id": "string", + "meter_number": "string", + "label": "string", + "unit": "string", + "min_value": 0, + "max_value": 0 + } + ], + "values": { + "meter_id": "string", + "counter_id": "string", + "value": 0 + }, + "field_error": "VALUE_INVALID", + "receipt": { + "reference": "string", + "meter_number": "string", + "value": 0, + "unit": "string", + "submitted_at": "string" + }, + "reason": "NO_METERS" +} +``` + +
+ +--- + +## Schemas + +### `ListWebsiteChatsResponse` + +```ts +type ListWebsiteChatsResponse = { + website_chats: Array<{ + agent_id: string // uuid + settings: { + allowed_origins: { ... } + default_locale: { ... } + design_id?: { ... } + authentication?: { ... } + self_service?: { ... } + } + website_chat_id: string // uuid + org_id: string + binding_id: string // uuid + version: number + created_at: string // date-time + updated_at: string // date-time + embed: { + script_url: { ... } + chat_api_origin: { ... } + demo_url: { ... } + } + }> + next_cursor?: string +} +``` + +### `WebsiteChat` + +```ts +type WebsiteChat = { + agent_id: string // uuid + settings: { + allowed_origins: string[] + default_locale: "en" | "de" + design_id?: string // uuid + authentication?: { + email_code?: { ... } + portal?: { ... } + } + self_service?: { + actions: { ... } + } + } + website_chat_id: string // uuid + org_id: string + binding_id: string // uuid + version: number + created_at: string // date-time + updated_at: string // date-time + embed: { + script_url: string // uri + chat_api_origin: string // uri + demo_url: string // uri + } +} +``` + +### `WebsiteChatSettings` + +```ts +type WebsiteChatSettings = { + allowed_origins: string[] + default_locale: "en" | "de" + design_id?: string // uuid + authentication?: { + email_code?: { + email_template_id?: { ... } + } + portal?: { + portal_id: { ... } + } + } + self_service?: { + actions: Array<{ + action: { ... } + enabled: { ... } + fulfilment: { ... } + journey_id?: { ... } + url?: { ... } + access: { ... } + guidance?: { ... } + }> + } +} +``` + +### `SelfServiceSettings` + +Self-service actions customers can start in this Website Chat. On update, the list is replaced as a whole; null removes all actions. + +```ts +type SelfServiceSettings = { + actions: Array<{ + action: "submit_meter_reading" | "change_installment_rate" | "update_payment_method" | "change_billing_address" | "update_customer_details" | "change_tariff" | "report_move" | "terminate_contract" + enabled: boolean + fulfilment: "in_chat" | "journey" | "link" + journey_id?: string // uuid + url?: string + access: "anonymous" | "identified" | "verified" + guidance?: string + }> +} +``` + +### `SelfServiceAction` + +How a self-service action is done and who can start it. A journey needs journey_id, a link needs url. in_chat is only available for submit_meter_reading and requires a verified customer. + +```ts +type SelfServiceAction = { + action: "submit_meter_reading" | "change_installment_rate" | "update_payment_method" | "change_billing_address" | "update_customer_details" | "change_tariff" | "report_move" | "terminate_contract" + enabled: boolean + fulfilment: "in_chat" | "journey" | "link" + journey_id?: string // uuid + url?: string + access: "anonymous" | "identified" | "verified" + guidance?: string +} +``` + +### `WebsiteChatPreviewGrantRequest` + +```ts +type WebsiteChatPreviewGrantRequest = { + design_id?: string // uuid + demo_customer?: boolean +} +``` + +### `WebsiteChatPreviewGrant` + +```ts +type WebsiteChatPreviewGrant = { + grant: string + expires_in: number + frame_origin: string // uri + website_chat: { + key: string + assistant_name?: { + de?: { ... } + en?: { ... } + } + greeting?: { + de?: { ... } + en?: { ... } + } + defaultLocale: "en" | "de" + login_methods: "email_code" | "portal_login"[] + starters?: { + de?: { ... } + en?: { ... } + } + actions?: { + meter_reading?: { ... } + meter_reading_journey_id?: { ... } + } + design?: { + id: { ... } + last_modified_at?: { ... } + style?: { ... } + spark_theme?: { ... } + } + locales: "en" | "de"[] + } +} +``` + +### `Error` + +```ts +type Error = { + error?: string + message?: string + details?: object +} +``` + +### `CreateWebsiteChatRequest` + +```ts +type CreateWebsiteChatRequest = { + agent_id: string // uuid + settings: { + allowed_origins: string[] + default_locale: "en" | "de" + design_id?: string // uuid + authentication?: { + email_code?: { ... } + portal?: { ... } + } + self_service?: { + actions: { ... } + } + } +} +``` + +### `UpdateWebsiteChatRequest` + +```ts +type UpdateWebsiteChatRequest = { + agent_id?: string // uuid + settings?: { + allowed_origins: string[] + default_locale: "en" | "de" + design_id?: string // uuid + authentication?: { + email_code?: { ... } + portal?: { ... } + } + self_service?: { + actions: { ... } + } + } + version: number +} +``` + +### `ActionRevision` + +```ts +type ActionRevision = { + expected_revision: number +} +``` + +### `ActionState` + +```ts +type ActionState = { + conversation_id: string // uuid + status: "none" | "needs_input" | "needs_confirmation" | "executing" | "completed" | "pending" | "rejected" | "handoff" + action_id?: string // uuid + revision?: number + options?: Array<{ + meter_id: string + counter_id: string + meter_number: string + label: string + unit: string + min_value?: number + max_value?: number + }> + values?: { + meter_id: string + counter_id: string + value: number + } + field_error?: "VALUE_INVALID" | "VALUE_OUT_OF_RANGE" | "TARGET_UNAVAILABLE" + receipt?: { + reference: string + meter_number: string + value: number + unit: string + submitted_at: string + } + reason?: "NO_METERS" | "SUBMISSION_REJECTED" | "SUBMISSION_UNCERTAIN" +} +``` + +### `VerificationState` + +```ts +type VerificationState = { + available: boolean + conversation_id: string // uuid + status: "anonymous" | "sending" | "pending" | "verified" + challenge_id?: string // uuid + code_expires_at?: number + resend_after?: number + email?: string // email + contact_resolution?: "matched" | "ambiguous" | "not_found" + access: { + tier: "anonymous" | "identified" | "verified" + method?: "email_code" | "portal_login" | "demo" + } +} +``` + +### `PortalLoginState` + +```ts +type PortalLoginState = { + available: boolean + conversation_id: string // uuid + status: "anonymous" | "pending" | "verified" + challenge_id?: string // uuid + code_expires_at?: number + attempts_left?: number + email?: string // email + contact_resolution?: "matched" | "not_found" + access: { + tier: "anonymous" | "identified" | "verified" + method?: "email_code" | "portal_login" | "demo" + } +} +``` + +### `LoginMethod` + +How a customer can log in or verify themselves in the chat. + +```ts +type LoginMethod = "email_code" | "portal_login" +``` + +### `AccessMethod` + +How the current customer identity was established. demo is the fictional, verified +customer of an Agent Builder preview; it is never a login method. + + +```ts +type AccessMethod = "email_code" | "portal_login" | "demo" +``` + +### `AccessTier` + +anonymous: no customer identity. identified: the Contact is known but ownership +is not proven. verified: ownership is proven (an email code or a portal login), or the +demo customer of an Agent Builder preview. + + +```ts +type AccessTier = "anonymous" | "identified" | "verified" +``` + +### `CustomerAccess` + +```ts +type CustomerAccess = { + tier: "anonymous" | "identified" | "verified" + method?: "email_code" | "portal_login" | "demo" +} +``` + +### `StarterQuestions` + +At most six. (No maxItems, which generated clients turn into fixed-length tuples.) + +```ts +type StarterQuestions = string[] +``` + +### `PublicWebsiteChat` + +```ts +type PublicWebsiteChat = { + key: string + assistant_name?: { + de?: string + en?: string + } + greeting?: { + de?: string + en?: string + } + defaultLocale: "en" | "de" + login_methods: "email_code" | "portal_login"[] + starters?: { + de?: string[] + en?: string[] + } + actions?: { + meter_reading?: boolean + meter_reading_journey_id?: string // uuid + } + design?: { + id: string // uuid + last_modified_at?: string + style?: { + palette?: { ... } + typography?: { ... } + shape?: { ... } + } + spark_theme?: { + accentColor?: { ... } + backgroundColor?: { ... } + fontBody?: { ... } + fontHeading?: { ... } + radius?: { ... } + scaling?: { ... } + spacing?: { ... } + appearance?: { ... } + neutralColor?: { ... } + styleVariant?: { ... } + labelPosition?: { ... } + inputStyle?: { ... } + inputColor?: { ... } + cardVariant?: { ... } + cardColor?: { ... } + highContrast?: { ... } + } + } + locales: "en" | "de"[] +} +``` + +### `WebsiteChatDesign` + +```ts +type WebsiteChatDesign = { + id: string // uuid + last_modified_at?: string + style?: { + palette?: { + primary?: { ... } + background?: { ... } + } + typography?: { + font?: { ... } + } + shape?: { + border_radius?: { ... } + } + } + spark_theme?: { + accentColor?: string + backgroundColor?: string + fontBody?: string + fontHeading?: string + radius?: string + scaling?: string + spacing?: string + appearance?: string + neutralColor?: string + styleVariant?: string + labelPosition?: string + inputStyle?: string + inputColor?: string + cardVariant?: string + cardColor?: string + highContrast?: boolean + } +} +``` + +### `PublicEvent` + +JSON payload of one SSE data frame from sendAnonymousChatMessage. + +```ts +type PublicEvent = { + type: "delta" + text: string + request_id: string // uuid +} | { + type: "complete" + text: string + request_id: string // uuid +} | { + type: "error" + code: "UNAVAILABLE" + request_id: string // uuid +} | { + type: "action" + action: { + action: string + fulfilment: "in_chat" | "journey" | "link" + journey_id?: string // uuid + url?: string + access: "anonymous" | "identified" | "verified" + } + request_id: string // uuid +} +``` + +### `SelfServiceDirective` + +```ts +type SelfServiceDirective = { + action: string + fulfilment: "in_chat" | "journey" | "link" + journey_id?: string // uuid + url?: string + access: "anonymous" | "identified" | "verified" +} +``` + +### `PublicChatError` + +```ts +type PublicChatError = { + code: "INVALID_VERIFICATION_CODE" | "VERIFICATION_EXPIRED" | "VERIFICATION_CONFLICT" | "VERIFICATION_DISABLED" | "VERIFICATION_UNAVAILABLE" | "IDENTITY_CHANGED" | "INVALID_REQUEST" | "ORIGIN_DENIED" | "NOT_FOUND" | "INVALID_GRANT" | "SESSION_EXPIRED" | "RATE_LIMITED" | "SESSION_LIMIT" | "USAGE_LIMIT" | "REQUEST_CONFLICT" | "IN_PROGRESS" | "UNAVAILABLE" | "TEMPORARILY_UNAVAILABLE" | "IDENTITY_REQUIRED" | "ACTION_UNAVAILABLE" | "ACTION_CONFLICT" | "ACTION_TARGET_DENIED" | "INVALID_LOGIN_CODE" | "LOGIN_EXPIRED" | "LOGIN_DISABLED" | "LOGIN_UNAVAILABLE" | "LOGIN_CONFLICT" | "LOGIN_REJECTED" + attempts_left?: number +} +``` diff --git a/docs/sdk/clients/configuration-hub.md b/docs/sdk/clients/configuration-hub.md new file mode 100644 index 00000000..46ddb507 --- /dev/null +++ b/docs/sdk/clients/configuration-hub.md @@ -0,0 +1,3957 @@ +--- +title: "Configuration Hub API" +description: "TypeScript SDK client for the epilot Configuration Hub API: usage with @epilot/sdk, all operations and schemas." +--- + +# Configuration Hub API + +- **Base URL:** `https://configuration-hub.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/configuration-hub](https://docs.epilot.io/api/configuration-hub) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.configurationHub.listConfigTypes(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/configuration-hub' + +const configurationHubClient = getClient() +authorize(configurationHubClient, () => '') +const { data } = await configurationHubClient.listConfigTypes(...) +``` + +## Operations + +**Configs** +- [`listConfigTypes`](#listconfigtypes) +- [`listConfigs`](#listconfigs) +- [`getConfigDependencies`](#getconfigdependencies) +- [`getConfigUsedBy`](#getconfigusedby) +- [`getIndex`](#getindex) +- [`rebuildIndex`](#rebuildindex) +- [`getConfigInventory`](#getconfiginventory) + +**Health** +- [`startHealthScan`](#starthealthscan) +- [`getHealthReport`](#gethealthreport) +- [`requestHealthCoverage`](#requesthealthcoverage) +- [`startHealthCleanup`](#starthealthcleanup) +- [`setHealthFindingsIgnored`](#sethealthfindingsignored) + +**Compare** +- [`compareConfigs`](#compareconfigs) +- [`suggestMatches`](#suggestmatches) +- [`confirmLineage`](#confirmlineage) +- [`breakLineage`](#breaklineage) + +**Sync** +- [`createSyncJob`](#createsyncjob) +- [`listSyncJobs`](#listsyncjobs) +- [`getSyncJob`](#getsyncjob) +- [`getSyncJobHealth`](#getsyncjobhealth) +- [`runSyncJobHealth`](#runsyncjobhealth) +- [`retrySyncJob`](#retrysyncjob) +- [`planSyncJobRetry`](#plansyncjobretry) +- [`cancelSyncJob`](#cancelsyncjob) +- [`listSyncJobEvents`](#listsyncjobevents) +- [`listSyncJobResources`](#listsyncjobresources) +- [`getSyncPlan`](#getsyncplan) +- [`listSyncPlanDiffs`](#listsyncplandiffs) +- [`getSyncPlanDiff`](#getsyncplandiff) +- [`applySyncPlan`](#applysyncplan) +- [`replanSyncPlan`](#replansyncplan) + +**Delete** +- [`createDeleteJob`](#createdeletejob) +- [`listDeleteJobs`](#listdeletejobs) +- [`getDeleteJob`](#getdeletejob) +- [`listDeleteJobResources`](#listdeletejobresources) + +**Previews** +- [`createPreview`](#createpreview) +- [`listPreviews`](#listpreviews) +- [`getPreview`](#getpreview) + +**Schemas** +- [`ResourceType`](#resourcetype) +- [`ConfigTypeInfo`](#configtypeinfo) +- [`ConfigNode`](#confignode) +- [`ConfigListResponse`](#configlistresponse) +- [`ConfigDependenciesResponse`](#configdependenciesresponse) +- [`IndexRebuildResponse`](#indexrebuildresponse) +- [`HealthScanStartResponse`](#healthscanstartresponse) +- [`HealthFinding`](#healthfinding) +- [`HealthReportResponse`](#healthreportresponse) +- [`IndexStatusResponse`](#indexstatusresponse) +- [`CompareRequest`](#comparerequest) +- [`CompareLineage`](#comparelineage) +- [`CompareRow`](#comparerow) +- [`CompareCounts`](#comparecounts) +- [`CompareResponse`](#compareresponse) +- [`SuggestMatchesRequest`](#suggestmatchesrequest) +- [`MatchSuggestion`](#matchsuggestion) +- [`SuggestMatchesResponse`](#suggestmatchesresponse) +- [`ConfirmLineageRequest`](#confirmlineagerequest) +- [`LineageEntryResponse`](#lineageentryresponse) +- [`BreakLineageResponse`](#breaklineageresponse) +- [`ErrorResponse`](#errorresponse) +- [`SyncJobStatus`](#syncjobstatus) +- [`SyncDirection`](#syncdirection) +- [`SyncPhase`](#syncphase) +- [`SyncJobResourceStatus`](#syncjobresourcestatus) +- [`SyncJobRequest`](#syncjobrequest) +- [`SyncJobResourceRef`](#syncjobresourceref) +- [`SyncJobRetryPlanRequest`](#syncjobretryplanrequest) +- [`SyncJobRetryPlan`](#syncjobretryplan) +- [`SyncJobRetryErrorResponse`](#syncjobretryerrorresponse) +- [`SyncJobRetryRequest`](#syncjobretryrequest) +- [`SyncJobCounts`](#syncjobcounts) +- [`SyncJobEvent`](#syncjobevent) +- [`SyncJobEventDependency`](#syncjobeventdependency) +- [`SyncDependencyReason`](#syncdependencyreason) +- [`SyncRequiredBy`](#syncrequiredby) +- [`SyncJobEventListResponse`](#syncjobeventlistresponse) +- [`SyncJobBatch`](#syncjobbatch) +- [`SyncJobHealthStatus`](#syncjobhealthstatus) +- [`HealthSeverityCounts`](#healthseveritycounts) +- [`SyncJobHealthCheck`](#syncjobhealthcheck) +- [`SyncJobHealth`](#syncjobhealth) +- [`SyncJob`](#syncjob) +- [`SyncJobListResponse`](#syncjoblistresponse) +- [`SyncJobResource`](#syncjobresource) +- [`SyncJobResourceListResponse`](#syncjobresourcelistresponse) +- [`SyncPlanAction`](#syncplanaction) +- [`SyncPlanMatch`](#syncplanmatch) +- [`SyncPlanDiffStatus`](#syncplandiffstatus) +- [`SyncResourcePlan`](#syncresourceplan) +- [`SyncPlanCounts`](#syncplancounts) +- [`SyncPlan`](#syncplan) +- [`SyncPlanChange`](#syncplanchange) +- [`SyncPlanDiff`](#syncplandiff) +- [`SyncPlanDiffListResponse`](#syncplandifflistresponse) +- [`SyncPlanApplyRequest`](#syncplanapplyrequest) +- [`SyncPlanReplanRequest`](#syncplanreplanrequest) +- [`SyncPlanMissingDependency`](#syncplanmissingdependency) +- [`SyncPlanApplyErrorResponse`](#syncplanapplyerrorresponse) +- [`DeleteJobStatus`](#deletejobstatus) +- [`DeleteJobResourceStatus`](#deletejobresourcestatus) +- [`DeleteJobCounts`](#deletejobcounts) +- [`DeleteJobRequest`](#deletejobrequest) +- [`DeleteJob`](#deletejob) +- [`DeleteJobListResponse`](#deletejoblistresponse) +- [`DeleteJobResource`](#deletejobresource) +- [`DeleteJobResourceListResponse`](#deletejobresourcelistresponse) +- [`SnapshotInventoryItem`](#snapshotinventoryitem) +- [`SnapshotInventorySkippedType`](#snapshotinventoryskippedtype) +- [`ConfigInventoryResponse`](#configinventoryresponse) +- [`CreatePreviewRequest`](#createpreviewrequest) +- [`PreviewStatus`](#previewstatus) +- [`Preview`](#preview) + +### `listConfigTypes` + +Returns the static list of available configuration types with display metadata. +This is a cheap call — no fan-out to downstream APIs. Returns all known types +with labels and icons. The frontend should + +`GET /v1/configs/types` + +```ts +const { data } = await client.listConfigTypes() +``` + +
+Response + +```json +{ + "results": [ + { + "type": "journey", + "label": "Journeys", + "icon": "Route", + "source_api": "https://journey.sls.epilot.io", + "sdk_client": "@epilot/sdk/journey", + "deletable": true + } + ] +} +``` + +
+ +--- + +### `listConfigs` + +List configs of a given type with pagination. Returns summary metadata only +(not full payloads). The frontend calls this per type folder when expanding. + +`GET /v1/configs/{type}` + +```ts +const { data } = await client.listConfigs({ + type: 'example', + cursor: 'example', + size: 1, + q: 'example', + updated_after: 'example', + updated_before: 'example', + purposes: 'example', + blueprint_ids: 'example', + sort: 'example', + active_only: true, +}) +``` + +
+Response + +```json +{ + "type": "journey", + "label": "string", + "icon": "string", + "total": 0, + "next_cursor": "string", + "results": [ + { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + } + ] +} +``` + +
+ +--- + +### `getConfigDependencies` + +Get configs that are referenced by the given config. +Used to render children when expanding a config node in the tree. + +`GET /v1/configs/{type}/{id}/dependencies` + +```ts +const { data } = await client.getConfigDependencies({ + type: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', + cursor: 'example', + size: 1, +}) +``` + +
+Response + +```json +{ + "total": 0, + "next_cursor": "string", + "results": [ + { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + } + ] +} +``` + +
+ +--- + +### `getConfigUsedBy` + +Get configs that reference the given config (reverse dependencies). +Scans the indexed config items for references to this config's ID or aliases. + +`GET /v1/configs/{type}/{id}/used_by` + +```ts +const { data } = await client.getConfigUsedBy({ + type: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "total": 0, + "next_cursor": "string", + "results": [ + { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + } + ] +} +``` + +
+ +--- + +### `getIndex` + +Return the current index build state for the caller's organization. +Clients poll this to decide whether to show a "building" indicator +and when to refetch data. + +`GET /v1/configs/index` + +```ts +const { data } = await client.getIndex() +``` + +
+Response + +```json +{ + "status": "missing", + "org_id": "string", + "last_built_at": "1970-01-01T00:00:00.000Z", + "total_items": 0, + "build_duration_ms": 0 +} +``` + +
+ +--- + +### `startHealthScan` + +Start an asynchronous org health scan — fire-and-forget, mirrors +`rebuildIndex`. The scan walks the indexed configs, fetches each +payload, extracts field-path-known references (journey→mapping, +automa + +`POST /v1/configs/health:scan` + +```ts +const { data } = await client.startHealthScan() +``` + +--- + +### `getHealthReport` + +Return the caller org's current health report: scan status, summary +counts by severity, new/resolved deltas vs the previous scan, and the +full finding list (errors first, then most recently appeared). + +`GET /v1/configs/health` + +```ts +const { data } = await client.getHealthReport() +``` + +
+Response + +```json +{ + "status": "missing", + "last_scanned_at": "1970-01-01T00:00:00.000Z", + "scan_duration_ms": 0, + "scanned_configs": 0, + "scanned_by_type": {}, + "counts": { + "error": 0, + "warning": 0, + "info": 0 + }, + "new_since_previous": 0, + "resolved_since_previous": 0, + "last_cleanup_at": "1970-01-01T00:00:00.000Z", + "cleaned_count": 0, + "history": [ + { + "scanned_at": "1970-01-01T00:00:00.000Z", + "clean": 0, + "total": 0 + } + ], + "error": "string", + "findings": [ + { + "id": "string", + "code": "broken_reference", + "severity": "error", + "source_type": "string", + "source_id": "string", + "source_title": "string", + "message": "string", + "message_key": "string", + "message_params": {}, + "ref_type": "string", + "ref_id": "string", + "ref_title": "string", + "source_link": "string", + "ref_link": "string", + "owner_type": "string", + "owner_id": "string", + "owner_title": "string", + "owner_link": "string", + "path": "string", + "cleanable": true, + "ignored": true, + "ignored_at": "1970-01-01T00:00:00.000Z", + "ignored_by": "string", + "ignored_reason": "string", + "first_seen": "1970-01-01T00:00:00.000Z", + "last_seen": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `requestHealthCoverage` + +Send a request for configuration the health check does not cover yet. +Posted to the #epilot-org-health Slack channel together with the calling +org and user. Returns 503 when no webhook is configured f + +`POST /v1/configs/health:coverage-request` + +```ts +const { data } = await client.requestHealthCoverage( + null, + { + message: 'string' + }, +) +``` + +--- + +### `startHealthCleanup` + +Remove references that are already inert: dangling `$relation` entries +on products and prices (a price selling with a deleted tax, a product +linking a deleted price, …), automation triggers pointed at + +`POST /v1/configs/health:cleanup` + +```ts +const { data } = await client.startHealthCleanup( + null, + { + finding_ids: ['string'] + }, +) +``` + +--- + +### `setHealthFindingsIgnored` + +Acknowledge findings as intentional (or undo that). An ignored +finding is excluded from the headline score and the default +breakdown, but stays visible under the Ignored filter and can be +un-ignored a + +`POST /v1/configs/health:ignore` + +```ts +const { data } = await client.setHealthFindingsIgnored( + null, + { + finding_ids: ['string'], + ignored: true, + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "status": "ok", + "count": 0 +} +``` + +
+ +--- + +### `compareConfigs` + +Compare the caller org's configs of a single type against another +(source) org, side by side. Rows are paired via the lineage registry in +both sync directions (caller imported from source, or source i + +`POST /v1/configs/compare` + +```ts +const { data } = await client.compareConfigs( + null, + { + source_org_id: 'string', + source_auth_token: 'string', + type: 'journey' + }, +) +``` + +
+Response + +```json +{ + "type": "journey", + "label": "string", + "icon": "string", + "rows": [ + { + "match_status": "matched", + "current": { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + }, + "source": { + "type": "journey", + "id": "string", + "title": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "tags": ["string"], + "aliases": ["string"], + "purposes": ["string"], + "link": "https://example.com/path", + "active": true, + "blueprints": [ + { + "id": "string", + "title": "string" + } + ], + "metadata": {} + }, + "lineage": { + "direction": "pull", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "last_sync_job_id": "string", + "origin": "string" + } + } + ], + "counts": { + "matched": 0, + "only_current": 0, + "only_source": 0 + } +} +``` + +
+ +--- + +### `suggestMatches` + +Run the sync-grade heuristic match (`lookupByHeuristic` — name / slug / +unique key) for a batch of source-org configs that have no lineage +entry, and return candidate counterparts in the caller's org. + +`POST /v1/configs/compare/suggestions` + +```ts +const { data } = await client.suggestMatches( + null, + { + source_org_id: 'string', + source_auth_token: 'string', + type: 'journey', + source_ids: ['string'] + }, +) +``` + +
+Response + +```json +{ + "type": "journey", + "suggestions": [ + { + "source_id": "string", + "candidate": { + "id": "string", + "title": "string" + } + } + ] +} +``` + +
+ +--- + +### `confirmLineage` + +Persist a lineage entry pairing a source-org config with a config in +the caller's org — used to confirm a heuristic suggestion from the +Compare view. Writes to the caller org's lineage partition (call + +`POST /v1/configs/lineage` + +```ts +const { data } = await client.confirmLineage( + null, + { + type: 'journey', + source_org_id: 'string', + source_id: 'string', + target_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "type": "journey", + "target_org_id": "string", + "source_org_id": "string", + "source_id": "string", + "target_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "origin": "string" +} +``` + +
+ +--- + +### `breakLineage` + +Delete a lineage entry from the caller org's partition (caller as sync +target), identified by `type` + `source_id`. Used to break a wrong or +stale match from the Compare view. Note: a future sync can + +`DELETE /v1/configs/lineage` + +```ts +const { data } = await client.breakLineage({ + type: 'example', + source_id: 'example', +}) +``` + +
+Response + +```json +{ + "deleted": true +} +``` + +
+ +--- + +### `createSyncJob` + +Create a new cross-org sync job. The job is enqueued for asynchronous execution +by the worker Lambda; the response returns the persisted job header with status +`pending`. + +`POST /v1/configs/sync-jobs` + +```ts +const { data } = await client.createSyncJob( + null, + { + source_org_id: 'string', + target_org_id: 'string', + target_auth_token: 'string', + name: 'string', + dry_run: false, + include_dependencies: true, + sync_portal_widgets: true, + resources: [ + { + type: 'string', + id: 'string' + } + ] + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": { + "outcome": "added", + "reason": "typed_reference", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string" + }, + "depth": 0 + } + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `listSyncJobs` + +List sync jobs scoped to the caller's organization, paginated with an opaque +cursor. Defaults to most-recent first. + +`GET /v1/configs/sync-jobs` + +```ts +const { data } = await client.listSyncJobs({ + cursor: 'example', + size: 1, + status: 'example', +}) +``` + +
+Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": { + "outcome": "added", + "reason": "typed_reference", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string" + }, + "depth": 0 + } + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] + } + ] +} +``` + +
+ +--- + +### `getSyncJob` + +Fetch a single sync job by ID. Returns the job header, counts summary, +current phase pointer, and the latest activity events. Frontend polls this +endpoint with a ramping interval. + +`GET /v1/configs/sync-jobs/{id}` + +```ts +const { data } = await client.getSyncJob({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": { + "outcome": "added", + "reason": "typed_reference", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string" + }, + "depth": 0 + } + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `getSyncJobHealth` + +Targeted health check of an applied (non-dry-run) sync job. When the job +reaches its terminal status, the target org is scanned asynchronously +for the configs the job wrote — rows with status `created + +`GET /v1/configs/sync-jobs/{id}/health` + +```ts +const { data } = await client.getSyncJobHealth({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "status": "pending", + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "scanned": 0, + "counts": { + "error": 0, + "warning": 0, + "info": 0 + }, + "error": "string", + "findings": [ + { + "id": "string", + "code": "broken_reference", + "severity": "error", + "source_type": "string", + "source_id": "string", + "source_title": "string", + "message": "string", + "message_key": "string", + "message_params": {}, + "ref_type": "string", + "ref_id": "string", + "ref_title": "string", + "source_link": "string", + "ref_link": "string", + "owner_type": "string", + "owner_id": "string", + "owner_title": "string", + "owner_link": "string", + "path": "string", + "cleanable": true, + "ignored": true, + "ignored_at": "1970-01-01T00:00:00.000Z", + "ignored_by": "string", + "ignored_reason": "string", + "first_seen": "1970-01-01T00:00:00.000Z", + "last_seen": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `runSyncJobHealth` + +Start the targeted health check of a finished, applied sync job again: +for jobs that finished before checks existed (`not_run`), checks that +failed or got stuck, or to re-check after fixing something. + +`POST /v1/configs/sync-jobs/{id}/health:run` + +```ts +const { data } = await client.runSyncJobHealth({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `retrySyncJob` + +Retry the unresolved resources from a prior sync job: `failed` rows, plus +rows the original run left at `pending`/`in_progress` because it stopped +early. Creates a new job whose scope is that `(type, + +`POST /v1/configs/sync-jobs/{id}/retry` + +```ts +const { data } = await client.retrySyncJob( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + target_auth_token: 'string', + resources: [ + { + type: 'string', + source_id: 'string' + } + ], + payload_overrides: {} + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": { + "outcome": "added", + "reason": "typed_reference", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string" + }, + "depth": 0 + } + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `planSyncJobRetry` + +Preview what `retrySyncJob` would re-run for the same `resources`, +without creating a job: the selected rows and the unresolved rows they +depend on. Read-only; needs no target token. + +`POST /v1/configs/sync-jobs/{id}/retry-plan` + +```ts +const { data } = await client.planSyncJobRetry( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + resources: [ + { + type: 'string', + source_id: 'string' + } + ] + }, +) +``` + +
+Response + +```json +{ + "selected": [ + { + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string", + "reason": "typed_reference" + }, + "status": "pending", + "phase": "phase_0", + "attempt": 0, + "error": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "source_link": "string", + "target_link": "string", + "plan": { + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changed_paths": ["string"], + "note": "string", + "depends_on": [ + { + "type": "string", + "source_id": "string" + } + ] + }, + "excluded_from_apply": "unchanged" + } + ], + "added_dependencies": [ + { + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string", + "reason": "typed_reference" + }, + "status": "pending", + "phase": "phase_0", + "attempt": 0, + "error": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "source_link": "string", + "target_link": "string", + "plan": { + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changed_paths": ["string"], + "note": "string", + "depends_on": [ + { + "type": "string", + "source_id": "string" + } + ] + }, + "excluded_from_apply": "unchanged" + } + ], + "dependency_resolution": "exact" +} +``` + +
+ +--- + +### `cancelSyncJob` + +Cancel a running sync job. Marks the job `cancelled` with a `finished_at` +so it stops being reported as in-flight, and the worker stops at its next +batch boundary — phases re-read the job status and a + +`POST /v1/configs/sync-jobs/{id}/cancel` + +```ts +const { data } = await client.cancelSyncJob({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": { + "outcome": "added", + "reason": "typed_reference", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string" + }, + "depth": 0 + } + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `listSyncJobEvents` + +Full activity log of a sync job, latest first: one event per resource +status change. Paginate older events with `next_cursor`, or poll for +new ones with `after` (the newest event id the client holds). + +`GET /v1/configs/sync-jobs/{id}/events` + +```ts +const { data } = await client.listSyncJobEvents({ + id: '123e4567-e89b-12d3-a456-426614174000', + cursor: 'example', + size: 1, + after: 'example', + kind: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": { + "outcome": "added", + "reason": "typed_reference", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string" + }, + "depth": 0 + } + } + ], + "next_cursor": "string", + "total": 0, + "truncated": true, + "source": "events" +} +``` + +
+ +--- + +### `listSyncJobResources` + +List the per-resource rows for a sync job. Supports filtering by status +(e.g. `failed`) and type, and cursor pagination. Used by the job detail +page, the failures table and the dry-run plan view in th + +`GET /v1/configs/sync-jobs/{id}/resources` + +```ts +const { data } = await client.listSyncJobResources({ + id: '123e4567-e89b-12d3-a456-426614174000', + cursor: 'example', + size: 1, + status: 'example', + type: 'example', + plan_action: 'example', +}) +``` + +
+Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string", + "reason": "typed_reference" + }, + "status": "pending", + "phase": "phase_0", + "attempt": 0, + "error": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "source_link": "string", + "target_link": "string", + "plan": { + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changed_paths": ["string"], + "note": "string", + "depends_on": [ + { + "type": "string", + "source_id": "string" + } + ] + }, + "excluded_from_apply": "unchanged" + } + ] +} +``` + +
+ +--- + +### `getSyncPlan` + +Summary of a plan: a dry-run sync job (`createSyncJob` with +`dry_run: true`). Says how many resources a real run would create, +update or leave unchanged, overall and per type. + +`GET /v1/configs/sync-jobs/{id}/plan` + +```ts +const { data } = await client.getSyncPlan({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "job_id": "string", + "status": "pending", + "ready": true, + "applicable": true, + "expires_at": "1970-01-01T00:00:00.000Z", + "planned_at": "1970-01-01T00:00:00.000Z", + "replanned_at": "1970-01-01T00:00:00.000Z", + "source_org_id": "string", + "target_org_id": "string", + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "by_type": [ + { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0, + "type": "string" + } + ], + "applied_by": ["string"] +} +``` + +
+ +--- + +### `listSyncPlanDiffs` + +Field-level diffs of a plan, one per planned resource: what the target +org has now (`before`) and what a real run would write (`after`). Use +it to review a plan in bulk, e.g. from an AI agent. + +`GET /v1/configs/sync-jobs/{id}/plan/diffs` + +```ts +const { data } = await client.listSyncPlanDiffs({ + id: '123e4567-e89b-12d3-a456-426614174000', + cursor: 'example', + size: 1, + type: 'example', + action: 'example', +}) +``` + +
+Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changes": [ + { + "path": "string", + "kind": "added", + "before": {}, + "after": {} + } + ], + "truncated": true, + "note": "string", + "planned_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `getSyncPlanDiff` + +Field-level diff of one planned resource. See `listSyncPlanDiffs`. + +`GET /v1/configs/sync-jobs/{id}/plan/diffs/{type}/{source_id}` + +```ts +const { data } = await client.getSyncPlanDiff({ + id: '123e4567-e89b-12d3-a456-426614174000', + type: 'example', + source_id: 'example', +}) +``` + +
+Response + +```json +{ + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "action": "create", + "match": "lineage", + "diff_status": "computed", + "change_count": 0, + "changes": [ + { + "path": "string", + "kind": "added", + "before": {}, + "after": {} + } + ], + "truncated": true, + "note": "string", + "planned_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `applySyncPlan` + +Run a finished plan for real. Creates a new sync job (it carries +`applied_from_plan`; the plan's `applied_by` gets the new job's id) +and enqueues it. + +`POST /v1/configs/sync-jobs/{id}/plan/apply` + +```ts +const { data } = await client.applySyncPlan( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + target_auth_token: 'string', + name: 'string', + resources: [ + { + type: 'string', + source_id: 'string' + } + ], + exclude: [ + { + type: 'string', + source_id: 'string' + } + ], + allow_missing_dependencies: false + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "direction": "push", + "source_org_id": "string", + "target_org_id": "string", + "dry_run": true, + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "succeeded": 0, + "failed": 0, + "skipped_unchanged": 0 + }, + "current_phase": "phase_0", + "current_batch": { + "index": 0, + "of": 0, + "level": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "health_check": { + "status": "pending", + "counts": { + "error": 0, + "warning": 0, + "info": 0 + } + }, + "events": [ + { + "id": "string", + "kind": "resource", + "seq": 0, + "ts": "1970-01-01T00:00:00.000Z", + "phase": "phase_0", + "type": "string", + "source_id": "string", + "target_id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "message": "string", + "error": "string", + "dependency": { + "outcome": "added", + "reason": "typed_reference", + "required_by": { + "type": "string", + "source_id": "string", + "title": "string" + }, + "depth": 0 + } + } + ], + "created_by": "string", + "retry_of": "string", + "retried_by": ["string"], + "plan_only": true, + "plan_summary": { + "total": 0, + "create": 0, + "update": 0, + "no_change": 0, + "skip": 0, + "failed": 0, + "not_compared": 0 + }, + "planned_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "applied_from_plan": "string", + "applied_by": ["string"], + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "approvals": [ + { + "job_id": "string", + "approved_by": "string", + "approved_at": "1970-01-01T00:00:00.000Z" + } + ], + "errors_sample": [ + { + "type": "string", + "source_id": "string", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `replanSyncPlan` + +Plan some rows of a plan again, in place, e.g. after fixing a +resource in the source org because its plan showed an unexpected +change. The listed resources are fetched from the source again, +their dep + +`POST /v1/configs/sync-jobs/{id}/plan/replan` + +```ts +const { data } = await client.replanSyncPlan( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + target_auth_token: 'string', + resources: [ + { + type: 'string', + source_id: 'string' + } + ] + }, +) +``` + +--- + +### `createDeleteJob` + +Create a bulk-delete job for the caller's organization. The selected +resources are deleted asynchronously by a worker Lambda; the response +returns the persisted job header with status `pending`. + +`POST /v1/configs/delete-jobs` + +```ts +const { data } = await client.createDeleteJob( + null, + { + name: 'string', + resources: [ + { + type: 'string', + id: 'string', + title: 'string' + } + ] + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "org_id": "string", + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "deleted": 0, + "skipped": 0, + "failed": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "rebuild_triggered": true +} +``` + +
+ +--- + +### `listDeleteJobs` + +List bulk-delete jobs scoped to the caller's organization, paginated +with an opaque cursor. Most-recent first. + +`GET /v1/configs/delete-jobs` + +```ts +const { data } = await client.listDeleteJobs({ + cursor: 'example', + size: 1, +}) +``` + +
+Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "id": "string", + "name": "string", + "status": "pending", + "org_id": "string", + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "deleted": 0, + "skipped": 0, + "failed": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "rebuild_triggered": true + } + ] +} +``` + +
+ +--- + +### `getDeleteJob` + +Fetch a single bulk-delete job by ID. Returns the job header and counts +summary. Frontend polls this endpoint while the job runs. + +`GET /v1/configs/delete-jobs/{id}` + +```ts +const { data } = await client.getDeleteJob({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "status": "pending", + "org_id": "string", + "counts": { + "total": 0, + "pending": 0, + "in_progress": 0, + "deleted": 0, + "skipped": 0, + "failed": 0 + }, + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "rebuild_triggered": true +} +``` + +
+ +--- + +### `listDeleteJobResources` + +List the per-resource rows for a delete job, cursor-paginated. Used by +the failures view in the frontend. + +`GET /v1/configs/delete-jobs/{id}/resources` + +```ts +const { data } = await client.listDeleteJobResources({ + id: '123e4567-e89b-12d3-a456-426614174000', + cursor: 'example', + size: 1, +}) +``` + +
+Response + +```json +{ + "next_cursor": "string", + "results": [ + { + "type": "string", + "id": "string", + "title": "string", + "status": "pending", + "attempt": 0, + "error": "string", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `rebuildIndex` + +Rebuild the configuration index for the caller's organization. +Fire-and-forget: invokes the async worker and returns immediately. +A new rebuild will cancel any in-flight build (see `build_token`). + +`POST /v1/configs/index:rebuild` + +```ts +const { data } = await client.rebuildIndex() +``` + +
+Response + +```json +{ + "status": "ready", + "last_built_at": "1970-01-01T00:00:00.000Z", + "total_items": 0, + "build_duration_ms": 0, + "failed_types": ["string"] +} +``` + +
+ +--- + +### `getConfigInventory` + +Returns a fresh inventory of an org's configuration resources — `{ type, id }` identities only, +no full payloads. Calls every adapter's `list()` live (bypasses the 7-day DynamoDB index). +Intended for + +`GET /v1/configs/inventory` + +```ts +const { data } = await client.getConfigInventory({ + include_dependency_only: true, +}) +``` + +
+Response + +```json +{ + "inventory_id": "string", + "org_id": "string", + "indexed_at": "1970-01-01T00:00:00.000Z", + "resources_count": 0, + "resources": [ + { + "type": "journey", + "id": "string" + } + ], + "skipped_types": [ + { + "type": "string", + "reason": "string" + } + ] +} +``` + +
+ +--- + +### `createPreview` + +Starts a preview of the caller's current org (internal callers: the org in `x-ivy-org-id`, +plus `requester`): a new, temporary org with +`organization_use: Preview` (parent = this org) that receives a + +`POST /v1/previews` + +```ts +const { data } = await client.createPreview( + null, + { + name: 'string', + requester: { + user_id: 'string', + email: 'user@example.com', + display_name: 'string', + language: 'de' + } + }, +) +``` + +--- + +### `listPreviews` + +Lists the previews requested from the caller's current org, newest first (max 50). + +`GET /v1/previews` + +```ts +const { data } = await client.listPreviews() +``` + +
+Response + +```json +{ + "results": [ + { + "id": "string", + "name": "string", + "status": "creating_org", + "source_org_id": "string", + "preview_org_id": "string", + "sync_job_id": "string", + "sync_status": "string", + "requested_by": { + "user_id": "string", + "email": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + ] +} +``` + +
+ +--- + +### `getPreview` + +Returns a preview requested from the caller's current org, with its progress. + +`GET /v1/previews/{id}` + +```ts +const { data } = await client.getPreview({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "status": "creating_org", + "source_org_id": "string", + "preview_org_id": "string", + "sync_job_id": "string", + "sync_status": "string", + "requested_by": { + "user_id": "string", + "email": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" +} +``` + +
+ +--- + +## Schemas + +### `ResourceType` + +Configuration resource type identifier. +Matches blueprint-manifest-api V3 naming conventions. + + +```ts +type ResourceType = "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" +``` + +### `ConfigTypeInfo` + +Static metadata for a config type folder in the tree. +No downstream API calls — just type + label + icon + source API info. + + +```ts +type ConfigTypeInfo = { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + label: string + icon: string + source_api: string + sdk_client: string + deletable: boolean +} +``` + +### `ConfigNode` + +Summary metadata for a single configuration item in the tree + +```ts +type ConfigNode = { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + id: string + title: string + updated_at?: string // date-time + updated_by?: string + tags?: string[] + aliases?: string[] + purposes?: string[] + link?: string // uri + active?: boolean + blueprints?: Array<{ + id: string + title: string + }> + metadata?: Record +} +``` + +### `ConfigListResponse` + +Cursor-paginated list of configs for a specific type + +```ts +type ConfigListResponse = { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + label: string + icon: string + total?: number + next_cursor?: string + results: Array<{ + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + id: string + title: string + updated_at?: string // date-time + updated_by?: string + tags?: string[] + aliases?: string[] + purposes?: string[] + link?: string // uri + active?: boolean + blueprints?: Array<{ + id: { ... } + title: { ... } + }> + metadata?: Record + }> +} +``` + +### `ConfigDependenciesResponse` + +Cursor-paginated list of configs referenced by a given config + +```ts +type ConfigDependenciesResponse = { + total?: number + next_cursor?: string + results: Array<{ + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + id: string + title: string + updated_at?: string // date-time + updated_by?: string + tags?: string[] + aliases?: string[] + purposes?: string[] + link?: string // uri + active?: boolean + blueprints?: Array<{ + id: { ... } + title: { ... } + }> + metadata?: Record + }> +} +``` + +### `IndexRebuildResponse` + +Result of an index rebuild operation + +```ts +type IndexRebuildResponse = { + status: "ready" | "building" | "failed" | "already_building" + last_built_at?: string // date-time + total_items?: number + build_duration_ms?: number + failed_types?: string[] +} +``` + +### `HealthScanStartResponse` + +```ts +type HealthScanStartResponse = { + status: "scanning" | "failed" + error?: string +} +``` + +### `HealthFinding` + +```ts +type HealthFinding = { + id: string + code: "broken_reference" | "inactive_reference" | "unreadable_config" | "orphaned_group_reference" | "uuid_group_label" | "duplicate_attribute_name" | "duplicate_headline" | "unreachable_attribute_purpose" | "orphaned_price" | "duplicate_price" | "inactive_price_in_use" | "incomplete_configuration" | "source_org_reference" | "secret_value_missing" | "env_value_missing" + severity: "error" | "warning" | "info" + source_type: string + source_id: string + source_title: string + message: string + message_key?: string + message_params?: Record + ref_type?: string + ref_id?: string + ref_title?: string + source_link?: string + ref_link?: string + owner_type?: string + owner_id?: string + owner_title?: string + owner_link?: string + path?: string + cleanable?: boolean + ignored?: boolean + ignored_at?: string // date-time + ignored_by?: string + ignored_reason?: string + first_seen: string // date-time + last_seen: string // date-time +} +``` + +### `HealthReportResponse` + +```ts +type HealthReportResponse = { + status: "missing" | "idle" | "scanning" | "cleaning" | "ready" | "failed" + last_scanned_at?: string // date-time + scan_duration_ms?: number + scanned_configs?: number + scanned_by_type?: Record + counts?: { + error?: number + warning?: number + info?: number + } + new_since_previous?: number + resolved_since_previous?: number + last_cleanup_at?: string // date-time + cleaned_count?: number + history?: Array<{ + scanned_at: string // date-time + clean: number + total: number + }> + error?: string + findings: Array<{ + id: string + code: "broken_reference" | "inactive_reference" | "unreadable_config" | "orphaned_group_reference" | "uuid_group_label" | "duplicate_attribute_name" | "duplicate_headline" | "unreachable_attribute_purpose" | "orphaned_price" | "duplicate_price" | "inactive_price_in_use" | "incomplete_configuration" | "source_org_reference" | "secret_value_missing" | "env_value_missing" + severity: "error" | "warning" | "info" + source_type: string + source_id: string + source_title: string + message: string + message_key?: string + message_params?: Record + ref_type?: string + ref_id?: string + ref_title?: string + source_link?: string + ref_link?: string + owner_type?: string + owner_id?: string + owner_title?: string + owner_link?: string + path?: string + cleanable?: boolean + ignored?: boolean + ignored_at?: string // date-time + ignored_by?: string + ignored_reason?: string + first_seen: string // date-time + last_seen: string // date-time + }> +} +``` + +### `IndexStatusResponse` + +Current index build state + +```ts +type IndexStatusResponse = { + status: "missing" | "building" | "ready" | "failed" + org_id?: string + last_built_at?: string // date-time + total_items?: number + build_duration_ms?: number +} +``` + +### `CompareRequest` + +Request body for a per-type cross-org comparison + +```ts +type CompareRequest = { + source_org_id: string + source_auth_token: string + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" +} +``` + +### `CompareLineage` + +Provenance of a lineage-backed match + +```ts +type CompareLineage = { + direction: "pull" | "push" + last_synced_at?: string // date-time + last_sync_job_id?: string + origin?: string +} +``` + +### `CompareRow` + +One row of the side-by-side comparison. `matched` rows carry both +configs plus lineage provenance; one-sided rows carry only the side +the config exists on. + + +```ts +type CompareRow = { + match_status: "matched" | "only_current" | "only_source" + current?: { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + id: string + title: string + updated_at?: string // date-time + updated_by?: string + tags?: string[] + aliases?: string[] + purposes?: string[] + link?: string // uri + active?: boolean + blueprints?: Array<{ + id: { ... } + title: { ... } + }> + metadata?: Record + } + source?: { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + id: string + title: string + updated_at?: string // date-time + updated_by?: string + tags?: string[] + aliases?: string[] + purposes?: string[] + link?: string // uri + active?: boolean + blueprints?: Array<{ + id: { ... } + title: { ... } + }> + metadata?: Record + } + lineage?: { + direction: "pull" | "push" + last_synced_at?: string // date-time + last_sync_job_id?: string + origin?: string + } +} +``` + +### `CompareCounts` + +Row counts per match status + +```ts +type CompareCounts = { + matched: number + only_current: number + only_source: number +} +``` + +### `CompareResponse` + +Side-by-side comparison of one config type across two orgs + +```ts +type CompareResponse = { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + label: string + icon: string + rows: Array<{ + match_status: "matched" | "only_current" | "only_source" + current?: { + type: { ... } + id: { ... } + title: { ... } + updated_at?: { ... } + updated_by?: { ... } + tags?: { ... } + aliases?: { ... } + purposes?: { ... } + link?: { ... } + active?: { ... } + blueprints?: { ... } + metadata?: { ... } + } + source?: { + type: { ... } + id: { ... } + title: { ... } + updated_at?: { ... } + updated_by?: { ... } + tags?: { ... } + aliases?: { ... } + purposes?: { ... } + link?: { ... } + active?: { ... } + blueprints?: { ... } + metadata?: { ... } + } + lineage?: { + direction: { ... } + last_synced_at?: { ... } + last_sync_job_id?: { ... } + origin?: { ... } + } + }> + counts: { + matched: number + only_current: number + only_source: number + } +} +``` + +### `SuggestMatchesRequest` + +Request body for batched heuristic match suggestions + +```ts +type SuggestMatchesRequest = { + source_org_id: string + source_auth_token: string + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + source_ids: string[] +} +``` + +### `MatchSuggestion` + +Heuristic candidate for one source config (null candidate = no match) + +```ts +type MatchSuggestion = { + source_id: string + candidate?: { + id: string + title?: string + } +} +``` + +### `SuggestMatchesResponse` + +```ts +type SuggestMatchesResponse = { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + suggestions: Array<{ + source_id: string + candidate?: { + id: { ... } + title?: { ... } + } + }> +} +``` + +### `ConfirmLineageRequest` + +Persist a source→target lineage pairing (caller org as target) + +```ts +type ConfirmLineageRequest = { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + source_org_id: string + source_id: string + target_id: string +} +``` + +### `LineageEntryResponse` + +A persisted lineage entry + +```ts +type LineageEntryResponse = { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + target_org_id: string + source_org_id: string + source_id: string + target_id: string + last_synced_at?: string // date-time + origin?: string +} +``` + +### `BreakLineageResponse` + +```ts +type BreakLineageResponse = { + deleted: boolean +} +``` + +### `ErrorResponse` + +```ts +type ErrorResponse = { + status: number + code?: string + error: string +} +``` + +### `SyncJobStatus` + +Lifecycle status of a sync job. See `docs/sync/INTERFACES.md` for state +transitions. + + +```ts +type SyncJobStatus = "pending" | "in_progress" | "succeeded" | "partial" | "failed" | "cancelled" +``` + +### `SyncDirection` + +Direction of the sync, derived from the source/target pane selection in the +configuration hub UI. + + +```ts +type SyncDirection = "push" | "pull" +``` + +### `SyncPhase` + +Three-phase orchestrator phase. `phase_0` fetches source payloads, +`dependencies` expands the selection with its dependencies (only when +`include_dependencies` is on), `phase_a` creates/matches with +topological batches, `phase_a5` resolves derived references, `phase_b` +patches with the full ID map, + +```ts +type SyncPhase = "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" +``` + +### `SyncJobResourceStatus` + +Per-resource status. `would_*` values are produced by dry-run jobs. + + +```ts +type SyncJobResourceStatus = "pending" | "in_progress" | "created" | "patched" | "skipped" | "would_create" | "would_patch" | "would_skip_unchanged" | "would_match_heuristic" | "failed" +``` + +### `SyncJobRequest` + +Request body for `createSyncJob`. `target_auth_token` is the destination +org's auth token and MUST NOT be persisted or logged — it is `writeOnly`. + + +```ts +type SyncJobRequest = { + source_org_id: string + target_org_id: string + target_auth_token: string + name?: string + dry_run?: boolean + include_dependencies?: boolean + sync_portal_widgets?: boolean + resources: Array<{ + type: string + id: string + }> +} +``` + +### `SyncJobResourceRef` + +```ts +type SyncJobResourceRef = { + type: string + source_id: string +} +``` + +### `SyncJobRetryPlanRequest` + +```ts +type SyncJobRetryPlanRequest = { + resources?: Array<{ + type: string + source_id: string + }> +} +``` + +### `SyncJobRetryPlan` + +```ts +type SyncJobRetryPlan = { + selected: Array<{ + type: string + source_id: string + target_id?: string + title?: string + required_by?: { + type: { ... } + source_id: { ... } + title?: { ... } + reason: { ... } + } + status: "pending" | "in_progress" | "created" | "patched" | "skipped" | "would_create" | "would_patch" | "would_skip_unchanged" | "would_match_heuristic" | "failed" + phase: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + attempt: number + error?: string + updated_at: string // date-time + source_link?: string + target_link?: string + plan?: { + action: { ... } + match: { ... } + diff_status?: { ... } + change_count?: { ... } + changed_paths?: { ... } + note?: { ... } + depends_on?: { ... } + } + excluded_from_apply?: "unchanged" | "excluded" | "not_syncable" + }> + added_dependencies: Array<{ + type: string + source_id: string + target_id?: string + title?: string + required_by?: { + type: { ... } + source_id: { ... } + title?: { ... } + reason: { ... } + } + status: "pending" | "in_progress" | "created" | "patched" | "skipped" | "would_create" | "would_patch" | "would_skip_unchanged" | "would_match_heuristic" | "failed" + phase: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + attempt: number + error?: string + updated_at: string // date-time + source_link?: string + target_link?: string + plan?: { + action: { ... } + match: { ... } + diff_status?: { ... } + change_count?: { ... } + changed_paths?: { ... } + note?: { ... } + depends_on?: { ... } + } + excluded_from_apply?: "unchanged" | "excluded" | "not_syncable" + }> + dependency_resolution: "exact" | "best_effort" +} +``` + +### `SyncJobRetryErrorResponse` + +```ts +type SyncJobRetryErrorResponse = { + status?: number + error?: string + invalid_resources?: Array<{ + type: string + source_id: string + }> +} +``` + +### `SyncJobRetryRequest` + +Optional body for `retrySyncJob`. Defaults to retrying every unresolved +resource of the original job (failed, pending or in_progress). + + +```ts +type SyncJobRetryRequest = { + target_auth_token?: string + resources?: Array<{ + type: string + source_id: string + }> + payload_overrides?: Record +} +``` + +### `SyncJobCounts` + +Aggregate counters by resource status. + +```ts +type SyncJobCounts = { + total: number + pending: number + in_progress: number + succeeded: number + failed: number + skipped_unchanged: number +} +``` + +### `SyncJobEvent` + +Activity-log entry surfaced to the frontend. Backed by the append-only +job event log, or by the op-log rows (`SYNC#``#OP#```) for jobs +that predate it. Key events by `id` when present. + + +```ts +type SyncJobEvent = { + id?: string + kind?: "resource" | "dependency" | "step" + seq: number + ts: string // date-time + phase?: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + type?: string + source_id?: string + target_id?: string + title?: string + status: "pending" | "in_progress" | "created" | "patched" | "skipped" | "would_create" | "would_patch" | "would_skip_unchanged" | "would_match_heuristic" | "failed" + attempt?: number + message?: string + error?: string + dependency?: { + outcome: "added" | "linked" | "skipped" | "not_found" + reason: "typed_reference" | "id_reference" | "automation_trigger" | "journey_datasource" | "file_reference" + required_by: { + type: { ... } + source_id: { ... } + title?: { ... } + } + depth: number + } +} +``` + +### `SyncJobEventDependency` + +Only on `kind: dependency` events. The event's `type`, `source_id` and +`title` describe the dependency itself. + + +```ts +type SyncJobEventDependency = { + outcome: "added" | "linked" | "skipped" | "not_found" + reason: "typed_reference" | "id_reference" | "automation_trigger" | "journey_datasource" | "file_reference" + required_by: { + type: string + source_id: string + title?: string + } + depth: number +} +``` + +### `SyncDependencyReason` + +How the dependency was found. `typed_reference`: a structural reference +in the payload (e.g. a workflow step's automation). `id_reference`: an +id in the payload resolved through the source index. +`automation_trigger`: an automation triggered by the resource (e.g. a +journey submission). `journey_data + +```ts +type SyncDependencyReason = "typed_reference" | "id_reference" | "automation_trigger" | "journey_datasource" | "file_reference" +``` + +### `SyncRequiredBy` + +The resource that referenced the dependency. + +```ts +type SyncRequiredBy = { + type: string + source_id: string + title?: string +} +``` + +### `SyncJobEventListResponse` + +```ts +type SyncJobEventListResponse = { + results: Array<{ + id?: string + kind?: "resource" | "dependency" | "step" + seq: number + ts: string // date-time + phase?: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + type?: string + source_id?: string + target_id?: string + title?: string + status: "pending" | "in_progress" | "created" | "patched" | "skipped" | "would_create" | "would_patch" | "would_skip_unchanged" | "would_match_heuristic" | "failed" + attempt?: number + message?: string + error?: string + dependency?: { + outcome: { ... } + reason: { ... } + required_by: { ... } + depth: { ... } + } + }> + next_cursor?: string + total?: number + truncated?: boolean + source: "events" | "op_log" +} +``` + +### `SyncJobBatch` + +Position within the current topological batch for the active phase. + +```ts +type SyncJobBatch = { + index: number + of: number + level: number +} +``` + +### `SyncJobHealthStatus` + +State of a sync job's post-import health check. `pending`: queued, +`running`: scanning, `done`: findings available, `failed`: the check +itself failed or did not finish (the import is unaffected), `skipped`: +nothing to check (a plan, a job that wrote nothing, or a cancelled +job), `not_run`: a finishe + +```ts +type SyncJobHealthStatus = "pending" | "running" | "done" | "failed" | "skipped" | "not_run" +``` + +### `HealthSeverityCounts` + +```ts +type HealthSeverityCounts = { + error: number + warning: number + info: number +} +``` + +### `SyncJobHealthCheck` + +Compact state of the job's post-import health check. Full results: +`getSyncJobHealth`. Absent on plans and on jobs that finished before +the check existed. + + +```ts +type SyncJobHealthCheck = { + status: "pending" | "running" | "done" | "failed" | "skipped" | "not_run" + counts: { + error: number + warning: number + info: number + } +} +``` + +### `SyncJobHealth` + +Targeted health check of the configs a sync job wrote into the target +org. Findings carry `first_seen` = `last_seen` = `finished_at`. + + +```ts +type SyncJobHealth = { + status: "pending" | "running" | "done" | "failed" | "skipped" | "not_run" + started_at?: string // date-time + finished_at?: string // date-time + scanned: number + counts: { + error: number + warning: number + info: number + } + error?: string + findings: Array<{ + id: string + code: "broken_reference" | "inactive_reference" | "unreadable_config" | "orphaned_group_reference" | "uuid_group_label" | "duplicate_attribute_name" | "duplicate_headline" | "unreachable_attribute_purpose" | "orphaned_price" | "duplicate_price" | "inactive_price_in_use" | "incomplete_configuration" | "source_org_reference" | "secret_value_missing" | "env_value_missing" + severity: "error" | "warning" | "info" + source_type: string + source_id: string + source_title: string + message: string + message_key?: string + message_params?: Record + ref_type?: string + ref_id?: string + ref_title?: string + source_link?: string + ref_link?: string + owner_type?: string + owner_id?: string + owner_title?: string + owner_link?: string + path?: string + cleanable?: boolean + ignored?: boolean + ignored_at?: string // date-time + ignored_by?: string + ignored_reason?: string + first_seen: string // date-time + last_seen: string // date-time + }> +} +``` + +### `SyncJob` + +Sync job header as surfaced by `getSyncJob` and the create response. The +canonical persistence shape is described in `docs/sync/INTERFACES.md`. + + +```ts +type SyncJob = { + id: string + name?: string + status: "pending" | "in_progress" | "succeeded" | "partial" | "failed" | "cancelled" + direction: "push" | "pull" + source_org_id: string + target_org_id: string + dry_run: boolean + counts: { + total: number + pending: number + in_progress: number + succeeded: number + failed: number + skipped_unchanged: number + } + current_phase?: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + current_batch?: { + index: number + of: number + level: number + } + started_at: string // date-time + finished_at?: string // date-time + health_check?: { + status: "pending" | "running" | "done" | "failed" | "skipped" | "not_run" + counts: { + error: { ... } + warning: { ... } + info: { ... } + } + } + events?: Array<{ + id?: string + kind?: "resource" | "dependency" | "step" + seq: number + ts: string // date-time + phase?: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + type?: string + source_id?: string + target_id?: string + title?: string + status: "pending" | "in_progress" | "created" | "patched" | "skipped" | "would_create" | "would_patch" | "would_skip_unchanged" | "would_match_heuristic" | "failed" + attempt?: number + message?: string + error?: string + dependency?: { + outcome: { ... } + reason: { ... } + required_by: { ... } + depth: { ... } + } + }> + created_by?: string + retry_of?: string + retried_by?: string[] + plan_only?: boolean + plan_summary?: { + total: number + create: number + update: number + no_change: number + skip: number + failed: number + not_compared: number + } + planned_at?: string // date-time + expires_at?: string // date-time + applied_from_plan?: string + applied_by?: string[] + approved_by?: string + approved_at?: string // date-time + approvals?: Array<{ + job_id: string + approved_by?: string + approved_at: string // date-time + }> + errors_sample?: Array<{ + type: string + source_id: string + error: string + }> +} +``` + +### `SyncJobListResponse` + +Cursor-paginated list of sync jobs. + +```ts +type SyncJobListResponse = { + next_cursor?: string + results: Array<{ + id: string + name?: string + status: "pending" | "in_progress" | "succeeded" | "partial" | "failed" | "cancelled" + direction: "push" | "pull" + source_org_id: string + target_org_id: string + dry_run: boolean + counts: { + total: { ... } + pending: { ... } + in_progress: { ... } + succeeded: { ... } + failed: { ... } + skipped_unchanged: { ... } + } + current_phase?: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + current_batch?: { + index: { ... } + of: { ... } + level: { ... } + } + started_at: string // date-time + finished_at?: string // date-time + health_check?: { + status: { ... } + counts: { ... } + } + events?: Array<{ + id?: { ... } + kind?: { ... } + seq: { ... } + ts: { ... } + phase?: { ... } + type?: { ... } + source_id?: { ... } + target_id?: { ... } + title?: { ... } + status: { ... } + attempt?: { ... } + message?: { ... } + error?: { ... } + dependency?: { ... } + }> + created_by?: string + retry_of?: string + retried_by?: string[] + plan_only?: boolean + plan_summary?: { + total: { ... } + create: { ... } + update: { ... } + no_change: { ... } + skip: { ... } + failed: { ... } + not_compared: { ... } + } + planned_at?: string // date-time + expires_at?: string // date-time + applied_from_plan?: string + applied_by?: string[] + approved_by?: string + approved_at?: string // date-time + approvals?: Array<{ + job_id: { ... } + approved_by?: { ... } + approved_at: { ... } + }> + errors_sample?: Array<{ + type: { ... } + source_id: { ... } + error: { ... } + }> + }> +} +``` + +### `SyncJobResource` + +Per-resource row backed by `SyncResourcesTable`. See +`docs/sync/INTERFACES.md` for the DDB shape. + + +```ts +type SyncJobResource = { + type: string + source_id: string + target_id?: string + title?: string + required_by?: { + type: string + source_id: string + title?: string + reason: "typed_reference" | "id_reference" | "automation_trigger" | "journey_datasource" | "file_reference" + } + status: "pending" | "in_progress" | "created" | "patched" | "skipped" | "would_create" | "would_patch" | "would_skip_unchanged" | "would_match_heuristic" | "failed" + phase: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + attempt: number + error?: string + updated_at: string // date-time + source_link?: string + target_link?: string + plan?: { + action: "create" | "update" | "no_change" | "skip" + match: "lineage" | "heuristic" | "none" + diff_status?: "computed" | "not_compared" + change_count?: number + changed_paths?: string[] + note?: string + depends_on?: Array<{ + type: { ... } + source_id: { ... } + }> + } + excluded_from_apply?: "unchanged" | "excluded" | "not_syncable" +} +``` + +### `SyncJobResourceListResponse` + +Cursor-paginated list of sync job resources. + +```ts +type SyncJobResourceListResponse = { + next_cursor?: string + results: Array<{ + type: string + source_id: string + target_id?: string + title?: string + required_by?: { + type: { ... } + source_id: { ... } + title?: { ... } + reason: { ... } + } + status: "pending" | "in_progress" | "created" | "patched" | "skipped" | "would_create" | "would_patch" | "would_skip_unchanged" | "would_match_heuristic" | "failed" + phase: "phase_0" | "dependencies" | "phase_a" | "phase_a5" | "phase_b" | "finalize" + attempt: number + error?: string + updated_at: string // date-time + source_link?: string + target_link?: string + plan?: { + action: { ... } + match: { ... } + diff_status?: { ... } + change_count?: { ... } + changed_paths?: { ... } + note?: { ... } + depends_on?: { ... } + } + excluded_from_apply?: "unchanged" | "excluded" | "not_syncable" + }> +} +``` + +### `SyncPlanAction` + +What a real run would do with a planned resource: +- `create`: no counterpart in the target; a new resource is created. +- `update`: the target's copy differs from the source and is + overwritten. Also used when the copies could not be compared + (`diff_status: not_compared`): such resources are re-ap + +```ts +type SyncPlanAction = "create" | "update" | "no_change" | "skip" +``` + +### `SyncPlanMatch` + +How the target counterpart was found: `lineage` (synced before), +`heuristic` (first sync, matched by name / slug / unique key) or +`none` (no counterpart: the resource is created). + + +```ts +type SyncPlanMatch = "lineage" | "heuristic" | "none" +``` + +### `SyncPlanDiffStatus` + +`computed` when both copies were read and compared. `not_compared` +when the target could not be read or compared (see `note`). + + +```ts +type SyncPlanDiffStatus = "computed" | "not_compared" +``` + +### `SyncResourcePlan` + +The plan for one resource. Set on rows of plan jobs (`dry_run`), and +copied onto the rows of the job that applies the plan. Absent on rows +planning failed for and on jobs created before plans existed. + + +```ts +type SyncResourcePlan = { + action: "create" | "update" | "no_change" | "skip" + match: "lineage" | "heuristic" | "none" + diff_status?: "computed" | "not_compared" + change_count?: number + changed_paths?: string[] + note?: string + depends_on?: Array<{ + type: string + source_id: string + }> +} +``` + +### `SyncPlanCounts` + +Planned resources by action. `not_compared` counts the `update` +resources whose copies could not be compared (it is part of +`update`, not in addition to it). `failed` counts resources planning +failed for. + + +```ts +type SyncPlanCounts = { + total: number + create: number + update: number + no_change: number + skip: number + failed: number + not_compared: number +} +``` + +### `SyncPlan` + +```ts +type SyncPlan = { + job_id: string + status: "pending" | "in_progress" | "succeeded" | "partial" | "failed" | "cancelled" + ready: boolean + applicable: boolean + expires_at?: string // date-time + planned_at?: string // date-time + replanned_at?: string // date-time + source_org_id: string + target_org_id: string + started_at?: string // date-time + finished_at?: string // date-time + summary: { + total: number + create: number + update: number + no_change: number + skip: number + failed: number + not_compared: number + } + by_type: Array<{ + total: number + create: number + update: number + no_change: number + skip: number + failed: number + not_compared: number + type: string + }> + applied_by?: string[] +} +``` + +### `SyncPlanChange` + +One changed field. `path` uses dots for object keys and +`[key=value]` for array items that have an identity (`name`, `slug`, +`key`, `id`, …), e.g. `steps[name=Contact].blocks[name=Email].label`. +`$` is the whole resource. + +Values are compared after removing fields that differ between orgs +by design: + +```ts +type SyncPlanChange = { + path: string + kind: "added" | "removed" | "changed" | "reordered" + before?: unknown + after?: unknown +} +``` + +### `SyncPlanDiff` + +```ts +type SyncPlanDiff = { + type: string + source_id: string + target_id?: string + title?: string + action: "create" | "update" | "no_change" | "skip" + match: "lineage" | "heuristic" | "none" + diff_status: "computed" | "not_compared" + change_count: number + changes: Array<{ + path: string + kind: "added" | "removed" | "changed" | "reordered" + before?: unknown + after?: unknown + }> + truncated: boolean + note?: string + planned_at?: string // date-time +} +``` + +### `SyncPlanDiffListResponse` + +```ts +type SyncPlanDiffListResponse = { + next_cursor?: string + results: Array<{ + type: string + source_id: string + target_id?: string + title?: string + action: "create" | "update" | "no_change" | "skip" + match: "lineage" | "heuristic" | "none" + diff_status: "computed" | "not_compared" + change_count: number + changes: Array<{ + path: { ... } + kind: { ... } + before?: { ... } + after?: { ... } + }> + truncated: boolean + note?: string + planned_at?: string // date-time + }> +} +``` + +### `SyncPlanApplyRequest` + +```ts +type SyncPlanApplyRequest = { + target_auth_token: string + name?: string + resources?: Array<{ + type: string + source_id: string + }> + exclude?: Array<{ + type: string + source_id: string + }> + allow_missing_dependencies?: boolean +} +``` + +### `SyncPlanReplanRequest` + +```ts +type SyncPlanReplanRequest = { + target_auth_token: string + resources?: Array<{ + type: string + source_id: string + }> +} +``` + +### `SyncPlanMissingDependency` + +```ts +type SyncPlanMissingDependency = { + type: string + source_id: string + title?: string + required_by: Array<{ + type: string + source_id: string + title?: string + }> +} +``` + +### `SyncPlanApplyErrorResponse` + +```ts +type SyncPlanApplyErrorResponse = { + status?: number + error?: string + code?: "target_auth_token_missing" | "empty_selection" | "invalid_resources" | "plan_not_ready" | "plan_expired" | "nothing_to_apply" | "missing_dependencies" + invalid_resources?: Array<{ + type: string + source_id: string + }> + missing_dependencies?: Array<{ + type: string + source_id: string + title?: string + required_by: Array<{ + type: { ... } + source_id: { ... } + title?: { ... } + }> + }> +} +``` + +### `DeleteJobStatus` + +Lifecycle status of a bulk-delete job. + +```ts +type DeleteJobStatus = "pending" | "in_progress" | "succeeded" | "partial" | "failed" | "cancelled" +``` + +### `DeleteJobResourceStatus` + +Per-resource delete status. `skipped` is used for protected resources +that are intentionally not deleted (e.g. built-in schemas). + + +```ts +type DeleteJobResourceStatus = "pending" | "in_progress" | "deleted" | "skipped" | "failed" +``` + +### `DeleteJobCounts` + +Aggregate counters by resource delete status. + +```ts +type DeleteJobCounts = { + total: number + pending: number + in_progress: number + deleted: number + skipped: number + failed: number +} +``` + +### `DeleteJobRequest` + +Request body for `createDeleteJob`. + +```ts +type DeleteJobRequest = { + name?: string + resources: Array<{ + type: string + id: string + title?: string + }> +} +``` + +### `DeleteJob` + +Bulk-delete job header surfaced by `createDeleteJob`/`getDeleteJob`. + +```ts +type DeleteJob = { + id: string + name?: string + status: "pending" | "in_progress" | "succeeded" | "partial" | "failed" | "cancelled" + org_id: string + counts: { + total: number + pending: number + in_progress: number + deleted: number + skipped: number + failed: number + } + started_at: string // date-time + finished_at?: string // date-time + rebuild_triggered?: boolean +} +``` + +### `DeleteJobListResponse` + +Cursor-paginated list of delete jobs. + +```ts +type DeleteJobListResponse = { + next_cursor?: string + results: Array<{ + id: string + name?: string + status: "pending" | "in_progress" | "succeeded" | "partial" | "failed" | "cancelled" + org_id: string + counts: { + total: { ... } + pending: { ... } + in_progress: { ... } + deleted: { ... } + skipped: { ... } + failed: { ... } + } + started_at: string // date-time + finished_at?: string // date-time + rebuild_triggered?: boolean + }> +} +``` + +### `DeleteJobResource` + +Per-resource row for a delete job. + +```ts +type DeleteJobResource = { + type: string + id: string + title?: string + status: "pending" | "in_progress" | "deleted" | "skipped" | "failed" + attempt: number + error?: string + updated_at: string // date-time +} +``` + +### `DeleteJobResourceListResponse` + +Cursor-paginated list of delete job resources. + +```ts +type DeleteJobResourceListResponse = { + next_cursor?: string + results: Array<{ + type: string + id: string + title?: string + status: "pending" | "in_progress" | "deleted" | "skipped" | "failed" + attempt: number + error?: string + updated_at: string // date-time + }> +} +``` + +### `SnapshotInventoryItem` + +Minimal identity of a single configuration resource. + +```ts +type SnapshotInventoryItem = { + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + id: string +} +``` + +### `SnapshotInventorySkippedType` + +A type that could not be listed during inventory collection. + +```ts +type SnapshotInventorySkippedType = { + type: string + reason: string +} +``` + +### `ConfigInventoryResponse` + +Fresh inventory of all configuration resources for an org. + +```ts +type ConfigInventoryResponse = { + inventory_id: string + org_id: string + indexed_at: string // date-time + resources_count: number + resources: Array<{ + type: "journey" | "datasource" | "automation_flow" | "workflow_definition" | "closing_reason" | "flow_template" | "schema" | "emailtemplate" | "product" | "price" | "tax" | "coupon" | "file" | "document_template" | "webhook" | "saved_view" | "dashboard" | "kanban" | "role" | "usergroup" | "validation_rule" | "integration" | "app" | "designbuilder" | "notification_template" | "custom_variable" | "environment_variable" | "taxonomy" | "taxonomy_classification" | "entity_mapping" | "portal_config" | "target" | "product_recommendation" | "access_token" | "email_signature" | "shared_inbox" | "org_setting" + id: string + }> + skipped_types: Array<{ + type: string + reason: string + }> +} +``` + +### `CreatePreviewRequest` + +```ts +type CreatePreviewRequest = { + name?: string + requester?: { + user_id?: string + email?: string // email + display_name?: string + language?: "de" | "en" + } +} +``` + +### `PreviewStatus` + +- creating_org: the preview org is being created +- copying_configuration: the sync job copying this org's configuration is running +- inviting: the requester is being invited to the preview org +- ready: the requester got the "your preview org is ready" email +- failed: see `error` + + +```ts +type PreviewStatus = "creating_org" | "copying_configuration" | "inviting" | "ready" | "failed" +``` + +### `Preview` + +```ts +type Preview = { + id: string + name: string + status: "creating_org" | "copying_configuration" | "inviting" | "ready" | "failed" + source_org_id: string + preview_org_id?: string + sync_job_id?: string + sync_status?: string + requested_by: { + user_id?: string + email?: string + } + created_at: string // date-time + updated_at: string // date-time + error?: string +} +``` diff --git a/docs/sdk/clients/customer-portal.md b/docs/sdk/clients/customer-portal.md index 41304b09..0bf69ef8 100644 --- a/docs/sdk/clients/customer-portal.md +++ b/docs/sdk/clients/customer-portal.md @@ -29,128 +29,95 @@ const { data } = await customerPortalClient.upsertPortal(...) ## Operations -**ECP Admin** -- [`upsertPortal`](#upsertportal) -- [`getPortalConfig`](#getportalconfig) -- [`deletePortal`](#deleteportal) -- [`getPortalExtensions`](#getportalextensions) -- [`getPortalExtensionsV3`](#getportalextensionsv3) -- [`getExternalLinks`](#getexternallinks) -- [`getExternalLinksV3`](#getexternallinksv3) -- [`getOrgPortalConfig`](#getorgportalconfig) -- [`getOrgPortalConfigV3`](#getorgportalconfigv3) -- [`getAllPortalConfigs`](#getallportalconfigs) -- [`upsertEmailTemplates`](#upsertemailtemplates) -- [`getEmailTemplates`](#getemailtemplates) -- [`upsertEmailTemplatesByPortalId`](#upsertemailtemplatesbyportalid) -- [`getEmailTemplatesByPortalId`](#getemailtemplatesbyportalid) -- [`upsertPortalWidget`](#upsertportalwidget) -- [`getPortalWidgets`](#getportalwidgets) -- [`replaceECPTemplateVariables`](#replaceecptemplatevariables) -- [`extraPermissionAttributes`](#extrapermissionattributes) -- [`validateCaaRecords`](#validatecaarecords) -- [`validateCaaRecordsV3`](#validatecaarecordsv3) -- [`getECPContact`](#getecpcontact) -- [`getValidSecondaryAttributes`](#getvalidsecondaryattributes) -- [`resendConfirmationEmail`](#resendconfirmationemail) -- [`fetchPortalUsersByRelatedEntity`](#fetchportalusersbyrelatedentity) -- [`getRecipientsToNotifyOnAutomation`](#getrecipientstonotifyonautomation) -- [`configureDistribution`](#configuredistribution) -- [`configureDistributionV3`](#configuredistributionv3) -- [`getEntityIdentifiers`](#getentityidentifiers) -- [`savePortalFiles`](#saveportalfiles) -- [`getRegistrationIdentifiers`](#getregistrationidentifiers) -- [`loginToPortalAsUser`](#logintoportalasuser) -- [`canTriggerPortalFlow`](#cantriggerportalflow) -- [`updatePortalPage`](#updateportalpage) -- [`deletePortalPage`](#deleteportalpage) -- [`createPortalPage`](#createportalpage) -- [`getDefaultPages`](#getdefaultpages) -- [`createPortalPageBlock`](#createportalpageblock) -- [`updatePortalPageBlock`](#updateportalpageblock) -- [`deletePortalPageBlock`](#deleteportalpageblock) -- [`createPortalConfig`](#createportalconfig) -- [`getPortalConfigV3`](#getportalconfigv3) -- [`putPortalConfig`](#putportalconfig) -- [`deletePortalConfig`](#deleteportalconfig) -- [`listAllPortalConfigs`](#listallportalconfigs) -- [`swapPortalConfig`](#swapportalconfig) - **Public** -- [`createUser`](#createuser) - [`createUserV3`](#createuserv3) - [`getPortalConfigByDomain`](#getportalconfigbydomain) -- [`getPublicPortalExtensionDetails`](#getpublicportalextensiondetails) - [`getPublicPortalExtensionDetailsV3`](#getpublicportalextensiondetailsv3) -- [`getPublicPortalConfig`](#getpublicportalconfig) - [`getPublicPortalConfigV3`](#getpublicportalconfigv3) -- [`getPublicPortalWidgets`](#getpublicportalwidgets) +- [`getPublicPortalWidgetsV3`](#getpublicportalwidgetsv3) - [`getSchemasByDomain`](#getschemasbydomain) +- [`getPublicSchemasV3`](#getpublicschemasv3) - [`getOrganizationSettingsByDomain`](#getorganizationsettingsbydomain) -- [`checkContactExists`](#checkcontactexists) - [`checkContactExistsV3`](#checkcontactexistsv3) +- [`identifyContact`](#identifycontact) +- [`checkAccountExists`](#checkaccountexists) - [`confirmUser`](#confirmuser) - [`confirmUserWithUserId`](#confirmuserwithuserid) -- [`userExists`](#userexists) - [`userExistsV3`](#userexistsv3) +- [`getPublicSSOProviderV3`](#getpublicssoproviderv3) - [`ssoRedirect`](#ssoredirect) - [`ssoCallback`](#ssocallback) - [`getPublicPages`](#getpublicpages) - [`getUserEntryPoint`](#getuserentrypoint) +- [`completeTemporaryPassword`](#completetemporarypassword) - [`deRegisterMLoginUser`](#deregistermloginuser) - [`notifyMLoginInterestChange`](#notifymlogininterestchange) **ECP** - [`validateToken`](#validatetoken) - [`revokeToken`](#revoketoken) +- [`createExport`](#createexport) +- [`getExport`](#getexport) - [`getConsumption`](#getconsumption) +- [`prepareVisualizationExport`](#preparevisualizationexport) +- [`getVisualizationMetadata`](#getvisualizationmetadata) - [`getCosts`](#getcosts) - [`getPrices`](#getprices) - [`getResolvedSeamlessLink`](#getresolvedseamlesslink) - [`getSchemas`](#getschemas) - [`getContact`](#getcontact) -- [`updateContact`](#updatecontact) +- [`getPortalCopilotAccess`](#getportalcopilotaccess) - [`getPortalUser`](#getportaluser) -- [`updatePortalUser`](#updateportaluser) - [`deletePortalUser`](#deleteportaluser) - [`updatePortalUserEmail`](#updateportaluseremail) -- [`getAllOrders`](#getallorders) +- [`changePortalUserPassword`](#changeportaluserpassword) +- [`getPortalUserNotificationPreferences`](#getportalusernotificationpreferences) +- [`updatePortalUserNotificationPreferences`](#updateportalusernotificationpreferences) +- [`listPortalUserPasskeys`](#listportaluserpasskeys) +- [`addPortalUserPasskey`](#addportaluserpasskey) +- [`createPortalUserPasskeyRegistrationOptions`](#createportaluserpasskeyregistrationoptions) +- [`sendPortalUserPasskeyVerificationCode`](#sendportaluserpasskeyverificationcode) +- [`renamePortalUserPasskey`](#renameportaluserpasskey) +- [`deletePortalUserPasskey`](#deleteportaluserpasskey) - [`postOrderAcceptance`](#postorderacceptance) -- [`getOrder`](#getorder) -- [`updateOrder`](#updateorder) -- [`getAllOpportunities`](#getallopportunities) -- [`getSearchableAttributesForOpportunities`](#getsearchableattributesforopportunities) -- [`getSearchResultsForOpportunities`](#getsearchresultsforopportunities) -- [`getOpportunity`](#getopportunity) -- [`updateOpportunity`](#updateopportunity) -- [`getAllRequests`](#getallrequests) -- [`getAllContracts`](#getallcontracts) -- [`getContract`](#getcontract) -- [`updateContract`](#updatecontract) +- [`getContractWithTemplates`](#getcontractwithtemplates) - [`addContractByIdentifiers`](#addcontractbyidentifiers) - [`validateCadenceEntityEditRules`](#validatecadenceentityeditrules) - [`searchPaymentRelationsInEntities`](#searchpaymentrelationsinentities) - [`createCustomEntityActivity`](#createcustomentityactivity) - [`saveEntityFile`](#saveentityfile) -- [`deleteEntityFile`](#deleteentityfile) -- [`getFileById`](#getfilebyid) +- [`getFilePreview`](#getfilepreview) - [`trackFileDownloaded`](#trackfiledownloaded) - [`getBillingEvents`](#getbillingevents) -- [`triggerEntityAccessEvent`](#triggerentityaccessevent) - [`triggerEntityAccessEventV3`](#triggerentityaccesseventv3) - [`getPortalUserEntity`](#getportaluserentity) - [`searchPortalUserEntities`](#searchportaluserentities) - [`getAutomationContext`](#getautomationcontext) - [`updateWorkflowStepAsDone`](#updateworkflowstepasdone) - [`getEntityWorkflows`](#getentityworkflows) +- [`getOutstandingTasks`](#getoutstandingtasks) +- [`getEntityPortalWorkflows`](#getentityportalworkflows) +- [`getEntityPortalWorkflowsBatch`](#getentityportalworkflowsbatch) - [`uploadMeterReadingPhoto`](#uploadmeterreadingphoto) - [`createMeterReading`](#createmeterreading) - [`getAllowedMeterReadingRange`](#getallowedmeterreadingrange) +- [`getMeterReadings`](#getmeterreadings) +- [`getMeter`](#getmeter) +- [`getMeterCounters`](#getmetercounters) +- [`createMeterReadings`](#createmeterreadings) +- [`getAllowedMeterReading`](#getallowedmeterreading) +- [`getMeterCounter`](#getmetercounter) +- [`getContractMeters`](#getcontractmeters) - [`getPortalPage`](#getportalpage) - [`getPortalPages`](#getportalpages) +- [`getTriggeredJourney`](#gettriggeredjourney) - [`getPortalPageBlocks`](#getportalpageblocks) - [`getPortalPageBlock`](#getportalpageblock) - [`updateCampaignPortalBlockStatus`](#updatecampaignportalblockstatus) +- [`listPortalNotifications`](#listportalnotifications) +- [`getPortalNotificationsUnreadCount`](#getportalnotificationsunreadcount) +- [`markAllPortalNotificationsRead`](#markallportalnotificationsread) +- [`markPortalNotificationRead`](#markportalnotificationread) - [`updateNotificationsStatus`](#updatenotificationsstatus) - [`invitePartner`](#invitepartner) - [`listBusinessPartners`](#listbusinesspartners) @@ -158,6 +125,60 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`revokePartner`](#revokepartner) - [`disablePartner`](#disablepartner) - [`enablePartner`](#enablepartner) +- [`portalProxyExecute`](#portalproxyexecute) + +**ECP Admin** +- [`getPortalExtensionsV3`](#getportalextensionsv3) +- [`getExternalLinksV3`](#getexternallinksv3) +- [`getOrgPortalConfigV3`](#getorgportalconfigv3) +- [`getAllPortalConfigs`](#getallportalconfigs) +- [`migrateEmailTemplateReferences`](#migrateemailtemplatereferences) +- [`listEmailTemplateReferences`](#listemailtemplatereferences) +- [`upsertEmailTemplatesByPortalId`](#upsertemailtemplatesbyportalid) +- [`getEmailTemplatesByPortalId`](#getemailtemplatesbyportalid) +- [`getPortalWidgetsV3`](#getportalwidgetsv3) +- [`upsertPortalWidgetV3`](#upsertportalwidgetv3) +- [`savePortalFilesV3`](#saveportalfilesv3) +- [`replaceECPTemplateVariables`](#replaceecptemplatevariables) +- [`extraPermissionAttributes`](#extrapermissionattributes) +- [`validateCaaRecordsV3`](#validatecaarecordsv3) +- [`getECPContact`](#getecpcontact) +- [`getValidSecondaryAttributes`](#getvalidsecondaryattributes) +- [`resendConfirmationEmail`](#resendconfirmationemail) +- [`fetchPortalUsersByRelatedEntity`](#fetchportalusersbyrelatedentity) +- [`getRecipientsToNotifyOnAutomation`](#getrecipientstonotifyonautomation) +- [`configureDistributionV3`](#configuredistributionv3) +- [`getEntityIdentifiers`](#getentityidentifiers) +- [`getRegistrationIdentifiers`](#getregistrationidentifiers) +- [`loginToPortalAsUser`](#logintoportalasuser) +- [`canTriggerPortalFlow`](#cantriggerportalflow) +- [`updatePortalPage`](#updateportalpage) +- [`deletePortalPage`](#deleteportalpage) +- [`detachPortalPage`](#detachportalpage) +- [`detachPortalPageBlock`](#detachportalpageblock) +- [`createPortalPage`](#createportalpage) +- [`interpolatePortalPages`](#interpolateportalpages) +- [`getDefaultPages`](#getdefaultpages) +- [`createPortalPageBlock`](#createportalpageblock) +- [`updatePortalPageBlock`](#updateportalpageblock) +- [`deletePortalPageBlock`](#deleteportalpageblock) +- [`createPortalConfig`](#createportalconfig) +- [`getPortalConfigV3`](#getportalconfigv3) +- [`putPortalConfig`](#putportalconfig) +- [`deletePortalConfig`](#deleteportalconfig) +- [`createPortalRevision`](#createportalrevision) +- [`listPortalRevisions`](#listportalrevisions) +- [`getPortalRevision`](#getportalrevision) +- [`updatePortalRevision`](#updateportalrevision) +- [`createPortalRevisionPreview`](#createportalrevisionpreview) +- [`publishPortalRevision`](#publishportalrevision) +- [`listAllPortalConfigs`](#listallportalconfigs) +- [`listPortalConfigSummaries`](#listportalconfigsummaries) +- [`swapPortalConfig`](#swapportalconfig) +- [`clonePortalConfig`](#cloneportalconfig) +- [`verifyDns`](#verifydns) +- [`getMobileConfig`](#getmobileconfig) +- [`putMobileConfig`](#putmobileconfig) **Activity** - [`getEntityActivityFeed`](#getentityactivityfeed) @@ -169,16 +190,27 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`getBillingAccount`](#getbillingaccount) **Login** -- [`ssoLogin`](#ssologin) - [`ssoLoginV3`](#ssologinv3) **Schemas** +- [`PortalUserPasskey`](#portaluserpasskey) +- [`MeterReadingCounterDetails`](#meterreadingcounterdetails) +- [`PortalNotification`](#portalnotification) +- [`PortalUserNotificationPreferences`](#portalusernotificationpreferences) +- [`MobileBuildStatus`](#mobilebuildstatus) +- [`MobileBranding`](#mobilebranding) +- [`MobileConfig`](#mobileconfig) +- [`MobileConfigUpdate`](#mobileconfigupdate) +- [`MobileOtaConfig`](#mobileotaconfig) +- [`NewDesignMigrationResult`](#newdesignmigrationresult) +- [`OtaPortal`](#otaportal) - [`ContextEntity`](#contextentity) - [`ContextEntities`](#contextentities) - [`ErrorResp`](#errorresp) +- [`SSOErrorResp`](#ssoerrorresp) +- [`SSODebugInfo`](#ssodebuginfo) - [`FailedRuleErrorResp`](#failedruleerrorresp) - [`EmailTemplates`](#emailtemplates) -- [`DeleteEntityFile`](#deleteentityfile) - [`SaveEntityFile`](#saveentityfile) - [`SavePortalFile`](#saveportalfile) - [`ExtraSchemaAttributes`](#extraschemaattributes) @@ -186,6 +218,8 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`AllowedFileExtensions`](#allowedfileextensions) - [`UpdateOnlyPortalConfigAttributes`](#updateonlyportalconfigattributes) - [`CommonConfigAttributes`](#commonconfigattributes) +- [`EngagementCenterTaskTemplates`](#engagementcentertasktemplates) +- [`NotificationTriggerConfig`](#notificationtriggerconfig) - [`UpsertPortalConfig`](#upsertportalconfig) - [`PortalConfig`](#portalconfig) - [`UpsertPortalWidget`](#upsertportalwidget) @@ -201,15 +235,21 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`DocumentWidget`](#documentwidget) - [`PaymentWidget`](#paymentwidget) - [`CampaignWidget`](#campaignwidget) +- [`ProductRecommendationsWidget`](#productrecommendationswidget) - [`PortalWidget`](#portalwidget) - [`ContactCountRequest`](#contactcountrequest) - [`ContactExistsRequest`](#contactexistsrequest) +- [`ContactIdentifyRequest`](#contactidentifyrequest) +- [`ContactIdentifyResponse`](#contactidentifyresponse) +- [`AccountExistsRequest`](#accountexistsrequest) - [`UserRequest`](#userrequest) - [`CreateUserRequest`](#createuserrequest) - [`OrganizationSettings`](#organizationsettings) - [`AuthConfig`](#authconfig) - [`Exists`](#exists) - [`EntitySlug`](#entityslug) +- [`EntitySlugConfig`](#entityslugconfig) +- [`TemplatesRef`](#templatesref) - [`EntityId`](#entityid) - [`BaseEntity`](#baseentity) - [`Schema`](#schema) @@ -219,7 +259,10 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`EntityResponse`](#entityresponse) - [`EntityResponseWithHits`](#entityresponsewithhits) - [`EntityResponseGroupedWithHits`](#entityresponsegroupedwithhits) +- [`SearchIncludes`](#searchincludes) - [`PortalUser`](#portaluser) +- [`PortalContactUpdate`](#portalcontactupdate) +- [`PortalContractUpdate`](#portalcontractupdate) - [`Contact`](#contact) - [`WorfklowIdentifier`](#worfklowidentifier) - [`Meter`](#meter) @@ -234,15 +277,28 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`EntityEditRule`](#entityeditrule) - [`ActivityItem`](#activityitem) - [`FileItem`](#fileitem) -- [`EntityFileCount`](#entityfilecount) +- [`FilePreviewResult`](#filepreviewresult) - [`AdminUser`](#adminuser) +- [`PortalSurface`](#portalsurface) +- [`PortalSurfaceDataAccess`](#portalsurfacedataaccess) +- [`PortalSurfaceEntityAccess`](#portalsurfaceentityaccess) - [`Grant`](#grant) - [`ActionLabel`](#actionlabel) - [`Rule`](#rule) - [`JourneyActions`](#journeyactions) +- [`JourneyContextUsagesRequest`](#journeycontextusagesrequest) +- [`JourneyContextUsagesResponse`](#journeycontextusagesresponse) - [`ExternalLink`](#externallink) +- [`OutstandingTask`](#outstandingtask) - [`WorkflowExecution`](#workflowexecution) - [`WorkflowStep`](#workflowstep) +- [`PortalWorkflow`](#portalworkflow) +- [`PortalWorkflowStage`](#portalworkflowstage) +- [`PortalNameOverrides`](#portalnameoverrides) +- [`PortalDescriptionOverrides`](#portaldescriptionoverrides) +- [`PortalWorkflowTask`](#portalworkflowtask) +- [`EntityPortalWorkflows`](#entityportalworkflows) +- [`PortalTaskConfig`](#portaltaskconfig) - [`BaseBillingEvent`](#basebillingevent) - [`InstallmentEvent`](#installmentevent) - [`ReimbursementEvent`](#reimbursementevent) @@ -254,15 +310,25 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`EntitySearchParams`](#entitysearchparams) - [`IdentifierAttribute`](#identifierattribute) - [`RegistrationIdentifier`](#registrationidentifier) +- [`AdditionalContactAttribute`](#additionalcontactattribute) - [`ContractIdentifier`](#contractidentifier) +- [`RegistrationValidationRule`](#registrationvalidationrule) - [`AcceptanceDecision`](#acceptancedecision) - [`TriggerPortalFlow`](#triggerportalflow) - [`ExtensionConfig`](#extensionconfig) - [`ExtensionHookSelection`](#extensionhookselection) - [`PublicExtensionCapabilities`](#publicextensioncapabilities) +- [`PublicSelfManagementExplanation`](#publicselfmanagementexplanation) +- [`PublicChangeEmailDetails`](#publicchangeemaildetails) +- [`PublicChangePasswordDetails`](#publicchangepassworddetails) +- [`PublicDeleteAccountDetails`](#publicdeleteaccountdetails) - [`DataRetrievalItem`](#dataretrievalitem) +- [`PublicAppDetails`](#publicappdetails) - [`PublicExtensionDetails`](#publicextensiondetails) - [`PublicDataRetrievalHookDetails`](#publicdataretrievalhookdetails) +- [`VisualizationMetadata`](#visualizationmetadata) +- [`VisualizationTypeOption`](#visualizationtypeoption) +- [`VisualizationDataRange`](#visualizationdatarange) - [`PublicContractIdentificationDetails`](#publiccontractidentificationdetails) - [`PublicMeterReadingPlausibilityCheckDetails`](#publicmeterreadingplausibilitycheckdetails) - [`Extension`](#extension) @@ -273,7 +339,13 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`ExtensionHookMeterReadingPlausibilityCheck`](#extensionhookmeterreadingplausibilitycheck) - [`ExtensionHookPriceDataRetrieval`](#extensionhookpricedataretrieval) - [`ExtensionHookConsumptionDataRetrieval`](#extensionhookconsumptiondataretrieval) +- [`ExtensionHookDataExport`](#extensionhookdataexport) +- [`ExtensionHookVisualizationMetadata`](#extensionhookvisualizationmetadata) - [`ExtensionHookCostDataRetrieval`](#extensionhookcostdataretrieval) +- [`ExtensionHookChangeEmail`](#extensionhookchangeemail) +- [`ExtensionHookChangePassword`](#extensionhookchangepassword) +- [`ExtensionHookDeleteAccount`](#extensionhookdeleteaccount) +- [`SecureProxyConfig`](#secureproxyconfig) - [`ExtensionAuthBlock`](#extensionauthblock) - [`Direction`](#direction) - [`TariffType`](#tarifftype) @@ -282,6 +354,8 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`ReadBy`](#readby) - [`ReadingStatus`](#readingstatus) - [`MeterReading`](#meterreading) +- [`PortalMeterReading`](#portalmeterreading) +- [`MeterCounter`](#metercounter) - [`MeterReadingPhoto`](#meterreadingphoto) - [`MeterReadingPhotoData`](#meterreadingphotodata) - [`SSOLoginToken`](#ssologintoken) @@ -289,6 +363,8 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`ProviderDisplayName`](#providerdisplayname) - [`ProviderConfig`](#providerconfig) - [`ProviderPublicConfig`](#providerpublicconfig) +- [`ProviderPublicConfigV3`](#providerpublicconfigv3) +- [`PublicIdentityProvider`](#publicidentityprovider) - [`AttributeMappingConfig`](#attributemappingconfig) - [`EntityMatchingConfig`](#entitymatchingconfig) - [`OIDCProviderConfig`](#oidcproviderconfig) @@ -299,197 +375,89 @@ const { data } = await customerPortalClient.upsertPortal(...) - [`SSOCallbackResponse`](#ssocallbackresponse) - [`BlockProps`](#blockprops) - [`BlockType`](#blocktype) +- [`HeldBackNode`](#heldbacknode) - [`BlockRequest`](#blockrequest) - [`BlockId`](#blockid) - [`Block`](#block) - [`PageRequest`](#pagerequest) - [`Page`](#page) +- [`PortalHeader`](#portalheader) +- [`PortalHeaderDesignOverrides`](#portalheaderdesignoverrides) - [`CommonConfigAttributesV3`](#commonconfigattributesv3) - [`PortalId`](#portalid) +- [`PortalDataExportColumn`](#portaldataexportcolumn) - [`UpsertPortalConfigV3`](#upsertportalconfigv3) - [`PortalConfigV3`](#portalconfigv3) +- [`PortalFeatureSettings`](#portalfeaturesettings) +- [`PortalCopilotVisibility`](#portalcopilotvisibility) +- [`PortalUsingDesign`](#portalusingdesign) +- [`PortalConfigSummaryV3`](#portalconfigsummaryv3) - [`JuiceSettings`](#juicesettings) +- [`RevisionPageRequest`](#revisionpagerequest) +- [`PortalRevisionRequest`](#portalrevisionrequest) +- [`PublishRevisionRequest`](#publishrevisionrequest) +- [`UpdatePortalRevisionRequest`](#updateportalrevisionrequest) +- [`RevisionSource`](#revisionsource) +- [`PortalRevisionSummary`](#portalrevisionsummary) +- [`PortalRevisionList`](#portalrevisionlist) +- [`PortalRevisionCreated`](#portalrevisioncreated) +- [`RevisionPage`](#revisionpage) +- [`PortalRevisionPreview`](#portalrevisionpreview) +- [`PreviewRevision`](#previewrevision) +- [`PortalRevision`](#portalrevision) +- [`PublishResult`](#publishresult) - [`SwappableConfig`](#swappableconfig) +- [`SwapPortalReferencesResult`](#swapportalreferencesresult) +- [`SwapPortalReferenceGroup`](#swapportalreferencegroup) +- [`SwapPortalReferenceItem`](#swapportalreferenceitem) - [`PortalUserRegistrationStatus`](#portaluserregistrationstatus) - [`BusinessPartnerItem`](#businesspartneritem) +- [`SupportReportType`](#supportreporttype) +- [`SupportRequestAttachment`](#supportrequestattachment) +- [`CleverPvContext`](#cleverpvcontext) +- [`CreateSupportRequest`](#createsupportrequest) +- [`SupportRequestResult`](#supportrequestresult) -### `upsertPortal` +### `createUserV3` -Upserts the settings for a portal of an organization. +Registers a portal user. +Supports two identification methods: +1. Using portal_id +2. Using domain -`POST /v2/portal/portal` +`POST /v3/portal/public/user` ```ts -const { data } = await client.upsertPortal( +const { data } = await client.createUserV3( { - origin: 'example', portal_id: 'example', + domain: 'example', }, { - entity_actions: [ - { - journey_id: '5da0a718-c822-403d-9f5d-20d4584e0528', - slug: 'contact', - action_Label: { /* ... */ } - } - ], - extensions: [ - { - id: 'string', - status: 'installed', - options: {} - } - ], - extension_hooks: {}, - default_user_to_notify: { - onPendingUser: [ - { /* ... */ } - ] - }, - enabled: true, - name: 'Installer Portal', - domain: 'abc.com', - is_epilot_domain: true, - epilot_domain: 'example-portal-12345.ecp.epilot.cloud', - domain_settings: { - is_custom_domain_enabled: true, - is_epilot_domain_enabled: true, - is_redirection_enabled: true - }, - design_id: '5da0a718-c822-403d-9f5d-20d4584e0528', - self_registration_setting: 'ALLOW_WITH_CONTACT_CREATION', - user_account_self_management: false, - feature_settings: { - start_page: true, - billing: true, - change_due_date: true, - new_design: true - }, - accessToken: 'string', - advanced_mfa: { - enabled: true - }, - auth_settings: { - passwordless_login: { - enabled: true + email: 'testemail921@yopmail.com', + first_name: 'John', + last_name: 'Doe', + contactId: '5da0a718-c822-403d-9f5d-20d4584e0528', + orgId: 728, + password: '124n$aAJs*d41h4', + contactIdentifiers: {}, + registration_identifiers: { + contact: { + email: 'john.doe@example.com' }, - entry_point: 'PASSWORD', - preferred_sso_providers: ['office-365-login'], - auto_redirect_to_sso: true - }, - cognito_details: { - cognito_user_pool_client_id: '6bsd0jkgoie74k2i8mrhc1vest', - cognito_user_pool_arn: 'arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341', - cognito_user_pool_id: 'eu-central-1_CUEQRNbUb', - password_policy: { - minimum_length: 8, - maximum_length: 256, - require_lowercase: true, - require_uppercase: true, - require_numbers: true, - require_symbols: true - } - }, - config: 'string', - contact_identifiers: ['email', 'last_name'], - approval_state_attributes: { - contact: ['name', 'address'], - contract: ['installment_amount'] - }, - email_templates: { - confirmAccount: '5da0a718-c822-403d-9f5d-20d4584e0528', - advancedAuth: '5da0a718-c822-403d-9f5d-20d4584e0528', - advancedMFA: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeySignUp: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeySignInOneTimePassword: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeyLoginOTP: '5da0a718-c822-403d-9f5d-20d4584e0528', - forgotPassword: '5da0a718-c822-403d-9f5d-20d4584e0528', - invitation: '5da0a718-c822-403d-9f5d-20d4584e0528', - partnerInvitation: '5da0a718-c822-403d-9f5d-20d4584e0528', - onNewQuote: '5da0a718-c822-403d-9f5d-20d4584e0528', - onMapAPendingUser: '5da0a718-c822-403d-9f5d-20d4584e0528', - onDocUpload: '5da0a718-c822-403d-9f5d-20d4584e0528', - onWorkflowStepAssigned: '5da0a718-c822-403d-9f5d-20d4584e0528', - confirmEmailUpdate: '5da0a718-c822-403d-9f5d-20d4584e0528', - verifyCodeToSetPassword: '5da0a718-c822-403d-9f5d-20d4584e0528' - }, - images: { - orderLeftTeaser: 'https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg', - orderRightTeaser: 'https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg', - welcomeBanner: 'https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg' - }, - entity_identifiers: { - type: { - isEnabled: true, - attributes: ['contract_number'] + contract: { + contract_number: '123456' } }, - contract_identifiers: [ - { - name: 'email', - schema: 'contact' - }, - { - name: 'last_name', - schema: 'contact' - }, - /* ... 1 more */ - ], - contract_selector_config: { - show_inactive: true, - title_path: 'string' + contact_identifiers_for_account: { + first_name: 'John', + last_name: 'Doe' }, - registration_identifiers: [ - { - name: 'last_name', - schema: 'contact' - }, - { - name: 'contract_number', - schema: 'contract' - } - ], - triggered_journeys: [ - { - trigger_name: 'FIRST_LOGIN', - journey_id: '5da0a718-c822-403d-9f5d-20d4584e0528' - } - ], - entity_edit_rules: [ - { - slug: 'contact', - attribute: 'first_name', - rule_type: 'cadence', - cadence_period_type: 'days', - cadence_period: 1, - changes_allowed: 1, - grace_period: 1, - allowed_increment: '10%', - allowed_decrement: '10%', - number_of_days_before_restriction: 10 - } - ], - allowed_file_extensions: { - document: ['pdf'], - image: ['jpg'], - spreadsheet: ['xls'], - presentation: ['ppt'], - audioVideo: ['mp4'], - email: ['eml'], - archive: ['zip'], - cad: ['cad'], - calendar: ['ics'], - other: ['txt'] + additional_contact_attributes: { + first_name: 'John', + last_name: 'Doe' }, - prevent_search_engine_indexing: true, - meter_reading_grace_period: 0, - inactive_contract_cutoff_years: 0, - is_dummy: true, - is_v3_item: true, - portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', - portal_sk_v3: 'PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c', - origin: 'string', - pages: {} + account_id: 'string' }, ) ``` @@ -499,24 +467,146 @@ const { data } = await client.upsertPortal( ```json { - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-12345.ecp.epilot.cloud", - "domain_settings": { - "is_custom_domain_enabled": true, - "is_epilot_domain_enabled": true, - "is_redirection_enabled": true - }, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", - "user_account_self_management": false, - "feature_settings": { - "start_page": true, + "message": "User created successfully" +} +``` + +
+ +--- + +### `validateToken` + +Validates Portal Token is valid. Pass the token via Authorization Header. + +`POST /v2/portal/token/validate` + +```ts +const { data } = await client.validateToken() +``` + +--- + +### `revokeToken` + +Revokes all of the access tokens for the given Refresh Token. + +`POST /v2/portal/token/revoke` + +```ts +const { data } = await client.revokeToken( + null, + { + refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' + }, +) +``` + +
+Response + +```json +{ + "message": "Token revoked successfully" +} +``` + +
+ +--- + +### `getPortalConfigByDomain` + +Retrieves the portal configuration by domain. + +`GET /v2/portal/public/config` + +```ts +const { data } = await client.getPortalConfigByDomain({ + domain: 'example', +}) +``` + +
+Response + +```json +{ + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", + "is_epilot_domain": true, + "epilot_domain": "example-portal-12345.ecp.epilot.cloud", + "domain_settings": { + "is_custom_domain_enabled": true, + "is_epilot_domain_enabled": true, + "is_redirection_enabled": true + }, + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": { + "design": { + "overrides": {} + } + }, + "allowed_portal_entities": ["contact", "contract"], + "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", + "user_account_self_management": false, + "feature_settings": { + "start_page": true, "billing": true, + "commodity_billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0, + "portal_copilot": false, + "portal_copilot_agent_id": "string", + "portal_copilot_visibility": { + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + } }, "accessToken": "string", "advanced_mfa": { @@ -526,21 +616,37 @@ const { data } = await client.upsertPortal( "passwordless_login": { "enabled": true }, + "passkeys": { + "enabled": false + }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_mobile_client_id": "3k9fj2l1m0n8b7v6c5x4z3a2s1", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -555,6 +661,7 @@ const { data } = await client.upsertPortal( "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -587,6 +694,7 @@ const { data } = await client.upsertPortal( "schema": "contact" } ], + "self_assignment_mode": "contracts", "contract_selector_config": { "show_inactive": true, "title_path": "string" @@ -601,10 +709,42 @@ const { data } = await client.upsertPortal( "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "identifiers": [], + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -638,12 +778,42 @@ const { data } = await client.upsertPortal( "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_added", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "target_ids": ["string"] + } + ], + "engagement_center_enabled": true, + "engagement_center_task_templates": { + "title": "{{task.name}}", + "subtitle": "{{workflow.name}} · {{entity._title}}" + }, + "engagement_center_title": { + "de": "Mein Postfach", + "en": "My inbox" + }, "id": 12345, "organization_id": 12345, + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"], + "held_back": [ + { + "page_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "block_id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "reason": "BLUEPRINT_MANAGED" + } + ], "org_settings": { "canary": { "enabled": true @@ -653,6 +823,7 @@ const { data } = await client.upsertPortal( } }, "feature_flags": {}, + "registration_validation_rules": {}, "grants": [ { "action": "entity-read", @@ -665,9 +836,15 @@ const { data } = await client.upsertPortal( "slug": "office-365-login", "display_name": "Office 365 Login", "oidc_config": {}, - "mobile_oidc_config": {} + "mobile_oidc_config": {}, + "debug_mode": false } - ] + ], + "preview_revision": { + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "name": "string", + "created_at": "1970-01-01T00:00:00.000Z" + } } ``` @@ -675,121 +852,62 @@ const { data } = await client.upsertPortal( --- -### `createUser` +### `createExport` -Registers a portal user +Request an asynchronous CSV export of the portal user's entities for one schema. Columns come from the request Returns a job id to poll. -`POST /v2/portal/public/user` +`POST /v1/portal/exports` ```ts -const { data } = await client.createUser( - { - origin: 'example', - }, +const { data } = await client.createExport( + null, { - email: 'testemail921@yopmail.com', - first_name: 'John', - last_name: 'Doe', - contactId: '5da0a718-c822-403d-9f5d-20d4584e0528', - orgId: 728, - password: '124n$aAJs*d41h4', - contactIdentifiers: {}, - registration_identifiers: { - contact: { - email: 'john.doe@example.com' - }, - contract: { - contract_number: '123456' - } + schema: 'string', + search: { + q: 'string', + q_fields: ['string'], + filters: [ + {} + ], + filters_context: [ + {} + ], + sort: {} }, - account_id: 'string' - }, -) -``` - -
-Response - -```json -{ - "message": "User created successfully" -} -``` - -
- ---- - -### `createUserV3` - -Registers a portal user with portal id - -`POST /v3/portal/public/user` - -```ts -const { data } = await client.createUserV3( - { - portal_id: 'example', - }, - { - email: 'testemail921@yopmail.com', - first_name: 'John', - last_name: 'Doe', - contactId: '5da0a718-c822-403d-9f5d-20d4584e0528', - orgId: 728, - password: '124n$aAJs*d41h4', - contactIdentifiers: {}, - registration_identifiers: { - contact: { - email: 'john.doe@example.com' - }, - contract: { - contract_number: '123456' + columns: [ + { + key: 'vertragsnummer', + header: { + de: 'Vertragsnummer', + en: 'Contract number' + }, + source: { + path: ['customer'], + attribute: 'customer_number', + address_field: 'full' + }, + formatter: 'text', + enum_labels: {} } - }, - account_id: 'string' + ], + expand_over: 'string', + language: 'de' }, ) ``` -
-Response - -```json -{ - "message": "User created successfully" -} -``` - -
- ---- - -### `validateToken` - -Validates Portal Token is valid. Pass the token via Authorization Header. - -`POST /v2/portal/token/validate` - -```ts -const { data } = await client.validateToken() -``` - --- -### `revokeToken` +### `getExport` -Revokes all of the access tokens for the given Refresh Token. +Get the status of an export job, including the download URL once ready. -`POST /v2/portal/token/revoke` +`GET /v1/portal/exports/{jobId}` ```ts -const { data } = await client.revokeToken( - null, - { - refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' - }, -) +const { data } = await client.getExport({ + jobId: 'example', +}) ```
@@ -797,7 +915,10 @@ const { data } = await client.revokeToken( ```json { - "message": "Token revoked successfully" + "jobId": "string", + "status": "queued", + "downloadUrl": "string", + "error": "string" } ``` @@ -805,15 +926,15 @@ const { data } = await client.revokeToken( --- -### `getPortalConfigByDomain` +### `getPortalExtensionsV3` -Retrieves the portal configuration by domain. +Retrieves the installed portal extensions. -`GET /v2/portal/public/config` +`GET /v3/portal/extensions` ```ts -const { data } = await client.getPortalConfigByDomain({ - domain: 'example', +const { data } = await client.getPortalExtensionsV3({ + portal_id: 'example', }) ``` @@ -821,192 +942,115 @@ const { data } = await client.getPortalConfigByDomain({ Response ```json -{ - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-12345.ecp.epilot.cloud", - "domain_settings": { - "is_custom_domain_enabled": true, - "is_epilot_domain_enabled": true, - "is_redirection_enabled": true - }, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", - "user_account_self_management": false, - "feature_settings": { - "start_page": true, - "billing": true, - "change_due_date": true, - "new_design": true - }, - "accessToken": "string", - "advanced_mfa": { - "enabled": true - }, - "auth_settings": { - "passwordless_login": { - "enabled": true - }, - "entry_point": "PASSWORD", - "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true - }, - "cognito_details": { - "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", - "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", - "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", - "password_policy": { - "minimum_length": 8, - "maximum_length": 256, - "require_lowercase": true, - "require_uppercase": true, - "require_numbers": true, - "require_symbols": true - } - }, - "config": "string", - "contact_identifiers": ["email", "last_name"], - "approval_state_attributes": { - "contact": ["name", "address"], - "contract": ["installment_amount"] - }, - "email_templates": { - "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", - "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", - "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", - "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" - }, - "images": { - "orderLeftTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg", - "orderRightTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg", - "welcomeBanner": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg" - }, - "entity_identifiers": { - "type": { - "isEnabled": true, - "attributes": ["contract_number"] - } - }, - "contract_identifiers": [ - { - "name": "email", - "schema": "contact" - }, - { - "name": "last_name", - "schema": "contact" - } - ], - "contract_selector_config": { - "show_inactive": true, - "title_path": "string" - }, - "registration_identifiers": [ - { - "name": "last_name", - "schema": "contact" +[ + { + "id": "string", + "app_id": "string", + "app_name": "string", + "name": { + "en": "string" }, - { - "name": "contract_number", - "schema": "contract" - } - ], - "triggered_journeys": [ - { - "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" - } - ], - "entity_edit_rules": [ - { - "slug": "contact", - "attribute": "first_name", - "rule_type": "cadence", - "cadence_period_type": "days", - "cadence_period": 1, - "changes_allowed": 1, - "grace_period": 1, - "allowed_increment": "10%", - "allowed_decrement": "10%", - "number_of_days_before_restriction": 10 - } - ], - "allowed_file_extensions": { - "document": ["pdf"], - "image": ["jpg"], - "spreadsheet": ["xls"], - "presentation": ["ppt"], - "audioVideo": ["mp4"], - "email": ["eml"], - "archive": ["zip"], - "cad": ["cad"], - "calendar": ["ics"], - "other": ["txt"] - }, - "prevent_search_engine_indexing": true, - "meter_reading_grace_period": 0, - "inactive_contract_cutoff_years": 0, - "is_dummy": true, - "is_v3_item": true, - "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "pages": {}, - "id": 12345, - "organization_id": 12345, - "org_settings": { - "canary": { - "enabled": true + "description": { + "en": "string" }, - "notracking": { - "enabled": true - } - }, - "feature_flags": {}, - "grants": [ - { - "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", - "effect": "allow" - } - ], - "identity_providers": [ - { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} - } - ] -} + "version": "string", + "options": [ + { + "id": "string", + "name": { + "en": "string" + }, + "type": "text", + "description": { + "en": "string" + }, + "default": "string", + "required": false + } + ], + "links": [ + { + "id": "string", + "name": { + "en": "string" + }, + "description": { + "en": "string" + }, + "type": "seamless", + "condition": "{{Contact.customer_number | is_not_empty}}", + "auth": { + "method": "GET", + "url": "string", + "params": {}, + "headers": {}, + "body": {}, + "cache": { + "key": "{{Options.api_key}}", + "ttl": "{{AuthResponse.data.expires_in}}" + } + }, + "redirect": { + "url": "string", + "params": {} + } + } + ], + "hooks": [ + { + "type": "registrationIdentifiersCheck", + "auth": { + "method": "GET", + "url": "string", + "params": {}, + "headers": {}, + "body": {}, + "cache": { + "key": "{{Options.api_key}}", + "ttl": "{{AuthResponse.data.expires_in}}" + } + }, + "call": { + "method": "POST", + "url": "string", + "params": {}, + "headers": {}, + "body": {}, + "result": "string" + }, + "resolved": { + "result": "string", + "error_message_path": "error.message" + }, + "use_static_ips": false, + "secure_proxy": { + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "use_case_slug": "string" + } + } + ] + } +] ```
--- -### `getPortalConfig` +### `getPublicPortalExtensionDetailsV3` -Retrieves the portal configuration. +Get public extension details shown to end customers and configuring users. +Supports two identification methods: +1. Using org_id + portal_id +2. Using domain -`GET /v2/portal/config` +`GET /v3/portal/public/extensions` ```ts -const { data } = await client.getPortalConfig({ - origin: 'example', +const { data } = await client.getPublicPortalExtensionDetailsV3({ + org_id: 'example', + portal_id: 'example', + domain: 'example', }) ``` @@ -1015,173 +1059,146 @@ const { data } = await client.getPortalConfig({ ```json { - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-12345.ecp.epilot.cloud", - "domain_settings": { - "is_custom_domain_enabled": true, - "is_epilot_domain_enabled": true, - "is_redirection_enabled": true - }, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", - "user_account_self_management": false, - "feature_settings": { - "start_page": true, - "billing": true, - "change_due_date": true, - "new_design": true - }, - "accessToken": "string", - "advanced_mfa": { - "enabled": true - }, - "auth_settings": { - "passwordless_login": { - "enabled": true - }, - "entry_point": "PASSWORD", - "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true - }, - "cognito_details": { - "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", - "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", - "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", - "password_policy": { - "minimum_length": 8, - "maximum_length": 256, - "require_lowercase": true, - "require_uppercase": true, - "require_numbers": true, - "require_symbols": true - } - }, - "config": "string", - "contact_identifiers": ["email", "last_name"], - "approval_state_attributes": { - "contact": ["name", "address"], - "contract": ["installment_amount"] - }, - "email_templates": { - "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", - "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", - "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", - "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" - }, - "images": { - "orderLeftTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg", - "orderRightTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg", - "welcomeBanner": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg" - }, - "entity_identifiers": { - "type": { - "isEnabled": true, - "attributes": ["contract_number"] - } - }, - "contract_identifiers": [ - { - "name": "email", - "schema": "contact" - }, + "consumptionDataRetrieval": [ { - "name": "last_name", - "schema": "contact" + "app": {}, + "extension": {}, + "hook": {} } ], - "contract_selector_config": { - "show_inactive": true, - "title_path": "string" - }, - "registration_identifiers": [ - { - "name": "last_name", - "schema": "contact" - }, + "dataExport": [ { - "name": "contract_number", - "schema": "contract" + "app": {}, + "extension": {}, + "hook": {} } ], - "triggered_journeys": [ + "priceDataRetrieval": [ { - "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "app": {}, + "extension": {}, + "hook": {} } ], - "entity_edit_rules": [ + "costDataRetrieval": [ { - "slug": "contact", - "attribute": "first_name", - "rule_type": "cadence", - "cadence_period_type": "days", - "cadence_period": 1, - "changes_allowed": 1, - "grace_period": 1, - "allowed_increment": "10%", - "allowed_decrement": "10%", - "number_of_days_before_restriction": 10 + "app": {}, + "extension": {}, + "hook": {} } ], - "allowed_file_extensions": { - "document": ["pdf"], - "image": ["jpg"], - "spreadsheet": ["xls"], - "presentation": ["ppt"], - "audioVideo": ["mp4"], - "email": ["eml"], - "archive": ["zip"], - "cad": ["cad"], - "calendar": ["ics"], - "other": ["txt"] + "contractIdentification": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "explanation": {} + } }, - "prevent_search_engine_indexing": true, - "meter_reading_grace_period": 0, - "inactive_contract_cutoff_years": 0, - "is_dummy": true, - "is_v3_item": true, - "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "pages": {}, - "id": 12345, - "organization_id": 12345, - "org_settings": { - "canary": { - "enabled": true + "meterReadingPlausibilityCheck": { + "extension": { + "id": "string", + "name": {} }, - "notracking": { - "enabled": true + "hook": { + "plausibility_mode": "check" } }, - "feature_flags": {}, - "grants": [ - { - "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", - "effect": "allow" + "changeEmail": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "change_mode": "asynchronous", + "require_password_confirmation": true, + "explanation": {} } - ], - "identity_providers": [ + }, + "changePassword": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "require_new_password": false, + "explanation": {} + } + }, + "deleteAccount": { + "app": { + "app_id": "string", + "name": {} + }, + "extension": { + "id": "string", + "name": {} + }, + "hook": { + "id": "string", + "explanation": {} + } + } +} +``` + +
+ +--- + +### `getConsumption` + +Get energy consumption data between a given time period. + +`GET /v2/portal/consumption` + +```ts +const { data } = await client.getConsumption({ + app_id: 'example', + extensionId: 'example', + hookId: 'example', + meter_id: 'example', + from: 'example', + to: 'example', + interval: 'example', + context_entities: 'example', +}) +``` + +
+Response + +```json +{ + "consumptions": [ { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} + "timestamp": "1970-01-01T00:00:00.000Z", + "value": 0, + "type": "nt", + "unit": "kWh", + "label": { + "en": "Billing period 1", + "de": "Abrechnungszeitraum 1" + }, + "period": { + "from": "2024-01-03T00:00:00.000Z", + "to": "2025-01-05T00:00:00.000Z" + } } ] } @@ -1191,29 +1208,105 @@ const { data } = await client.getPortalConfig({ --- -### `deletePortal` +### `prepareVisualizationExport` -Deletes the portal. +Asks an installed App to prepare a downloadable export of a visualization (consumption chart, dynamic tariff chart, etc.). The export is produced by the third-party App via a configured portal extensi -`DELETE /v2/portal/config` +`POST /v2/portal/visualization:export` ```ts -const { data } = await client.deletePortal({ - origin: 'example', +const { data } = await client.prepareVisualizationExport( + null, + { + app_id: 'string', + extension_id: 'string', + hook_id: 'string', + from: '1970-01-01T00:00:00.000Z', + to: '1970-01-01T00:00:00.000Z', + context_entities: [ + { + entity_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + entity_schema: 'contract' + } + ] + }, +) +``` + +
+Response + +```json +{ + "download_url": "string", + "filename": "string", + "content_type": "text/csv", + "expires_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getVisualizationMetadata` + +Returns runtime metadata describing how a visualization (consumption / price / cost chart) should be rendered for a given portal context (meter, contract, etc). Resolves the extension's `visualization + +`GET /v2/portal/visualization/metadata` + +```ts +const { data } = await client.getVisualizationMetadata({ + app_id: 'example', + extensionId: 'example', + context_entities: 'example', }) ``` +
+Response + +```json +{ + "type_options": [ + { + "id": "string", + "label": {}, + "aggregation_group": "string", + "statistical_method": "sum", + "unit": "string", + "color": "primary", + "precision": 0 + } + ], + "intervals": ["PT15M"], + "data_range": { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ --- -### `getPortalExtensions` +### `getCosts` -Retrieves the installed portal extensions. +Get energy cost data between a given time period. -`GET /v2/portal/extensions` +`GET /v2/portal/costs` ```ts -const { data } = await client.getPortalExtensions({ - origin: 'example', +const { data } = await client.getCosts({ + app_id: 'example', + extensionId: 'example', + hookId: 'example', + meter_id: 'example', + from: 'example', + to: 'example', + interval: 'example', + context_entities: 'example', }) ``` @@ -1221,103 +1314,40 @@ const { data } = await client.getPortalExtensions({ Response ```json -[ - { - "id": "string", - "app_id": "string", - "app_name": "string", - "name": { - "en": "string" - }, - "description": { - "en": "string" - }, - "version": "string", - "options": [ - { - "id": "string", - "name": { - "en": "string" - }, - "type": "text", - "description": { - "en": "string" - }, - "default": "string", - "required": false - } - ], - "links": [ - { - "id": "string", - "name": { - "en": "string" - }, - "description": { - "en": "string" - }, - "type": "seamless", - "condition": "{{Contact.customer_number | is_not_empty}}", - "auth": { - "method": "GET", - "url": "string", - "params": {}, - "headers": {}, - "body": {}, - "cache": { - "key": "{{Options.api_key}}", - "ttl": "{{AuthResponse.data.expires_in}}" - } - }, - "redirect": { - "url": "string", - "params": {} - } - } - ], - "hooks": [ - { - "type": "registrationIdentifiersCheck", - "auth": { - "method": "GET", - "url": "string", - "params": {}, - "headers": {}, - "body": {}, - "cache": { - "key": "{{Options.api_key}}", - "ttl": "{{AuthResponse.data.expires_in}}" - } - }, - "call": { - "method": "POST", - "url": "string", - "params": {}, - "headers": {}, - "body": {}, - "result": "string" - }, - "use_static_ips": false - } - ] - } -] +{ + "costs": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "unit_amount": 1234, + "unit_amount_currency": "EUR", + "unit_amount_decimal": "12.34", + "tax_behavior": "exclusive", + "tax_rate": 19 + } + ] +} ```
--- -### `getPublicPortalExtensionDetails` +### `getPrices` -Get public extension details shown to end customers and configuring users. +Get energy prices data between a given time period. -`GET /v2/portal/public/extensions` +`GET /v2/portal/prices` ```ts -const { data } = await client.getPublicPortalExtensionDetails({ - org_id: 'example', - origin: 'example', +const { data } = await client.getPrices({ + app_id: 'example', + extensionId: 'example', + hookId: 'example', + meter_id: 'example', + from: 'example', + to: 'example', + interval: 'example', + context_entities: 'example', }) ``` @@ -1326,81 +1356,28 @@ const { data } = await client.getPublicPortalExtensionDetails({ ```json { - "consumptionDataRetrieval": [ - { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } - } - ], - "priceDataRetrieval": [ - { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } - } - ], - "costDataRetrieval": [ + "prices": [ { - "extension": { - "id": "string", - "name": { - "en": "string" - } + "timestamp": "1970-01-01T00:00:00.000Z", + "unit_amount": 1234, + "unit_amount_currency": "EUR", + "unit_amount_decimal": "12.34", + "components": { + "auction_price_amount": 1000, + "auction_price_amount_decimal": "10.00", + "taxes_levies_amount": 50, + "taxes_levies_amount_decimal": "0.50", + "source_fee_amount": 50, + "source_fee_amount_decimal": "0.50", + "grid_fee_amount": 100, + "grid_fee_amount_decimal": "1.00", + "margin_amount": 34, + "margin_amount_decimal": "0.34" }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } - } - ], - "contractIdentification": { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "explanation": { - "en": "This process will give you access to all Contracts kept" - } - } - }, - "meterReadingPlausibilityCheck": { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "plausibility_mode": "check" + "tax_behavior": "exclusive", + "tax_rate": 19 } - } + ] } ``` @@ -1408,15 +1385,16 @@ const { data } = await client.getPublicPortalExtensionDetails({ --- -### `getPortalExtensionsV3` +### `getExternalLinksV3` -Retrieves the installed portal extensions. +Retrieves the portal configuration external links. -`GET /v3/portal/extensions` +`GET /v3/portal/external-links` ```ts -const { data } = await client.getPortalExtensionsV3({ +const { data } = await client.getExternalLinksV3({ portal_id: 'example', + contactId: 'example', }) ``` @@ -1427,209 +1405,40 @@ const { data } = await client.getPortalExtensionsV3({ [ { "id": "string", - "app_id": "string", - "app_name": "string", - "name": { - "en": "string" - }, - "description": { - "en": "string" - }, - "version": "string", - "options": [ - { - "id": "string", - "name": { - "en": "string" - }, - "type": "text", - "description": { - "en": "string" - }, - "default": "string", - "required": false - } - ], - "links": [ - { - "id": "string", - "name": { - "en": "string" - }, - "description": { - "en": "string" - }, - "type": "seamless", - "condition": "{{Contact.customer_number | is_not_empty}}", - "auth": { - "method": "GET", - "url": "string", - "params": {}, - "headers": {}, - "body": {}, - "cache": { - "key": "{{Options.api_key}}", - "ttl": "{{AuthResponse.data.expires_in}}" - } - }, - "redirect": { - "url": "string", - "params": {} - } - } + "label": {}, + "type": "link", + "link": "string", + "rules": [ + {} ], - "hooks": [ - { - "type": "registrationIdentifiersCheck", - "auth": { - "method": "GET", - "url": "string", - "params": {}, - "headers": {}, - "body": {}, - "cache": { - "key": "{{Options.api_key}}", - "ttl": "{{AuthResponse.data.expires_in}}" - } - }, - "call": { - "method": "POST", - "url": "string", - "params": {}, - "headers": {}, - "body": {}, - "result": "string" - }, - "use_static_ips": false - } - ] - } -] -``` - -
- ---- - -### `getPublicPortalExtensionDetailsV3` - -Get public extension details shown to end customers and configuring users. -Supports two identification methods: -1. Using org_id + portal_id -2. Using domain - -`GET /v3/portal/public/extensions` - -```ts -const { data } = await client.getPublicPortalExtensionDetailsV3({ - org_id: 'example', - portal_id: 'example', - domain: 'example', -}) -``` - -
-Response - -```json -{ - "consumptionDataRetrieval": [ - { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } - } - ], - "priceDataRetrieval": [ - { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } - } - ], - "costDataRetrieval": [ - { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "id": "string", - "name": { - "en": "string" - }, - "intervals": ["string"] - } - } - ], - "contractIdentification": { - "extension": { - "id": "string", - "name": { - "en": "string" - } - }, - "hook": { - "explanation": { - "en": "This process will give you access to all Contracts kept" - } - } - }, - "meterReadingPlausibilityCheck": { - "extension": { - "id": "string", - "name": { - "en": "string" - } + "attribute": "string", + "entity": "string", + "attribute_value": "string", + "icon": { + "name": "string", + "color": "string", + "size": 0 }, - "hook": { - "plausibility_mode": "check" - } + "extension_link_id": ["string"] } -} +] ```
--- -### `getConsumption` +### `getResolvedSeamlessLink` -Get Consumption +Retrieves a resolved seamless portal link. -`GET /v2/portal/consumption` +`GET /v2/portal/resolve:seamless-link` ```ts -const { data } = await client.getConsumption({ +const { data } = await client.getResolvedSeamlessLink({ app_id: 'example', - extensionId: 'example', - hookId: 'example', - meter_id: 'example', - from: 'example', - to: 'example', - interval: 'example', + extension_id: 'example', + link_id: 'example', context_entities: 'example', }) ``` @@ -1639,13 +1448,7 @@ const { data } = await client.getConsumption({ ```json { - "consumptions": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "value": 0, - "type": "string" - } - ] + "link": "string" } ``` @@ -1653,22 +1456,16 @@ const { data } = await client.getConsumption({ --- -### `getCosts` +### `getPublicPortalConfigV3` -Get Costs +Retrieves the public portal configuration. -`GET /v2/portal/costs` +`GET /v3/portal/public/portal/config` ```ts -const { data } = await client.getCosts({ - app_id: 'example', - extensionId: 'example', - hookId: 'example', - meter_id: 'example', - from: 'example', - to: 'example', - interval: 'example', - context_entities: 'example', +const { data } = await client.getPublicPortalConfigV3({ + org_id: 'example', + portal_id: 'example', }) ``` @@ -1677,226 +1474,81 @@ const { data } = await client.getCosts({ ```json { - "costs": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "unit_amount": 1234, - "unit_amount_currency": "EUR", - "unit_amount_decimal": "12.34", - "tax_behavior": "exclusive", - "tax_rate": 19 + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" } - ] -} -``` - -
- ---- - -### `getPrices` - -Get Prices - -`GET /v2/portal/prices` - -```ts -const { data } = await client.getPrices({ - app_id: 'example', - extensionId: 'example', - hookId: 'example', - meter_id: 'example', - from: 'example', - to: 'example', - interval: 'example', - context_entities: 'example', -}) -``` - -
-Response - -```json -{ - "prices": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "unit_amount": 1234, - "unit_amount_currency": "EUR", - "unit_amount_decimal": "12.34", - "components": { - "auction_price_amount": 1000, - "auction_price_amount_decimal": "10.00", - "taxes_levies_amount": 50, - "taxes_levies_amount_decimal": "0.50", - "source_fee_amount": 50, - "source_fee_amount_decimal": "0.50", - "grid_fee_amount": 100, - "grid_fee_amount_decimal": "1.00", - "margin_amount": 34, - "margin_amount_decimal": "0.34" - }, - "tax_behavior": "exclusive", - "tax_rate": 19 + }, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", + "is_epilot_domain": true, + "epilot_domain": "example-portal-12345.ecp.epilot.cloud", + "domain_settings": { + "is_custom_domain_enabled": true, + "is_epilot_domain_enabled": true, + "is_redirection_enabled": true + }, + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": { + "design": { + "overrides": {} } - ] -} -``` - -
- ---- - -### `getExternalLinks` - -Retrieves the portal configuration external links. - -`GET /v2/portal/external-links` - -```ts -const { data } = await client.getExternalLinks({ - origin: 'example', - contactId: 'example', -}) -``` - -
-Response - -```json -[ - { - "id": "string", - "label": {}, - "type": "link", - "link": "string", - "rules": [ - {} - ], - "attribute": "string", - "entity": "string", - "attribute_value": "string", - "icon": { - "name": "string", - "color": "string", - "size": 0 - }, - "extension_link_id": ["string"] - } -] -``` - -
- ---- - -### `getExternalLinksV3` - -Retrieves the portal configuration external links. - -`GET /v3/portal/external-links` - -```ts -const { data } = await client.getExternalLinksV3({ - portal_id: 'example', - contactId: 'example', -}) -``` - -
-Response - -```json -[ - { - "id": "string", - "label": {}, - "type": "link", - "link": "string", - "rules": [ - {} - ], - "attribute": "string", - "entity": "string", - "attribute_value": "string", - "icon": { - "name": "string", - "color": "string", - "size": 0 - }, - "extension_link_id": ["string"] - } -] -``` - -
- ---- - -### `getResolvedSeamlessLink` - -Retrieves a resolved seamless portal link. - -`GET /v2/portal/resolve:seamless-link` - -```ts -const { data } = await client.getResolvedSeamlessLink({ - app_id: 'example', - extension_id: 'example', - link_id: 'example', - context_entities: 'example', -}) -``` - -
-Response - -```json -{ - "link": "string" -} -``` - -
- ---- - -### `getPublicPortalConfig` - -Retrieves the public portal configuration. - -`GET /v2/portal/public/portal/config` - -```ts -const { data } = await client.getPublicPortalConfig({ - org_id: 'example', - origin: 'example', -}) -``` - -
-Response - -```json -{ - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-12345.ecp.epilot.cloud", - "domain_settings": { - "is_custom_domain_enabled": true, - "is_epilot_domain_enabled": true, - "is_redirection_enabled": true }, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, + "commodity_billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0, + "portal_copilot": false, + "portal_copilot_agent_id": "string", + "portal_copilot_visibility": { + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + } }, "accessToken": "string", "advanced_mfa": { @@ -1906,21 +1558,37 @@ const { data } = await client.getPublicPortalConfig({ "passwordless_login": { "enabled": true }, + "passkeys": { + "enabled": false + }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_mobile_client_id": "3k9fj2l1m0n8b7v6c5x4z3a2s1", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -1935,6 +1603,7 @@ const { data } = await client.getPublicPortalConfig({ "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -1967,6 +1636,7 @@ const { data } = await client.getPublicPortalConfig({ "schema": "contact" } ], + "self_assignment_mode": "contracts", "contract_selector_config": { "show_inactive": true, "title_path": "string" @@ -1981,10 +1651,42 @@ const { data } = await client.getPublicPortalConfig({ "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "identifiers": [], + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -2018,12 +1720,42 @@ const { data } = await client.getPublicPortalConfig({ "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_added", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "target_ids": ["string"] + } + ], + "engagement_center_enabled": true, + "engagement_center_task_templates": { + "title": "{{task.name}}", + "subtitle": "{{workflow.name}} · {{entity._title}}" + }, + "engagement_center_title": { + "de": "Mein Postfach", + "en": "My inbox" + }, "id": 12345, "organization_id": 12345, + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"], + "held_back": [ + { + "page_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "block_id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "reason": "BLUEPRINT_MANAGED" + } + ], "org_settings": { "canary": { "enabled": true @@ -2033,6 +1765,7 @@ const { data } = await client.getPublicPortalConfig({ } }, "feature_flags": {}, + "registration_validation_rules": {}, "grants": [ { "action": "entity-read", @@ -2045,9 +1778,15 @@ const { data } = await client.getPublicPortalConfig({ "slug": "office-365-login", "display_name": "Office 365 Login", "oidc_config": {}, - "mobile_oidc_config": {} + "mobile_oidc_config": {}, + "debug_mode": false } - ] + ], + "preview_revision": { + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "name": "string", + "created_at": "1970-01-01T00:00:00.000Z" + } } ``` @@ -2055,15 +1794,15 @@ const { data } = await client.getPublicPortalConfig({ --- -### `getOrgPortalConfig` +### `getOrgPortalConfigV3` Retrieves the portal configuration for the organization. -`GET /v2/portal/org/portal/config` +`GET /v3/portal/org/portal/config` ```ts -const { data } = await client.getOrgPortalConfig({ - origin: 'example', +const { data } = await client.getOrgPortalConfigV3({ + portal_id: 'example', }) ``` @@ -2072,6 +1811,43 @@ const { data } = await client.getOrgPortalConfig({ ```json { + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -2083,13 +1859,33 @@ const { data } = await client.getOrgPortalConfig({ "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": { + "design": { + "overrides": {} + } + }, + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, + "commodity_billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0, + "portal_copilot": false, + "portal_copilot_agent_id": "string", + "portal_copilot_visibility": { + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + } }, "accessToken": "string", "advanced_mfa": { @@ -2099,21 +1895,37 @@ const { data } = await client.getOrgPortalConfig({ "passwordless_login": { "enabled": true }, + "passkeys": { + "enabled": false + }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_mobile_client_id": "3k9fj2l1m0n8b7v6c5x4z3a2s1", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -2128,6 +1940,7 @@ const { data } = await client.getOrgPortalConfig({ "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -2160,6 +1973,7 @@ const { data } = await client.getOrgPortalConfig({ "schema": "contact" } ], + "self_assignment_mode": "contracts", "contract_selector_config": { "show_inactive": true, "title_path": "string" @@ -2174,10 +1988,42 @@ const { data } = await client.getOrgPortalConfig({ "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "identifiers": [], + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -2211,12 +2057,42 @@ const { data } = await client.getOrgPortalConfig({ "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", "pages": {}, + "global_blocks": {}, + "notification_triggers": [ + { + "trigger_type": "entity_added", + "entity_schema": "opportunity", + "enabled": true, + "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "target_ids": ["string"] + } + ], + "engagement_center_enabled": true, + "engagement_center_task_templates": { + "title": "{{task.name}}", + "subtitle": "{{workflow.name}} · {{entity._title}}" + }, + "engagement_center_title": { + "de": "Mein Postfach", + "en": "My inbox" + }, "id": 12345, "organization_id": 12345, + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"], + "held_back": [ + { + "page_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "block_id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "reason": "BLUEPRINT_MANAGED" + } + ], "org_settings": { "canary": { "enabled": true @@ -2226,6 +2102,7 @@ const { data } = await client.getOrgPortalConfig({ } }, "feature_flags": {}, + "registration_validation_rules": {}, "grants": [ { "action": "entity-read", @@ -2238,9 +2115,20 @@ const { data } = await client.getOrgPortalConfig({ "slug": "office-365-login", "display_name": "Office 365 Login", "oidc_config": {}, - "mobile_oidc_config": {} + "mobile_oidc_config": {}, + "debug_mode": false, + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "expose_client_secret": false, + "debug_mode_until": "2026-10-30T12:00:00.000Z" } ], + "preview_revision": { + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "name": "string", + "created_at": "1970-01-01T00:00:00.000Z" + }, "certificate_details": { "status": "PENDING_VALIDATION", "failed_reason": "CAA_ERROR" @@ -2252,17 +2140,14 @@ const { data } = await client.getOrgPortalConfig({ --- -### `getPublicPortalConfigV3` +### `getAllPortalConfigs` -Retrieves the public portal configuration. +Retrieves all portal configurations. -`GET /v3/portal/public/portal/config` +`GET /v2/portal/configs` ```ts -const { data } = await client.getPublicPortalConfigV3({ - org_id: 'example', - portal_id: 'example', -}) +const { data } = await client.getAllPortalConfigs() ```
@@ -2270,62 +2155,193 @@ const { data } = await client.getPublicPortalConfigV3({ ```json { - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-12345.ecp.epilot.cloud", - "domain_settings": { - "is_custom_domain_enabled": true, - "is_epilot_domain_enabled": true, - "is_redirection_enabled": true - }, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", - "user_account_self_management": false, - "feature_settings": { - "start_page": true, - "billing": true, - "change_due_date": true, - "new_design": true - }, - "accessToken": "string", - "advanced_mfa": { - "enabled": true - }, - "auth_settings": { - "passwordless_login": { - "enabled": true - }, - "entry_point": "PASSWORD", - "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true - }, - "cognito_details": { - "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", - "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", - "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", - "password_policy": { - "minimum_length": 8, - "maximum_length": 256, - "require_lowercase": true, - "require_uppercase": true, - "require_numbers": true, - "require_symbols": true - } - }, - "config": "string", - "contact_identifiers": ["email", "last_name"], - "approval_state_attributes": { - "contact": ["name", "address"], - "contract": ["installment_amount"] - }, - "email_templates": { - "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", + "data": [ + { + "mobile_config": {}, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", + "is_epilot_domain": true, + "epilot_domain": "example-portal-12345.ecp.epilot.cloud", + "domain_settings": {}, + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": {}, + "allowed_portal_entities": ["contact", "contract"], + "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", + "user_account_self_management": false, + "feature_settings": {}, + "accessToken": "string", + "advanced_mfa": {}, + "auth_settings": {}, + "cognito_details": {}, + "config": "string", + "contact_identifiers": ["email", "last_name"], + "approval_state_attributes": {}, + "email_templates": {}, + "images": {}, + "entity_identifiers": {}, + "contract_identifiers": [], + "self_assignment_mode": "contracts", + "contract_selector_config": {}, + "registration_identifiers": [], + "surfaces": [], + "contact_identifiers_for_account": [], + "additional_contact_attributes": [], + "triggered_journeys": [], + "entity_edit_rules": [], + "allowed_file_extensions": {}, + "prevent_search_engine_indexing": true, + "meter_reading_grace_period": 0, + "inactive_contract_cutoff_years": 0, + "is_dummy": true, + "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "origin": "string", + "pages": {}, + "global_blocks": {}, + "notification_triggers": [], + "engagement_center_enabled": true, + "engagement_center_task_templates": {}, + "engagement_center_title": {}, + "id": 12345, + "organization_id": 12345, + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"], + "held_back": [], + "org_settings": {}, + "feature_flags": {}, + "registration_validation_rules": {}, + "grants": [], + "identity_providers": [], + "preview_revision": {} + } + ] +} +``` + +
+ +--- + +### `migrateEmailTemplateReferences` + +Walk every email-template config row in the caller's org and re-point any +field on `email_templates` that currently references `source_template_id` +at `destination_template_id`. Intended to be called + +`POST /v3/portal/email-templates:migrate-references` + +```ts +const { data } = await client.migrateEmailTemplateReferences( + null, + { + source_template_id: 'string', + destination_template_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "migrated_portal_count": 2, + "migrated_portal_ids": ["string"], + "failed_portal_ids": ["string"] +} +``` + +
+ +--- + +### `listEmailTemplateReferences` + +Read-only sibling of migrateEmailTemplateReferences. Lists every portal in +the caller's org whose `email_templates` config references `template_id`, +without rewriting anything. Used by the email-templ + +`POST /v3/portal/email-templates:list-references` + +```ts +const { data } = await client.listEmailTemplateReferences( + null, + { + template_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "portals": [ + { + "id": "string", + "name": "string" + } + ] +} +``` + +
+ +--- + +### `upsertEmailTemplatesByPortalId` + +Upserts the email templates of a portal by portal ID. On a portal with versioning enabled, the change is stored as a revision (`Updated via API`) and published in the same call, so every change to the + +`POST /v3/portal/email-templates/{portal_id}` + +```ts +const { data } = await client.upsertEmailTemplatesByPortalId( + { + portal_id: 'example', + }, + { + confirmAccount: '5da0a718-c822-403d-9f5d-20d4584e0528', + advancedAuth: '5da0a718-c822-403d-9f5d-20d4584e0528', + advancedMFA: '5da0a718-c822-403d-9f5d-20d4584e0528', + journeySignUp: '5da0a718-c822-403d-9f5d-20d4584e0528', + journeySignInOneTimePassword: '5da0a718-c822-403d-9f5d-20d4584e0528', + passkeyVerificationCode: '5da0a718-c822-403d-9f5d-20d4584e0528', + journeyLoginOTP: '5da0a718-c822-403d-9f5d-20d4584e0528', + forgotPassword: '5da0a718-c822-403d-9f5d-20d4584e0528', + invitation: '5da0a718-c822-403d-9f5d-20d4584e0528', + partnerInvitation: '5da0a718-c822-403d-9f5d-20d4584e0528', + onNewQuote: '5da0a718-c822-403d-9f5d-20d4584e0528', + onMapAPendingUser: '5da0a718-c822-403d-9f5d-20d4584e0528', + onDocUpload: '5da0a718-c822-403d-9f5d-20d4584e0528', + onWorkflowStepAssigned: '5da0a718-c822-403d-9f5d-20d4584e0528', + confirmEmailUpdate: '5da0a718-c822-403d-9f5d-20d4584e0528', + verifyCodeToSetPassword: '5da0a718-c822-403d-9f5d-20d4584e0528' + }, +) +``` + +
+Response + +```json +{ + "message": "Email Templates upserted successfully", + "emailTemplates": { + "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -2336,109 +2352,7 @@ const { data } = await client.getPublicPortalConfigV3({ "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" - }, - "images": { - "orderLeftTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg", - "orderRightTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg", - "welcomeBanner": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg" - }, - "entity_identifiers": { - "type": { - "isEnabled": true, - "attributes": ["contract_number"] - } - }, - "contract_identifiers": [ - { - "name": "email", - "schema": "contact" - }, - { - "name": "last_name", - "schema": "contact" - } - ], - "contract_selector_config": { - "show_inactive": true, - "title_path": "string" - }, - "registration_identifiers": [ - { - "name": "last_name", - "schema": "contact" - }, - { - "name": "contract_number", - "schema": "contract" - } - ], - "triggered_journeys": [ - { - "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" - } - ], - "entity_edit_rules": [ - { - "slug": "contact", - "attribute": "first_name", - "rule_type": "cadence", - "cadence_period_type": "days", - "cadence_period": 1, - "changes_allowed": 1, - "grace_period": 1, - "allowed_increment": "10%", - "allowed_decrement": "10%", - "number_of_days_before_restriction": 10 - } - ], - "allowed_file_extensions": { - "document": ["pdf"], - "image": ["jpg"], - "spreadsheet": ["xls"], - "presentation": ["ppt"], - "audioVideo": ["mp4"], - "email": ["eml"], - "archive": ["zip"], - "cad": ["cad"], - "calendar": ["ics"], - "other": ["txt"] - }, - "prevent_search_engine_indexing": true, - "meter_reading_grace_period": 0, - "inactive_contract_cutoff_years": 0, - "is_dummy": true, - "is_v3_item": true, - "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "pages": {}, - "id": 12345, - "organization_id": 12345, - "org_settings": { - "canary": { - "enabled": true - }, - "notracking": { - "enabled": true - } - }, - "feature_flags": {}, - "grants": [ - { - "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", - "effect": "allow" - } - ], - "identity_providers": [ - { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} - } - ] + } } ``` @@ -2446,14 +2360,14 @@ const { data } = await client.getPublicPortalConfigV3({ --- -### `getOrgPortalConfigV3` +### `getEmailTemplatesByPortalId` -Retrieves the portal configuration for the organization. +Retrieves the email templates of a portal by portal ID -`GET /v3/portal/org/portal/config` +`GET /v3/portal/email-templates/{portal_id}` ```ts -const { data } = await client.getOrgPortalConfigV3({ +const { data } = await client.getEmailTemplatesByPortalId({ portal_id: 'example', }) ``` @@ -2463,179 +2377,83 @@ const { data } = await client.getOrgPortalConfigV3({ ```json { - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-12345.ecp.epilot.cloud", - "domain_settings": { - "is_custom_domain_enabled": true, - "is_epilot_domain_enabled": true, - "is_redirection_enabled": true - }, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", - "user_account_self_management": false, - "feature_settings": { - "start_page": true, - "billing": true, - "change_due_date": true, - "new_design": true - }, - "accessToken": "string", - "advanced_mfa": { - "enabled": true - }, - "auth_settings": { - "passwordless_login": { - "enabled": true - }, - "entry_point": "PASSWORD", - "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true - }, - "cognito_details": { - "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", - "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", - "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", - "password_policy": { - "minimum_length": 8, - "maximum_length": 256, - "require_lowercase": true, - "require_uppercase": true, - "require_numbers": true, - "require_symbols": true - } - }, - "config": "string", - "contact_identifiers": ["email", "last_name"], - "approval_state_attributes": { - "contact": ["name", "address"], - "contract": ["installment_amount"] - }, - "email_templates": { - "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", - "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", - "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", - "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" - }, - "images": { - "orderLeftTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg", - "orderRightTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg", - "welcomeBanner": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg" - }, - "entity_identifiers": { - "type": { - "isEnabled": true, - "attributes": ["contract_number"] - } - }, - "contract_identifiers": [ - { - "name": "email", - "schema": "contact" - }, - { - "name": "last_name", - "schema": "contact" - } - ], - "contract_selector_config": { - "show_inactive": true, - "title_path": "string" - }, - "registration_identifiers": [ - { - "name": "last_name", - "schema": "contact" - }, - { - "name": "contract_number", - "schema": "contract" - } - ], - "triggered_journeys": [ - { - "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" - } - ], - "entity_edit_rules": [ - { - "slug": "contact", - "attribute": "first_name", - "rule_type": "cadence", - "cadence_period_type": "days", - "cadence_period": 1, - "changes_allowed": 1, - "grace_period": 1, - "allowed_increment": "10%", - "allowed_decrement": "10%", - "number_of_days_before_restriction": 10 - } - ], - "allowed_file_extensions": { - "document": ["pdf"], - "image": ["jpg"], - "spreadsheet": ["xls"], - "presentation": ["ppt"], - "audioVideo": ["mp4"], - "email": ["eml"], - "archive": ["zip"], - "cad": ["cad"], - "calendar": ["ics"], - "other": ["txt"] - }, - "prevent_search_engine_indexing": true, - "meter_reading_grace_period": 0, - "inactive_contract_cutoff_years": 0, - "is_dummy": true, + "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", + "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", + "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", + "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" +} +``` + +
+ +--- + +### `getPublicPortalWidgetsV3` + +Retrieves the public widgets of a portal. +Supports two identification methods: +1. Using org_id + portal_id +2. Using domain + +`GET /v3/portal/public/widgets` + +```ts +const { data } = await client.getPublicPortalWidgetsV3({ + org_id: 'example', + portal_id: 'example', + domain: 'example', +}) +``` + +
+Response + +```json +{ + "portal_sk_v3": "string", "is_v3_item": true, - "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "pages": {}, - "id": 12345, - "organization_id": 12345, - "org_settings": { - "canary": { - "enabled": true - }, - "notracking": { - "enabled": true - } - }, - "feature_flags": {}, - "grants": [ + "widgets": [ { - "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", - "effect": "allow" - } - ], - "identity_providers": [ + "id": "string", + "type": "ACTION_WIDGET", + "listIndex": 0, + "headline": { + "en": "string", + "de": "string" + }, + "subHeadline": { + "en": "string", + "de": "string" + }, + "schema": "string" + }, { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} + "id": "string", + "type": "ACTION_WIDGET", + "listIndex": 0, + "headline": { + "en": "string", + "de": "string" + }, + "subHeadline": { + "en": "string", + "de": "string" + }, + "content": "string" } - ], - "certificate_details": { - "status": "PENDING_VALIDATION", - "failed_reason": "CAA_ERROR" - } + ] } ``` @@ -2643,14 +2461,17 @@ const { data } = await client.getOrgPortalConfigV3({ --- -### `getAllPortalConfigs` +### `getPortalWidgetsV3` -Retrieves all portal configurations. +Retrieves the widgets of a portal by portal_id. -`GET /v2/portal/configs` +`GET /v3/portal/widgets` ```ts -const { data } = await client.getAllPortalConfigs() +const { data } = await client.getPortalWidgetsV3({ + portal_id: 'example', + contract_id: 'example', +}) ```
@@ -2658,277 +2479,9 @@ const { data } = await client.getAllPortalConfigs() ```json { - "data": [ - { - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-12345.ecp.epilot.cloud", - "domain_settings": {}, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", - "user_account_self_management": false, - "feature_settings": {}, - "accessToken": "string", - "advanced_mfa": {}, - "auth_settings": {}, - "cognito_details": {}, - "config": "string", - "contact_identifiers": ["email", "last_name"], - "approval_state_attributes": {}, - "email_templates": {}, - "images": {}, - "entity_identifiers": {}, - "contract_identifiers": [], - "contract_selector_config": {}, - "registration_identifiers": [], - "triggered_journeys": [], - "entity_edit_rules": [], - "allowed_file_extensions": {}, - "prevent_search_engine_indexing": true, - "meter_reading_grace_period": 0, - "inactive_contract_cutoff_years": 0, - "is_dummy": true, - "is_v3_item": true, - "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "pages": {}, - "id": 12345, - "organization_id": 12345, - "org_settings": {}, - "feature_flags": {}, - "grants": [], - "identity_providers": [] - } - ] -} -``` - -
- ---- - -### `upsertEmailTemplates` - -Upserts the email templates of a portal - -`POST /v2/portal/email-templates` - -```ts -const { data } = await client.upsertEmailTemplates( - { - origin: 'example', - }, - { - confirmAccount: '5da0a718-c822-403d-9f5d-20d4584e0528', - advancedAuth: '5da0a718-c822-403d-9f5d-20d4584e0528', - advancedMFA: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeySignUp: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeySignInOneTimePassword: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeyLoginOTP: '5da0a718-c822-403d-9f5d-20d4584e0528', - forgotPassword: '5da0a718-c822-403d-9f5d-20d4584e0528', - invitation: '5da0a718-c822-403d-9f5d-20d4584e0528', - partnerInvitation: '5da0a718-c822-403d-9f5d-20d4584e0528', - onNewQuote: '5da0a718-c822-403d-9f5d-20d4584e0528', - onMapAPendingUser: '5da0a718-c822-403d-9f5d-20d4584e0528', - onDocUpload: '5da0a718-c822-403d-9f5d-20d4584e0528', - onWorkflowStepAssigned: '5da0a718-c822-403d-9f5d-20d4584e0528', - confirmEmailUpdate: '5da0a718-c822-403d-9f5d-20d4584e0528', - verifyCodeToSetPassword: '5da0a718-c822-403d-9f5d-20d4584e0528' - }, -) -``` - -
-Response - -```json -{ - "message": "Email Templates upserted successfully", - "emailTemplates": { - "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", - "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", - "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", - "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" - } -} -``` - -
- ---- - -### `getEmailTemplates` - -Retrieves the email templates of a portal - -`GET /v2/portal/email-templates` - -```ts -const { data } = await client.getEmailTemplates({ - origin: 'example', -}) -``` - -
-Response - -```json -{ - "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", - "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", - "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", - "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" -} -``` - -
- ---- - -### `upsertEmailTemplatesByPortalId` - -Upserts the email templates of a portal by portal ID - -`POST /v3/portal/email-templates/{portal_id}` - -```ts -const { data } = await client.upsertEmailTemplatesByPortalId( - { - portal_id: 'example', - }, - { - confirmAccount: '5da0a718-c822-403d-9f5d-20d4584e0528', - advancedAuth: '5da0a718-c822-403d-9f5d-20d4584e0528', - advancedMFA: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeySignUp: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeySignInOneTimePassword: '5da0a718-c822-403d-9f5d-20d4584e0528', - journeyLoginOTP: '5da0a718-c822-403d-9f5d-20d4584e0528', - forgotPassword: '5da0a718-c822-403d-9f5d-20d4584e0528', - invitation: '5da0a718-c822-403d-9f5d-20d4584e0528', - partnerInvitation: '5da0a718-c822-403d-9f5d-20d4584e0528', - onNewQuote: '5da0a718-c822-403d-9f5d-20d4584e0528', - onMapAPendingUser: '5da0a718-c822-403d-9f5d-20d4584e0528', - onDocUpload: '5da0a718-c822-403d-9f5d-20d4584e0528', - onWorkflowStepAssigned: '5da0a718-c822-403d-9f5d-20d4584e0528', - confirmEmailUpdate: '5da0a718-c822-403d-9f5d-20d4584e0528', - verifyCodeToSetPassword: '5da0a718-c822-403d-9f5d-20d4584e0528' - }, -) -``` - -
-Response - -```json -{ - "message": "Email Templates upserted successfully", - "emailTemplates": { - "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", - "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", - "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", - "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" - } -} -``` - -
- ---- - -### `getEmailTemplatesByPortalId` - -Retrieves the email templates of a portal by portal ID - -`GET /v3/portal/email-templates/{portal_id}` - -```ts -const { data } = await client.getEmailTemplatesByPortalId({ - portal_id: 'example', -}) -``` - -
-Response - -```json -{ - "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", - "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", - "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", - "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", - "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", - "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", - "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" -} -``` - -
- ---- - -### `getPublicPortalWidgets` - -Retrieves the public widgets of a portal - -`GET /v2/portal/public-widgets` - -```ts -const { data } = await client.getPublicPortalWidgets({ - org_id: 'example', - origin: 'example', -}) -``` - -
-Response - -```json -{ - "widgets": [ + "portal_sk_v3": "string", + "is_v3_item": true, + "widgets": [ { "id": "string", "type": "ACTION_WIDGET", @@ -2965,18 +2518,20 @@ const { data } = await client.getPublicPortalWidgets({ --- -### `upsertPortalWidget` +### `upsertPortalWidgetV3` -Upsert widget for a portal of an organization. +Upsert widget for a portal by portal_id. -`POST /v2/portal/widgets` +`POST /v3/portal/widgets` ```ts -const { data } = await client.upsertPortalWidget( +const { data } = await client.upsertPortalWidgetV3( { - origin: 'example', + portal_id: 'example', }, { + portal_sk_v3: 'string', + is_v3_item: true, widgets: [ { id: 'string', @@ -3006,7 +2561,7 @@ const { data } = await client.upsertPortalWidget( }, content: 'string' }, - /* ... 7 more */ + /* ... 8 more */ ] }, ) @@ -3017,6 +2572,8 @@ const { data } = await client.upsertPortalWidget( ```json { + "portal_sk_v3": "string", + "is_v3_item": true, "widgets": [ { "id": "string", @@ -3054,52 +2611,56 @@ const { data } = await client.upsertPortalWidget( --- -### `getPortalWidgets` +### `savePortalFilesV3` -Retrieves the widgets of a portal +Add files to portal by portal_id -`GET /v2/portal/widgets` +`POST /v3/portal/portal/files` ```ts -const { data } = await client.getPortalWidgets({ - origin: 'example', - contract_id: 'example', -}) -``` - -
-Response - -```json -{ - "widgets": [ - { - "id": "string", - "type": "ACTION_WIDGET", - "listIndex": 0, - "headline": { - "en": "string", - "de": "string" - }, - "subHeadline": { - "en": "string", - "de": "string" - }, - "schema": "string" - }, +const { data } = await client.savePortalFilesV3( + { + portal_id: 'example', + }, + { + origin: 'string', + draft: false, + files: [ + { + filename: 12345, + file_type: 'orderRightTeaser', + _tags: 12345, + s3ref: { + bucket: 12345, + key: 12345 + } + } + ] + }, +) +``` + +
+Response + +```json +{ + "createdFiles": [ { - "id": "string", - "type": "ACTION_WIDGET", - "listIndex": 0, - "headline": { - "en": "string", - "de": "string" - }, - "subHeadline": { - "en": "string", - "de": "string" - }, - "content": "string" + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "file" } ] } @@ -3131,18 +2692,21 @@ const { data } = await client.replaceECPTemplateVariables( ```json { "customerPortal": { + "link": "https://end-customer-portal.ecp.dev.epilot.io", "invitationLink": "https://end-customer-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", "newDocumentLink": "https://end-customer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", "entityLink": "https://end-customer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", "userEmailsOnEntity": ["john@doe.com", "mary@doe.com"] }, "installerPortal": { + "link": "https://installer-portal.ecp.dev.epilot.io", "invitationLink": "https://installer-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", "newDocumentLink": "https://installer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", "entityLink": "https://installer-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", "userEmailsOnEntity": ["peter@doe.com", "jane@doe.com"] }, "portalUser": { + "link": "https://employee-portal.ecp.dev.epilot.io", "invitationLink": "https://employee-portal.ecp.dev.epilot.io/register?contactId=7aa44fb8-d60e-40cc-9a3a-ba09a1ff7f51&email=john@doe.com", "newDocumentLink": "https://employee-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", "entityLink": "https://employee-portal.ecp.dev.epilot.io/requests/opportunities/b8fef220-abe0-4382-a704-26848f60977b", @@ -3211,6 +2775,40 @@ const { data } = await client.getSchemasByDomain({ --- +### `getPublicSchemasV3` + +Retrieves schemas by portal. Only schemas and attributes used on public pages are returned. +Supports two identification methods: +1. Using org_id + portal_id +2. Using domain + +`GET /v3/portal/public/schemas` + +```ts +const { data } = await client.getPublicSchemasV3({ + org_id: 'example', + portal_id: 'example', + domain: 'example', +}) +``` + +
+Response + +```json +{ + "schemas": [ + { + "slug": "contact" + } + ] +} +``` + +
+ +--- + ### `getOrganizationSettingsByDomain` Retrieves organization settings by domain. Only public organization settings are returned. @@ -3360,33 +2958,6 @@ const { data } = await client.extraPermissionAttributes() --- -### `validateCaaRecords` - -Validates the CAA records of a portal - -`POST /v2/portal/validate/caa-records` - -```ts -const { data } = await client.validateCaaRecords({ - origin: 'example', -}) -``` - -
-Response - -```json -{ - "retry": true, - "message": "string", - "isDNSConfigured": true -} -``` - -
- ---- - ### `validateCaaRecordsV3` Validates the CAA records of a portal @@ -3436,6 +3007,13 @@ const { data } = await client.getContact() "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "contact" }, "files": [ @@ -3446,6 +3024,13 @@ const { data } = await client.getContact() "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "file" } ], @@ -3457,6 +3042,13 @@ const { data } = await client.getContact() "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "templates_output": { "content_top_name": "Customer #123456", "main_content_name": "Orange Flexible A2 (654321)", @@ -3493,17 +3085,16 @@ const { data } = await client.getContact() --- -### `updateContact` +### `getECPContact` -Updates the contact details. +Get the Contact by id -`PATCH /v2/portal/contact` +`GET /v2/portal/ecp/contact` ```ts -const { data } = await client.updateContact( - null, - {}, -) +const { data } = await client.getECPContact({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) ```
@@ -3518,6 +3109,13 @@ const { data } = await client.updateContact( "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "contact" } } @@ -3527,16 +3125,34 @@ const { data } = await client.updateContact( --- -### `getECPContact` +### `checkContactExistsV3` -Get the Contact by id +True if contact with given identifiers exists. +Supports two identification methods: +1. Using portal_id +2. Using domain -`GET /v2/portal/ecp/contact` +`POST /v3/portal/public/contact/exists` ```ts -const { data } = await client.getECPContact({ - id: '123e4567-e89b-12d3-a456-426614174000', -}) +const { data } = await client.checkContactExistsV3( + { + portal_id: 'example', + domain: 'example', + }, + { + org_id: 728, + registration_identifiers: { + contact: { + email: 'john.doe@example.com' + }, + contract: { + contract_number: '123456' + } + }, + trigger_identifiers_check: true + }, +) ```
@@ -3544,15 +3160,10 @@ const { data } = await client.getECPContact({ ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "contact" - } + "exists": true, + "contactId": "5da0a718-c822-403d-9f5d-20d4584e0528", + "accountId": "5da0a718-c822-403d-9f5d-20d4584e0528", + "reason": "TIMEOUT" } ``` @@ -3560,16 +3171,18 @@ const { data } = await client.getECPContact({ --- -### `checkContactExists` +### `identifyContact` -True if contact with given identifiers exists. +Identify a contact by the surface's identifiers and, on a match, issue a short-lived +bearer token that acts as that contact. -`POST /v2/portal/public/contact/exists` +`POST /v3/portal/public/contact/identify` ```ts -const { data } = await client.checkContactExists( +const { data } = await client.identifyContact( { - origin: 'example', + portal_id: 'example', + domain: 'example', }, { org_id: 728, @@ -3580,7 +3193,9 @@ const { data } = await client.checkContactExists( contract: { contract_number: '123456' } - } + }, + trigger_identifiers_check: true, + surface_id: 'website-journeys' }, ) ``` @@ -3590,8 +3205,16 @@ const { data } = await client.checkContactExists( ```json { - "exists": true, - "contactId": "5da0a718-c822-403d-9f5d-20d4584e0528" + "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "account_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", + "token_type": "contact_identification", + "surface_id": "website-journeys", + "expires_at": "2026-08-11T10:35:00.000Z", + "allowed_operations": [], + "has_portal_user": false, + "portal_user_email": "john.doe@example.com", + "reason": "TIMEOUT" } ``` @@ -3599,22 +3222,26 @@ const { data } = await client.checkContactExists( --- -### `checkContactExistsV3` +### `checkAccountExists` -True if contact with given identifiers exists. +True if account with given identifiers exists. +Supports two identification methods: +1. Using portal_id +2. Using domain -`POST /v3/portal/public/contact/exists` +`POST /v3/portal/public/account/exists` ```ts -const { data } = await client.checkContactExistsV3( +const { data } = await client.checkAccountExists( { portal_id: 'example', + domain: 'example', }, { org_id: 728, registration_identifiers: { - contact: { - email: 'john.doe@example.com' + account: { + customer_number: 'ACC-123456' }, contract: { contract_number: '123456' @@ -3630,7 +3257,7 @@ const { data } = await client.checkContactExistsV3( ```json { "exists": true, - "contactId": "5da0a718-c822-403d-9f5d-20d4584e0528" + "accountId": "5da0a718-c822-403d-9f5d-20d4584e0528" } ``` @@ -3666,14 +3293,14 @@ const { data } = await client.getValidSecondaryAttributes() --- -### `getPortalUser` +### `getPortalCopilotAccess` -Get the portal user details +Whether the signed-in portal user may use the portal chat. False when the chat is off for the portal, when the user does not match its target visibility, or when targets cannot be matched. -`GET /v2/portal/user` +`GET /v2/portal/copilot/access` ```ts -const { data } = await client.getPortalUser() +const { data } = await client.getPortalCopilotAccess() ```
@@ -3681,15 +3308,7 @@ const { data } = await client.getPortalUser() ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "portal_user" - } + "allowed": true } ``` @@ -3697,17 +3316,14 @@ const { data } = await client.getPortalUser() --- -### `updatePortalUser` +### `getPortalUser` -Update the portal user details +Get the portal user details -`PATCH /v2/portal/user` +`GET /v2/portal/user` ```ts -const { data } = await client.updatePortalUser( - null, - {}, -) +const { data } = await client.getPortalUser() ```
@@ -3722,6 +3338,13 @@ const { data } = await client.updatePortalUser( "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], "_schema": "portal_user" } } @@ -3784,16 +3407,20 @@ const { data } = await client.updatePortalUserEmail( --- -### `resendConfirmationEmail` +### `changePortalUserPassword` -Resend confirmation email +Hand over a password change to the third-party system configured via the `changePassword` portal extension hook. +Only available when such a hook is configured for the portal; the built-in password cha -`POST /v2/portal/user/resend/confirmation-email/{id}` +`PUT /v2/portal/user/change/password` ```ts -const { data } = await client.resendConfirmationEmail({ - id: '123e4567-e89b-12d3-a456-426614174000', -}) +const { data } = await client.changePortalUserPassword( + null, + { + new_password: 'string' + }, +) ```
@@ -3801,7 +3428,7 @@ const { data } = await client.resendConfirmationEmail({ ```json { - "message": "Confirmation email sent successfully." + "message": "string" } ``` @@ -3809,17 +3436,14 @@ const { data } = await client.resendConfirmationEmail({ --- -### `fetchPortalUsersByRelatedEntity` +### `getPortalUserNotificationPreferences` -Get all users for a given entity +Returns the notification preferences of the authenticated portal user. Notifications follow an opt-out model: a preference that was never stored on the portal user defaults to enabled (true). Responds -`GET /v2/portal/users/by-related-entity` +`GET /v2/portal/user/notification-preferences` ```ts -const { data } = await client.fetchPortalUsersByRelatedEntity({ - entity_id: 'example', - slug: 'example', -}) +const { data } = await client.getPortalUserNotificationPreferences() ```
@@ -3827,17 +3451,7 @@ const { data } = await client.fetchPortalUsersByRelatedEntity({ ```json { - "portalUsers": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "portal_user" - } - ] + "in_app": true } ``` @@ -3845,17 +3459,19 @@ const { data } = await client.fetchPortalUsersByRelatedEntity({ --- -### `confirmUser` +### `updatePortalUserNotificationPreferences` -Confirm a portal user +Partially updates the notification preferences of the authenticated portal user. Only the channels present in the request body are changed; omitted channels keep their stored value (or the enabled-by- -`GET /v2/portal/user/confirm` +`PUT /v2/portal/user/notification-preferences` ```ts -const { data } = await client.confirmUser({ - confirmation_link_token: 'example', - use_redirect: true, -}) +const { data } = await client.updatePortalUserNotificationPreferences( + null, + { + in_app: true + }, +) ```
@@ -3863,8 +3479,7 @@ const { data } = await client.confirmUser({ ```json { - "confirmed": true, - "user_already_confirmed": true + "in_app": true } ``` @@ -3872,34 +3487,14 @@ const { data } = await client.confirmUser({ --- -### `confirmUserWithUserId` +### `listPortalUserPasskeys` -Confirm a portal user +Lists the passkeys the logged-in portal user has added. -`GET /v2/portal/user/confirm/{id}` +`GET /v2/portal/user/passkeys` ```ts -const { data } = await client.confirmUserWithUserId({ - origin: 'example', - id: '123e4567-e89b-12d3-a456-426614174000', - org_id: 'example', -}) -``` - ---- - -### `userExists` - -Checks whether a user exists in the portal - -`GET /v2/portal/public/user/exists` - -```ts -const { data } = await client.userExists({ - email: 'example', - org_id: 'example', - origin: 'example', -}) +const { data } = await client.listPortalUserPasskeys() ```
@@ -3907,7 +3502,18 @@ const { data } = await client.userExists({ ```json { - "exists": true + "results": [ + { + "credential_id": "string", + "name": "string", + "rp_id": "kundenportal.example.de", + "is_usable": true, + "device_type": "singleDevice", + "backed_up": true, + "created_at": "1970-01-01T00:00:00.000Z", + "last_used_at": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -3915,18 +3521,22 @@ const { data } = await client.userExists({ --- -### `userExistsV3` +### `addPortalUserPasskey` -Checks whether a user exists in the portal +Stores a new passkey for the logged-in portal user. +Send the browser's `navigator.credentials.create()` result for options from `createPortalUserPasskeyRegistrationOptions`. +Only available when `auth_ -`GET /v3/portal/public/user/exists` +`POST /v2/portal/user/passkeys` ```ts -const { data } = await client.userExistsV3({ - email: 'example', - org_id: 'example', - portal_id: 'example', -}) +const { data } = await client.addPortalUserPasskey( + null, + { + registration_response: {}, + name: 'string' + }, +) ```
@@ -3934,7 +3544,14 @@ const { data } = await client.userExistsV3({ ```json { - "exists": true + "credential_id": "string", + "name": "string", + "rp_id": "kundenportal.example.de", + "is_usable": true, + "device_type": "singleDevice", + "backed_up": true, + "created_at": "1970-01-01T00:00:00.000Z", + "last_used_at": "1970-01-01T00:00:00.000Z" } ``` @@ -3942,19 +3559,18 @@ const { data } = await client.userExistsV3({ --- -### `getRecipientsToNotifyOnAutomation` +### `createPortalUserPasskeyRegistrationOptions` -Get recipients to notify on automation +Returns WebAuthn options for `navigator.credentials.create()` to add a passkey for the logged-in portal user. +Needs the code from `sendPortalUserPasskeyVerificationCode`, so a session alone can't add -`POST /v2/portal/recipients-to-notify` +`POST /v2/portal/user/passkeys/registration-options` ```ts -const { data } = await client.getRecipientsToNotifyOnAutomation( +const { data } = await client.createPortalUserPasskeyRegistrationOptions( null, { - emails: ['john@doe.com'], - template_id: '5da0a718-c822-403d-9f5d-20d4584e0528', - context_id: '5da0a718-c822-403d-9f5d-20d4584e0528' + verification_code: 'string' }, ) ``` @@ -3963,31 +3579,42 @@ const { data } = await client.getRecipientsToNotifyOnAutomation( Response ```json -{ - "recipients": [ - { - "email": "john@doe.com", - "recipient_id": "5da0a718-c822-403d-9f5d-20d4584e0528" - } - ], - "message": "string" -} +{} ```
--- -### `configureDistribution` +### `sendPortalUserPasskeyVerificationCode` -Configure the distribution for the portal's custom domain +Emails the logged-in portal user a 6-digit code needed to add a passkey (`createPortalUserPasskeyRegistrationOptions`). +The code is valid for 10 minutes and allows 5 attempts; a new code replaces the -`GET /v2/portal/configure-distribution` +`POST /v2/portal/user/passkeys/verification-code` ```ts -const { data } = await client.configureDistribution({ - origin: 'example', -}) +const { data } = await client.sendPortalUserPasskeyVerificationCode() +``` + +--- + +### `renamePortalUserPasskey` + +Renames one of the logged-in portal user's passkeys. An empty name removes the label. +Works even when passkeys are turned off for the portal. + +`PATCH /v2/portal/user/passkeys/{credential_id}` + +```ts +const { data } = await client.renamePortalUserPasskey( + { + credential_id: 'example', + }, + { + name: 'string' + }, +) ```
@@ -3995,7 +3622,14 @@ const { data } = await client.configureDistribution({ ```json { - "domainName": "dsj8op4ha01jha23.cloudfront.net" + "credential_id": "string", + "name": "string", + "rp_id": "kundenportal.example.de", + "is_usable": true, + "device_type": "singleDevice", + "backed_up": true, + "created_at": "1970-01-01T00:00:00.000Z", + "last_used_at": "1970-01-01T00:00:00.000Z" } ``` @@ -4003,15 +3637,29 @@ const { data } = await client.configureDistribution({ --- -### `configureDistributionV3` +### `deletePortalUserPasskey` -Configure the distribution for the portal's custom domain +Removes one of the logged-in portal user's passkeys. Works even when passkeys are turned off for the portal. -`GET /v3/portal/configure-distribution` +`DELETE /v2/portal/user/passkeys/{credential_id}` ```ts -const { data } = await client.configureDistributionV3({ - portal_id: 'example', +const { data } = await client.deletePortalUserPasskey({ + credential_id: 'example', +}) +``` + +--- + +### `resendConfirmationEmail` + +Resend confirmation email + +`POST /v2/portal/user/resend/confirmation-email/{id}` + +```ts +const { data } = await client.resendConfirmationEmail({ + id: '123e4567-e89b-12d3-a456-426614174000', }) ``` @@ -4020,7 +3668,7 @@ const { data } = await client.configureDistributionV3({ ```json { - "domainName": "dsj8op4ha01jha23.cloudfront.net" + "message": "Confirmation email sent successfully." } ``` @@ -4028,16 +3676,16 @@ const { data } = await client.configureDistributionV3({ --- -### `getAllOrders` +### `fetchPortalUsersByRelatedEntity` -Get all orders for the portal user +Get all users for a given entity -`GET /v2/portal/order` +`GET /v2/portal/users/by-related-entity` ```ts -const { data } = await client.getAllOrders({ - from: 1, - size: 1, +const { data } = await client.fetchPortalUsersByRelatedEntity({ + entity_id: 'example', + slug: 'example', }) ``` @@ -4046,7 +3694,7 @@ const { data } = await client.getAllOrders({ ```json { - "data": [ + "portalUsers": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -4054,22 +3702,14 @@ const { data } = await client.getAllOrders({ "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order", - "journey_actions": { - "journey_id": "string", - "action_label": { - "en": "string", - "de": "string" - }, - "slug": "string", - "rules": [ - { - "entity": "string", - "attribute": "string", - "attribute_value": "string" - } - ] - } + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "portal_user" } ] } @@ -4079,21 +3719,17 @@ const { data } = await client.getAllOrders({ --- -### `postOrderAcceptance` +### `confirmUser` -Accept/decline an offer by id +Confirm a portal user -`POST /v2/portal/order/{id}/acceptance` +`GET /v2/portal/user/confirm` ```ts -const { data } = await client.postOrderAcceptance( - { - id: '123e4567-e89b-12d3-a456-426614174000', - }, - { - decision: 'accept' - }, -) +const { data } = await client.confirmUser({ + confirmation_link_token: 'example', + use_redirect: true, +}) ```
@@ -4101,15 +3737,8 @@ const { data } = await client.postOrderAcceptance( ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order" - } + "confirmed": true, + "user_already_confirmed": true } ``` @@ -4117,15 +3746,37 @@ const { data } = await client.postOrderAcceptance( --- -### `getOrder` +### `confirmUserWithUserId` -Get an order by id +Confirm a portal user -`GET /v2/portal/order/{id}` +`GET /v2/portal/user/confirm/{id}` ```ts -const { data } = await client.getOrder({ +const { data } = await client.confirmUserWithUserId({ + origin: 'example', id: '123e4567-e89b-12d3-a456-426614174000', + org_id: 'example', +}) +``` + +--- + +### `userExistsV3` + +Checks whether a user exists in the portal. +Supports two identification methods: +1. Using org_id + portal_id +2. Using domain + +`GET /v3/portal/public/user/exists` + +```ts +const { data } = await client.userExistsV3({ + email: 'example', + org_id: 'example', + portal_id: 'example', + domain: 'example', }) ``` @@ -4134,81 +3785,7 @@ const { data } = await client.getOrder({ ```json { - "entity": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order" - }, - "files": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" - } - ], - "relations": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": {}, - "_schema": "contact" - } - ], - "products": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "product" - } - ], - "crossSellableProducts": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "product" - } - ], - "workflow": [ - { - "id": "8gja72h6kas6h", - "name": "Lead Qualification", - "trigger": "MANUAL", - "status": "STARTED", - "creationTime": "2021-04-27T12:01:13.000Z", - "lastUpdateTime": "2021-04-27T12:01:13.000Z", - "dueDate": "2021-04-27T12:01:13.000Z", - "assignedTo": ["252", "29052"], - "flow": [] - } - ], - "journey_actions": [ - { - "journey_id": "string", - "action_label": {}, - "slug": "string", - "rules": [] - } - ] + "exists": true } ``` @@ -4216,18 +3793,20 @@ const { data } = await client.getOrder({ --- -### `updateOrder` +### `getRecipientsToNotifyOnAutomation` -Update an order by id +Get recipients to notify on automation -`PATCH /v2/portal/order/{id}` +`POST /v2/portal/recipients-to-notify` ```ts -const { data } = await client.updateOrder( +const { data } = await client.getRecipientsToNotifyOnAutomation( + null, { - id: '123e4567-e89b-12d3-a456-426614174000', + emails: ['john@doe.com'], + template_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + context_id: '5da0a718-c822-403d-9f5d-20d4584e0528' }, - {}, ) ``` @@ -4236,15 +3815,13 @@ const { data } = await client.updateOrder( ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order" - } + "recipients": [ + { + "email": "john@doe.com", + "recipient_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + } + ], + "message": "string" } ``` @@ -4252,67 +3829,15 @@ const { data } = await client.updateOrder( --- -### `getAllOpportunities` +### `configureDistributionV3` -Get all opportunities of a portal user +Configure the distribution for the portal's custom domain -`GET /v2/portal/opportunity` +`GET /v3/portal/configure-distribution` ```ts -const { data } = await client.getAllOpportunities({ - from: 1, - size: 1, -}) -``` - -
-Response - -```json -{ - "data": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity", - "journey_actions": { - "journey_id": "string", - "action_label": { - "en": "string", - "de": "string" - }, - "slug": "string", - "rules": [ - { - "entity": "string", - "attribute": "string", - "attribute_value": "string" - } - ] - } - } - ] -} -``` - -
- ---- - -### `getSearchableAttributesForOpportunities` - -Get all opportunity searchable attributes for a portal user - -`GET /v2/portal/opportunities/searchable-attributes` - -```ts -const { data } = await client.getSearchableAttributesForOpportunities({ - from: 1, - size: 1, +const { data } = await client.configureDistributionV3({ + portal_id: 'example', }) ``` @@ -4321,17 +3846,7 @@ const { data } = await client.getSearchableAttributesForOpportunities({ ```json { - "data": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" - } - ] + "domainName": "dsj8op4ha01jha23.cloudfront.net" } ``` @@ -4339,25 +3854,19 @@ const { data } = await client.getSearchableAttributesForOpportunities({ --- -### `getSearchResultsForOpportunities` +### `postOrderAcceptance` -Get all opportunity with the given serached attributes +Accept/decline an offer by id -`POST /v2/portal/opportunities/search` +`POST /v2/portal/order/{id}/acceptance` ```ts -const { data } = await client.getSearchResultsForOpportunities( +const { data } = await client.postOrderAcceptance( { - from: 1, - size: 1, + id: '123e4567-e89b-12d3-a456-426614174000', }, { - addresses: ['string'], - customers: ['string'], - purposes: ['5da0a718-c822-403d-9f5d-20d4584e0528'], - workflows: [ - {} - ] + decision: 'accept' }, ) ``` @@ -4367,17 +3876,22 @@ const { data } = await client.getSearchResultsForOpportunities( ```json { - "data": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" - } - ] + "data": { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "order" + } } ``` @@ -4385,16 +3899,27 @@ const { data } = await client.getSearchResultsForOpportunities( --- -### `getOpportunity` +### `getContractWithTemplates` -Get an opportunity by id +Resolve Handlebars templates against a contract's related meters and return the contract with templates_output populated per meter. This is a read-only operation — it does not modify the contract. It -`GET /v2/portal/opportunities/{id}` +`POST /v2/portal/contract/{id}/resolve-templates` ```ts -const { data } = await client.getOpportunity({ - id: '123e4567-e89b-12d3-a456-426614174000', -}) +const { data } = await client.getContractWithTemplates( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + templates: {}, + templates_ref: { + page_id: 'string', + block_id: 'string', + config_id: 'string', + global_search_config_id: 'string' + } + }, +) ```
@@ -4409,7 +3934,32 @@ const { data } = await client.getOpportunity({ "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" + "templates_output_highlighted": {}, + "search_snippets": [ + {} + ], + "contract_name": "Grid Contract", + "contract_number": "12345", + "status": "approved", + "description": "This contract is for the supply of widgets.", + "account_number": "67890", + "branch": "power", + "billing_address": "123 Main St, Anytown", + "delivery_address": "456 Elm St, Anytown", + "additional_addresses": "789 Oak St, Anytown", + "termination_date": "2022-01-01", + "termination_reason": "Non-payment", + "billing_period": "monthly", + "billing_duration_amount": 30, + "renewal_duration_amount": 365, + "renewal_duration_unit": "years", + "notice_time_amount": 30, + "notice_time_unit": "months", + "start_date": "2021-01-01", + "billing_due_day": 2, + "installment_amount": 10050, + "balance": 8990, + "balance_currency": "EUR" }, "orders": [ { @@ -4419,9 +3969,25 @@ const { data } = await client.getOpportunity({ "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [], "_schema": "order" } ], + "meters": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [], + "_schema": "meter", + "templates_output": {} + } + ], "files": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -4430,6 +3996,8 @@ const { data } = await client.getOpportunity({ "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [], "_schema": "file" } ], @@ -4441,6 +4009,8 @@ const { data } = await client.getOpportunity({ "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [], "templates_output": {}, "_schema": "contact" } @@ -4473,18 +4043,23 @@ const { data } = await client.getOpportunity({ --- -### `updateOpportunity` +### `addContractByIdentifiers` -Update an opportunity by id +Self-assign contract(s) by pre-configured identifiers. -`PATCH /v2/portal/opportunities/{id}` +`POST /v2/portal/contract/by-identifiers` ```ts -const { data } = await client.updateOpportunity( +const { data } = await client.addContractByIdentifiers( + null, { - id: '123e4567-e89b-12d3-a456-426614174000', + contract: { + contract_number: '123456' + }, + meter: { + meter_number: '123456' + } }, - {}, ) ``` @@ -4493,15 +4068,34 @@ const { data } = await client.updateOpportunity( ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" - } + "data": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" + } + ], + "hits": 0 } ``` @@ -4509,16 +4103,15 @@ const { data } = await client.updateOpportunity( --- -### `getAllRequests` +### `getEntityIdentifiers` -Get all opportunities & orders of a portal user +Retrieve a list of entity identifiers used for entity search by portal users. -`GET /v2/portal/request` +`GET /v2/portal/entity/identifiers/{slug}` ```ts -const { data } = await client.getAllRequests({ - from: 1, - size: 1, +const { data } = await client.getEntityIdentifiers({ + slug: 'example', }) ``` @@ -4527,16 +4120,10 @@ const { data } = await client.getAllRequests({ ```json { - "hits": 1, - "results": [ + "data": [ { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "opportunity" + "name": "contract_number", + "type": "string" } ] } @@ -4546,16 +4133,22 @@ const { data } = await client.getAllRequests({ --- -### `getAllContracts` +### `getEntityActivityFeed` -Get all contracts for a portal user +Get activity feed for an entity -`GET /v2/portal/contract` +`GET /v2/portal/entity/{slug}/{id}/activity` ```ts -const { data } = await client.getAllContracts({ +const { data } = await client.getEntityActivityFeed({ + slug: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', + after: 'example', + before: 'example', from: 1, size: 1, + type: 'example', + include_relations: true, }) ``` @@ -4564,50 +4157,19 @@ const { data } = await client.getAllContracts({ ```json { - "data": [ + "total": 1, + "results": [ { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", - "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", - "billing_period": "monthly", - "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", - "notice_time_amount": 30, - "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, - "balance": 8990, - "balance_currency": "EUR", - "journey_actions": { - "journey_id": "string", - "action_label": { - "en": "string", - "de": "string" - }, - "slug": "string", - "rules": [ - { - "entity": "string", - "attribute": "string", - "attribute_value": "string" - } - ] + "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", + "timestamp": "1970-01-01T00:00:00.000Z", + "type": "MyCustomActivity", + "title": "My custom activity", + "message": "{{caller}} did something with {{entity payload.entity.id}}.", + "payload": { + "entity": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "schema": "contact" + } } } ] @@ -4618,15 +4180,17 @@ const { data } = await client.getAllContracts({ --- -### `getContract` +### `validateCadenceEntityEditRules` -Get a contract by id +Validate if cadence rule is valid for an entity -`GET /v2/portal/contract/{id}` +`GET /v2/portal/{slug}/{id}:validateRule` ```ts -const { data } = await client.getContract({ +const { data } = await client.validateCadenceEntityEditRules({ + slug: 'example', id: '123e4567-e89b-12d3-a456-426614174000', + attribute: 'example', }) ``` @@ -4635,70 +4199,44 @@ const { data } = await client.getContract({ ```json { - "entity": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", - "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", - "billing_period": "monthly", - "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", - "notice_time_amount": 30, - "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, - "balance": 8990, - "balance_currency": "EUR" - }, - "orders": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "order" - } - ], - "meters": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "meter" - } - ], - "files": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" - } - ], - "relations": [ + "isBlockedByRules": false, + "failedRule": { + "slug": "contact", + "attribute": "string", + "rule_type": "string", + "cadence_period_type": "string", + "changes_allowed": 0, + "cadence_period": 0, + "allowed_decrement": "string", + "allowed_increment": "string", + "number_of_days_before_restriction": 0, + "grace_period": 0 + } +} +``` + +
+ +--- + +### `searchPaymentRelationsInEntities` + +Search for entities that have the payment relation with the given payment id + +`GET /v2/portal/entities-by-payment/{id}` + +```ts +const { data } = await client.searchPaymentRelationsInEntities({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "results": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -4706,31 +4244,26 @@ const { data } = await client.getContract({ "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": {}, + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, "_schema": "contact" } ], - "workflow": [ - { - "id": "8gja72h6kas6h", - "name": "Lead Qualification", - "trigger": "MANUAL", - "status": "STARTED", - "creationTime": "2021-04-27T12:01:13.000Z", - "lastUpdateTime": "2021-04-27T12:01:13.000Z", - "dueDate": "2021-04-27T12:01:13.000Z", - "assignedTo": ["252", "29052"], - "flow": [] - } - ], - "journey_actions": [ - { - "journey_id": "string", - "action_label": {}, - "slug": "string", - "rules": [] - } - ] + "hits": 50 } ``` @@ -4738,18 +4271,20 @@ const { data } = await client.getContract({ --- -### `updateContract` +### `createCustomEntityActivity` -Update a contract by id +Create a custom activity that can be displayed in activity feed of an entity. -`PATCH /v2/portal/contract/{id}` +`PUT /v2/portal/entity/activity` ```ts -const { data } = await client.updateContract( +const { data } = await client.createCustomEntityActivity( { - id: '123e4567-e89b-12d3-a456-426614174000', + entities: ['...'], + }, + { + type: 'PortalUserResetPassword' }, - {}, ) ``` @@ -4758,35 +4293,16 @@ const { data } = await client.updateContract( ```json { - "data": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "contract_name": "Grid Contract", - "contract_number": "12345", - "status": "approved", - "description": "This contract is for the supply of widgets.", - "account_number": "67890", - "branch": "power", - "billing_address": "123 Main St, Anytown", - "delivery_address": "456 Elm St, Anytown", - "additional_addresses": "789 Oak St, Anytown", - "termination_date": "2022-01-01", - "termination_reason": "Non-payment", - "billing_period": "monthly", - "billing_duration_amount": 30, - "renewal_duration_amount": 365, - "renewal_duration_unit": "years", - "notice_time_amount": 30, - "notice_time_unit": "months", - "start_date": "2021-01-01", - "billing_due_day": 2, - "installment_amount": 10050, - "balance": 8990, - "balance_currency": "EUR" + "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", + "timestamp": "1970-01-01T00:00:00.000Z", + "type": "MyCustomActivity", + "title": "My custom activity", + "message": "{{caller}} did something with {{entity payload.entity.id}}.", + "payload": { + "entity": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "schema": "contact" + } } } ``` @@ -4795,22 +4311,28 @@ const { data } = await client.updateContract( --- -### `addContractByIdentifiers` +### `saveEntityFile` -Self-assign contract(s) by pre-configured identifiers. +Add files to an entity -`POST /v2/portal/contract/by-identifiers` +`POST /v2/portal/entity/file` ```ts -const { data } = await client.addContractByIdentifiers( +const { data } = await client.saveEntityFile( null, { - contract: { - contract_number: '123456' - }, - meter: { - meter_number: '123456' - } + entity_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + entity_type: 'order', + files: [ + { + filename: 'document.pdf', + access_control: 'private', + s3ref: { + bucket: 12345, + key: 12345 + } + } + ] }, ) ``` @@ -4820,7 +4342,7 @@ const { data } = await client.addContractByIdentifiers( ```json { - "data": [ + "createdFiles": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -4828,19 +4350,16 @@ const { data } = await client.addContractByIdentifiers( "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" } - }, - "_schema": "contact" + ], + "_schema": "file" } - ], - "hits": 0 + ] } ``` @@ -4848,16 +4367,14 @@ const { data } = await client.addContractByIdentifiers( --- -### `getEntityIdentifiers` +### `getRegistrationIdentifiers` -Retrieve a list of entity identifiers used for entity search by portal users. +Get valid attributes from entities that can be used as identifier to map contact to user on registration -`GET /v2/portal/entity/identifiers/{slug}` +`GET /v2/portal/registration/identifiers` ```ts -const { data } = await client.getEntityIdentifiers({ - slug: 'example', -}) +const { data } = await client.getRegistrationIdentifiers() ```
@@ -4865,12 +4382,22 @@ const { data } = await client.getEntityIdentifiers({ ```json { - "data": [ - { - "name": "contract_number", - "type": "string" - } - ] + "data": { + "contact": [ + { + "label": "First name", + "name": "first_name", + "type": "string" + } + ], + "contract": [ + { + "label": "Contract number", + "name": "contract_number", + "type": "string" + } + ] + } } ``` @@ -4878,22 +4405,15 @@ const { data } = await client.getEntityIdentifiers({ --- -### `getEntityActivityFeed` +### `getFilePreview` -Get activity feed for an entity +resolves an in-portal preview for a file. Returns a Content-Disposition: inline URL for directly-previewable files (PDF, common image formats), or a document-api PDF conversion result for the Office f -`GET /v2/portal/entity/{slug}/{id}/activity` +`GET /v2/portal/user/file/{id}/preview` ```ts -const { data } = await client.getEntityActivityFeed({ - slug: 'example', +const { data } = await client.getFilePreview({ id: '123e4567-e89b-12d3-a456-426614174000', - after: 'example', - before: 'example', - from: 1, - size: 1, - type: 'example', - include_relations: true, }) ``` @@ -4902,22 +4422,10 @@ const { data } = await client.getEntityActivityFeed({ ```json { - "total": 1, - "results": [ - { - "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", - "timestamp": "1970-01-01T00:00:00.000Z", - "type": "MyCustomActivity", - "title": "My custom activity", - "message": "{{caller}} did something with {{entity payload.entity.id}}.", - "payload": { - "entity": { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "schema": "contact" - } - } - } - ] + "kind": "pdf", + "url": "https://example.com/path", + "requires_auth": true, + "download_url": "https://example.com/path" } ``` @@ -4925,17 +4433,15 @@ const { data } = await client.getEntityActivityFeed({ --- -### `validateCadenceEntityEditRules` +### `trackFileDownloaded` -Validate if cadence rule is valid for an entity +Track that user has downloaded a file -`GET /v2/portal/{slug}/{id}:validateRule` +`POST /v2/portal/user/file/{id}/downloaded` ```ts -const { data } = await client.validateCadenceEntityEditRules({ - slug: 'example', +const { data } = await client.trackFileDownloaded({ id: '123e4567-e89b-12d3-a456-426614174000', - attribute: 'example', }) ``` @@ -4944,18 +4450,35 @@ const { data } = await client.validateCadenceEntityEditRules({ ```json { - "isBlockedByRules": false, - "failedRule": { - "slug": "contact", - "attribute": "string", - "rule_type": "string", - "cadence_period_type": "string", - "changes_allowed": 0, - "cadence_period": 0, - "allowed_decrement": "string", - "allowed_increment": "string", - "number_of_days_before_restriction": 0, - "grace_period": 0 + "file": { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "file", + "filename": "document.pdf", + "access_control": "private", + "file_date": "2021-02-09T12:41:43.662Z", + "public_url": "https://epilot-files-prod.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", + "type": "document", + "mime_type": "application/pdf", + "_relations": [ + { + "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_schema": "contact" + } + ], + "is_new": true, + "custom_download_url_auth": "token" } } ``` @@ -4964,15 +4487,22 @@ const { data } = await client.validateCadenceEntityEditRules({ --- -### `searchPaymentRelationsInEntities` +### `getBillingEvents` -Search for entities that have the payment relation with the given payment id +Fetch billing events for a portal user -`GET /v2/portal/entities-by-payment/{id}` +`GET /v2/portal/billing/events` ```ts -const { data } = await client.searchPaymentRelationsInEntities({ - id: '123e4567-e89b-12d3-a456-426614174000', +const { data } = await client.getBillingEvents({ + from: 1, + size: 1, + entity_id: ['...'], + event_type: 'example', + paid: true, + date_after: 'example', + date_before: 'example', + sort: 'example', }) ``` @@ -4983,22 +4513,33 @@ const { data } = await client.searchPaymentRelationsInEntities({ { "results": [ { + "billing_amount_decimal": "100.50", + "billing_amount": 10050, + "billing_currency": "EUR", + "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", + "contract": { + "$relation": [ + { + "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + } + ] + }, "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", "_org": "123", "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" } - }, - "_schema": "contact" + ], + "type": "installment", + "due_date": "1970-01-01", + "paid_date": "1970-01-01" } ], "hits": 50 @@ -5009,21 +4550,14 @@ const { data } = await client.searchPaymentRelationsInEntities({ --- -### `createCustomEntityActivity` +### `getCustomerBalance` -Create a custom activity that can be displayed in activity feed of an entity. +Get total balance across all contracts and orders of a customer entity. -`PUT /v2/portal/entity/activity` +`GET /v2/portal/billing/customers/balance` ```ts -const { data } = await client.createCustomEntityActivity( - { - entities: ['...'], - }, - { - type: 'PortalUserResetPassword' - }, -) +const { data } = await client.getCustomerBalance() ```
@@ -5031,17 +4565,9 @@ const { data } = await client.createCustomEntityActivity( ```json { - "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", - "timestamp": "1970-01-01T00:00:00.000Z", - "type": "MyCustomActivity", - "title": "My custom activity", - "message": "{{caller}} did something with {{entity payload.entity.id}}.", - "payload": { - "entity": { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "schema": "contact" - } - } + "balance": 8990, + "balance_decimal": "89.90", + "balance_currency": "EUR" } ``` @@ -5049,30 +4575,16 @@ const { data } = await client.createCustomEntityActivity( --- -### `saveEntityFile` +### `getBillingAccount` -Add files to an entity +Get a billing account by id. -`POST /v2/portal/entity/file` +`GET /v2/portal/billing/accounts/{id}` ```ts -const { data } = await client.saveEntityFile( - null, - { - entity_id: '5da0a718-c822-403d-9f5d-20d4584e0528', - entity_type: 'order', - files: [ - { - filename: 'document.pdf', - access_control: 'private', - s3ref: { - bucket: 12345, - key: 12345 - } - } - ] - }, -) +const { data } = await client.getBillingAccount({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) ```
@@ -5080,7 +4592,42 @@ const { data } = await client.saveEntityFile( ```json { - "createdFiles": [ + "entity": { + "billing_account_number": "string", + "balance": 0, + "balance_decimal": "string", + "balance_currency": "EUR", + "billing_contact": { + "$relation": [ + { + "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + } + ] + }, + "billing_address": { + "$relation_ref": [ + { + "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896", + "path": "address", + "_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + } + ] + }, + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ] + }, + "relations": [ { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", @@ -5088,7 +4635,23 @@ const { data } = await client.saveEntityFile( "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" } ] } @@ -5098,47 +4661,20 @@ const { data } = await client.saveEntityFile( --- -### `deleteEntityFile` - -Delete files from an entity - -`DELETE /v2/portal/entity/file` - -```ts -const { data } = await client.deleteEntityFile( - null, - { - entity_id: '5da0a718-c822-403d-9f5d-20d4584e0528', - entity_type: 'order', - file_entity_ids: ['5da0a718-c822-403d-9f5d-20d4584e0528'] - }, -) -``` - ---- - -### `savePortalFiles` +### `loginToPortalAsUser` -Add files to portal +Generate a token to log in to a portal impersonating a users. -`POST /v2/portal/portal/files` +`POST /v2/portal/admin:login-as-user` ```ts -const { data } = await client.savePortalFiles( +const { data } = await client.loginToPortalAsUser( null, { + email: 'portal-customer@email.com', origin: 'string', - files: [ - { - filename: 12345, - file_type: 'orderRightTeaser', - _tags: 12345, - s3ref: { - bucket: 12345, - key: 12345 - } - } - ] + portal_id: 'string', + domain: 'string' }, ) ``` @@ -5148,17 +4684,8 @@ const { data } = await client.savePortalFiles( ```json { - "createdFiles": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file" - } - ] + "login_as_token": "string", + "portal_url": "https://my-portal.ecp.epilot.io" } ``` @@ -5166,14 +4693,22 @@ const { data } = await client.savePortalFiles( --- -### `getRegistrationIdentifiers` +### `triggerEntityAccessEventV3` -Get valid attributes from entities that can be used as identifier to map contact to user on registration +Trigger entity access event for a portal user. +Supports two identification methods: +1. Using portal_id +2. Using domain -`GET /v2/portal/registration/identifiers` +`POST /v3/portal/entity/{schema}/access` ```ts -const { data } = await client.getRegistrationIdentifiers() +const { data } = await client.triggerEntityAccessEventV3({ + schema: 'example', + entity_id: 'example', + portal_id: 'example', + domain: 'example', +}) ```
@@ -5181,22 +4716,7 @@ const { data } = await client.getRegistrationIdentifiers() ```json { - "data": { - "contact": [ - { - "label": "First name", - "name": "first_name", - "type": "string" - } - ], - "contract": [ - { - "label": "Contract number", - "name": "contract_number", - "type": "string" - } - ] - } + "eventId": "string" } ``` @@ -5204,16 +4724,61 @@ const { data } = await client.getRegistrationIdentifiers() --- -### `getFileById` +### `getPortalUserEntity` -Fetch a document with ID +Get a single entity for a portal user -`GET /v2/portal/user/file/{id}` +`POST /v2/portal/entity:get` ```ts -const { data } = await client.getFileById({ - id: '123e4567-e89b-12d3-a456-426614174000', -}) +const { data } = await client.getPortalUserEntity( + null, + { + slug: 'contact', + entity_id: '3ec28ab5-8598-41ef-9486-b57fca1d5e2a', + hydrate: false, + fields: ['_id', '_title'], + templates: { + content_top_name: 'Customer #{{contract.customer_number}}', + main_content_name: '{{contract.contract_name}} ({{contract.contract_number}})', + content_bottom_name: '{{custom_contract_delivery_address}}', + nested_content: { + title: '{{contract.contract_name}}', + subtitle: '{{contract.contract_number}}' + } + }, + templates_ref: { + page_id: 'string', + block_id: 'string', + config_id: 'string', + global_search_config_id: 'string' + }, + filters: [ + { + term: { + 'status.keyword': 'active' + } + }, + { + range: { + _created_at: { + gte: '2023-01-01' + } + } + } + ], + filters_context: [ + { + portal_user: true + }, + { + contact: true + }, + /* ... 1 more */ + ], + targets: ['3ec28ab5-8598-41ef-9486-b57fca1d5e2a'] + }, +) ```
@@ -5221,28 +4786,30 @@ const { data } = await client.getFileById({ ```json { - "file": { + "result": { "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", "_title": "Example Entity", "_org": "123", "_tags": ["example", "mock"], "_created_at": "2021-02-09T12:41:43.662Z", "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file", - "filename": "document.pdf", - "access_control": "private", - "file_date": "2021-02-09T12:41:43.662Z", - "public_url": "https://epilot-files-prod.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", - "type": "document", - "mime_type": "application/pdf", - "_relations": [ + "templates_output_highlighted": {}, + "search_snippets": [ { - "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_schema": "contact", - "_title": "Opportunity ABC" + "field": "string", + "fragment": "string" } ], - "is_new": true + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" } } ``` @@ -5251,16 +4818,69 @@ const { data } = await client.getFileById({ --- -### `trackFileDownloaded` +### `searchPortalUserEntities` -Track that user has downloaded a file +Search all entities of a portal user -`POST /v2/portal/user/file/{id}/downloaded` +`POST /v2/portal/entity:search` ```ts -const { data } = await client.trackFileDownloaded({ - id: '123e4567-e89b-12d3-a456-426614174000', -}) +const { data } = await client.searchPortalUserEntities( + null, + { + slug: 'contact', + q: 'contract', + q_fields: ['_title', 'customer._title', 'customer.first_name', 'customer.last_name'], + group: 'customer._title', + group_title: '{{customer[Primary].first_name}} {{customer[Primary].last_name}}', + group_size: 100, + group_sort: 'desc', + group_after_key: {}, + sort: '_created_at:desc', + from: 0, + size: 100, + hydrate: false, + fields: ['_id', '_title'], + templates: { + content_top_name: 'Customer #{{contract.customer_number}}', + main_content_name: '{{contract.contract_name}} ({{contract.contract_number}})', + content_bottom_name: '{{custom_contract_delivery_address}}' + }, + templates_ref: { + page_id: 'string', + block_id: 'string', + config_id: 'string', + global_search_config_id: 'string' + }, + filters: [ + { + term: { + 'status.keyword': 'active' + } + }, + { + range: { + _created_at: { + gte: '2023-01-01' + } + } + } + ], + filters_context: [ + { + portal_user: true + }, + { + contact: true + }, + /* ... 1 more */ + ], + targets: ['3ec28ab5-8598-41ef-9486-b57fca1d5e2a'], + match_any_targets: ['3ec28ab5-8598-41ef-9486-b57fca1d5e2a', '5f2c1e7a-6b0d-4a8e-9c3f-1d2e3f4a5b6c'], + include: ['active_workflow'], + highlight: {} + }, +) ```
@@ -5268,28 +4888,42 @@ const { data } = await client.trackFileDownloaded({ ```json { - "file": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "_schema": "file", - "filename": "document.pdf", - "access_control": "private", - "file_date": "2021-02-09T12:41:43.662Z", - "public_url": "https://epilot-files-prod.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", - "type": "document", - "mime_type": "application/pdf", - "_relations": [ - { - "entity_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_schema": "contact", - "_title": "Opportunity ABC" - } - ], - "is_new": true + "results": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" + } + ], + "pagination": { + "from": 0, + "size": 10, + "total": 50, + "has_more": true + }, + "hits": 10, + "includes": { + "active_workflow": {} } } ``` @@ -5298,23 +4932,28 @@ const { data } = await client.trackFileDownloaded({ --- -### `getBillingEvents` +### `canTriggerPortalFlow` -Fetch billing events for a portal user +Returns whether the user can trigger a portal flow -`GET /v2/portal/billing/events` +`POST /v2/portal/can-trigger-portal-flow` ```ts -const { data } = await client.getBillingEvents({ - from: 1, - size: 1, - entity_id: ['...'], - event_type: 'example', - paid: true, - date_after: 'example', - date_before: 'example', - sort: 'example', -}) +const { data } = await client.canTriggerPortalFlow( + { + origin: 'example', + portal_id: 'example', + }, + { + activity_id: '01F130Q52Q6MWSNS8N2AVXV4JN', + ecp_config: { + file_config: { + shared_with_end_customer: true, + _tags: ['example', 'mock'] + } + } + }, +) ```
@@ -5322,31 +4961,7 @@ const { data } = await client.getBillingEvents({ ```json { - "results": [ - { - "billing_amount_decimal": "100.50", - "billing_amount": 10050, - "billing_currency": "EUR", - "external_id": "d4fb2a4e-3f74-4fc4-8fba-6fdaaaa3b08e", - "contract": { - "$relation": [ - { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "type": "installment", - "due_date": "string", - "paid_date": "string" - } - ], - "hits": 50 + "can_trigger": true } ``` @@ -5354,40 +4969,40 @@ const { data } = await client.getBillingEvents({ --- -### `getCustomerBalance` +### `getAutomationContext` -Get total balance across all contracts and orders of a customer entity. +Retrieves the automation context. -`GET /v2/portal/billing/customers/balance` +`GET /v2/portal/automation-context` ```ts -const { data } = await client.getCustomerBalance() +const { data } = await client.getAutomationContext({ + activity_id: 'example', + type: 'example', +}) ```
Response ```json -{ - "balance": 8990, - "balance_decimal": "89.90", - "balance_currency": "EUR" -} +{} ```
--- -### `getBillingAccount` +### `updateWorkflowStepAsDone` -Get a billing account by id. +Update a workflow step as done -`GET /v2/portal/billing/accounts/{id}` +`PUT /v2/portal/workflow/{workflow_id}/{step_id}:markDone` ```ts -const { data } = await client.getBillingAccount({ - id: '123e4567-e89b-12d3-a456-426614174000', +const { data } = await client.updateWorkflowStepAsDone({ + workflow_id: 'example', + step_id: 'example', }) ``` @@ -5396,52 +5011,85 @@ const { data } = await client.getBillingAccount({ ```json { - "entity": { - "billing_account_number": "string", - "balance": 0, - "balance_decimal": "string", - "balance_currency": "EUR", - "billing_contact": { - "$relation": [ + "startedTime": "2024-01-12T13:29:55.942Z", + "requirements": [], + "created": "2023-10-20T17:41:10.256Z", + "executionType": "MANUAL", + "assignedToInProgress": "-", + "sectionId": "lzxsw2sblj7", + "type": "STEP", + "entityRefId": "q1d6vcbsqvn", + "assignedTo": ["10014532"], + "lastUpdated": "2024-01-13T05:18:43.838Z", + "ecp": {}, + "userIds": [], + "name": "Hinterlege den vereinbarten LIC Termin", + "id": "q1d6vcbsqvn", + "definitionId": "9UjHKq", + "status": "COMPLETED", + "manuallyCreated": false, + "enabled": true, + "completedTime": "2024-01-13T05:18:43.827Z" +} +``` + +
+ +--- + +### `getEntityWorkflows` + +Get all workflows associated with an entity (requires access to the entity) + +`GET /v2/portal/entity/{slug}/{id}/workflows` + +```ts +const { data } = await client.getEntityWorkflows({ + slug: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "workflow_executions": [ + { + "id": "8gja72h6kas6h", + "name": "Lead Qualification", + "trigger": "MANUAL", + "status": "STARTED", + "creationTime": "2021-04-27T12:01:13.000Z", + "lastUpdateTime": "2021-04-27T12:01:13.000Z", + "dueDate": "2021-04-27T12:01:13.000Z", + "assignedTo": ["252", "29052"], + "flow": [ { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" - } - ] - }, - "billing_address": { - "$relation_ref": [ + "id": "sectionId1", + "name": "Initial Information Gathering", + "steps": [ + { + "id": "sada5641f3a21", + "name": "Call client and confirm address and product", + "status": "ASSIGNED", + "assignedTo": ["11"] + }, + { + "id": "sada5641f3a22", + "name": "Check product availability", + "status": "UNASSIGNED" + } + ] + }, { - "entity_id": "f589786b-3024-43cd-9cb3-5a3c953f2896", - "path": "address", - "_id": "f589786b-3024-43cd-9cb3-5a3c953f2896" + "id": "firstLevelStepId1", + "name": "Print and send catalog", + "status": "SKIPPED", + "dueDate": "2023-01-15T20:00:00" } ] - }, - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z" - }, - "relations": [ - { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" - } - }, - "_schema": "contact" } ] } @@ -5451,20 +5099,14 @@ const { data } = await client.getBillingAccount({ --- -### `loginToPortalAsUser` +### `getOutstandingTasks` -Generate a token to log in to a portal impersonating a users. +Get outstanding workflow tasks for the portal user -`POST /v2/portal/admin:login-as-user` +`GET /v2/portal/engagement/tasks` ```ts -const { data } = await client.loginToPortalAsUser( - null, - { - email: 'portal-customer@email.com', - origin: 'string' - }, -) +const { data } = await client.getOutstandingTasks() ```
@@ -5472,7 +5114,22 @@ const { data } = await client.loginToPortalAsUser( ```json { - "login_as_token": "string" + "tasks": [ + { + "entity_id": "string", + "entity_schema": "string", + "entity_title": "string", + "workflow_id": "string", + "workflow_name": "string", + "step_id": "string", + "step_name": "string", + "journey_id": "string", + "complete_task_automatically": true, + "title": "string", + "subtitle": "string" + } + ], + "total": 0 } ``` @@ -5480,17 +5137,17 @@ const { data } = await client.loginToPortalAsUser( --- -### `triggerEntityAccessEvent` +### `getEntityPortalWorkflows` -Trigger entity access event for a portal user +Get all portal-relevant workflows associated with an entity (requires access to the entity), +linearized by the Workflows API into a flat, ordered list of portal-visible tasks. -`POST /v2/portal/entity/{schema}/access` +`GET /v2/portal/entity/{slug}/{id}/workflows/linearized` ```ts -const { data } = await client.triggerEntityAccessEvent({ - schema: 'example', - entity_id: 'example', - origin: 'example', +const { data } = await client.getEntityPortalWorkflows({ + slug: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', }) ``` @@ -5499,7 +5156,96 @@ const { data } = await client.triggerEntityAccessEvent({ ```json { - "eventId": "string" + "portal_workflows": [ + { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "version": 2, + "created_at": "string", + "updated_at": "string", + "completed_at": "string", + "due_date": "string", + "assigned_to": ["string"], + "contexts": [ + { + "entity_id": "string", + "entity_schema": "string", + "is_primary": true + } + ], + "is_path_complete": true, + "tasks": [ + { + "id": "string", + "name": "string", + "order": 0, + "status": "COMPLETED", + "is_active": true, + "start_date": "1970-01-01T00:00:00.000Z", + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true + } + }, + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true + }, + "assigned_to": ["string"], + "phase_id": "string", + "phase_name": "string", + "stage_id": "string", + "completed_at": "string", + "updated_at": "string" + } + ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "status": "COMPLETED", + "completed_at": "string", + "portal_names": { + "ecp": "string", + "installer": "string" + }, + "portal_descriptions": { + "ecp": "string", + "installer": "string" + } + } + ], + "portal_titles": { + "ecp": "string", + "installer": "string" + } + } + ] } ``` @@ -5507,18 +5253,26 @@ const { data } = await client.triggerEntityAccessEvent({ --- -### `triggerEntityAccessEventV3` +### `getEntityPortalWorkflowsBatch` -Trigger entity access event for a portal user +Batch variant of `getEntityPortalWorkflows`: returns portal-relevant workflows for +up to 50 entities — schemas may differ — in a single call, each already linearized +by the Workflows API into a flat, -`POST /v3/portal/entity/{schema}/access` +`POST /v2/portal/entities/workflows/linearized/batch` ```ts -const { data } = await client.triggerEntityAccessEventV3({ - schema: 'example', - entity_id: 'example', - portal_id: 'example', -}) +const { data } = await client.getEntityPortalWorkflowsBatch( + null, + { + entities: [ + { + id: 'string', + slug: 'order' + } + ] + }, +) ```
@@ -5526,7 +5280,101 @@ const { data } = await client.triggerEntityAccessEventV3({ ```json { - "eventId": "string" + "results": [ + { + "entity_id": "string", + "portal_workflows": [ + { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "version": 2, + "created_at": "string", + "updated_at": "string", + "completed_at": "string", + "due_date": "string", + "assigned_to": ["string"], + "contexts": [ + { + "entity_id": "string", + "entity_schema": "string", + "is_primary": true + } + ], + "is_path_complete": true, + "tasks": [ + { + "id": "string", + "name": "string", + "order": 0, + "status": "COMPLETED", + "is_active": true, + "start_date": "1970-01-01T00:00:00.000Z", + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true + } + }, + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true + }, + "assigned_to": ["string"], + "phase_id": "string", + "phase_name": "string", + "stage_id": "string", + "completed_at": "string", + "updated_at": "string" + } + ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "status": "COMPLETED", + "completed_at": "string", + "portal_names": { + "ecp": "string", + "installer": "string" + }, + "portal_descriptions": { + "ecp": "string", + "installer": "string" + } + } + ], + "portal_titles": { + "ecp": "string", + "installer": "string" + } + } + ] + } + ] } ``` @@ -5534,53 +5382,20 @@ const { data } = await client.triggerEntityAccessEventV3({ --- -### `getPortalUserEntity` +### `uploadMeterReadingPhoto` -Get a single entity for a portal user +Uploads a Meter Reading photo and - if enabled - gives back data extracted from the photo. -`POST /v2/portal/entity:get` +`POST /v2/portal/metering/reading/photo` ```ts -const { data } = await client.getPortalUserEntity( +const { data } = await client.uploadMeterReadingPhoto( null, { - slug: 'contact', - entity_id: '3ec28ab5-8598-41ef-9486-b57fca1d5e2a', - hydrate: false, - fields: ['_id', '_title'], - templates: { - content_top_name: 'Customer #{{contract.customer_number}}', - main_content_name: '{{contract.contract_name}} ({{contract.contract_number}})', - content_bottom_name: '{{custom_contract_delivery_address}}', - nested_content: { - title: '{{contract.contract_name}}', - subtitle: '{{contract.contract_number}}' - } - }, - filters: [ - { - term: { - 'status.keyword': 'active' - } - }, - { - range: { - _created_at: { - gte: '2023-01-01' - } - } - } - ], - filters_context: [ - { - portal_user: true - }, - { - contact: true - }, - /* ... 1 more */ - ], - targets: ['3ec28ab5-8598-41ef-9486-b57fca1d5e2a'] + filename: 'Reading 10.01.2025.jpg', + mime_type: 'image/jpeg', + contents: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxMTEhUTExMWFhUXGBgYGBgYGBgYGBgYGBgYFxgYFxgYHSggGBolHRgXITEhJSkrLi4uFx8zODMtNygtLisBCgoKDg0OGhAQGy0lHyUt', + meter_id: '5da0a718-c822-403d-9f5d-20d4584e0528' }, ) ``` @@ -5590,23 +5405,16 @@ const { data } = await client.getPortalUserEntity( ```json { - "result": { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" - } + "data": { + "filename": "Reading 10.01.2025.jpg", + "s3ref": { + "bucket": "meter-readings", + "key": "uuid/reading-10.01.2025.jpg" }, - "_schema": "contact" + "reading": "000123.45", + "sector": "water", + "meter_numbers": ["00123456"], + "file_id": "abc123def456" } } ``` @@ -5615,58 +5423,33 @@ const { data } = await client.getPortalUserEntity( --- -### `searchPortalUserEntities` +### `createMeterReading` -Search all entities of a portal user +Inserts a new meter reading. -`POST /v2/portal/entity:search` +`POST /v2/portal/metering/reading` ```ts -const { data } = await client.searchPortalUserEntities( - null, +const { data } = await client.createMeterReading( { - slug: 'contact', - q: 'contract', - q_fields: ['_title', 'customer._title', 'customer.first_name', 'customer.last_name'], - group: 'customer._title', - group_title: '{{customer[Primary].first_name}} {{customer[Primary].last_name}}', - group_size: 100, - group_sort: 'desc', - group_after_key: {}, - sort: '_created_at:desc', - from: 0, - size: 100, - hydrate: false, - fields: ['_id', '_title'], - templates: { - content_top_name: 'Customer #{{contract.customer_number}}', - main_content_name: '{{contract.contract_name}} ({{contract.contract_number}})', - content_bottom_name: '{{custom_contract_delivery_address}}' - }, - filters: [ - { - term: { - 'status.keyword': 'active' - } - }, - { - range: { - _created_at: { - gte: '2023-01-01' - } - } - } - ], - filters_context: [ - { - portal_user: true - }, - { - contact: true - }, - /* ... 1 more */ - ], - targets: ['3ec28ab5-8598-41ef-9486-b57fca1d5e2a'] + override_plausibility: true, + }, + { + value: 240, + read_by: 'John Doe', + reason: 'Storing the feed-in record', + meter_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + counter_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + direction: 'feed-in', + timestamp: '2022-10-10', + source: 'ECP', + status: 'valid', + external_id: 'string', + remark: 'Customer reported unusual consumption', + metadata: { + registration_id: '1234567890', + business_unit: 'ABC' + } }, ) ``` @@ -5676,33 +5459,59 @@ const { data } = await client.searchPortalUserEntities( ```json { - "results": [ + "data": { + "value": 240, + "read_by": "John Doe", + "reason": "Storing the feed-in record", + "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "counter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "direction": "feed-in", + "timestamp": "2022-10-10", + "source": "ECP", + "status": "valid", + "external_id": "string", + "remark": "Customer reported unusual consumption", + "metadata": { + "registration_id": "1234567890", + "business_unit": "ABC" + } + } +} +``` + +
+ +--- + +### `getAllowedMeterReadingRange` + +Get allowed reading range for all counters of a meter from the configured +third-party plausibility check hook using 'range' mode. This endpoint requires +a plausibility check hook to be configured for + +`GET /v2/portal/metering/reading/allowed-range/{meter_id}` + +```ts +const { data } = await client.getAllowedMeterReadingRange({ + meter_id: 'example', + origin: 'example', + timestamp: 'example', + context_entities: 'example', +}) +``` + +
+Response + +```json +{ + "data": [ { - "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "_title": "Example Entity", - "_org": "123", - "_tags": ["example", "mock"], - "_created_at": "2021-02-09T12:41:43.662Z", - "_updated_at": "2021-02-09T12:41:43.662Z", - "templates_output": { - "content_top_name": "Customer #123456", - "main_content_name": "Orange Flexible A2 (654321)", - "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", - "nested_content": { - "title": "Orange Flexible A2", - "subtitle": "654321" - } - }, - "_schema": "contact" + "meter_counter_id": "string", + "min_value": 0, + "max_value": 0 } - ], - "pagination": { - "from": 0, - "size": 10, - "total": 50, - "has_more": true - }, - "hits": 10 + ] } ``` @@ -5710,25 +5519,30 @@ const { data } = await client.searchPortalUserEntities( --- -### `canTriggerPortalFlow` +### `getMeterReadings` -Returns whether the user can trigger a portal flow +Fetches meter readings for a counter and optionally resolves Handlebars +template strings against each reading object using @epilot/variables. -`POST /v2/portal/can-trigger-portal-flow` +`POST /v2/portal/metering/readings` ```ts -const { data } = await client.canTriggerPortalFlow( - { - origin: 'example', - portal_id: 'example', - }, +const { data } = await client.getMeterReadings( + null, { - activity_id: '01F130Q52Q6MWSNS8N2AVXV4JN', - ecp_config: { - file_config: { - shared_with_end_customer: true, - _tags: ['example', 'mock'] - } + meter_id: 'string', + counter_id: 'string', + sort: 'desc', + from: 0, + size: 10, + templates: {}, + counter_templates: {}, + include_counter: false, + templates_ref: { + page_id: 'string', + block_id: 'string', + config_id: 'string', + global_search_config_id: 'string' } }, ) @@ -5739,7 +5553,19 @@ const { data } = await client.canTriggerPortalFlow( ```json { - "can_trigger": true + "results": [ + { + "templates_output": {} + } + ], + "hits": 0, + "counter_templates_output": {}, + "counter": { + "unit": "kwh", + "obis_number": "1-1:1.8.1", + "direction": "feed-in", + "tariff_type": "string" + } } ``` @@ -5747,16 +5573,15 @@ const { data } = await client.canTriggerPortalFlow( --- -### `getAutomationContext` +### `getMeter` -Retrieves the automation context. +Retrieves a meter of the portal user, with its journey actions and related entities. -`GET /v2/portal/automation-context` +`GET /v2/portal/metering/meter/{meter_id}` ```ts -const { data } = await client.getAutomationContext({ - activity_id: 'example', - type: 'example', +const { data } = await client.getMeter({ + meter_id: 'example', }) ``` @@ -5764,23 +5589,83 @@ const { data } = await client.getAutomationContext({ Response ```json -{} +{ + "data": { + "entity": { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "meter" + }, + "journey_actions": { + "journey_id": "string", + "action_label": { + "en": "string", + "de": "string" + }, + "slug": "string", + "rules": [ + { + "entity": "string", + "attribute": "string", + "attribute_value": "string" + } + ] + }, + "relations": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "templates_output": { + "content_top_name": "Customer #123456", + "main_content_name": "Orange Flexible A2 (654321)", + "content_bottom_name": "Porscheplatz 1, 70435 Stuttgart, Germany", + "nested_content": { + "title": "Orange Flexible A2", + "subtitle": "654321" + } + }, + "_schema": "contact" + } + ] + } +} ```
--- -### `updateWorkflowStepAsDone` +### `getMeterCounters` -Update a workflow step as done +Retrieves the counters of a meter of the portal user. -`PUT /v2/portal/workflow/{workflow_id}/{step_id}:markDone` +`GET /v2/portal/metering/meter/{meter_id}/counters` ```ts -const { data } = await client.updateWorkflowStepAsDone({ - workflow_id: 'example', - step_id: 'example', +const { data } = await client.getMeterCounters({ + meter_id: 'example', }) ``` @@ -5789,25 +5674,27 @@ const { data } = await client.updateWorkflowStepAsDone({ ```json { - "startedTime": "2024-01-12T13:29:55.942Z", - "requirements": [], - "created": "2023-10-20T17:41:10.256Z", - "executionType": "MANUAL", - "assignedToInProgress": "-", - "sectionId": "lzxsw2sblj7", - "type": "STEP", - "entityRefId": "q1d6vcbsqvn", - "assignedTo": ["10014532"], - "lastUpdated": "2024-01-13T05:18:43.838Z", - "ecp": {}, - "userIds": [], - "name": "Hinterlege den vereinbarten LIC Termin", - "id": "q1d6vcbsqvn", - "definitionId": "9UjHKq", - "status": "COMPLETED", - "manuallyCreated": false, - "enabled": true, - "completedTime": "2024-01-13T05:18:43.827Z" + "data": [ + { + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "_schema": "meter_counter", + "obis_number": "string", + "direction": "feed-in", + "transformer_ratio": 0, + "unit": "string", + "forecast_reading_value": "string", + "forecast_as_of": "string", + "current_consumption": 0, + "last_reading": "string", + "conversion_factor": 0, + "tariff_type": "ht" + } + ] } ``` @@ -5815,17 +5702,36 @@ const { data } = await client.updateWorkflowStepAsDone({ --- -### `getEntityWorkflows` +### `createMeterReadings` -Get workflows for an entity +Inserts readings for several counters of a meter of the portal user at once, one reading per +counter and at most 100 per request. Use `createMeterReading` instead when the portal has a +meter reading p -`GET /v2/portal/entity/{slug}/{id}/workflows` +`POST /v2/portal/metering/meter/{meter_id}/readings` ```ts -const { data } = await client.getEntityWorkflows({ - slug: 'example', - id: '123e4567-e89b-12d3-a456-426614174000', -}) +const { data } = await client.createMeterReadings( + { + meter_id: 'example', + }, + { + readings: [ + { + value: 0, + counter_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + direction: 'feed-in', + timestamp: 'string', + read_by: 'John Doe', + reason: 'Storing the feed-in record', + source: 'ECP', + status: 'valid', + remark: 'string', + metadata: {} + } + ] + }, +) ```
@@ -5833,41 +5739,23 @@ const { data } = await client.getEntityWorkflows({ ```json { - "workflow_executions": [ + "data": [ { - "id": "8gja72h6kas6h", - "name": "Lead Qualification", - "trigger": "MANUAL", - "status": "STARTED", - "creationTime": "2021-04-27T12:01:13.000Z", - "lastUpdateTime": "2021-04-27T12:01:13.000Z", - "dueDate": "2021-04-27T12:01:13.000Z", - "assignedTo": ["252", "29052"], - "flow": [ - { - "id": "sectionId1", - "name": "Initial Information Gathering", - "steps": [ - { - "id": "sada5641f3a21", - "name": "Call client and confirm address and product", - "status": "ASSIGNED", - "assignedTo": ["11"] - }, - { - "id": "sada5641f3a22", - "name": "Check product availability", - "status": "UNASSIGNED" - } - ] - }, - { - "id": "firstLevelStepId1", - "name": "Print and send catalog", - "status": "SKIPPED", - "dueDate": "2023-01-15T20:00:00" - } - ] + "value": 240, + "read_by": "John Doe", + "reason": "Storing the feed-in record", + "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "counter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "direction": "feed-in", + "timestamp": "2022-10-10", + "source": "ECP", + "status": "valid", + "external_id": "string", + "remark": "Customer reported unusual consumption", + "metadata": { + "registration_id": "1234567890", + "business_unit": "ABC" + } } ] } @@ -5877,22 +5765,18 @@ const { data } = await client.getEntityWorkflows({ --- -### `uploadMeterReadingPhoto` +### `getAllowedMeterReading` -Upload Meter Reading Photo +Returns the allowed min/max reading per counter of the meter, derived from its reading history. +Unlike `getAllowedMeterReadingRange`, this needs no plausibility check hook. -`POST /v2/portal/metering/reading/photo` +`GET /v2/portal/metering/meter/{meter_id}/allowed-reading` ```ts -const { data } = await client.uploadMeterReadingPhoto( - null, - { - filename: 'Reading 10.01.2025.jpg', - mime_type: 'image/jpeg', - contents: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxMTEhUTExMWFhUXGBgYGBgYGBgYGBgYGBgYFxgYFxgYHSggGBolHRgXITEhJSkrLi4uFx8zODMtNygtLisBCgoKDg0OGhAQGy0lHyUt', - meter_id: '5da0a718-c822-403d-9f5d-20d4584e0528' - }, -) +const { data } = await client.getAllowedMeterReading({ + meter_id: 'example', + timestamp: 'example', +}) ```
@@ -5900,16 +5784,14 @@ const { data } = await client.uploadMeterReadingPhoto( ```json { - "data": { - "filename": "Reading 10.01.2025.jpg", - "s3ref": { - "bucket": "meter-readings", - "key": "uuid/reading-10.01.2025.jpg" - }, - "reading": "000123.45", - "sector": "water", - "meter_numbers": ["00123456"] - } + "data": [ + { + "counter_id": "string", + "min_value": 0, + "max_value": 0, + "last_reading": "1970-01-01T00:00:00.000Z" + } + ] } ``` @@ -5917,35 +5799,16 @@ const { data } = await client.uploadMeterReadingPhoto( --- -### `createMeterReading` +### `getMeterCounter` -Create Meter Reading +Retrieves a counter of a meter of the portal user, incl. its unit and last reading. -`POST /v2/portal/metering/reading` +`GET /v2/portal/metering/counter/{counter_id}` ```ts -const { data } = await client.createMeterReading( - { - override_plausibility: true, - }, - { - value: 240, - read_by: 'John Doe', - reason: 'Storing the feed-in record', - meter_id: '5da0a718-c822-403d-9f5d-20d4584e0528', - counter_id: '5da0a718-c822-403d-9f5d-20d4584e0528', - direction: 'feed-in', - timestamp: '2022-10-10T00:00:00.000Z', - source: 'ECP', - status: 'valid', - external_id: 'string', - remark: 'Customer reported unusual consumption', - metadata: { - registration_id: '1234567890', - business_unit: 'ABC' - } - }, -) +const { data } = await client.getMeterCounter({ + counter_id: 'example', +}) ```
@@ -5954,21 +5817,23 @@ const { data } = await client.createMeterReading( ```json { "data": { - "value": 240, - "read_by": "John Doe", - "reason": "Storing the feed-in record", - "meter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "counter_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "_schema": "meter_counter", + "obis_number": "string", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", - "source": "ECP", - "status": "valid", - "external_id": "string", - "remark": "Customer reported unusual consumption", - "metadata": { - "registration_id": "1234567890", - "business_unit": "ABC" - } + "transformer_ratio": 0, + "unit": "string", + "forecast_reading_value": "string", + "forecast_as_of": "string", + "current_consumption": 0, + "last_reading": "string", + "conversion_factor": 0, + "tariff_type": "ht" } } ``` @@ -5977,16 +5842,15 @@ const { data } = await client.createMeterReading( --- -### `getAllowedMeterReadingRange` +### `getContractMeters` -`GET /v2/portal/metering/reading/allowed-range/{meter_id}` +Retrieves the meters of a contract of the portal user. + +`GET /v2/portal/metering/contract/{contract_id}/meters` ```ts -const { data } = await client.getAllowedMeterReadingRange({ - meter_id: 'example', - origin: 'example', - timestamp: 'example', - context_entities: 'example', +const { data } = await client.getContractMeters({ + contract_id: 'example', }) ``` @@ -5997,9 +5861,20 @@ const { data } = await client.getAllowedMeterReadingRange({ { "data": [ { - "meter_counter_id": "string", - "min_value": 0, - "max_value": 0 + "_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "_title": "Example Entity", + "_org": "123", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "templates_output_highlighted": {}, + "search_snippets": [ + { + "field": "string", + "fragment": "string" + } + ], + "_schema": "meter" } ] } @@ -6009,23 +5884,19 @@ const { data } = await client.getAllowedMeterReadingRange({ --- -### `ssoLogin` +### `getPublicSSOProviderV3` -Initiate login using external SSO identity. +Returns the public configuration of a single SSO identity provider with env var +placeholders (incl. secrets) already resolved against the organization's environment. -`POST /v2/portal/public/sso/login` +`GET /v3/portal/public/sso/providers/{provider_slug}` ```ts -const { data } = await client.ssoLogin( - { - origin: 'example', - org_id: 'example', - contact_id: 'example', - }, - { - provider_slug: 'office-365-login' - }, -) +const { data } = await client.getPublicSSOProviderV3({ + provider_slug: 'example', + org_id: 'example', + portal_id: 'example', +}) ```
@@ -6033,8 +5904,31 @@ const { data } = await client.ssoLogin( ```json { - "token": "string", - "email": "portal-customer@email.com" + "slug": "office-365-login", + "display_name": "Office 365 Login", + "oidc_config": { + "type": "implicit", + "oidc_issuer": "https://login.microsoftonline.com/33d4f3e5-3df2-421e-b92e-a63cfa680a88/v2.0", + "redirect_uri": "https://customer-portal.com/login", + "client_id": "ab81daf8-8b1f-42d6-94ca-c51621054c75", + "client_secret": "7BIUnn~6shh.7fNtXb..3k1Mp3s6k6WK3B", + "has_client_secret": true, + "scope": "openid email", + "metadata": { + "response_modes_supported": ["form_post"], + "authorization_endpoint": "https://www.facebook.com/v12.0/dialog/oauth", + "token_endpoint": "https://graph.facebook.com/v12.0/oauth/access_token", + "userinfo_endpoint": "https://graph.facebook.com/me", + "logout_uri": "https://login.microsoftonline.com/common/oauth2/v2.0/logout", + "logout_redirect_uri": "https://customer-portal.com/login", + "skip_login_as_logout": false, + "mobile_redirect_uri": "msauth.io.epilot.ecp://auth", + "test_auth_username": "test@epilot.io", + "test_auth_password": "string" + }, + "prompt": "login" + }, + "debug_mode": false } ``` @@ -6053,10 +5947,12 @@ const { data } = await client.ssoLoginV3( { portal_id: 'example', org_id: 'example', + domain: 'example', contact_id: 'example', }, { - provider_slug: 'office-365-login' + provider_slug: 'office-365-login', + login_only: false }, ) ``` @@ -6107,7 +6003,7 @@ const { data } = await client.ssoCallback( token_endpoint: 'https://www.facebook.com/v12.0/dialog/oauth', grant_type: 'authorization_code', code: '123456', - redirect_uri: 'https://customer-portal.com/login', + redirect_uri: 'https://customer-portal.com/sso', client_id: '123456', code_verifier: '123456' }, @@ -6152,7 +6048,16 @@ const { data } = await client.getPortalPage({ "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -6160,12 +6065,18 @@ const { data } = await client.getPortalPage({ "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ``` @@ -6175,7 +6086,7 @@ const { data } = await client.getPortalPage({ ### `updatePortalPage` -Update a portal page by id +Update a portal page by id. On a portal with versioning enabled, the change is stored as a revision (`Updated via API`) and published in the same call, so every change to the portal has a revision. A `PUT /v2/portal/pages/{id}` @@ -6188,7 +6099,16 @@ const { data } = await client.updatePortalPage( slug: 'dashboard', path: '/dashboard', schema: ['string'], - visibility: {}, + visibility: { + is_hidden: true, + hidden_in_app: true, + start_date: '1970-01-01T00:00:00.000Z', + end_date: '1970-01-01T00:00:00.000Z', + visible_for_targets: ['string'], + visible_for_operator: 'and', + hidden_for_targets: ['string'], + hidden_for_operator: 'and' + }, content: {}, design: {}, blocks: {}, @@ -6196,6 +6116,7 @@ const { data } = await client.updatePortalPage( is_system: false, is_detail: false, detail_schema: 'contact', + show_in_navigation: false, is_public: true, parentId: 'c495fef9-eeca-4019-a989-8390dcd9825b', is_entry_route: false, @@ -6212,7 +6133,16 @@ const { data } = await client.updatePortalPage( "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -6220,12 +6150,18 @@ const { data } = await client.updatePortalPage( "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ``` @@ -6235,7 +6171,7 @@ const { data } = await client.updatePortalPage( ### `deletePortalPage` -Delete a portal page by id +Delete a portal page by id. On a portal with versioning enabled, the change is stored as a revision (`Updated via API`) and published in the same call, so every change to the portal has a revision. A `DELETE /v2/portal/pages/{id}` @@ -6247,6 +6183,110 @@ const { data } = await client.deletePortalPage({ --- +### `detachPortalPage` + +Detach a blueprint-managed page from its blueprint. The page and all of its blocks become local (editable, no longer updated by the blueprint) and the page's lineage is tombstoned on the portal so fut + +`POST /v2/portal/pages/{id}/detach` + +```ts +const { data } = await client.detachPortalPage({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] +} +``` + +
+ +--- + +### `detachPortalPageBlock` + +Detach a blueprint-managed block. The block becomes the customer's and its lineage is tombstoned on the page so future syncs skip it. A managed page stays managed and keeps receiving blueprint updates + +`POST /v2/portal/pages/{id}/blocks/{block_id}/detach` + +```ts +const { data } = await client.detachPortalPageBlock({ + id: '123e4567-e89b-12d3-a456-426614174000', + block_id: 'example', +}) +``` + +
+Response + +```json +{ + "props": { + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, + "content": {}, + "design": {} + }, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "type": "tab", + "order": 1, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "_manifest": ["string"], + "_lineage_id": "string", + "_level": "string" +} +``` + +
+ +--- + ### `getPortalPages` Fetch all portal pages @@ -6272,7 +6312,16 @@ const { data } = await client.getPortalPages({ "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -6280,12 +6329,18 @@ const { data } = await client.getPortalPages({ "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ] ``` @@ -6296,7 +6351,7 @@ const { data } = await client.getPortalPages({ ### `createPortalPage` -Create a new portal page +Create a new portal page. On a portal with versioning enabled, the change is stored as a revision (`Updated via API`) and published in the same call, so every change to the portal has a revision. A co `POST /v2/portal/pages` @@ -6309,7 +6364,16 @@ const { data } = await client.createPortalPage( slug: 'dashboard', path: '/dashboard', schema: ['string'], - visibility: {}, + visibility: { + is_hidden: true, + hidden_in_app: true, + start_date: '1970-01-01T00:00:00.000Z', + end_date: '1970-01-01T00:00:00.000Z', + visible_for_targets: ['string'], + visible_for_operator: 'and', + hidden_for_targets: ['string'], + hidden_for_operator: 'and' + }, content: {}, design: {}, blocks: {}, @@ -6317,6 +6381,7 @@ const { data } = await client.createPortalPage( is_system: false, is_detail: false, detail_schema: 'contact', + show_in_navigation: false, is_public: true, parentId: 'c495fef9-eeca-4019-a989-8390dcd9825b', is_entry_route: false, @@ -6333,7 +6398,16 @@ const { data } = await client.createPortalPage( "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -6341,12 +6415,18 @@ const { data } = await client.createPortalPage( "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ``` @@ -6377,7 +6457,16 @@ const { data } = await client.getPublicPages({ "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -6385,12 +6474,18 @@ const { data } = await client.getPublicPages({ "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ] ``` @@ -6399,14 +6494,61 @@ const { data } = await client.getPublicPages({ --- -### `getDefaultPages` +### `interpolatePortalPages` -Fetch all default portal pages +Interpolate template variables in portal pages without reading from the database. Accepts pages in the request body and returns them with templates resolved. Portal Builder preview only: requires a 36 -`GET /v2/portal/pages/default` +`POST /v2/portal/pages/interpolate` ```ts -const { data } = await client.getDefaultPages() +const { data } = await client.interpolatePortalPages( + null, + { + pages: [ + { + slug: 'dashboard', + path: '/dashboard', + schema: ['string'], + visibility: { + is_hidden: true, + hidden_in_app: true, + start_date: '1970-01-01T00:00:00.000Z', + end_date: '1970-01-01T00:00:00.000Z', + visible_for_targets: ['string'], + visible_for_operator: 'and', + hidden_for_targets: ['string'], + hidden_for_operator: 'and' + }, + content: {}, + design: {}, + blocks: {}, + order: 1, + is_system: false, + is_detail: false, + detail_schema: 'contact', + show_in_navigation: false, + is_public: true, + parentId: 'c495fef9-eeca-4019-a989-8390dcd9825b', + is_entry_route: false, + is_deleted: false, + id: 'c495fef9-eeca-4019-a989-8390dcd9825b', + last_modified_at: '2021-02-09T12:41:43.662Z', + portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', + past_routes: ['old-dashboard', 'home'], + _manifest: ['string'], + _lineage_id: 'string', + detached_lineage_ids: ['string'] + } + ], + context_entities: [ + { + entity_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + entity_schema: 'contract' + } + ], + evaluate_targeting: true + }, +) ```
@@ -6418,7 +6560,16 @@ const { data } = await client.getDefaultPages() "slug": "dashboard", "path": "/dashboard", "schema": ["string"], - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {}, "blocks": {}, @@ -6426,12 +6577,18 @@ const { data } = await client.getDefaultPages() "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ] ``` @@ -6440,22 +6597,125 @@ const { data } = await client.getDefaultPages() --- -### `createPortalPageBlock` +### `getTriggeredJourney` -Create a new portal page block +Returns the auto-triggered journey configured for the given trigger +with handlebars templates in `context_params` already resolved. +Uses the caller's auth context (contact, portal user) plus any +`cont -`POST /v2/portal/pages/{id}/blocks` +`GET /v2/portal/config/triggered-journeys/{trigger_name}` ```ts -const { data } = await client.createPortalPageBlock( - { - id: '123e4567-e89b-12d3-a456-426614174000', - }, - { - props: { - visibility: {}, - content: {}, - design: {} +const { data } = await client.getTriggeredJourney({ + trigger_name: 'example', + context_entities: 'example', +}) +``` + +
+Response + +```json +{ + "trigger_name": "FIRST_LOGIN", + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [ + { + "key": "string", + "value": "string" + } + ] +} +``` + +
+ +--- + +### `getDefaultPages` + +Fetch all default portal pages + +`GET /v2/portal/pages/default` + +```ts +const { data } = await client.getDefaultPages() +``` + +
+Response + +```json +[ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": { + "is_hidden": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] + } +] +``` + +
+ +--- + +### `createPortalPageBlock` + +Create a new portal page block. On a portal with versioning enabled, the change is stored as a revision (`Updated via API`) and published in the same call, so every change to the portal has a revision + +`POST /v2/portal/pages/{id}/blocks` + +```ts +const { data } = await client.createPortalPageBlock( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + props: { + visibility: { + is_hidden: true, + hidden_on_mobile: true, + hidden_on_desktop: true, + hidden_in_app: true, + start_date: '1970-01-01T00:00:00.000Z', + end_date: '1970-01-01T00:00:00.000Z', + visible_for_targets: ['string'], + visible_for_operator: 'and', + hidden_for_targets: ['string'], + hidden_for_operator: 'and' + }, + content: {}, + design: {} }, parentId: 'c495fef9-eeca-4019-a989-8390dcd9825b', type: 'tab', @@ -6470,14 +6730,28 @@ const { data } = await client.createPortalPageBlock( ```json { "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "type": "tab", "order": 1, - "id": "c495fef9-eeca-4019-a989-8390dcd9825b" + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "_manifest": ["string"], + "_lineage_id": "string", + "_level": "string" } ``` @@ -6504,14 +6778,28 @@ const { data } = await client.getPortalPageBlocks({ [ { "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "type": "tab", "order": 1, - "id": "c495fef9-eeca-4019-a989-8390dcd9825b" + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "_manifest": ["string"], + "_lineage_id": "string", + "_level": "string" } ] ``` @@ -6539,14 +6827,28 @@ const { data } = await client.getPortalPageBlock({ ```json { "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "type": "tab", "order": 1, - "id": "c495fef9-eeca-4019-a989-8390dcd9825b" + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "_manifest": ["string"], + "_lineage_id": "string", + "_level": "string" } ``` @@ -6556,7 +6858,7 @@ const { data } = await client.getPortalPageBlock({ ### `updatePortalPageBlock` -Update a portal page block by id +Update a portal page block by id. On a portal with versioning enabled, the change is stored as a revision (`Updated via API`) and published in the same call, so every change to the portal has a revisi `PUT /v2/portal/pages/{id}/blocks/{block_id}` @@ -6568,7 +6870,18 @@ const { data } = await client.updatePortalPageBlock( }, { props: { - visibility: {}, + visibility: { + is_hidden: true, + hidden_on_mobile: true, + hidden_on_desktop: true, + hidden_in_app: true, + start_date: '1970-01-01T00:00:00.000Z', + end_date: '1970-01-01T00:00:00.000Z', + visible_for_targets: ['string'], + visible_for_operator: 'and', + hidden_for_targets: ['string'], + hidden_for_operator: 'and' + }, content: {}, design: {} }, @@ -6585,14 +6898,28 @@ const { data } = await client.updatePortalPageBlock( ```json { "props": { - "visibility": {}, + "visibility": { + "is_hidden": true, + "hidden_on_mobile": true, + "hidden_on_desktop": true, + "hidden_in_app": true, + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + }, "content": {}, "design": {} }, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "type": "tab", "order": 1, - "id": "c495fef9-eeca-4019-a989-8390dcd9825b" + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "_manifest": ["string"], + "_lineage_id": "string", + "_level": "string" } ``` @@ -6602,7 +6929,7 @@ const { data } = await client.updatePortalPageBlock( ### `deletePortalPageBlock` -Delete a portal page block by id +Delete a portal page block by id. On a portal with versioning enabled, the change is stored as a revision (`Updated via API`) and published in the same call, so every change to the portal has a revisi `DELETE /v2/portal/pages/{id}/blocks/{block_id}` @@ -6644,9 +6971,41 @@ const { data } = await client.getUserEntryPoint({ --- +### `completeTemporaryPassword` + +Replaces a portal user's temporary password with the password they chose. + +`POST /v3/portal/public/user/temporary-password/complete` + +```ts +const { data } = await client.completeTemporaryPassword( + null, + { + org_id: '123', + portal_id: '7hj28akg-97fb-4f5c-b2a1-3e4fbc1d8c7a', + email: 'user@example.com', + temporary_password: 'string', + new_password: 'string' + }, +) +``` + +
+Response + +```json +{ + "message": "Password set successfully." +} +``` + +
+ +--- + ### `updateCampaignPortalBlockStatus` -Update Campaign Portal Block Status +Updates the status of a campaign portal block for multiple recipients. `PUT /v2/portal/campaign/{campaign_id}/entity:status` @@ -6683,6 +7042,100 @@ const { data } = await client.updateCampaignPortalBlockStatus( --- +### `listPortalNotifications` + +Lists the 360 notifications addressed to the authenticated portal user, newest first. The organization and the portal user are derived from the authenticated session, so a user can only ever read thei + +`GET /v2/portal/notifications` + +```ts +const { data } = await client.listPortalNotifications({ + cursor: 'example', + limit: 1, +}) +``` + +
+Response + +```json +{ + "cursor": "string", + "total_unread": 0, + "results": [ + { + "id": "1234567890", + "notification_id": 1234567890, + "type": "workflow_step_overdue", + "title": { + "en": "string", + "de": "string" + }, + "message": { + "en": "string", + "de": "string" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "read": false, + "redirect_url": "string" + } + ] +} +``` + +
+ +--- + +### `getPortalNotificationsUnreadCount` + +Returns the number of unread notifications for the authenticated portal user. + +`GET /v2/portal/notifications/unread-count` + +```ts +const { data } = await client.getPortalNotificationsUnreadCount() +``` + +
+Response + +```json +{ + "count": 3 +} +``` + +
+ +--- + +### `markAllPortalNotificationsRead` + +Marks all notifications of the authenticated portal user as read. + +`PUT /v2/portal/notifications/read-all` + +```ts +const { data } = await client.markAllPortalNotificationsRead() +``` + +--- + +### `markPortalNotificationRead` + +Marks a single notification of the authenticated portal user as read. + +`PUT /v2/portal/notifications/{id}/read` + +```ts +const { data } = await client.markPortalNotificationRead({ + id: 1, +}) +``` + +--- + ### `updateNotificationsStatus` Updates the statuses of multiple notifications at once. @@ -6790,6 +7243,56 @@ const { data } = await client.createPortalConfig( { /* ... */ } ] }, + identity_providers: [ + { + slug: 'office-365-login', + display_name: 'Office 365 Login', + provider_type: 'OIDC', + attribute_mappings: { /* ... */ }, + entity_matching: { /* ... */ }, + oidc_config: { /* ... */ }, + mobile_oidc_config: { /* ... */ }, + expose_client_secret: false, + debug_mode_until: '2026-10-30T12:00:00.000Z' + } + ], + mobile_config: { + portal_id: 'string', + enabled: true, + display_name: 'string', + app_host: 'string', + environment: 'prod', + branding: { + app_icon: 'string', + splash: 'string', + splash_dark: 'string', + icon_background_color: 'string', + splash_background_color: 'string', + splash_background_color_dark: 'string' + }, + ios: { + bundle_id: 'string', + team_id: 'string', + credentials_status: 'not_configured', + app_store_id: 'string', + store_url: 'string', + last_build: { /* ... */ } + }, + android: { + package_name: 'string', + credentials_status: 'not_configured', + upload_key_status: 'not_configured', + store_url: 'string', + last_build: { /* ... */ } + }, + ota: { + enabled: true, + channel: 'canary', + auto_update: true, + update_strategy: 'next-launch', + min_native_version: 'string' + } + }, enabled: true, name: 'Installer Portal', domain: 'abc.com', @@ -6801,13 +7304,33 @@ const { data } = await client.createPortalConfig( is_redirection_enabled: true }, design_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + header: { + design: { + overrides: { /* ... */ } + } + }, + allowed_portal_entities: ['contact', 'contract'], self_registration_setting: 'ALLOW_WITH_CONTACT_CREATION', + self_registration_account_setting: 'ALLOW_WITH_CREATION', + block_registration_if_portal_user_exists: true, + self_registration_entity: 'contact', user_account_self_management: false, feature_settings: { start_page: true, billing: true, + commodity_billing: true, change_due_date: true, - new_design: true + new_design: true, + mcp_enabled: true, + mcp_grant_version: 0, + portal_copilot: false, + portal_copilot_agent_id: 'string', + portal_copilot_visibility: { + visible_for_targets: ['string'], + visible_for_operator: 'and', + hidden_for_targets: ['string'], + hidden_for_operator: 'and' + } }, accessToken: 'string', advanced_mfa: { @@ -6817,21 +7340,37 @@ const { data } = await client.createPortalConfig( passwordless_login: { enabled: true }, + passkeys: { + enabled: false + }, entry_point: 'PASSWORD', preferred_sso_providers: ['office-365-login'], - auto_redirect_to_sso: true + auto_redirect_to_sso: true, + prevent_user_enumeration: true }, cognito_details: { cognito_user_pool_client_id: '6bsd0jkgoie74k2i8mrhc1vest', + cognito_mobile_client_id: '3k9fj2l1m0n8b7v6c5x4z3a2s1', cognito_user_pool_arn: 'arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341', cognito_user_pool_id: 'eu-central-1_CUEQRNbUb', + timeouts: { + refresh_token: 300, + access_token: 300, + id_token: 300 + }, + advanced_authentication: { + user_activity_logging: true, + adaptive_authentication: true, + compromised_credentials_detection: true + }, password_policy: { minimum_length: 8, maximum_length: 256, require_lowercase: true, require_uppercase: true, require_numbers: true, - require_symbols: true + require_symbols: true, + password_history_size: 3 } }, config: 'string', @@ -6846,6 +7385,7 @@ const { data } = await client.createPortalConfig( advancedMFA: '5da0a718-c822-403d-9f5d-20d4584e0528', journeySignUp: '5da0a718-c822-403d-9f5d-20d4584e0528', journeySignInOneTimePassword: '5da0a718-c822-403d-9f5d-20d4584e0528', + passkeyVerificationCode: '5da0a718-c822-403d-9f5d-20d4584e0528', journeyLoginOTP: '5da0a718-c822-403d-9f5d-20d4584e0528', forgotPassword: '5da0a718-c822-403d-9f5d-20d4584e0528', invitation: '5da0a718-c822-403d-9f5d-20d4584e0528', @@ -6879,6 +7419,7 @@ const { data } = await client.createPortalConfig( }, /* ... 1 more */ ], + self_assignment_mode: 'contracts', contract_selector_config: { show_inactive: true, title_path: 'string' @@ -6893,10 +7434,42 @@ const { data } = await client.createPortalConfig( schema: 'contract' } ], + surfaces: [ + { + id: 'website-journeys', + name: 'Website journeys', + description: 'string', + authentication: 'login', + token_ttl_seconds: 300, + identifiers: [ /* ... */ ], + data_access: { /* ... */ } + } + ], + contact_identifiers_for_account: [ + { + name: 'first_name', + schema: 'contact' + }, + { + name: 'last_name', + schema: 'contact' + } + ], + additional_contact_attributes: [ + { + name: 'first_name', + required: true + }, + { + name: 'last_name', + required: true + } + ], triggered_journeys: [ { trigger_name: 'FIRST_LOGIN', - journey_id: '5da0a718-c822-403d-9f5d-20d4584e0528' + journey_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + context_params: [ /* ... */ ] } ], entity_edit_rules: [ @@ -6930,15 +7503,17 @@ const { data } = await client.createPortalConfig( inactive_contract_cutoff_years: 0, is_dummy: true, is_v3_item: true, + published_revision_id: '2026-08-25T14:03:11.482Z-a7f3c1d9', portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', portal_sk_v3: 'PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c', origin: 'string', + global_blocks: {}, pages: [ { slug: 'dashboard', path: '/dashboard', schema: ['string'], - visibility: {}, + visibility: { /* ... */ }, content: {}, design: {}, blocks: {}, @@ -6946,6 +7521,7 @@ const { data } = await client.createPortalConfig( is_system: false, is_detail: false, detail_schema: 'contact', + show_in_navigation: false, is_public: true, parentId: 'c495fef9-eeca-4019-a989-8390dcd9825b', is_entry_route: false, @@ -6981,6 +7557,57 @@ const { data } = await client.createPortalConfig( {} ] }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false, + "debug_mode_until": "2026-10-30T12:00:00.000Z", + "debug_mode": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -6992,13 +7619,33 @@ const { data } = await client.createPortalConfig( "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": { + "design": { + "overrides": {} + } + }, + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, + "commodity_billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0, + "portal_copilot": false, + "portal_copilot_agent_id": "string", + "portal_copilot_visibility": { + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + } }, "accessToken": "string", "advanced_mfa": { @@ -7008,21 +7655,37 @@ const { data } = await client.createPortalConfig( "passwordless_login": { "enabled": true }, + "passkeys": { + "enabled": false + }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_mobile_client_id": "3k9fj2l1m0n8b7v6c5x4z3a2s1", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -7037,6 +7700,7 @@ const { data } = await client.createPortalConfig( "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -7069,6 +7733,7 @@ const { data } = await client.createPortalConfig( "schema": "contact" } ], + "self_assignment_mode": "contracts", "contract_selector_config": { "show_inactive": true, "title_path": "string" @@ -7083,10 +7748,42 @@ const { data } = await client.createPortalConfig( "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "identifiers": [], + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -7120,9 +7817,11 @@ const { data } = await client.createPortalConfig( "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", + "global_blocks": {}, "organization_id": 12345, "org_settings": { "canary": { @@ -7140,14 +7839,6 @@ const { data } = await client.createPortalConfig( "effect": "allow" } ], - "identity_providers": [ - { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} - } - ], "pages": [ { "slug": "dashboard", @@ -7161,12 +7852,18 @@ const { data } = await client.createPortalConfig( "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ] } @@ -7213,9 +7910,60 @@ const { data } = await client.getPortalConfigV3({ {} ] }, - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false, + "debug_mode_until": "2026-10-30T12:00:00.000Z", + "debug_mode": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", "is_epilot_domain": true, "epilot_domain": "example-portal-1.ecp.epilot.io", "domain_settings": { @@ -7224,13 +7972,33 @@ const { data } = await client.getPortalConfigV3({ "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": { + "design": { + "overrides": {} + } + }, + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, + "commodity_billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0, + "portal_copilot": false, + "portal_copilot_agent_id": "string", + "portal_copilot_visibility": { + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + } }, "accessToken": "string", "advanced_mfa": { @@ -7240,21 +8008,37 @@ const { data } = await client.getPortalConfigV3({ "passwordless_login": { "enabled": true }, + "passkeys": { + "enabled": false + }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_mobile_client_id": "3k9fj2l1m0n8b7v6c5x4z3a2s1", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -7269,6 +8053,7 @@ const { data } = await client.getPortalConfigV3({ "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -7301,6 +8086,7 @@ const { data } = await client.getPortalConfigV3({ "schema": "contact" } ], + "self_assignment_mode": "contracts", "contract_selector_config": { "show_inactive": true, "title_path": "string" @@ -7315,10 +8101,42 @@ const { data } = await client.getPortalConfigV3({ "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "identifiers": [], + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -7352,9 +8170,11 @@ const { data } = await client.getPortalConfigV3({ "inactive_contract_cutoff_years": 0, "is_dummy": true, "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", "origin": "string", + "global_blocks": {}, "organization_id": 12345, "org_settings": { "canary": { @@ -7372,14 +8192,6 @@ const { data } = await client.getPortalConfigV3({ "effect": "allow" } ], - "identity_providers": [ - { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} - } - ], "pages": [ { "slug": "dashboard", @@ -7393,12 +8205,18 @@ const { data } = await client.getPortalConfigV3({ "is_system": false, "is_detail": false, "detail_schema": "contact", + "show_in_navigation": false, "is_public": true, "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", "is_entry_route": false, "is_deleted": false, "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ] } @@ -7410,7 +8228,7 @@ const { data } = await client.getPortalConfigV3({ ### `putPortalConfig` -Updates a specific portal configuration by ID. +Updates a specific portal configuration by ID. On a portal with versioning enabled, the change is stored as a revision (`Updated via API`) and published in the same call, so every change to the portal `PUT /v3/portal/config/{portal_id}` @@ -7418,6 +8236,8 @@ Updates a specific portal configuration by ID. const { data } = await client.putPortalConfig( { portal_id: 'example', + page_upsert_mode: 'example', + expected_updated_at: 'example', }, { entity_actions: [ @@ -7440,6 +8260,57 @@ const { data } = await client.putPortalConfig( { /* ... */ } ] }, + identity_providers: [ + { + slug: 'office-365-login', + display_name: 'Office 365 Login', + provider_type: 'OIDC', + attribute_mappings: { /* ... */ }, + entity_matching: { /* ... */ }, + oidc_config: { /* ... */ }, + mobile_oidc_config: { /* ... */ }, + expose_client_secret: false, + debug_mode_until: '2026-10-30T12:00:00.000Z', + debug_mode: false + } + ], + mobile_config: { + portal_id: 'string', + enabled: true, + display_name: 'string', + app_host: 'string', + environment: 'prod', + branding: { + app_icon: 'string', + splash: 'string', + splash_dark: 'string', + icon_background_color: 'string', + splash_background_color: 'string', + splash_background_color_dark: 'string' + }, + ios: { + bundle_id: 'string', + team_id: 'string', + credentials_status: 'not_configured', + app_store_id: 'string', + store_url: 'string', + last_build: { /* ... */ } + }, + android: { + package_name: 'string', + credentials_status: 'not_configured', + upload_key_status: 'not_configured', + store_url: 'string', + last_build: { /* ... */ } + }, + ota: { + enabled: true, + channel: 'canary', + auto_update: true, + update_strategy: 'next-launch', + min_native_version: 'string' + } + }, enabled: true, name: 'Installer Portal', domain: 'abc.com', @@ -7451,13 +8322,33 @@ const { data } = await client.putPortalConfig( is_redirection_enabled: true }, design_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + header: { + design: { + overrides: { /* ... */ } + } + }, + allowed_portal_entities: ['contact', 'contract'], self_registration_setting: 'ALLOW_WITH_CONTACT_CREATION', + self_registration_account_setting: 'ALLOW_WITH_CREATION', + block_registration_if_portal_user_exists: true, + self_registration_entity: 'contact', user_account_self_management: false, feature_settings: { start_page: true, billing: true, + commodity_billing: true, change_due_date: true, - new_design: true + new_design: true, + mcp_enabled: true, + mcp_grant_version: 0, + portal_copilot: false, + portal_copilot_agent_id: 'string', + portal_copilot_visibility: { + visible_for_targets: ['string'], + visible_for_operator: 'and', + hidden_for_targets: ['string'], + hidden_for_operator: 'and' + } }, accessToken: 'string', advanced_mfa: { @@ -7467,21 +8358,37 @@ const { data } = await client.putPortalConfig( passwordless_login: { enabled: true }, + passkeys: { + enabled: false + }, entry_point: 'PASSWORD', preferred_sso_providers: ['office-365-login'], - auto_redirect_to_sso: true + auto_redirect_to_sso: true, + prevent_user_enumeration: true }, cognito_details: { cognito_user_pool_client_id: '6bsd0jkgoie74k2i8mrhc1vest', + cognito_mobile_client_id: '3k9fj2l1m0n8b7v6c5x4z3a2s1', cognito_user_pool_arn: 'arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341', cognito_user_pool_id: 'eu-central-1_CUEQRNbUb', + timeouts: { + refresh_token: 300, + access_token: 300, + id_token: 300 + }, + advanced_authentication: { + user_activity_logging: true, + adaptive_authentication: true, + compromised_credentials_detection: true + }, password_policy: { minimum_length: 8, maximum_length: 256, require_lowercase: true, require_uppercase: true, require_numbers: true, - require_symbols: true + require_symbols: true, + password_history_size: 3 } }, config: 'string', @@ -7496,6 +8403,7 @@ const { data } = await client.putPortalConfig( advancedMFA: '5da0a718-c822-403d-9f5d-20d4584e0528', journeySignUp: '5da0a718-c822-403d-9f5d-20d4584e0528', journeySignInOneTimePassword: '5da0a718-c822-403d-9f5d-20d4584e0528', + passkeyVerificationCode: '5da0a718-c822-403d-9f5d-20d4584e0528', journeyLoginOTP: '5da0a718-c822-403d-9f5d-20d4584e0528', forgotPassword: '5da0a718-c822-403d-9f5d-20d4584e0528', invitation: '5da0a718-c822-403d-9f5d-20d4584e0528', @@ -7529,6 +8437,7 @@ const { data } = await client.putPortalConfig( }, /* ... 1 more */ ], + self_assignment_mode: 'contracts', contract_selector_config: { show_inactive: true, title_path: 'string' @@ -7543,10 +8452,42 @@ const { data } = await client.putPortalConfig( schema: 'contract' } ], + surfaces: [ + { + id: 'website-journeys', + name: 'Website journeys', + description: 'string', + authentication: 'login', + token_ttl_seconds: 300, + identifiers: [ /* ... */ ], + data_access: { /* ... */ } + } + ], + contact_identifiers_for_account: [ + { + name: 'first_name', + schema: 'contact' + }, + { + name: 'last_name', + schema: 'contact' + } + ], + additional_contact_attributes: [ + { + name: 'first_name', + required: true + }, + { + name: 'last_name', + required: true + } + ], triggered_journeys: [ { trigger_name: 'FIRST_LOGIN', - journey_id: '5da0a718-c822-403d-9f5d-20d4584e0528' + journey_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + context_params: [ /* ... */ ] } ], entity_edit_rules: [ @@ -7580,9 +8521,11 @@ const { data } = await client.putPortalConfig( inactive_contract_cutoff_years: 0, is_dummy: true, is_v3_item: true, + published_revision_id: '2026-08-25T14:03:11.482Z-a7f3c1d9', portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', portal_sk_v3: 'PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c', origin: 'string', + global_blocks: {}, organization_id: 12345, org_settings: { canary: { @@ -7592,43 +8535,1372 @@ const { data } = await client.putPortalConfig( enabled: true } }, - feature_flags: {}, - grants: [ - { - action: 'entity-read', - resource: 'entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947', - effect: 'allow' - } - ], - identity_providers: [ - { - slug: 'office-365-login', - display_name: 'Office 365 Login', - oidc_config: { /* ... */ }, - mobile_oidc_config: { /* ... */ } - } - ], - pages: [ - { - slug: 'dashboard', - path: '/dashboard', - schema: ['string'], - visibility: {}, - content: {}, - design: {}, - blocks: {}, - order: 1, - is_system: false, - is_detail: false, - detail_schema: 'contact', - is_public: true, - parentId: 'c495fef9-eeca-4019-a989-8390dcd9825b', - is_entry_route: false, - is_deleted: false, - id: 'c495fef9-eeca-4019-a989-8390dcd9825b', - last_modified_at: '2021-02-09T12:41:43.662Z' - } - ] + feature_flags: {}, + grants: [ + { + action: 'entity-read', + resource: 'entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947', + effect: 'allow' + } + ], + pages: [ + { + slug: 'dashboard', + path: '/dashboard', + schema: ['string'], + visibility: { /* ... */ }, + content: {}, + design: {}, + blocks: {}, + order: 1, + is_system: false, + is_detail: false, + detail_schema: 'contact', + show_in_navigation: false, + is_public: true, + parentId: 'c495fef9-eeca-4019-a989-8390dcd9825b', + is_entry_route: false, + is_deleted: false, + id: 'c495fef9-eeca-4019-a989-8390dcd9825b', + last_modified_at: '2021-02-09T12:41:43.662Z', + portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', + past_routes: ['old-dashboard', 'home'], + _manifest: ['string'], + _lineage_id: 'string', + detached_lineage_ids: ['string'] + } + ] + }, +) +``` + +
+Response + +```json +{ + "entity_actions": [ + { + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "slug": "contact", + "action_Label": {} + } + ], + "extensions": [ + { + "id": "string", + "status": "installed", + "options": {} + } + ], + "extension_hooks": {}, + "default_user_to_notify": { + "onPendingUser": [ + {} + ] + }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false, + "debug_mode_until": "2026-10-30T12:00:00.000Z", + "debug_mode": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", + "is_epilot_domain": true, + "epilot_domain": "example-portal-1.ecp.epilot.io", + "domain_settings": { + "is_custom_domain_enabled": true, + "is_epilot_domain_enabled": true, + "is_redirection_enabled": true + }, + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": { + "design": { + "overrides": {} + } + }, + "allowed_portal_entities": ["contact", "contract"], + "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", + "user_account_self_management": false, + "feature_settings": { + "start_page": true, + "billing": true, + "commodity_billing": true, + "change_due_date": true, + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0, + "portal_copilot": false, + "portal_copilot_agent_id": "string", + "portal_copilot_visibility": { + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + } + }, + "accessToken": "string", + "advanced_mfa": { + "enabled": true + }, + "auth_settings": { + "passwordless_login": { + "enabled": true + }, + "passkeys": { + "enabled": false + }, + "entry_point": "PASSWORD", + "preferred_sso_providers": ["office-365-login"], + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true + }, + "cognito_details": { + "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_mobile_client_id": "3k9fj2l1m0n8b7v6c5x4z3a2s1", + "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", + "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, + "password_policy": { + "minimum_length": 8, + "maximum_length": 256, + "require_lowercase": true, + "require_uppercase": true, + "require_numbers": true, + "require_symbols": true, + "password_history_size": 3 + } + }, + "config": "string", + "contact_identifiers": ["email", "last_name"], + "approval_state_attributes": { + "contact": ["name", "address"], + "contract": ["installment_amount"] + }, + "email_templates": { + "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", + "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", + "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", + "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" + }, + "images": { + "orderLeftTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg", + "orderRightTeaser": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg", + "welcomeBanner": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg" + }, + "entity_identifiers": { + "type": { + "isEnabled": true, + "attributes": ["contract_number"] + } + }, + "contract_identifiers": [ + { + "name": "email", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "self_assignment_mode": "contracts", + "contract_selector_config": { + "show_inactive": true, + "title_path": "string" + }, + "registration_identifiers": [ + { + "name": "last_name", + "schema": "contact" + }, + { + "name": "contract_number", + "schema": "contract" + } + ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "identifiers": [], + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], + "triggered_journeys": [ + { + "trigger_name": "FIRST_LOGIN", + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] + } + ], + "entity_edit_rules": [ + { + "slug": "contact", + "attribute": "first_name", + "rule_type": "cadence", + "cadence_period_type": "days", + "cadence_period": 1, + "changes_allowed": 1, + "grace_period": 1, + "allowed_increment": "10%", + "allowed_decrement": "10%", + "number_of_days_before_restriction": 10 + } + ], + "allowed_file_extensions": { + "document": ["pdf"], + "image": ["jpg"], + "spreadsheet": ["xls"], + "presentation": ["ppt"], + "audioVideo": ["mp4"], + "email": ["eml"], + "archive": ["zip"], + "cad": ["cad"], + "calendar": ["ics"], + "other": ["txt"] + }, + "prevent_search_engine_indexing": true, + "meter_reading_grace_period": 0, + "inactive_contract_cutoff_years": 0, + "is_dummy": true, + "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "origin": "string", + "global_blocks": {}, + "organization_id": 12345, + "org_settings": { + "canary": { + "enabled": true + }, + "notracking": { + "enabled": true + } + }, + "feature_flags": {}, + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "effect": "allow" + } + ], + "pages": [ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": {}, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] + } + ] +} +``` + +
+ +--- + +### `deletePortalConfig` + +Deletes a specific portal configuration by ID, together with everything the portal owns: +its pages, revisions, email templates and widget configuration. The custom domain network +setup is torn down as + +`DELETE /v3/portal/config/{portal_id}` + +```ts +const { data } = await client.deletePortalConfig({ + portal_id: 'example', +}) +``` + +--- + +### `createPortalRevision` + +Creates a new revision — a complete, immutable snapshot of the portal's configuration, pages and email templates. Nothing about the live portal changes; the snapshot only becomes live when it is publi + +`POST /v3/portal/config/{portal_id}/revisions` + +```ts +const { data } = await client.createPortalRevision( + { + portal_id: 'example', + }, + { + entity_actions: [ + { + journey_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + slug: 'contact', + action_Label: { /* ... */ } + } + ], + extensions: [ + { + id: 'string', + status: 'installed', + options: {} + } + ], + extension_hooks: {}, + default_user_to_notify: { + onPendingUser: [ + { /* ... */ } + ] + }, + identity_providers: [ + { + slug: 'office-365-login', + display_name: 'Office 365 Login', + provider_type: 'OIDC', + attribute_mappings: { /* ... */ }, + entity_matching: { /* ... */ }, + oidc_config: { /* ... */ }, + mobile_oidc_config: { /* ... */ }, + expose_client_secret: false, + debug_mode_until: '2026-10-30T12:00:00.000Z' + } + ], + mobile_config: { + portal_id: 'string', + enabled: true, + display_name: 'string', + app_host: 'string', + environment: 'prod', + branding: { + app_icon: 'string', + splash: 'string', + splash_dark: 'string', + icon_background_color: 'string', + splash_background_color: 'string', + splash_background_color_dark: 'string' + }, + ios: { + bundle_id: 'string', + team_id: 'string', + credentials_status: 'not_configured', + app_store_id: 'string', + store_url: 'string', + last_build: { /* ... */ } + }, + android: { + package_name: 'string', + credentials_status: 'not_configured', + upload_key_status: 'not_configured', + store_url: 'string', + last_build: { /* ... */ } + }, + ota: { + enabled: true, + channel: 'canary', + auto_update: true, + update_strategy: 'next-launch', + min_native_version: 'string' + } + }, + enabled: true, + name: 'Installer Portal', + domain: 'abc.com', + is_epilot_domain: true, + epilot_domain: 'example-portal-1.ecp.epilot.io', + domain_settings: { + is_custom_domain_enabled: true, + is_epilot_domain_enabled: true, + is_redirection_enabled: true + }, + design_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + header: { + design: { + overrides: { /* ... */ } + } + }, + allowed_portal_entities: ['contact', 'contract'], + self_registration_setting: 'ALLOW_WITH_CONTACT_CREATION', + self_registration_account_setting: 'ALLOW_WITH_CREATION', + block_registration_if_portal_user_exists: true, + self_registration_entity: 'contact', + user_account_self_management: false, + feature_settings: { + start_page: true, + billing: true, + commodity_billing: true, + change_due_date: true, + new_design: true, + mcp_enabled: true, + mcp_grant_version: 0, + portal_copilot: false, + portal_copilot_agent_id: 'string', + portal_copilot_visibility: { + visible_for_targets: ['string'], + visible_for_operator: 'and', + hidden_for_targets: ['string'], + hidden_for_operator: 'and' + } + }, + accessToken: 'string', + advanced_mfa: { + enabled: true + }, + auth_settings: { + passwordless_login: { + enabled: true + }, + passkeys: { + enabled: false + }, + entry_point: 'PASSWORD', + preferred_sso_providers: ['office-365-login'], + auto_redirect_to_sso: true, + prevent_user_enumeration: true + }, + cognito_details: { + cognito_user_pool_client_id: '6bsd0jkgoie74k2i8mrhc1vest', + cognito_mobile_client_id: '3k9fj2l1m0n8b7v6c5x4z3a2s1', + cognito_user_pool_arn: 'arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341', + cognito_user_pool_id: 'eu-central-1_CUEQRNbUb', + timeouts: { + refresh_token: 300, + access_token: 300, + id_token: 300 + }, + advanced_authentication: { + user_activity_logging: true, + adaptive_authentication: true, + compromised_credentials_detection: true + }, + password_policy: { + minimum_length: 8, + maximum_length: 256, + require_lowercase: true, + require_uppercase: true, + require_numbers: true, + require_symbols: true, + password_history_size: 3 + } + }, + config: 'string', + contact_identifiers: ['email', 'last_name'], + approval_state_attributes: { + contact: ['name', 'address'], + contract: ['installment_amount'] + }, + email_templates: { + confirmAccount: '5da0a718-c822-403d-9f5d-20d4584e0528', + advancedAuth: '5da0a718-c822-403d-9f5d-20d4584e0528', + advancedMFA: '5da0a718-c822-403d-9f5d-20d4584e0528', + journeySignUp: '5da0a718-c822-403d-9f5d-20d4584e0528', + journeySignInOneTimePassword: '5da0a718-c822-403d-9f5d-20d4584e0528', + passkeyVerificationCode: '5da0a718-c822-403d-9f5d-20d4584e0528', + journeyLoginOTP: '5da0a718-c822-403d-9f5d-20d4584e0528', + forgotPassword: '5da0a718-c822-403d-9f5d-20d4584e0528', + invitation: '5da0a718-c822-403d-9f5d-20d4584e0528', + partnerInvitation: '5da0a718-c822-403d-9f5d-20d4584e0528', + onNewQuote: '5da0a718-c822-403d-9f5d-20d4584e0528', + onMapAPendingUser: '5da0a718-c822-403d-9f5d-20d4584e0528', + onDocUpload: '5da0a718-c822-403d-9f5d-20d4584e0528', + onWorkflowStepAssigned: '5da0a718-c822-403d-9f5d-20d4584e0528', + confirmEmailUpdate: '5da0a718-c822-403d-9f5d-20d4584e0528', + verifyCodeToSetPassword: '5da0a718-c822-403d-9f5d-20d4584e0528' + }, + images: { + orderLeftTeaser: 'https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-left-teaser.jpeg', + orderRightTeaser: 'https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/order-right-teaser.jpeg', + welcomeBanner: 'https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/6538fddb-f0e9-4f0f-af51-6e57891ff20a/welcome-banner.jpeg' + }, + entity_identifiers: { + type: { + isEnabled: true, + attributes: ['contract_number'] + } + }, + contract_identifiers: [ + { + name: 'email', + schema: 'contact' + }, + { + name: 'last_name', + schema: 'contact' + }, + /* ... 1 more */ + ], + self_assignment_mode: 'contracts', + contract_selector_config: { + show_inactive: true, + title_path: 'string' + }, + registration_identifiers: [ + { + name: 'last_name', + schema: 'contact' + }, + { + name: 'contract_number', + schema: 'contract' + } + ], + surfaces: [ + { + id: 'website-journeys', + name: 'Website journeys', + description: 'string', + authentication: 'login', + token_ttl_seconds: 300, + identifiers: [ /* ... */ ], + data_access: { /* ... */ } + } + ], + contact_identifiers_for_account: [ + { + name: 'first_name', + schema: 'contact' + }, + { + name: 'last_name', + schema: 'contact' + } + ], + additional_contact_attributes: [ + { + name: 'first_name', + required: true + }, + { + name: 'last_name', + required: true + } + ], + triggered_journeys: [ + { + trigger_name: 'FIRST_LOGIN', + journey_id: '5da0a718-c822-403d-9f5d-20d4584e0528', + context_params: [ /* ... */ ] + } + ], + entity_edit_rules: [ + { + slug: 'contact', + attribute: 'first_name', + rule_type: 'cadence', + cadence_period_type: 'days', + cadence_period: 1, + changes_allowed: 1, + grace_period: 1, + allowed_increment: '10%', + allowed_decrement: '10%', + number_of_days_before_restriction: 10 + } + ], + allowed_file_extensions: { + document: ['pdf'], + image: ['jpg'], + spreadsheet: ['xls'], + presentation: ['ppt'], + audioVideo: ['mp4'], + email: ['eml'], + archive: ['zip'], + cad: ['cad'], + calendar: ['ics'], + other: ['txt'] + }, + prevent_search_engine_indexing: true, + meter_reading_grace_period: 0, + inactive_contract_cutoff_years: 0, + is_dummy: true, + is_v3_item: true, + published_revision_id: '2026-08-25T14:03:11.482Z-a7f3c1d9', + portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', + portal_sk_v3: 'PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c', + origin: 'string', + global_blocks: {}, + based_on_revision_id: 'string', + base_published_revision_id: 'string', + revision_source: { + type: 'blueprint_sync', + blueprint_title: 'string' + }, + publish: { + name: 'string', + description: 'string', + force: false + }, + pages: [ + { + id: 'c495fef9-eeca-4019-a989-8390dcd9825b', + slug: 'dashboard', + order: 0, + blocks: {} + } + ] + }, +) +``` + +
+Response + +```json +{ + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "FAQ page launch", + "description": "string", + "source": { + "type": "blueprint_sync", + "blueprint_title": "string" + }, + "page_count": 0, + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "is_published": true, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": { + "contact": { + "email": "email", + "first_name": "first_name", + "last_name": "last_name", + "phone": "tel", + "preferred_language": "language", + "concession": "GPE", + "installer_number": 123456 + }, + "account": { + "name": "company_name", + "street": "street_name", + "house_number": "house_number", + "postal_code": "postal_code", + "city": "city" + }, + "portal_user": { + "access_status": "access_status", + "expires_at": "expires_at" + }, + "concession_attributes": { + "water": "water", + "energy": "energy", + "gas": "gas" + } + }, + "entity_matching": { + "portal_user": { + "external_id": "sub" + }, + "contact": { + "customer_number": "customer_id", + "external_id": "sub" + }, + "auto_create_cognito_user": true + }, + "oidc_config": { + "type": "implicit", + "oidc_issuer": "https://login.microsoftonline.com/33d4f3e5-3df2-421e-b92e-a63cfa680a88/v2.0", + "redirect_uri": "https://customer-portal.com/login", + "client_id": "ab81daf8-8b1f-42d6-94ca-c51621054c75", + "client_secret": "7BIUnn~6shh.7fNtXb..3k1Mp3s6k6WK3B", + "has_client_secret": true, + "scope": "openid email", + "metadata": { + "response_modes_supported": ["form_post"], + "authorization_endpoint": "https://www.facebook.com/v12.0/dialog/oauth", + "token_endpoint": "https://graph.facebook.com/v12.0/oauth/access_token", + "userinfo_endpoint": "https://graph.facebook.com/me", + "logout_uri": "https://login.microsoftonline.com/common/oauth2/v2.0/logout", + "logout_redirect_uri": "https://customer-portal.com/login", + "skip_login_as_logout": false, + "mobile_redirect_uri": "msauth.io.epilot.ecp://auth", + "test_auth_username": "test@epilot.io", + "test_auth_password": "string" + }, + "prompt": "login" + }, + "mobile_oidc_config": { + "client_id": 123456, + "client_secret": 123456 + }, + "expose_client_secret": false, + "debug_mode_until": "2026-10-30T12:00:00.000Z" + } + ], + "published": { + "revision_id": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "name": "FAQ page launch", + "post_publish_warnings": ["string"], + "held_back": ["allowed_entities_change"] + } +} +``` + +
+ +--- + +### `listPortalRevisions` + +Lists a portal's revision history, newest first. Metadata only — no config blob, no page bodies. `is_published` says whether that revision is the one currently live, which is a different question from + +`GET /v3/portal/config/{portal_id}/revisions` + +```ts +const { data } = await client.listPortalRevisions({ + portal_id: 'example', + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "FAQ page launch", + "description": "string", + "source": { + "type": "blueprint_sync", + "blueprint_title": "string" + }, + "page_count": 0, + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "is_published": true + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `getPortalRevision` + +Returns the full content of one revision: the snapshotted config, its pages (in the live `Page` shape), email templates and identity providers with secrets redacted. + +`GET /v3/portal/config/{portal_id}/revisions/{revision_id}` + +```ts +const { data } = await client.getPortalRevision({ + portal_id: 'example', + revision_id: 'example', +}) +``` + +
+Response + +```json +{ + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "FAQ page launch", + "description": "string", + "source": { + "type": "blueprint_sync", + "blueprint_title": "string" + }, + "page_count": 0, + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "is_published": true, + "config": {}, + "pages": [ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": {}, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"], + "org_id": "string" + } + ], + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false, + "debug_mode_until": "2026-10-30T12:00:00.000Z" + } + ], + "email_templates": { + "confirmAccount": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedAuth": "5da0a718-c822-403d-9f5d-20d4584e0528", + "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", + "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", + "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "partnerInvitation": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onNewQuote": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onMapAPendingUser": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onDocUpload": "5da0a718-c822-403d-9f5d-20d4584e0528", + "onWorkflowStepAssigned": "5da0a718-c822-403d-9f5d-20d4584e0528", + "confirmEmailUpdate": "5da0a718-c822-403d-9f5d-20d4584e0528", + "verifyCodeToSetPassword": "5da0a718-c822-403d-9f5d-20d4584e0528" + }, + "email_template_settings": {} +} +``` + +
+ +--- + +### `updatePortalRevision` + +Renames a revision without publishing it. Any revision can be renamed, published or not. Only the revision's `name` changes: its content, `published_at`, `published_by` and which revision is live stay + +`PATCH /v3/portal/config/{portal_id}/revisions/{revision_id}` + +```ts +const { data } = await client.updatePortalRevision( + { + portal_id: 'example', + revision_id: 'example', + }, + { + name: 'FAQ page launch' + }, +) +``` + +
+Response + +```json +{ + "revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "FAQ page launch", + "description": "string", + "source": { + "type": "blueprint_sync", + "blueprint_title": "string" + }, + "page_count": 0, + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "is_published": true +} +``` + +
+ +--- + +### `createPortalRevisionPreview` + +Mints a short-lived preview token for one revision and returns a link that opens the revision inside the real end-customer portal, on the portal's live domain, without publishing it. + +`POST /v3/portal/config/{portal_id}/revisions/{revision_id}:preview` + +```ts +const { data } = await client.createPortalRevisionPreview({ + portal_id: 'example', + revision_id: 'example', +}) +``` + +
+Response + +```json +{ + "preview_token": "string", + "expires_at": "1970-01-01T00:00:00.000Z", + "url": "https://portal.example.com/?preview_token=eyJhbGciOiJIUzI1NiIs..." +} +``` + +
+ +--- + +### `publishPortalRevision` + +Makes one revision the portal's live configuration, atomically: either everything below takes effect or nothing does. Publish is a full-snapshot replace: it writes config, every page and email templat + +`POST /v3/portal/config/{portal_id}/publish` + +```ts +const { data } = await client.publishPortalRevision( + { + portal_id: 'example', + }, + { + revision_id: '2026-08-25T14:03:11.482Z-a7f3c1d9', + name: 'FAQ page launch', + description: 'string', + force: false + }, +) +``` + +
+Response + +```json +{ + "revision_id": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "name": "FAQ page launch", + "post_publish_warnings": ["string"], + "held_back": ["allowed_entities_change"] +} +``` + +
+ +--- + +### `listAllPortalConfigs` + +Retrieves all portal configurations. + +`GET /v3/portal/configs` + +```ts +const { data } = await client.listAllPortalConfigs() +``` + +
+Response + +```json +{ + "data": [ + { + "entity_actions": [], + "extensions": [], + "extension_hooks": {}, + "default_user_to_notify": {}, + "identity_providers": [], + "mobile_config": {}, + "enabled": true, + "name": "Installer Portal", + "domain": "abc.com", + "is_epilot_domain": true, + "epilot_domain": "example-portal-1.ecp.epilot.io", + "domain_settings": {}, + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": {}, + "allowed_portal_entities": ["contact", "contract"], + "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", + "user_account_self_management": false, + "feature_settings": {}, + "accessToken": "string", + "advanced_mfa": {}, + "auth_settings": {}, + "cognito_details": {}, + "config": "string", + "contact_identifiers": ["email", "last_name"], + "approval_state_attributes": {}, + "email_templates": {}, + "images": {}, + "entity_identifiers": {}, + "contract_identifiers": [], + "self_assignment_mode": "contracts", + "contract_selector_config": {}, + "registration_identifiers": [], + "surfaces": [], + "contact_identifiers_for_account": [], + "additional_contact_attributes": [], + "triggered_journeys": [], + "entity_edit_rules": [], + "allowed_file_extensions": {}, + "prevent_search_engine_indexing": true, + "meter_reading_grace_period": 0, + "inactive_contract_cutoff_years": 0, + "is_dummy": true, + "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "origin": "string", + "global_blocks": {}, + "organization_id": 12345, + "org_settings": {}, + "feature_flags": {}, + "grants": [], + "pages": [] + } + ] +} +``` + +
+ +--- + +### `listPortalConfigSummaries` + +Lists the portals of the organization as lightweight summaries: the identifying, +display and registration fields of each portal config, without pages, email +templates, grants, feature flags, identity + +`GET /v3/portal/configs/summaries` + +```ts +const { data } = await client.listPortalConfigSummaries() +``` + +
+Response + +```json +{ + "data": [ + { + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "organization_id": 12345, + "origin": "string", + "name": "string", + "enabled": true, + "domain": "string", + "epilot_domain": "string", + "is_epilot_domain": true, + "dnsStatus": "CONFIGURING", + "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "logo_image": { + "url": "https://epilot-bucket.s3.eu-central-1.amazonaws.com/12344/logo.png", + "dark_url": "string" + }, + "default_user_to_notify": { + "onPendingUser": [ + { + "type": "user", + "user_id": "123456", + "display_name": "John", + "image_uri": { + "original": "https://fuafjvoHKsu.cloudimg.io/v7/e-mage-sam-bucket-dev.s3.eu-central-1.amazonaws.com/files/fuafjvoHKsudhfagweucjasdvga/original", + "thumbnail_32": "https://fuafjvoHKsu.cloudimg.io/v7/e-mage-sam-bucket-dev.s3.eu-central-1.amazonaws.com/files/fuafjvoHKsudhfagweucjasdvga/original?w=32&h=32", + "thumbnail_64": "https://fuafjvoHKsu.cloudimg.io/v7/e-mage-sam-bucket-dev.s3.eu-central-1.amazonaws.com/files/fuafjvoHKsudhfagweucjasdvga/original?w=64&h=64", + "key": "fuafjvoHKsudhfagweucjasdvga" + }, + "org_id": "123", + "email": "j.doe@epilot.cloud", + "phone": "12345 67890" + } + ] + }, + "feature_settings": { + "start_page": true, + "billing": true, + "commodity_billing": true, + "change_due_date": true, + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0, + "portal_copilot": false, + "portal_copilot_agent_id": "string", + "portal_copilot_visibility": { + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + } + }, + "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", + "user_account_self_management": true, + "registration_identifiers": [ + { + "name": "string", + "schema": "contact", + "validation_rule_id": "string" + } + ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "identifiers": [ + { + "name": "customer_number", + "schema": "contact" + }, + { + "name": "meter_number", + "schema": "meter" + } + ], + "data_access": { + "entities": [ + { + "schema": "contract", + "target_ids": ["string"] + } + ], + "role_id": "728:public_journeys_readonly" + } + } + ], + "is_dummy": true, + "is_v3_item": true, + "published_revision_id": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `swapPortalConfig` + +Swaps the portal configuration of two portals. Without `mode` both portals exchange pages and experience config live, as before. With `mode: copy` (portal versioning only) nothing live changes: the so + +`POST /v3/portal/config/swap` + +```ts +const { data } = await client.swapPortalConfig( + null, + { + source_portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', + target_portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', + items_to_swap: ['email_templates'], + mode: 'copy' + }, +) +``` + +
+Response + +```json +{ + "message": "Domain and users swapped successfully.", + "portal_references": { + "journeys": { + "updated": [ + { + "id": "string", + "name": "string", + "paths": ["steps[0].uischema.elements[2].options.portalId"], + "error": "string" + } + ], + "failed": [ + { + "id": "string", + "name": "string", + "paths": ["steps[0].uischema.elements[2].options.portalId"], + "error": "string" + } + ], + "list_error": "string" + }, + "automation_flows": { + "updated": [ + { + "id": "string", + "name": "string", + "paths": ["steps[0].uischema.elements[2].options.portalId"], + "error": "string" + } + ], + "failed": [ + { + "id": "string", + "name": "string", + "paths": ["steps[0].uischema.elements[2].options.portalId"], + "error": "string" + } + ], + "list_error": "string" + } + }, + "revisions": [ + { + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "revision_id": "string" + } + ] +} +``` + +
+ +--- + +### `clonePortalConfig` + +Creates a new portal by cloning configuration and pages from an existing portal. The new portal gets its own domain, users, email templates, and authentication settings. + +`POST /v3/portal/config/clone` + +```ts +const { data } = await client.clonePortalConfig( + null, + { + source_portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', + name: 'string' }, ) ``` @@ -7658,6 +9930,57 @@ const { data } = await client.putPortalConfig( {} ] }, + "identity_providers": [ + { + "slug": "office-365-login", + "display_name": "Office 365 Login", + "provider_type": "OIDC", + "attribute_mappings": {}, + "entity_matching": {}, + "oidc_config": {}, + "mobile_oidc_config": {}, + "expose_client_secret": false, + "debug_mode_until": "2026-10-30T12:00:00.000Z", + "debug_mode": false + } + ], + "mobile_config": { + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": {} + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": {} + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } + }, "enabled": true, "name": "Installer Portal", "domain": "abc.com", @@ -7669,13 +9992,33 @@ const { data } = await client.putPortalConfig( "is_redirection_enabled": true }, "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "header": { + "design": { + "overrides": {} + } + }, + "allowed_portal_entities": ["contact", "contract"], "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", + "self_registration_account_setting": "ALLOW_WITH_CREATION", + "block_registration_if_portal_user_exists": true, + "self_registration_entity": "contact", "user_account_self_management": false, "feature_settings": { "start_page": true, "billing": true, + "commodity_billing": true, "change_due_date": true, - "new_design": true + "new_design": true, + "mcp_enabled": true, + "mcp_grant_version": 0, + "portal_copilot": false, + "portal_copilot_agent_id": "string", + "portal_copilot_visibility": { + "visible_for_targets": ["string"], + "visible_for_operator": "and", + "hidden_for_targets": ["string"], + "hidden_for_operator": "and" + } }, "accessToken": "string", "advanced_mfa": { @@ -7685,21 +10028,37 @@ const { data } = await client.putPortalConfig( "passwordless_login": { "enabled": true }, + "passkeys": { + "enabled": false + }, "entry_point": "PASSWORD", "preferred_sso_providers": ["office-365-login"], - "auto_redirect_to_sso": true + "auto_redirect_to_sso": true, + "prevent_user_enumeration": true }, "cognito_details": { "cognito_user_pool_client_id": "6bsd0jkgoie74k2i8mrhc1vest", + "cognito_mobile_client_id": "3k9fj2l1m0n8b7v6c5x4z3a2s1", "cognito_user_pool_arn": "arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_123412341", "cognito_user_pool_id": "eu-central-1_CUEQRNbUb", + "timeouts": { + "refresh_token": 300, + "access_token": 300, + "id_token": 300 + }, + "advanced_authentication": { + "user_activity_logging": true, + "adaptive_authentication": true, + "compromised_credentials_detection": true + }, "password_policy": { "minimum_length": 8, "maximum_length": 256, "require_lowercase": true, "require_uppercase": true, "require_numbers": true, - "require_symbols": true + "require_symbols": true, + "password_history_size": 3 } }, "config": "string", @@ -7714,6 +10073,7 @@ const { data } = await client.putPortalConfig( "advancedMFA": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignUp": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeySignInOneTimePassword": "5da0a718-c822-403d-9f5d-20d4584e0528", + "passkeyVerificationCode": "5da0a718-c822-403d-9f5d-20d4584e0528", "journeyLoginOTP": "5da0a718-c822-403d-9f5d-20d4584e0528", "forgotPassword": "5da0a718-c822-403d-9f5d-20d4584e0528", "invitation": "5da0a718-c822-403d-9f5d-20d4584e0528", @@ -7746,6 +10106,7 @@ const { data } = await client.putPortalConfig( "schema": "contact" } ], + "self_assignment_mode": "contracts", "contract_selector_config": { "show_inactive": true, "title_path": "string" @@ -7760,10 +10121,42 @@ const { data } = await client.putPortalConfig( "schema": "contract" } ], + "surfaces": [ + { + "id": "website-journeys", + "name": "Website journeys", + "description": "string", + "authentication": "login", + "token_ttl_seconds": 300, + "identifiers": [], + "data_access": {} + } + ], + "contact_identifiers_for_account": [ + { + "name": "first_name", + "schema": "contact" + }, + { + "name": "last_name", + "schema": "contact" + } + ], + "additional_contact_attributes": [ + { + "name": "first_name", + "required": true + }, + { + "name": "last_name", + "required": true + } + ], "triggered_journeys": [ { "trigger_name": "FIRST_LOGIN", - "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528" + "journey_id": "5da0a718-c822-403d-9f5d-20d4584e0528", + "context_params": [] } ], "entity_edit_rules": [ @@ -7796,138 +10189,54 @@ const { data } = await client.putPortalConfig( "meter_reading_grace_period": 0, "inactive_contract_cutoff_years": 0, "is_dummy": true, - "is_v3_item": true, - "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "organization_id": 12345, - "org_settings": { - "canary": { - "enabled": true - }, - "notracking": { - "enabled": true - } - }, - "feature_flags": {}, - "grants": [ - { - "action": "entity-read", - "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", - "effect": "allow" - } - ], - "identity_providers": [ - { - "slug": "office-365-login", - "display_name": "Office 365 Login", - "oidc_config": {}, - "mobile_oidc_config": {} - } - ], - "pages": [ - { - "slug": "dashboard", - "path": "/dashboard", - "schema": ["string"], - "visibility": {}, - "content": {}, - "design": {}, - "blocks": {}, - "order": 1, - "is_system": false, - "is_detail": false, - "detail_schema": "contact", - "is_public": true, - "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", - "is_entry_route": false, - "is_deleted": false, - "id": "c495fef9-eeca-4019-a989-8390dcd9825b", - "last_modified_at": "2021-02-09T12:41:43.662Z" - } - ] -} -``` - -
- ---- - -### `deletePortalConfig` - -Deletes a specific portal configuration by ID. - -`DELETE /v3/portal/config/{portal_id}` - -```ts -const { data } = await client.deletePortalConfig({ - portal_id: 'example', -}) -``` - ---- - -### `listAllPortalConfigs` - -Retrieves all portal configurations. - -`GET /v3/portal/configs` - -```ts -const { data } = await client.listAllPortalConfigs() -``` - -
-Response - -```json -{ - "data": [ - { - "entity_actions": [], - "extensions": [], - "extension_hooks": {}, - "default_user_to_notify": {}, - "enabled": true, - "name": "Installer Portal", - "domain": "abc.com", - "is_epilot_domain": true, - "epilot_domain": "example-portal-1.ecp.epilot.io", - "domain_settings": {}, - "design_id": "5da0a718-c822-403d-9f5d-20d4584e0528", - "self_registration_setting": "ALLOW_WITH_CONTACT_CREATION", - "user_account_self_management": false, - "feature_settings": {}, - "accessToken": "string", - "advanced_mfa": {}, - "auth_settings": {}, - "cognito_details": {}, - "config": "string", - "contact_identifiers": ["email", "last_name"], - "approval_state_attributes": {}, - "email_templates": {}, - "images": {}, - "entity_identifiers": {}, - "contract_identifiers": [], - "contract_selector_config": {}, - "registration_identifiers": [], - "triggered_journeys": [], - "entity_edit_rules": [], - "allowed_file_extensions": {}, - "prevent_search_engine_indexing": true, - "meter_reading_grace_period": 0, - "inactive_contract_cutoff_years": 0, - "is_dummy": true, - "is_v3_item": true, + "is_v3_item": true, + "published_revision_id": "2026-08-25T14:03:11.482Z-a7f3c1d9", + "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", + "origin": "string", + "global_blocks": {}, + "organization_id": 12345, + "org_settings": { + "canary": { + "enabled": true + }, + "notracking": { + "enabled": true + } + }, + "feature_flags": {}, + "grants": [ + { + "action": "entity-read", + "resource": "entity:123:contact:f7c22299-ca72-4bca-8538-0a88eeefc947", + "effect": "allow" + } + ], + "pages": [ + { + "slug": "dashboard", + "path": "/dashboard", + "schema": ["string"], + "visibility": {}, + "content": {}, + "design": {}, + "blocks": {}, + "order": 1, + "is_system": false, + "is_detail": false, + "detail_schema": "contact", + "show_in_navigation": false, + "is_public": true, + "parentId": "c495fef9-eeca-4019-a989-8390dcd9825b", + "is_entry_route": false, + "is_deleted": false, + "id": "c495fef9-eeca-4019-a989-8390dcd9825b", + "last_modified_at": "2021-02-09T12:41:43.662Z", "portal_id": "453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "portal_sk_v3": "PORTAL_CONFIG#453ad7bf-86d5-46c8-8252-bcc868df5e3c", - "origin": "string", - "organization_id": 12345, - "org_settings": {}, - "feature_flags": {}, - "grants": [], - "identity_providers": [], - "pages": [] + "past_routes": ["old-dashboard", "home"], + "_manifest": ["string"], + "_lineage_id": "string", + "detached_lineage_ids": ["string"] } ] } @@ -7937,36 +10246,6 @@ const { data } = await client.listAllPortalConfigs() --- -### `swapPortalConfig` - -Swaps the portal configuration of two portals. - -`POST /v3/portal/config/swap` - -```ts -const { data } = await client.swapPortalConfig( - null, - { - source_portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', - target_portal_id: '453ad7bf-86d5-46c8-8252-bcc868df5e3c', - items_to_swap: ['all'] - }, -) -``` - -
-Response - -```json -{ - "message": "Domain and users swapped successfully." -} -``` - -
- ---- - ### `invitePartner` Invites a partner to a portal @@ -7978,7 +10257,8 @@ const { data } = await client.invitePartner( null, { email: 'string', - represents_contact_list: ['5da0a718-c822-403d-9f5d-20d4584e0528'] + contact_data: {}, + portal_user_data: {} }, ) ``` @@ -8101,36 +10381,499 @@ const { data } = await client.disablePartner({ } ``` -
+
+ +--- + +### `enablePartner` + +Enables a partner from a portal + +`POST /v3/portal/partner/{partner_id}/enable` + +```ts +const { data } = await client.enablePartner({ + partner_id: 'example', +}) +``` + +
+Response + +```json +{ + "message": "Partner enabled from portal successfully" +} +``` + +
+ +--- + +### `verifyDns` + +Manually triggers DNS verification for a portal's domain setup. Runs the same verification logic as the scheduled processAllPendingNetworks lambda. + +`POST /v3/portal/verify-dns` + +```ts +const { data } = await client.verifyDns({ + portal_id: 'example', +}) +``` + +
+Response + +```json +{ + "domain_status": "PENDING", + "message": "string" +} +``` + +
+ +--- + +### `portalProxyExecute` + +Execute an Integration Hub managed-call use case on behalf of a portal user. +Bridges PortalAuth to the Integration API by generating an internal token. + +`POST /v2/portal/proxy/execute` + +```ts +const { data } = await client.portalProxyExecute( + null, + { + integration_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + use_case_slug: 'string', + payload: {} + }, +) +``` + +
+Response + +```json +{ + "success": true, + "data": {} +} +``` + +
+ +--- + +### `getMobileConfig` + +Returns the portal's mobile app configuration. By default the response is build-ready (resolved): base info (display_name from the portal name, app_host from the domain, environment) and branding (log + +`GET /v1/portal/mobile-config` + +```ts +const { data } = await client.getMobileConfig({ + portal_id: 'example', + raw: true, +}) +``` + +
+Response + +```json +{ + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": { + "version": "string", + "build_number": 0, + "track": "string", + "status": "building", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": { + "version": "string", + "build_number": 0, + "track": "string", + "status": "building", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } +} +``` + +
+ +--- + +### `putMobileConfig` + +Merges the provided fields into the portal's mobile app configuration +(deep merge). Only mobile_config is modified; all other portal settings +are left untouched. + +`PUT /v1/portal/mobile-config` + +```ts +const { data } = await client.putMobileConfig( + { + portal_id: 'example', + }, + { + enabled: true, + ios: { + bundle_id: 'string', + team_id: 'string', + store_url: 'string', + app_store_id: 'string' + }, + android: { + package_name: 'string', + store_url: 'string' + }, + branding: { + app_icon: 'string', + splash: 'string', + splash_dark: 'string', + icon_background_color: 'string', + splash_background_color: 'string', + splash_background_color_dark: 'string' + }, + ota: { + enabled: true, + channel: 'canary', + auto_update: true, + update_strategy: 'next-launch', + min_native_version: 'string' + } + }, +) +``` + +
+Response + +```json +{ + "portal_id": "string", + "enabled": true, + "display_name": "string", + "app_host": "string", + "environment": "prod", + "branding": { + "app_icon": "string", + "splash": "string", + "splash_dark": "string", + "icon_background_color": "string", + "splash_background_color": "string", + "splash_background_color_dark": "string" + }, + "ios": { + "bundle_id": "string", + "team_id": "string", + "credentials_status": "not_configured", + "app_store_id": "string", + "store_url": "string", + "last_build": { + "version": "string", + "build_number": 0, + "track": "string", + "status": "building", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + }, + "android": { + "package_name": "string", + "credentials_status": "not_configured", + "upload_key_status": "not_configured", + "store_url": "string", + "last_build": { + "version": "string", + "build_number": 0, + "track": "string", + "status": "building", + "updated_at": "1970-01-01T00:00:00.000Z", + "error": "string" + } + }, + "ota": { + "enabled": true, + "channel": "canary", + "auto_update": true, + "update_strategy": "next-launch", + "min_native_version": "string" + } +} +``` + +
+ +--- + +## Schemas + +### `PortalUserPasskey` + +```ts +type PortalUserPasskey = { + credential_id: string + name?: string + rp_id: string + is_usable: boolean + device_type?: "singleDevice" | "multiDevice" + backed_up?: boolean + created_at: string // date-time + last_used_at?: string // date-time +} +``` + +### `MeterReadingCounterDetails` + +Display details of the counter the readings belong to. Only returned when `include_counter` is true and the counter could be resolved. + +```ts +type MeterReadingCounterDetails = { + unit?: string + obis_number?: string + direction?: string + tariff_type?: string +} +``` + +### `PortalNotification` + +A 360 notification addressed to a portal user. + +```ts +type PortalNotification = { + id: string + notification_id?: number + type?: string + title?: { + en?: string + de?: string + } + message?: { + en?: string + de?: string + } + created_at?: string // date-time + read: boolean + redirect_url?: string +} +``` + +### `PortalUserNotificationPreferences` + +Resolved notification preferences of a portal user. Notifications are opt-out: a channel that was never stored on the portal user resolves to enabled (true). + +```ts +type PortalUserNotificationPreferences = { + in_app: boolean +} +``` + +### `MobileBuildStatus` + +Latest build/upload status for a platform (system-written). + +```ts +type MobileBuildStatus = { + version?: string + build_number?: number + track?: string + status?: "building" | "uploaded" | "failed" + updated_at?: string // date-time + error?: string +} +``` + +### `MobileBranding` + +```ts +type MobileBranding = { + app_icon?: string + splash?: string + splash_dark?: string + icon_background_color?: string + splash_background_color?: string + splash_background_color_dark?: string +} +``` + +### `MobileConfig` + +Mobile app configuration for the portal. Stored inside the portal's config object. Identifiers/branding are non-secret; signing credentials live in a secure store, never here. + +```ts +type MobileConfig = { + portal_id?: string + enabled?: boolean + display_name?: string + app_host?: string + environment?: "prod" | "staging" | "dev" + branding?: { + app_icon?: string + splash?: string + splash_dark?: string + icon_background_color?: string + splash_background_color?: string + splash_background_color_dark?: string + } + ios?: { + bundle_id?: string + team_id?: string + credentials_status?: "not_configured" | "configured" + app_store_id?: string + store_url?: string + last_build?: { + version?: { ... } + build_number?: { ... } + track?: { ... } + status?: { ... } + updated_at?: { ... } + error?: { ... } + } + } + android?: { + package_name?: string + credentials_status?: "not_configured" | "configured" + upload_key_status?: "not_configured" | "generated" | "enrolled" + store_url?: string + last_build?: { + version?: { ... } + build_number?: { ... } + track?: { ... } + status?: { ... } + updated_at?: { ... } + error?: { ... } + } + } + ota?: { + enabled?: boolean + channel?: "canary" | "stable" + auto_update?: boolean + update_strategy?: "next-launch" | "immediate" + min_native_version?: string + } +} +``` + +### `MobileConfigUpdate` ---- +Editable mobile fields for PUT. Only mobile-relevant settings + app branding can be changed. Portal-derived values (display_name, app_host), the portal logo, and system-written fields (credentials_status, app_store_id, last_build, …) are ignored if sent. -### `enablePartner` +```ts +type MobileConfigUpdate = { + enabled?: boolean + ios?: { + bundle_id?: string + team_id?: string + store_url?: string + app_store_id?: string + } + android?: { + package_name?: string + store_url?: string + } + branding?: { + app_icon?: string + splash?: string + splash_dark?: string + icon_background_color?: string + splash_background_color?: string + splash_background_color_dark?: string + } + ota?: { + enabled?: boolean + channel?: "canary" | "stable" + auto_update?: boolean + update_strategy?: "next-launch" | "immediate" + min_native_version?: string + } +} +``` -Enables a partner from a portal +### `MobileOtaConfig` -`POST /v3/portal/partner/{partner_id}/enable` +OTA (over-the-air) update settings for the portal's mobile app. Drives the OTA build pipeline and the per-portal manifest. channel / update_strategy / min_native_version are epilot-internal controls. ```ts -const { data } = await client.enablePartner({ - partner_id: 'example', -}) +type MobileOtaConfig = { + enabled?: boolean + channel?: "canary" | "stable" + auto_update?: boolean + update_strategy?: "next-launch" | "immediate" + min_native_version?: string +} ``` -
-Response +### `NewDesignMigrationResult` -```json -{ - "message": "Partner enabled from portal successfully" +```ts +type NewDesignMigrationResult = { + org_id?: string + portal_id?: string + origin?: string + name?: string + is_v3_item?: boolean + dry_run?: boolean + migrated?: boolean + summary?: Record + before?: Record } ``` -
+### `OtaPortal` ---- +A portal that has mobile OTA updates enabled. -## Schemas +```ts +type OtaPortal = { + domain: string + channel: "canary" | "stable" + autoUpdate: boolean + updateStrategy: "next-launch" | "immediate" + minNativeVersion?: string +} +``` ### `ContextEntity` @@ -8159,6 +10902,60 @@ type ContextEntities = Array<{ ```ts type ErrorResp = { message?: string + reason?: string +} +``` + +### `SSOErrorResp` + +Error response of the public SSO endpoints. Like every error response the message is in +`error`; `reason` carries a stable machine-readable cause when one is known (e.g. +`MISSING_EMAIL_CLAIM`, `INVALID_PROVIDER`, `SELF_REGISTRATION_NOT_ALLOWED`, +`TOKEN_EXCHANGE_FAILED`). `debug` is only present whil + +```ts +type SSOErrorResp = { + status?: number + error?: string + reason?: string + debug?: { + stage?: "exchange" | "login" + reason?: string + message?: string + upstream_status?: number + oauth_error?: string + oauth_error_description?: string + token_endpoint_host?: string + token_endpoint_path?: string + redirect_uri?: string + received_claims?: string[] + request_id?: string + hint?: string + } +} +``` + +### `SSODebugInfo` + +Technical details of a failed SSO login or token exchange, returned only while SSO debug +mode is active for the provider. Never carries secrets, authorization codes, PKCE +verifiers, tokens or claim values. + + +```ts +type SSODebugInfo = { + stage?: "exchange" | "login" + reason?: string + message?: string + upstream_status?: number + oauth_error?: string + oauth_error_description?: string + token_endpoint_host?: string + token_endpoint_path?: string + redirect_uri?: string + received_claims?: string[] + request_id?: string + hint?: string } ``` @@ -8182,6 +10979,7 @@ type EmailTemplates = { advancedMFA?: string // uuid journeySignUp?: string // uuid journeySignInOneTimePassword?: string // uuid + passkeyVerificationCode?: string // uuid journeyLoginOTP?: string // uuid forgotPassword?: string // uuid invitation?: string // uuid @@ -8195,16 +10993,6 @@ type EmailTemplates = { } ``` -### `DeleteEntityFile` - -```ts -type DeleteEntityFile = { - entity_id: string // uuid - entity_type: string - file_entity_ids: string // uuid[] -} -``` - ### `SaveEntityFile` ```ts @@ -8227,6 +11015,7 @@ type SaveEntityFile = { ```ts type SavePortalFile = { origin: string + draft?: boolean files: Array<{ filename?: string file_type: string @@ -8309,6 +11098,39 @@ type UpdateOnlyPortalConfigAttributes = { phone?: { ... } }> } + identity_providers?: Array<{ + slug?: string + display_name: string + provider_type: "OIDC" + attribute_mappings?: { + contact: { ... } + account?: { ... } + portal_user?: { ... } + concession_attributes?: { ... } + } + entity_matching?: { + portal_user?: { ... } + contact?: { ... } + auto_create_cognito_user?: { ... } + } + oidc_config?: { + type?: { ... } + oidc_issuer: { ... } + redirect_uri?: { ... } + client_id: { ... } + client_secret?: { ... } + has_client_secret?: { ... } + scope: { ... } + metadata?: { ... } + prompt?: { ... } + } + mobile_oidc_config?: { + client_id?: { ... } + client_secret?: { ... } + } + expose_client_secret?: boolean + debug_mode_until?: string // date-time + }> } ``` @@ -8316,9 +11138,46 @@ type UpdateOnlyPortalConfigAttributes = { ```ts type CommonConfigAttributes = { + mobile_config?: { + portal_id?: string + enabled?: boolean + display_name?: string + app_host?: string + environment?: "prod" | "staging" | "dev" + branding?: { + app_icon?: { ... } + splash?: { ... } + splash_dark?: { ... } + icon_background_color?: { ... } + splash_background_color?: { ... } + splash_background_color_dark?: { ... } + } + ios?: { + bundle_id?: { ... } + team_id?: { ... } + credentials_status?: { ... } + app_store_id?: { ... } + store_url?: { ... } + last_build?: { ... } + } + android?: { + package_name?: { ... } + credentials_status?: { ... } + upload_key_status?: { ... } + store_url?: { ... } + last_build?: { ... } + } + ota?: { + enabled?: { ... } + channel?: { ... } + auto_update?: { ... } + update_strategy?: { ... } + min_native_version?: { ... } + } + } enabled?: boolean name?: string - domain: string + domain?: string is_epilot_domain?: boolean epilot_domain?: string domain_settings?: { @@ -8327,13 +11186,33 @@ type CommonConfigAttributes = { is_redirection_enabled?: boolean } design_id?: string // uuid + header?: { + design?: { + overrides?: { ... } + } + } + allowed_portal_entities?: string[] self_registration_setting?: "ALLOW_WITH_CONTACT_CREATION" | "ALLOW_WITHOUT_CONTACT_CREATION" | "DENY" | "ALWAYS_CREATE_CONTACT" | "DISALLOW_COMPLETELY" | "BLOCK_IF_PORTAL_USER_EXISTS" + self_registration_account_setting?: "ALLOW_WITH_CREATION" | "DENY" | "ALWAYS_CREATE" | "BLOCK_IF_PORTAL_USER_EXISTS" | "DISALLOW_COMPLETELY" + block_registration_if_portal_user_exists?: boolean + self_registration_entity?: "contact" | "account" user_account_self_management?: boolean feature_settings?: { start_page?: boolean billing?: boolean + commodity_billing?: boolean change_due_date?: boolean new_design?: boolean + mcp_enabled?: boolean + mcp_grant_version?: number + portal_copilot?: boolean + portal_copilot_agent_id?: string + portal_copilot_visibility?: { + visible_for_targets?: { ... } + visible_for_operator?: { ... } + hidden_for_targets?: { ... } + hidden_for_operator?: { ... } + } } accessToken?: string advanced_mfa?: { @@ -8343,82 +11222,48 @@ type CommonConfigAttributes = { passwordless_login?: { enabled?: { ... } } + passkeys?: { + enabled?: { ... } + } entry_point?: "PASSWORD" | "SSO" preferred_sso_providers?: string[] auto_redirect_to_sso?: boolean + prevent_user_enumeration?: boolean } cognito_details?: { cognito_user_pool_client_id?: string + cognito_mobile_client_id?: string cognito_user_pool_arn?: string cognito_user_pool_id?: string - password_policy?: { - minimum_length?: { ... } - maximum_length?: { ... } - require_lowercase?: { ... } - require_uppercase?: { ... } - require_numbers?: { ... } - require_symbols?: { ... } - } - } - config?: string - contact_identifiers?: string[] - approval_state_attributes?: Record - email_templates?: { - confirmAccount?: string // uuid - advancedAuth?: string // uuid - advancedMFA?: string // uuid - journeySignUp?: string // uuid - journeySignInOneTimePassword?: string // uuid - journeyLoginOTP?: string // uuid - forgotPassword?: string // uuid - invitation?: string // uuid - partnerInvitation?: string // uuid - onNewQuote?: string // uuid - onMapAPendingUser?: string // uuid - onDocUpload?: string // uuid - onWorkflowStepAssigned?: string // uuid - confirmEmailUpdate?: string // uuid - verifyCodeToSetPassword?: string // uuid - } - images?: { - orderLeftTeaser?: string - orderRightTeaser?: string - welcomeBanner?: string - } - entity_identifiers?: { - type?: { - isEnabled?: { ... } - attributes?: { ... } - } - } - contract_identifiers?: Array<{ - name?: string - schema?: string - }> - contract_selector_config?: { - show_inactive?: boolean - title_path?: string - } - registration_identifiers?: Array<{ - name?: string - schema?: string - }> - triggered_journeys?: Array<{ - trigger_name?: "FIRST_LOGIN" | "ACCEPT_ORDER" | "DECLINE_ORDER" - journey_id?: string // uuid - }> - entity_edit_rules?: Array<{ - slug?: string - attribute?: string - rule_type?: "cadence" | "relative_to_current_value" | "days_before_date" | "overdue_payments" - cadence_period_type?: "days" | "weeks" | "months" - cadence_period?: number - changes_allowed?: number - grace_period?: number + timeouts?: { + refresh_token?: { ... } // ... } ``` +### `EngagementCenterTaskTemplates` + +Handlebars templates rendering each outstanding task (to-do) row in the portal's engagement center. Resolved server-side per task against the task's entity (same variable syntax as page block templates, e.g. `{{order.order_number}}`, custom and environment variables) plus `task.*` (the workflow step + +```ts +type EngagementCenterTaskTemplates = { + title?: string + subtitle?: string +} +``` + +### `NotificationTriggerConfig` + +```ts +type NotificationTriggerConfig = { + trigger_type: "entity_added" | "entity_created" | "entity_assigned" | "workflow_step_overdue" + entity_schema?: string + enabled?: boolean + template_id?: string // uuid + target_ids?: string[] +} +``` + ### `UpsertPortalConfig` ```ts @@ -8452,76 +11297,76 @@ type UpsertPortalConfig = { phone?: { ... } }> } - enabled?: boolean - name?: string - domain: string - is_epilot_domain?: boolean - epilot_domain?: string - domain_settings?: { - is_custom_domain_enabled?: boolean - is_epilot_domain_enabled?: boolean - is_redirection_enabled?: boolean - } - design_id?: string // uuid - self_registration_setting?: "ALLOW_WITH_CONTACT_CREATION" | "ALLOW_WITHOUT_CONTACT_CREATION" | "DENY" | "ALWAYS_CREATE_CONTACT" | "DISALLOW_COMPLETELY" | "BLOCK_IF_PORTAL_USER_EXISTS" - user_account_self_management?: boolean - feature_settings?: { - start_page?: boolean - billing?: boolean - change_due_date?: boolean - new_design?: boolean - } - accessToken?: string - advanced_mfa?: { + identity_providers?: Array<{ + slug?: string + display_name: string + provider_type: "OIDC" + attribute_mappings?: { + contact: { ... } + account?: { ... } + portal_user?: { ... } + concession_attributes?: { ... } + } + entity_matching?: { + portal_user?: { ... } + contact?: { ... } + auto_create_cognito_user?: { ... } + } + oidc_config?: { + type?: { ... } + oidc_issuer: { ... } + redirect_uri?: { ... } + client_id: { ... } + client_secret?: { ... } + has_client_secret?: { ... } + scope: { ... } + metadata?: { ... } + prompt?: { ... } + } + mobile_oidc_config?: { + client_id?: { ... } + client_secret?: { ... } + } + expose_client_secret?: boolean + debug_mode_until?: string // date-time + }> + mobile_config?: { + portal_id?: string enabled?: boolean - } - auth_settings?: { - passwordless_login?: { + display_name?: string + app_host?: string + environment?: "prod" | "staging" | "dev" + branding?: { + app_icon?: { ... } + splash?: { ... } + splash_dark?: { ... } + icon_background_color?: { ... } + splash_background_color?: { ... } + splash_background_color_dark?: { ... } + } + ios?: { + bundle_id?: { ... } + team_id?: { ... } + credentials_status?: { ... } + app_store_id?: { ... } + store_url?: { ... } + last_build?: { ... } + } + android?: { + package_name?: { ... } + credentials_status?: { ... } + upload_key_status?: { ... } + store_url?: { ... } + last_build?: { ... } + } + ota?: { enabled?: { ... } + channel?: { ... } + auto_update?: { ... } + update_strategy?: { ... } + min_native_version?: { ... } } - entry_point?: "PASSWORD" | "SSO" - preferred_sso_providers?: string[] - auto_redirect_to_sso?: boolean - } - cognito_details?: { - cognito_user_pool_client_id?: string - cognito_user_pool_arn?: string - cognito_user_pool_id?: string - password_policy?: { - minimum_length?: { ... } - maximum_length?: { ... } - require_lowercase?: { ... } - require_uppercase?: { ... } - require_numbers?: { ... } - require_symbols?: { ... } - } - } - config?: string - contact_identifiers?: string[] - approval_state_attributes?: Record - email_templates?: { - confirmAccount?: string // uuid - advancedAuth?: string // uuid - advancedMFA?: string // uuid - journeySignUp?: string // uuid - journeySignInOneTimePassword?: string // uuid - journeyLoginOTP?: string // uuid - forgotPassword?: string // uuid - invitation?: string // uuid - partnerInvitation?: string // uuid - onNewQuote?: string // uuid - onMapAPendingUser?: string // uuid - onDocUpload?: string // uuid - onWorkflowStepAssigned?: string // uuid - confirmEmailUpdate?: string // uuid - verifyCodeToSetPassword?: string // uuid } - images?: { - orderLeftTeaser?: string - orderRightTeaser?: string - welcomeBanner?: string - } - entity_identifiers?: { // ... } ``` @@ -8530,9 +11375,46 @@ type UpsertPortalConfig = { ```ts type PortalConfig = { + mobile_config?: { + portal_id?: string + enabled?: boolean + display_name?: string + app_host?: string + environment?: "prod" | "staging" | "dev" + branding?: { + app_icon?: { ... } + splash?: { ... } + splash_dark?: { ... } + icon_background_color?: { ... } + splash_background_color?: { ... } + splash_background_color_dark?: { ... } + } + ios?: { + bundle_id?: { ... } + team_id?: { ... } + credentials_status?: { ... } + app_store_id?: { ... } + store_url?: { ... } + last_build?: { ... } + } + android?: { + package_name?: { ... } + credentials_status?: { ... } + upload_key_status?: { ... } + store_url?: { ... } + last_build?: { ... } + } + ota?: { + enabled?: { ... } + channel?: { ... } + auto_update?: { ... } + update_strategy?: { ... } + min_native_version?: { ... } + } + } enabled?: boolean name?: string - domain: string + domain?: string is_epilot_domain?: boolean epilot_domain?: string domain_settings?: { @@ -8541,13 +11423,33 @@ type PortalConfig = { is_redirection_enabled?: boolean } design_id?: string // uuid + header?: { + design?: { + overrides?: { ... } + } + } + allowed_portal_entities?: string[] self_registration_setting?: "ALLOW_WITH_CONTACT_CREATION" | "ALLOW_WITHOUT_CONTACT_CREATION" | "DENY" | "ALWAYS_CREATE_CONTACT" | "DISALLOW_COMPLETELY" | "BLOCK_IF_PORTAL_USER_EXISTS" + self_registration_account_setting?: "ALLOW_WITH_CREATION" | "DENY" | "ALWAYS_CREATE" | "BLOCK_IF_PORTAL_USER_EXISTS" | "DISALLOW_COMPLETELY" + block_registration_if_portal_user_exists?: boolean + self_registration_entity?: "contact" | "account" user_account_self_management?: boolean feature_settings?: { start_page?: boolean billing?: boolean + commodity_billing?: boolean change_due_date?: boolean new_design?: boolean + mcp_enabled?: boolean + mcp_grant_version?: number + portal_copilot?: boolean + portal_copilot_agent_id?: string + portal_copilot_visibility?: { + visible_for_targets?: { ... } + visible_for_operator?: { ... } + hidden_for_targets?: { ... } + hidden_for_operator?: { ... } + } } accessToken?: string advanced_mfa?: { @@ -8557,78 +11459,21 @@ type PortalConfig = { passwordless_login?: { enabled?: { ... } } + passkeys?: { + enabled?: { ... } + } entry_point?: "PASSWORD" | "SSO" preferred_sso_providers?: string[] auto_redirect_to_sso?: boolean + prevent_user_enumeration?: boolean } cognito_details?: { cognito_user_pool_client_id?: string + cognito_mobile_client_id?: string cognito_user_pool_arn?: string cognito_user_pool_id?: string - password_policy?: { - minimum_length?: { ... } - maximum_length?: { ... } - require_lowercase?: { ... } - require_uppercase?: { ... } - require_numbers?: { ... } - require_symbols?: { ... } - } - } - config?: string - contact_identifiers?: string[] - approval_state_attributes?: Record - email_templates?: { - confirmAccount?: string // uuid - advancedAuth?: string // uuid - advancedMFA?: string // uuid - journeySignUp?: string // uuid - journeySignInOneTimePassword?: string // uuid - journeyLoginOTP?: string // uuid - forgotPassword?: string // uuid - invitation?: string // uuid - partnerInvitation?: string // uuid - onNewQuote?: string // uuid - onMapAPendingUser?: string // uuid - onDocUpload?: string // uuid - onWorkflowStepAssigned?: string // uuid - confirmEmailUpdate?: string // uuid - verifyCodeToSetPassword?: string // uuid - } - images?: { - orderLeftTeaser?: string - orderRightTeaser?: string - welcomeBanner?: string - } - entity_identifiers?: { - type?: { - isEnabled?: { ... } - attributes?: { ... } - } - } - contract_identifiers?: Array<{ - name?: string - schema?: string - }> - contract_selector_config?: { - show_inactive?: boolean - title_path?: string - } - registration_identifiers?: Array<{ - name?: string - schema?: string - }> - triggered_journeys?: Array<{ - trigger_name?: "FIRST_LOGIN" | "ACCEPT_ORDER" | "DECLINE_ORDER" - journey_id?: string // uuid - }> - entity_edit_rules?: Array<{ - slug?: string - attribute?: string - rule_type?: "cadence" | "relative_to_current_value" | "days_before_date" | "overdue_payments" - cadence_period_type?: "days" | "weeks" | "months" - cadence_period?: number - changes_allowed?: number - grace_period?: number + timeouts?: { + refresh_token?: { ... } // ... } ``` @@ -8637,9 +11482,11 @@ type PortalConfig = { ```ts type UpsertPortalWidget = { + portal_sk_v3?: string + is_v3_item?: boolean widgets: Array<{ id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: { ... } @@ -8652,7 +11499,7 @@ type UpsertPortalWidget = { schema?: string } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: { ... } @@ -8665,7 +11512,7 @@ type UpsertPortalWidget = { content?: string } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: { ... } @@ -8684,7 +11531,7 @@ type UpsertPortalWidget = { }> } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: { ... } @@ -8701,7 +11548,7 @@ type UpsertPortalWidget = { } } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: { ... } @@ -8713,7 +11560,7 @@ type UpsertPortalWidget = { } } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: { ... } @@ -8725,7 +11572,7 @@ type UpsertPortalWidget = { } } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: { ... } @@ -8734,8 +11581,6 @@ type UpsertPortalWidget = { subHeadline?: { en?: { ... } de?: { ... } - } - schema?: string // ... } ``` @@ -8757,7 +11602,7 @@ type DomainSettings = { ```ts type WidgetBase = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8775,7 +11620,7 @@ type WidgetBase = { ```ts type EntityWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8794,7 +11639,7 @@ type EntityWidget = { ```ts type MeterReadingWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8813,7 +11658,7 @@ type MeterReadingWidget = { ```ts type MeterChartWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8851,7 +11696,7 @@ type WidgetAction = { ```ts type ActionWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8883,7 +11728,7 @@ type ActionWidget = { ```ts type TeaserWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8909,7 +11754,7 @@ type TeaserWidget = { ```ts type ContentWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8928,7 +11773,7 @@ type ContentWidget = { ```ts type DocumentWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8946,7 +11791,7 @@ type DocumentWidget = { ```ts type PaymentWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8967,12 +11812,20 @@ type CampaignWidget = { } ``` +### `ProductRecommendationsWidget` + +```ts +type ProductRecommendationsWidget = { + campaign_id?: string +} +``` + ### `PortalWidget` ```ts type PortalWidget = { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8985,7 +11838,7 @@ type PortalWidget = { schema?: string } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -8998,7 +11851,7 @@ type PortalWidget = { content?: string } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -9024,7 +11877,7 @@ type PortalWidget = { }> } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -9044,7 +11897,7 @@ type PortalWidget = { } } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -9056,7 +11909,7 @@ type PortalWidget = { } } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number headline?: { en?: string @@ -9068,7 +11921,7 @@ type PortalWidget = { } } | { id: string - type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" + type: "ACTION_WIDGET" | "CONTENT_WIDGET" | "ENTITY_WIDGET" | "TEASER_WIDGET" | "DOCUMENT_WIDGET" | "PAYMENT_WIDGET" | "METER_READING_WIDGET" | "METER_CHART_WIDGET" | "CAMPAIGN_WIDGET" | "PRODUCT_RECOMMENDATIONS_WIDGET" listIndex: number // ... } @@ -9089,6 +11942,47 @@ type ContactCountRequest = { type ContactExistsRequest = { org_id: string registration_identifiers: Record> + trigger_identifiers_check?: boolean +} +``` + +### `ContactIdentifyRequest` + +ContactExistsRequest plus the surface the token is requested for. `registration_identifiers` carries the values of the surface's effective identifiers (keyed by schema, then attribute name): the surface's own `identifiers` when it configures any, otherwise the portal's `registration_identifiers`. + + +```ts +type ContactIdentifyRequest = { + org_id: string + registration_identifiers: Record> + trigger_identifiers_check?: boolean + surface_id: string +} +``` + +### `ContactIdentifyResponse` + +```ts +type ContactIdentifyResponse = { + contact_id?: string // uuid + account_id?: string // uuid + token?: string + token_type?: "contact_identification" + surface_id?: string + expires_at?: string // date-time + allowed_operations?: string[] + has_portal_user?: boolean + portal_user_email?: string + reason?: "TIMEOUT" | "NOT_FOUND" +} +``` + +### `AccountExistsRequest` + +```ts +type AccountExistsRequest = { + org_id: string + registration_identifiers: Record> } ``` @@ -9115,6 +12009,8 @@ type CreateUserRequest = { password?: string contactIdentifiers?: Record registration_identifiers?: Record> + contact_identifiers_for_account?: Record + additional_contact_attributes?: Record account_id?: string } ``` @@ -9211,6 +12107,38 @@ URL-friendly identifier for the entity schema type EntitySlug = string ``` +### `EntitySlugConfig` + +Per-slug search configuration with scoped targets and templates + +```ts +type EntitySlugConfig = { + slug: string + targets?: string // uuid[] + match_any_targets?: string // uuid[] + templates?: Record + templates_ref?: { + page_id?: string + block_id?: string + config_id?: string + global_search_config_id?: string + } +} +``` + +### `TemplatesRef` + +Reference to admin-authored portal configuration (a page block or a global search configuration item) from which the API derives Handlebars templates server-side. This replaces client-supplied template strings so portal users can never submit arbitrary templates for resolution. When both a reference + +```ts +type TemplatesRef = { + page_id?: string + block_id?: string + config_id?: string + global_search_config_id?: string +} +``` + ### `EntityId` Entity ID @@ -9243,7 +12171,13 @@ type Schema = { ### `Entity` ```ts -type Entity = Record +type Entity = { + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> +} ``` ### `EntityTemplates` @@ -9264,6 +12198,11 @@ type EntityItem = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> templates_output?: Record> _schema: string } @@ -9282,6 +12221,11 @@ type EntityResponse = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: { ... } + fragment?: { ... } + }> templates_output?: Record> _schema: string } @@ -9301,6 +12245,11 @@ type EntityResponseWithHits = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: { ... } + fragment?: { ... } + }> templates_output?: Record> _schema: string }> @@ -9311,6 +12260,9 @@ type EntityResponseWithHits = { has_more?: boolean } hits?: number + includes?: { + active_workflow?: Record + } } ``` @@ -9331,6 +12283,8 @@ type EntityResponseGroupedWithHits = { _tags?: { ... } _created_at: { ... } _updated_at: { ... } + templates_output_highlighted?: { ... } + search_snippets?: { ... } templates_output?: { ... } _schema: { ... } }> @@ -9346,6 +12300,19 @@ type EntityResponseGroupedWithHits = { after_key?: Record } hits?: number + includes?: { + active_workflow?: Record + } +} +``` + +### `SearchIncludes` + +Side-loaded enrichment data requested via the `include` parameter. + +```ts +type SearchIncludes = { + active_workflow?: Record } ``` @@ -9361,10 +12328,51 @@ type PortalUser = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> _schema: "portal_user" } ``` +### `PortalContactUpdate` + +Contact attributes a portal user can change. Other attributes are ignored. +Value types follow the organization's contact schema. + + +```ts +type PortalContactUpdate = { + language?: string + first_name?: unknown + last_name?: unknown + salutation?: unknown + phone?: unknown + phone_number?: unknown + mobile?: unknown + street?: unknown + street_number?: unknown + postal_code?: unknown + city?: unknown + country?: unknown + preferred_language?: unknown + communication_preferences?: unknown +} +``` + +### `PortalContractUpdate` + +Contract attributes a portal user can change. Other attributes are ignored. + +```ts +type PortalContractUpdate = { + installment_amount?: number + installment_amount_decimal?: string +} +``` + ### `Contact` The mapped contact of the portal user @@ -9377,6 +12385,11 @@ type Contact = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> _schema: "contact" } ``` @@ -9404,6 +12417,11 @@ type Meter = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> _schema: "meter" } ``` @@ -9420,6 +12438,11 @@ type Order = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> _schema: "order" } ``` @@ -9436,6 +12459,11 @@ type Opportunity = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> _schema: "opportunity" } ``` @@ -9452,6 +12480,11 @@ type Contract = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> contract_name?: string contract_number?: string status?: "draft" | "in_approval_process" | "approved" | "active" | "deactivated" | "revoked" | "terminated" | "expired" @@ -9489,6 +12522,11 @@ type File = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> _schema: "file" } ``` @@ -9505,6 +12543,11 @@ type Product = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> _schema: "product" } ``` @@ -9595,20 +12638,20 @@ type FileItem = { _relations?: Array<{ entity_id?: string // uuid _schema?: string - _title?: string }> is_new?: boolean + custom_download_url_auth?: "token" | "presigned" } ``` -### `EntityFileCount` +### `FilePreviewResult` ```ts -type EntityFileCount = { - entity_id: string // uuid - _schema: string - _title?: string - file_count: number +type FilePreviewResult = { + kind: "pdf" | "image" | "unsupported" + url?: string // uri + requires_auth?: boolean + download_url?: string // uri } ``` @@ -9631,6 +12674,61 @@ type AdminUser = { } ``` +### `PortalSurface` + +One surface a portal's data is reached from (see `surfaces` on the portal config). + +A surface names how callers authenticate on it and what they may reach once they +have. Data access is always a subset of the portal's own: a schema not in +`allowed_portal_entities` cannot be opened up by a surface, a + +```ts +type PortalSurface = { + id: string + name: string + description?: string + authentication: "login" | "registration_identifiers" + token_ttl_seconds?: number + identifiers?: Array<{ + name?: string + schema?: string + validation_rule_id?: string + }> + data_access?: { + entities?: Array<{ + schema: { ... } + target_ids?: { ... } + }> + role_id?: string + } +} +``` + +### `PortalSurfaceDataAccess` + +What a caller on a surface may reach. Every property is optional; omitting all of them is the portal's default scope. + +```ts +type PortalSurfaceDataAccess = { + entities?: Array<{ + schema: string + target_ids?: string[] + }> + role_id?: string +} +``` + +### `PortalSurfaceEntityAccess` + +One schema this surface reaches, with the targets that always apply to it. + +```ts +type PortalSurfaceEntityAccess = { + schema: string + target_ids?: string[] +} +``` + ### `Grant` ```ts @@ -9678,6 +12776,43 @@ type JourneyActions = { } ``` +### `JourneyContextUsagesRequest` + +```ts +type JourneyContextUsagesRequest = { + journey_id: string + param_keys: string[] + param_ids?: string[] +} +``` + +### `JourneyContextUsagesResponse` + +```ts +type JourneyContextUsagesResponse = { + status: "ok" | "partial" + scanned: number + usages: Array<{ + kind: "portal-config" | "portal-block" + resource: { + type: { ... } + id: { ... } + name?: { ... } + } + location: Record + matched_as: { + dialect: { ... } + token: { ... } + at?: { ... } + } + link_hint?: { + route: { ... } + params: { ... } + } + }> +} +``` + ### `ExternalLink` ```ts @@ -9699,6 +12834,24 @@ type ExternalLink = { } ``` +### `OutstandingTask` + +```ts +type OutstandingTask = { + entity_id: string + entity_schema: string + entity_title: string + workflow_id: string + workflow_name: string + step_id: string + step_name: string + journey_id: string + complete_task_automatically?: boolean + title?: string + subtitle?: string +} +``` + ### `WorkflowExecution` ```ts @@ -9711,6 +12864,271 @@ type WorkflowExecution = Record type WorkflowStep = Record ``` +### `PortalWorkflow` + +A portal-facing projection of a workflow execution (V1 or V2), with the execution +graph already linearized by the Workflows API into a flat, ordered list of +portal-visible tasks. + + +```ts +type PortalWorkflow = { + id: string + definition_id?: string + name: string + status: "STARTED" | "DONE" | "CLOSED" + version: 2 | 3 + created_at?: string + updated_at?: string + completed_at?: string + due_date?: string + assigned_to?: string[] + contexts?: Array<{ + entity_id?: string + entity_schema?: string + is_primary?: boolean + }> + is_path_complete: boolean + tasks: Array<{ + id: string + name: string + order: number + status: "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "PENDING" + is_active: boolean + start_date?: string // date-time + ecp?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + installer?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + } + assigned_to?: string[] + phase_id?: string + phase_name?: string + stage_id?: string + completed_at?: string + updated_at?: string + }> + stages?: Array<{ + id: string + name: string + description?: string + status: "COMPLETED" | "IN_PROGRESS" | "UPCOMING" | "NOT_REACHED" + completed_at?: string + portal_names?: { + ecp?: { ... } + installer?: { ... } + } + portal_descriptions?: { + ecp?: { ... } + installer?: { ... } + } + }> + portal_titles?: { + ecp?: string + installer?: string + } +} +``` + +### `PortalWorkflowStage` + +A customer-facing stage of a flow execution, with a progress status derived +from the execution's tasks by the Workflows API. Stages form a strict total +order; the array order is the stage order. + + +```ts +type PortalWorkflowStage = { + id: string + name: string + description?: string + status: "COMPLETED" | "IN_PROGRESS" | "UPCOMING" | "NOT_REACHED" + completed_at?: string + portal_names?: { + ecp?: string + installer?: string + } + portal_descriptions?: { + ecp?: string + installer?: string + } +} +``` + +### `PortalNameOverrides` + +Portal-facing overrides of a flow or stage title, configured per portal +audience in the Flows Hub. Served unresolved because this endpoint asks +the Workflows API for audience `all` — one cached response feeds blocks +of both audiences, so each block picks its own override and falls back +to `name` whe + +```ts +type PortalNameOverrides = { + ecp?: string + installer?: string +} +``` + +### `PortalDescriptionOverrides` + +Portal-facing overrides of a stage description, configured per portal +audience in the Flows Hub. Served unresolved for the same reason as +`PortalNameOverrides`; a block falls back to `description` when its +audience's key is absent. The values are rich text, like `description` +itself. + + +```ts +type PortalDescriptionOverrides = { + ecp?: string + installer?: string +} +``` + +### `PortalWorkflowTask` + +A single portal-visible task of a linearized workflow execution + +```ts +type PortalWorkflowTask = { + id: string + name: string + order: number + status: "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "PENDING" + is_active: boolean + start_date?: string // date-time + ecp?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + } + } + installer?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + } + } + journey?: { + id?: string + journeyId?: string + name?: string + portal_button_label?: string + complete_task_automatically?: boolean + } + assigned_to?: string[] + phase_id?: string + phase_name?: string + stage_id?: string + completed_at?: string + updated_at?: string +} +``` + +### `EntityPortalWorkflows` + +Linearized portal workflows of a single entity + +```ts +type EntityPortalWorkflows = { + entity_id: string + portal_workflows: Array<{ + id: string + definition_id?: string + name: string + status: "STARTED" | "DONE" | "CLOSED" + version: 2 | 3 + created_at?: string + updated_at?: string + completed_at?: string + due_date?: string + assigned_to?: string[] + contexts?: Array<{ + entity_id?: { ... } + entity_schema?: { ... } + is_primary?: { ... } + }> + is_path_complete: boolean + tasks: Array<{ + id: { ... } + name: { ... } + order: { ... } + status: { ... } + is_active: { ... } + start_date?: { ... } + ecp?: { ... } + installer?: { ... } + journey?: { ... } + assigned_to?: { ... } + phase_id?: { ... } + phase_name?: { ... } + stage_id?: { ... } + completed_at?: { ... } + updated_at?: { ... } + }> + stages?: Array<{ + id: { ... } + name: { ... } + description?: { ... } + status: { ... } + completed_at?: { ... } + portal_names?: { ... } + portal_descriptions?: { ... } + }> + portal_titles?: { + ecp?: { ... } + installer?: { ... } + } + }> +} +``` + +### `PortalTaskConfig` + +Portal-specific (ECP / installer) display config of a workflow task + +```ts +type PortalTaskConfig = { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: string + journeyId?: string + name?: string + portal_button_label?: string + complete_task_automatically?: boolean + } +} +``` + ### `BaseBillingEvent` A base billing event to be inherited by all billing events. @@ -9723,6 +13141,11 @@ type BaseBillingEvent = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> } ``` @@ -9814,6 +13237,11 @@ type BillingAccount = { _tags?: string[] _created_at: string // date-time _updated_at: string // date-time + templates_output_highlighted?: Record> + search_snippets?: Array<{ + field?: string + fragment?: string + }> } ``` @@ -9844,6 +13272,12 @@ type EntityGetParams = { hydrate?: boolean fields?: string[] templates?: Record> + templates_ref?: { + page_id?: string + block_id?: string + config_id?: string + global_search_config_id?: string + } filters?: object[] filters_context?: Record[] targets?: string // uuid[] @@ -9854,7 +13288,18 @@ type EntityGetParams = { ```ts type EntitySearchParams = { - slug: string | string[] + slug: string | string[] | Array<{ + slug: string + targets?: string // uuid[] + match_any_targets?: string // uuid[] + templates?: Record + templates_ref?: { + page_id?: { ... } + block_id?: { ... } + config_id?: { ... } + global_search_config_id?: { ... } + } + }> q?: string q_fields?: string[] group?: string @@ -9862,15 +13307,24 @@ type EntitySearchParams = { group_size?: number group_sort?: "asc" | "desc" group_after_key?: Record - sort?: string + sort?: string | string[] from?: number size?: number hydrate?: boolean fields?: string[] templates?: Record + templates_ref?: { + page_id?: string + block_id?: string + config_id?: string + global_search_config_id?: string + } filters?: object[] filters_context?: Record[] targets?: string // uuid[] + match_any_targets?: string // uuid[] + include?: "active_workflow"[] + highlight?: object } ``` @@ -9890,6 +13344,22 @@ type IdentifierAttribute = { type RegistrationIdentifier = { name?: string schema?: string + validation_rule_id?: string +} +``` + +### `AdditionalContactAttribute` + +A contact attribute that is collected from the user during self-registration +and written onto the newly created contact, but is NOT used to identify +an existing contact. + + +```ts +type AdditionalContactAttribute = { + name: string + required?: boolean + validation_rule_id?: string } ``` @@ -9899,6 +13369,20 @@ type RegistrationIdentifier = { type ContractIdentifier = { name?: string schema?: string + validation_rule_id?: string +} +``` + +### `RegistrationValidationRule` + +A validation rule of the organization, as embedded in the public portal config. + +```ts +type RegistrationValidationRule = { + _id: string + _schema_version: string + title: string + rule: Record } ``` @@ -9949,6 +13433,10 @@ type ExtensionHookSelection = { ```ts type PublicExtensionCapabilities = { consumptionDataRetrieval?: Array<{ + app?: { + app_id?: { ... } + name?: { ... } + } extension?: { id?: { ... } name?: { ... } @@ -9957,9 +13445,30 @@ type PublicExtensionCapabilities = { id?: { ... } name?: { ... } intervals?: { ... } + block_types?: { ... } + } + }> + dataExport?: Array<{ + app?: { + app_id?: { ... } + name?: { ... } + } + extension?: { + id?: { ... } + name?: { ... } + } + hook?: { + id?: { ... } + name?: { ... } + intervals?: { ... } + block_types?: { ... } } }> priceDataRetrieval?: Array<{ + app?: { + app_id?: { ... } + name?: { ... } + } extension?: { id?: { ... } name?: { ... } @@ -9968,9 +13477,14 @@ type PublicExtensionCapabilities = { id?: { ... } name?: { ... } intervals?: { ... } + block_types?: { ... } } }> costDataRetrieval?: Array<{ + app?: { + app_id?: { ... } + name?: { ... } + } extension?: { id?: { ... } name?: { ... } @@ -9979,9 +13493,14 @@ type PublicExtensionCapabilities = { id?: { ... } name?: { ... } intervals?: { ... } + block_types?: { ... } } }> contractIdentification?: { + app?: { + app_id?: { ... } + name?: { ... } + } extension?: { id?: { ... } name?: { ... } @@ -9990,14 +13509,74 @@ type PublicExtensionCapabilities = { explanation?: { ... } } } - meterReadingPlausibilityCheck?: { - extension?: { - id?: { ... } - name?: { ... } - } - hook?: { - plausibility_mode?: { ... } - } + meterReadingPlausibilityCheck?: { + extension?: { + id?: { ... } + name?: { ... } + } + hook?: { + plausibility_mode?: { ... } + } + } + changeEmail?: { + app?: { + app_id?: { ... } + name?: { ... } + } + extension?: { + id?: { ... } + name?: { ... } + } + hook?: { + id?: { ... } + change_mode?: { ... } + require_password_confirmation?: { ... } + // ... +} +``` + +### `PublicSelfManagementExplanation` + +Explanation of the hook. + +```ts +type PublicSelfManagementExplanation = { + en: string +} +``` + +### `PublicChangeEmailDetails` + +```ts +type PublicChangeEmailDetails = { + id?: string + change_mode?: "synchronous" | "asynchronous" + require_password_confirmation?: boolean + explanation?: { + en: string + } +} +``` + +### `PublicChangePasswordDetails` + +```ts +type PublicChangePasswordDetails = { + id?: string + require_new_password?: boolean + explanation?: { + en: string + } +} +``` + +### `PublicDeleteAccountDetails` + +```ts +type PublicDeleteAccountDetails = { + id?: string + explanation?: { + en: string } } ``` @@ -10006,6 +13585,12 @@ type PublicExtensionCapabilities = { ```ts type DataRetrievalItem = { + app?: { + app_id?: string + name?: { + en: { ... } + } + } extension?: { id?: string name?: { @@ -10018,6 +13603,18 @@ type DataRetrievalItem = { en: { ... } } intervals?: string[] + block_types?: string[] + } +} +``` + +### `PublicAppDetails` + +```ts +type PublicAppDetails = { + app_id?: string + name?: { + en: string } } ``` @@ -10042,6 +13639,56 @@ type PublicDataRetrievalHookDetails = { en: string } intervals?: string[] + block_types?: string[] +} +``` + +### `VisualizationMetadata` + +Runtime metadata describing how a visualization should be rendered for a given portal context. Returned by `GET /v2/portal/visualization/metadata`. + + +```ts +type VisualizationMetadata = { + type_options?: Array<{ + id: string + label?: Record + aggregation_group?: string + statistical_method?: "sum" | "average" | "min" | "max" + unit?: string + color?: "primary" | "slate" | "mauve" | "orange" | "red" | "tomato" | "amber" | "green" | "blue" + precision?: number + }> + intervals?: "PT15M" | "PT1H" | "P1D" | "P1M" | "P1Y" | "custom"[] + data_range?: { + from?: string // date-time + to?: string // date-time + } +} +``` + +### `VisualizationTypeOption` + +```ts +type VisualizationTypeOption = { + id: string + label?: Record + aggregation_group?: string + statistical_method?: "sum" | "average" | "min" | "max" + unit?: string + color?: "primary" | "slate" | "mauve" | "orange" | "red" | "tomato" | "amber" | "green" | "blue" + precision?: number +} +``` + +### `VisualizationDataRange` + +Earliest / latest timestamps for which data is available in the current context. + +```ts +type VisualizationDataRange = { + from?: string // date-time + to?: string // date-time } ``` @@ -10185,7 +13832,15 @@ type ExtensionHookRegistrationIdentifiersCheck = { body?: object result?: string } + resolved?: { + result?: string + error_message_path?: string + } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -10220,12 +13875,20 @@ type ExtensionHookContractIdentification = { body?: object result?: string } + resolved?: { + result?: string + error_message_path?: string + } assignment_mode?: "contracts" | "contact_to_contracts" | "contact_to_portal_user" contact_relation_attribute?: string explanation?: { en: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -10258,13 +13921,19 @@ type ExtensionHookMeterReadingPlausibilityCheck = { headers: Record } resolved: { + data_path?: string dataPath?: string counter_identifiers?: string | Record valid?: string upper_limit?: string lower_limit?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -10296,9 +13965,15 @@ type ExtensionHookPriceDataRetrieval = { body?: Record } resolved?: { + data_path?: string dataPath?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -10330,9 +14005,91 @@ type ExtensionHookConsumptionDataRetrieval = { body?: Record } resolved?: { + data_path?: string + dataPath?: string + error_message_path?: string + } + use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `ExtensionHookDataExport` + +Generic data export hook. When configured on a visualization block, the portal delegates the export action (e.g. CSV/Excel/PDF download) to the configured external source instead of generating the file itself. Can be used by any block that supports export — consumption charts, dynamic tariff charts, + +```ts +type ExtensionHookDataExport = { + type: "dataExport" + block_types?: string[] + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + } + resolved?: { + error_message_path?: string + } + use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `ExtensionHookVisualizationMetadata` + +Hook that returns runtime metadata describing how a visualization should be rendered for a given portal context. Invoked by the portal before fetching data, with the same context the data hook receives. + + +```ts +type ExtensionHookVisualizationMetadata = { + type: "visualizationMetadata" + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + } + resolved?: { + data_path?: string dataPath?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } } ``` @@ -10364,9 +14121,147 @@ type ExtensionHookCostDataRetrieval = { body?: Record } resolved?: { + data_path?: string dataPath?: string + error_message_path?: string } use_static_ips?: boolean + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `ExtensionHookChangeEmail` + +Hook that replaces the built-in change email functionality for portal users. When configured, the portal does not run its own change email flow. Instead, this hook makes an HTTP call to the third-party system, which is expected to handle the email change. +The `change_mode` controls what the portal d + +```ts +type ExtensionHookChangeEmail = { + type: "changeEmail" + change_mode?: "synchronous" | "asynchronous" + require_password_confirmation?: boolean + explanation?: { + en: string + } + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers: Record + body?: object + } + resolved?: { + error_message_path?: string + } + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `ExtensionHookChangePassword` + +Hook that replaces the built-in change password functionality for portal users. When configured, the portal does not change the user's password itself. Instead, this hook makes an HTTP call to the third-party system, which is expected to handle the password change (most likely by sending the user in + +```ts +type ExtensionHookChangePassword = { + type: "changePassword" + require_new_password?: boolean + explanation?: { + en: string + } + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers: Record + body?: object + } + resolved?: { + error_message_path?: string + } + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `ExtensionHookDeleteAccount` + +Hook that replaces the built-in delete account functionality for portal users. When configured, the portal does not delete the user itself. Instead, this hook makes an HTTP call to the third-party system, which is expected to handle the deletion. +The `deletion_mode` controls what the portal does aft + +```ts +type ExtensionHookDeleteAccount = { + type: "deleteAccount" + deletion_mode?: "synchronous" | "asynchronous" + delete_contact?: "none" | "soft" | "hard" + explanation?: { + en: string + } + auth?: { + method?: string + url: string + params?: Record + headers?: Record + body?: Record + cache?: { + key: { ... } + ttl: { ... } + } + } + call: { + method?: string + url: string + params?: Record + headers: Record + body?: object + } + resolved?: { + error_message_path?: string + } + secure_proxy?: { + integration_id: string // uuid + use_case_slug: string + } +} +``` + +### `SecureProxyConfig` + +Configuration for routing requests through the ERP Integration secure proxy. Mutually exclusive with use_static_ips. + +```ts +type SecureProxyConfig = { + integration_id: string // uuid + use_case_slug: string } ``` @@ -10438,12 +14333,57 @@ type MeterReading = { meter_id: string // uuid counter_id?: string // uuid direction?: "feed-in" | "feed-out" - timestamp?: string - source: "ECP" | "ERP" | "360" | "journey-submission" - status?: "valid" | "in-validation" | "implausible" | null | "" - external_id?: string - remark?: string - metadata?: Record + timestamp?: string + source: "ECP" | "ERP" | "360" | "journey-submission" + status?: "valid" | "in-validation" | "implausible" | null | "" + external_id?: string + remark?: string + metadata?: Record +} +``` + +### `PortalMeterReading` + +A meter reading submitted by a portal user for a counter of the meter in the path. + +```ts +type PortalMeterReading = { + value: number + counter_id: string // uuid + direction?: "feed-in" | "feed-out" + timestamp?: string + read_by?: string + reason?: "" | "regular" | "irregular" | "last" | "first" | "meter_change" | "contract_change" | "meter_adjustment" + source?: "ECP" | "ERP" | "360" | "journey-submission" + status?: "valid" | "in-validation" | "implausible" | null | "" + remark?: string + metadata?: Record +} +``` + +### `MeterCounter` + +A counter (measurement channel) of a meter + +```ts +type MeterCounter = { + _id: string // uuid + _title: string + _org: string + _tags?: string[] + _created_at: string // date-time + _updated_at: string // date-time + _schema: "meter_counter" + obis_number?: string + direction?: "feed-in" | "feed-out" + transformer_ratio?: number + unit?: string + forecast_reading_value?: string + forecast_as_of?: string + current_consumption?: number + last_reading?: string + conversion_factor?: number + tariff_type?: "ht" | "nt" } ``` @@ -10470,6 +14410,7 @@ type MeterReadingPhotoData = { reading?: string sector?: string meter_numbers?: string[] + file_id?: string } ``` @@ -10497,6 +14438,13 @@ type ProviderDisplayName = string ### `ProviderConfig` +SSO identity provider configuration. + +Env var interpolation: only string fields under `oidc_config` and +`mobile_oidc_config` (incl. their nested `metadata`) are passed through +Liquid templating, so they may contain `{{ env.VAR }}` placeholders that +get resolved at runtime against the organization's + ```ts type ProviderConfig = { slug?: string @@ -10543,6 +14491,7 @@ type ProviderConfig = { has_client_secret?: boolean scope: string metadata?: { + response_modes_supported?: { ... } authorization_endpoint?: { ... } token_endpoint?: { ... } userinfo_endpoint?: { ... } @@ -10553,12 +14502,14 @@ type ProviderConfig = { test_auth_username?: { ... } test_auth_password?: { ... } } - prompt?: "login" | "select_account" | "consent" + prompt?: "login" | "select_account" | "consent" | "signup" } mobile_oidc_config?: { client_id?: string client_secret?: string } + expose_client_secret?: boolean + debug_mode_until?: string // date-time } ``` @@ -10577,6 +14528,7 @@ type ProviderPublicConfig = { has_client_secret?: boolean scope: string metadata?: { + response_modes_supported?: { ... } authorization_endpoint?: { ... } token_endpoint?: { ... } userinfo_endpoint?: { ... } @@ -10587,12 +14539,62 @@ type ProviderPublicConfig = { test_auth_username?: { ... } test_auth_password?: { ... } } - prompt?: "login" | "select_account" | "consent" + prompt?: "login" | "select_account" | "consent" | "signup" } mobile_oidc_config?: { client_id?: string client_secret?: string } + debug_mode?: boolean +} +``` + +### `ProviderPublicConfigV3` + +Web-only public provider configuration served by `getPublicSSOProviderV3`. +Unlike `ProviderPublicConfig` there is no `mobile_oidc_config`, and +`oidc_config` never carries `client_secret` or the `metadata.test_auth_*` +credentials — `oidc_config.has_client_secret` signals their presence so +clients rou + +```ts +type ProviderPublicConfigV3 = { + slug: string + display_name: string + oidc_config?: { + type?: "authorization_code" | "implicit" + oidc_issuer: string + redirect_uri?: string + client_id: string + client_secret?: string + has_client_secret?: boolean + scope: string + metadata?: { + response_modes_supported?: { ... } + authorization_endpoint?: { ... } + token_endpoint?: { ... } + userinfo_endpoint?: { ... } + logout_uri?: { ... } + logout_redirect_uri?: { ... } + skip_login_as_logout?: { ... } + mobile_redirect_uri?: { ... } + test_auth_username?: { ... } + test_auth_password?: { ... } + } + prompt?: "login" | "select_account" | "consent" | "signup" + } + debug_mode?: boolean +} +``` + +### `PublicIdentityProvider` + +Minimal public identity provider info — enough to render a provider login button. + +```ts +type PublicIdentityProvider = { + slug: string + display_name: string } ``` @@ -10644,6 +14646,13 @@ type EntityMatchingConfig = { ### `OIDCProviderConfig` +OIDC provider configuration. Values are resolved at SSO invocation time +(login / callback), so the fields below may reference org env vars via +mustache-like templates, e.g. `{{ env.MY_PROVIDER_CLIENT_SECRET }}`. + +Fields used to render the SSO buttons up-front (`ProviderConfig.slug`, +`ProviderConfig. + ```ts type OIDCProviderConfig = { type?: "authorization_code" | "implicit" @@ -10654,6 +14663,7 @@ type OIDCProviderConfig = { has_client_secret?: boolean scope: string metadata?: { + response_modes_supported?: "form_post" | "fragment" | "query"[] authorization_endpoint?: string token_endpoint?: string userinfo_endpoint?: string @@ -10664,12 +14674,17 @@ type OIDCProviderConfig = { test_auth_username?: string test_auth_password?: string } - prompt?: "login" | "select_account" | "consent" + prompt?: "login" | "select_account" | "consent" | "signup" } ``` ### `MoblieOIDCConfig` +Mobile OIDC configuration. Values are resolved at SSO invocation time, so the +fields below may reference org env vars via mustache-like templates, e.g. +`{{ env.MOBILE_CLIENT_SECRET }}`. + + ```ts type MoblieOIDCConfig = { client_id?: string @@ -10681,6 +14696,7 @@ type MoblieOIDCConfig = { ```ts type OIDCProviderMetadata = { + response_modes_supported?: "form_post" | "fragment" | "query"[] authorization_endpoint?: string token_endpoint?: string userinfo_endpoint?: string @@ -10707,7 +14723,7 @@ type SSOCallbackRequest = { token_endpoint: string grant_type: string code: string - redirect_uri: string + redirect_uri?: string client_id: string code_verifier: string } @@ -10730,7 +14746,18 @@ type SSOCallbackResponse = { ```ts type BlockProps = { - visibility?: Record + visibility?: { + is_hidden?: boolean + hidden_on_mobile?: boolean + hidden_on_desktop?: boolean + hidden_in_app?: boolean + start_date?: string // date-time + end_date?: string // date-time + visible_for_targets?: string[] + visible_for_operator?: "and" | "or" + hidden_for_targets?: string[] + hidden_for_operator?: "and" | "or" + } content?: Record design?: Record } @@ -10744,12 +14771,35 @@ The type of the block. eg; tabs, tab, group, attribute type BlockType = string ``` +### `HeldBackNode` + +A blueprint-managed page or block a write tried to change; the stored version was kept. + +```ts +type HeldBackNode = { + page_id: string + block_id?: string + reason: "BLUEPRINT_MANAGED" +} +``` + ### `BlockRequest` ```ts type BlockRequest = { props?: { - visibility?: Record + visibility?: { + is_hidden?: { ... } + hidden_on_mobile?: { ... } + hidden_on_desktop?: { ... } + hidden_in_app?: { ... } + start_date?: { ... } + end_date?: { ... } + visible_for_targets?: { ... } + visible_for_operator?: { ... } + hidden_for_targets?: { ... } + hidden_for_operator?: { ... } + } content?: Record design?: Record } @@ -10772,7 +14822,18 @@ type BlockId = string // uuid ```ts type Block = { props?: { - visibility?: Record + visibility?: { + is_hidden?: { ... } + hidden_on_mobile?: { ... } + hidden_on_desktop?: { ... } + hidden_in_app?: { ... } + start_date?: { ... } + end_date?: { ... } + visible_for_targets?: { ... } + visible_for_operator?: { ... } + hidden_for_targets?: { ... } + hidden_for_operator?: { ... } + } content?: Record design?: Record } @@ -10780,6 +14841,9 @@ type Block = { type: string order: number id?: string // uuid + _manifest?: string[] + _lineage_id?: string + _level?: string } ``` @@ -10790,7 +14854,16 @@ type PageRequest = { slug: string path?: string schema?: string[] - visibility?: Record + visibility?: { + is_hidden?: boolean + hidden_in_app?: boolean + start_date?: string // date-time + end_date?: string // date-time + visible_for_targets?: string[] + visible_for_operator?: "and" | "or" + hidden_for_targets?: string[] + hidden_for_operator?: "and" | "or" + } content?: Record design?: Record blocks?: Record order: number is_system?: boolean is_detail?: boolean detail_schema?: string + show_in_navigation?: boolean is_public?: boolean parentId?: string is_entry_route?: boolean @@ -10822,7 +14899,16 @@ type Page = { slug: string path?: string schema?: string[] - visibility?: Record + visibility?: { + is_hidden?: boolean + hidden_in_app?: boolean + start_date?: string // date-time + end_date?: string // date-time + visible_for_targets?: string[] + visible_for_operator?: "and" | "or" + hidden_for_targets?: string[] + hidden_for_operator?: "and" | "or" + } content?: Record design?: Record blocks?: Record order: number is_system?: boolean is_detail?: boolean detail_schema?: string + show_in_navigation?: boolean is_public?: boolean parentId?: string is_entry_route?: boolean is_deleted?: boolean id?: string // uuid last_modified_at?: string // date-time + portal_id?: string + past_routes?: string[] + _manifest?: string[] + _lineage_id?: string + detached_lineage_ids?: string[] +} +``` + +### `PortalHeader` + +Settings of the portal's header bar, stored once per portal. + + +```ts +type PortalHeader = { + design?: { + overrides?: { + components?: { ... } + elements?: { ... } + } + } +} +``` + +### `PortalHeaderDesignOverrides` + +Design overrides scoped to the header bar. Only `components.inputs` and `elements.icon_actions` can be overridden; colours, shape and every other key are refused with a 400 on every write. `null` clears the overrides. + + +```ts +type PortalHeaderDesignOverrides = { + components?: { + inputs?: { + style?: { ... } + color?: { ... } + label_position?: { ... } + } + } + elements?: { + icon_actions?: { + variant?: { ... } + } + } } ``` @@ -10853,6 +14986,43 @@ type Page = { ```ts type CommonConfigAttributesV3 = { + mobile_config?: { + portal_id?: string + enabled?: boolean + display_name?: string + app_host?: string + environment?: "prod" | "staging" | "dev" + branding?: { + app_icon?: { ... } + splash?: { ... } + splash_dark?: { ... } + icon_background_color?: { ... } + splash_background_color?: { ... } + splash_background_color_dark?: { ... } + } + ios?: { + bundle_id?: { ... } + team_id?: { ... } + credentials_status?: { ... } + app_store_id?: { ... } + store_url?: { ... } + last_build?: { ... } + } + android?: { + package_name?: { ... } + credentials_status?: { ... } + upload_key_status?: { ... } + store_url?: { ... } + last_build?: { ... } + } + ota?: { + enabled?: { ... } + channel?: { ... } + auto_update?: { ... } + update_strategy?: { ... } + min_native_version?: { ... } + } + } enabled?: boolean name?: string domain?: string @@ -10864,13 +15034,33 @@ type CommonConfigAttributesV3 = { is_redirection_enabled?: boolean } design_id?: string // uuid + header?: { + design?: { + overrides?: { ... } + } + } + allowed_portal_entities?: string[] self_registration_setting?: "ALLOW_WITH_CONTACT_CREATION" | "ALLOW_WITHOUT_CONTACT_CREATION" | "DENY" | "ALWAYS_CREATE_CONTACT" | "DISALLOW_COMPLETELY" | "BLOCK_IF_PORTAL_USER_EXISTS" + self_registration_account_setting?: "ALLOW_WITH_CREATION" | "DENY" | "ALWAYS_CREATE" | "BLOCK_IF_PORTAL_USER_EXISTS" | "DISALLOW_COMPLETELY" + block_registration_if_portal_user_exists?: boolean + self_registration_entity?: "contact" | "account" user_account_self_management?: boolean feature_settings?: { start_page?: boolean billing?: boolean + commodity_billing?: boolean change_due_date?: boolean new_design?: boolean + mcp_enabled?: boolean + mcp_grant_version?: number + portal_copilot?: boolean + portal_copilot_agent_id?: string + portal_copilot_visibility?: { + visible_for_targets?: { ... } + visible_for_operator?: { ... } + hidden_for_targets?: { ... } + hidden_for_operator?: { ... } + } } accessToken?: string advanced_mfa?: { @@ -10880,78 +15070,21 @@ type CommonConfigAttributesV3 = { passwordless_login?: { enabled?: { ... } } + passkeys?: { + enabled?: { ... } + } entry_point?: "PASSWORD" | "SSO" preferred_sso_providers?: string[] auto_redirect_to_sso?: boolean + prevent_user_enumeration?: boolean } cognito_details?: { cognito_user_pool_client_id?: string + cognito_mobile_client_id?: string cognito_user_pool_arn?: string cognito_user_pool_id?: string - password_policy?: { - minimum_length?: { ... } - maximum_length?: { ... } - require_lowercase?: { ... } - require_uppercase?: { ... } - require_numbers?: { ... } - require_symbols?: { ... } - } - } - config?: string - contact_identifiers?: string[] - approval_state_attributes?: Record - email_templates?: { - confirmAccount?: string // uuid - advancedAuth?: string // uuid - advancedMFA?: string // uuid - journeySignUp?: string // uuid - journeySignInOneTimePassword?: string // uuid - journeyLoginOTP?: string // uuid - forgotPassword?: string // uuid - invitation?: string // uuid - partnerInvitation?: string // uuid - onNewQuote?: string // uuid - onMapAPendingUser?: string // uuid - onDocUpload?: string // uuid - onWorkflowStepAssigned?: string // uuid - confirmEmailUpdate?: string // uuid - verifyCodeToSetPassword?: string // uuid - } - images?: { - orderLeftTeaser?: string - orderRightTeaser?: string - welcomeBanner?: string - } - entity_identifiers?: { - type?: { - isEnabled?: { ... } - attributes?: { ... } - } - } - contract_identifiers?: Array<{ - name?: string - schema?: string - }> - contract_selector_config?: { - show_inactive?: boolean - title_path?: string - } - registration_identifiers?: Array<{ - name?: string - schema?: string - }> - triggered_journeys?: Array<{ - trigger_name?: "FIRST_LOGIN" | "ACCEPT_ORDER" | "DECLINE_ORDER" - journey_id?: string // uuid - }> - entity_edit_rules?: Array<{ - slug?: string - attribute?: string - rule_type?: "cadence" | "relative_to_current_value" | "days_before_date" | "overdue_payments" - cadence_period_type?: "days" | "weeks" | "months" - cadence_period?: number - changes_allowed?: number - grace_period?: number + timeouts?: { + refresh_token?: { ... } // ... } ``` @@ -10964,6 +15097,24 @@ ID of the portal type PortalId = string ``` +### `PortalDataExportColumn` + +One column of the portal data export CSV. + +```ts +type PortalDataExportColumn = { + key: string + header: Record + source: { + path?: string[] + attribute: string + address_field?: "full" | "street" | "street_number" | "postal_code" | "city" | "additional_info" | "country" + } + formatter?: "text" | "date" | "money_cents" | "enum" | "address" + enum_labels?: Record> +} +``` + ### `UpsertPortalConfigV3` ```ts @@ -10997,6 +15148,170 @@ type UpsertPortalConfigV3 = { phone?: { ... } }> } + identity_providers?: Array<{ + slug?: string + display_name: string + provider_type: "OIDC" + attribute_mappings?: { + contact: { ... } + account?: { ... } + portal_user?: { ... } + concession_attributes?: { ... } + } + entity_matching?: { + portal_user?: { ... } + contact?: { ... } + auto_create_cognito_user?: { ... } + } + oidc_config?: { + type?: { ... } + oidc_issuer: { ... } + redirect_uri?: { ... } + client_id: { ... } + client_secret?: { ... } + has_client_secret?: { ... } + scope: { ... } + metadata?: { ... } + prompt?: { ... } + } + mobile_oidc_config?: { + client_id?: { ... } + client_secret?: { ... } + } + expose_client_secret?: boolean + debug_mode_until?: string // date-time + }> + mobile_config?: { + portal_id?: string + enabled?: boolean + display_name?: string + app_host?: string + environment?: "prod" | "staging" | "dev" + branding?: { + app_icon?: { ... } + splash?: { ... } + splash_dark?: { ... } + icon_background_color?: { ... } + splash_background_color?: { ... } + splash_background_color_dark?: { ... } + } + ios?: { + bundle_id?: { ... } + team_id?: { ... } + credentials_status?: { ... } + app_store_id?: { ... } + store_url?: { ... } + last_build?: { ... } + } + android?: { + package_name?: { ... } + credentials_status?: { ... } + upload_key_status?: { ... } + store_url?: { ... } + last_build?: { ... } + } + ota?: { + enabled?: { ... } + channel?: { ... } + auto_update?: { ... } + update_strategy?: { ... } + min_native_version?: { ... } + } + } + // ... +} +``` + +### `PortalConfigV3` + +```ts +type PortalConfigV3 = { + entity_actions?: Array<{ + journey_id?: string // uuid + slug?: string + action_Label?: { + en?: { ... } + de?: { ... } + } + }> + extensions?: Array<{ + id: string + status: "installed" | "enabled" + options?: Record + }> + extension_hooks?: Record + default_user_to_notify?: { + onPendingUser?: Array<{ + type?: { ... } + user_id?: { ... } + display_name?: { ... } + image_uri?: { ... } + org_id?: { ... } + email?: { ... } + phone?: { ... } + }> + } + identity_providers?: Array<{ + slug: string + display_name: string + oidc_config?: { + type?: { ... } + oidc_issuer: { ... } + redirect_uri?: { ... } + client_id: { ... } + client_secret?: { ... } + has_client_secret?: { ... } + scope: { ... } + metadata?: { ... } + prompt?: { ... } + } + mobile_oidc_config?: { + client_id?: { ... } + client_secret?: { ... } + } + debug_mode?: boolean + }> + mobile_config?: { + portal_id?: string + enabled?: boolean + display_name?: string + app_host?: string + environment?: "prod" | "staging" | "dev" + branding?: { + app_icon?: { ... } + splash?: { ... } + splash_dark?: { ... } + icon_background_color?: { ... } + splash_background_color?: { ... } + splash_background_color_dark?: { ... } + } + ios?: { + bundle_id?: { ... } + team_id?: { ... } + credentials_status?: { ... } + app_store_id?: { ... } + store_url?: { ... } + last_build?: { ... } + } + android?: { + package_name?: { ... } + credentials_status?: { ... } + upload_key_status?: { ... } + store_url?: { ... } + last_build?: { ... } + } + ota?: { + enabled?: { ... } + channel?: { ... } + auto_update?: { ... } + update_strategy?: { ... } + min_native_version?: { ... } + } + } enabled?: boolean name?: string domain?: string @@ -11008,73 +15323,192 @@ type UpsertPortalConfigV3 = { is_redirection_enabled?: boolean } design_id?: string // uuid - self_registration_setting?: "ALLOW_WITH_CONTACT_CREATION" | "ALLOW_WITHOUT_CONTACT_CREATION" | "DENY" | "ALWAYS_CREATE_CONTACT" | "DISALLOW_COMPLETELY" | "BLOCK_IF_PORTAL_USER_EXISTS" - user_account_self_management?: boolean - feature_settings?: { - start_page?: boolean - billing?: boolean - change_due_date?: boolean - new_design?: boolean - } - accessToken?: string - advanced_mfa?: { - enabled?: boolean - } - auth_settings?: { - passwordless_login?: { - enabled?: { ... } - } - entry_point?: "PASSWORD" | "SSO" - preferred_sso_providers?: string[] - auto_redirect_to_sso?: boolean + header?: { + design?: { + // ... +} +``` + +### `PortalFeatureSettings` + +Feature settings for the portal + +```ts +type PortalFeatureSettings = { + start_page?: boolean + billing?: boolean + commodity_billing?: boolean + change_due_date?: boolean + new_design?: boolean + mcp_enabled?: boolean + mcp_grant_version?: number + portal_copilot?: boolean + portal_copilot_agent_id?: string + portal_copilot_visibility?: { + visible_for_targets?: string[] + visible_for_operator?: "and" | "or" + hidden_for_targets?: string[] + hidden_for_operator?: "and" | "or" } - cognito_details?: { - cognito_user_pool_client_id?: string - cognito_user_pool_arn?: string - cognito_user_pool_id?: string - password_policy?: { - minimum_length?: { ... } - maximum_length?: { ... } - require_lowercase?: { ... } - require_uppercase?: { ... } - require_numbers?: { ... } - require_symbols?: { ... } - } - } - config?: string - contact_identifiers?: string[] - approval_state_attributes?: Record - email_templates?: { - confirmAccount?: string // uuid - advancedAuth?: string // uuid - advancedMFA?: string // uuid - journeySignUp?: string // uuid - journeySignInOneTimePassword?: string // uuid - journeyLoginOTP?: string // uuid - forgotPassword?: string // uuid - invitation?: string // uuid - partnerInvitation?: string // uuid - onNewQuote?: string // uuid - onMapAPendingUser?: string // uuid - onDocUpload?: string // uuid - onWorkflowStepAssigned?: string // uuid - confirmEmailUpdate?: string // uuid - verifyCodeToSetPassword?: string // uuid +} +``` + +### `PortalCopilotVisibility` + +Limits portal chat to portal users matching targets, with the same rules as page and block visibility. Without targets every signed-in portal user can use the chat. + +```ts +type PortalCopilotVisibility = { + visible_for_targets?: string[] + visible_for_operator?: "and" | "or" + hidden_for_targets?: string[] + hidden_for_operator?: "and" | "or" +} +``` + +### `PortalUsingDesign` + +A portal whose design_id is the design asked about. + +```ts +type PortalUsingDesign = { + portal_id: string + name?: string + origin?: string + design_id?: string +} +``` + +### `PortalConfigSummaryV3` + +Lightweight view of a portal config for lists and pickers. Carries the identifying, +display and registration fields only. Pages, email templates, grants, feature flags, +identity providers and certificate details are left out; read them per portal with +`getPortalConfigV3`. + + +```ts +type PortalConfigSummaryV3 = { + portal_id?: string + organization_id?: string + origin?: string + name?: string + enabled?: boolean + domain?: string + epilot_domain?: string + is_epilot_domain?: boolean + dnsStatus?: "CONFIGURING" | "PENDING" | "SUCCEED" | "EXPIRED" | "NEW_CERT_IN_PROGRESS" + design_id?: string // uuid + logo_image?: { + url?: string + dark_url?: string } - images?: { - orderLeftTeaser?: string - orderRightTeaser?: string - welcomeBanner?: string + default_user_to_notify?: { + onPendingUser?: Array<{ + type?: { ... } + user_id?: { ... } + display_name?: { ... } + image_uri?: { ... } + org_id?: { ... } + email?: { ... } + phone?: { ... } + }> } - entity_identifiers?: { - // ... + feature_settings?: { + start_page?: boolean + billing?: boolean + commodity_billing?: boolean + change_due_date?: boolean + new_design?: boolean + mcp_enabled?: boolean + mcp_grant_version?: number + portal_copilot?: boolean + portal_copilot_agent_id?: string + portal_copilot_visibility?: { + visible_for_targets?: { ... } + visible_for_operator?: { ... } + hidden_for_targets?: { ... } + hidden_for_operator?: { ... } + } + } + self_registration_setting?: "ALLOW_WITH_CONTACT_CREATION" | "ALLOW_WITHOUT_CONTACT_CREATION" | "DENY" | "ALWAYS_CREATE_CONTACT" | "DISALLOW_COMPLETELY" | "BLOCK_IF_PORTAL_USER_EXISTS" + self_registration_account_setting?: "ALLOW_WITH_CREATION" | "DENY" | "ALWAYS_CREATE" | "BLOCK_IF_PORTAL_USER_EXISTS" | "DISALLOW_COMPLETELY" + block_registration_if_portal_user_exists?: boolean + self_registration_entity?: "contact" | "account" + user_account_self_management?: boolean + registration_identifiers?: Array<{ + name?: string + schema?: string + validation_rule_id?: string + }> + surfaces?: Array<{ + id: string + name: string + description?: string + authentication: "login" | "registration_identifiers" + token_ttl_seconds?: number + identifiers?: Array<{ + name?: { ... } + schema?: { ... } + validation_rule_id?: { ... } + }> + data_access?: { + entities?: { ... } + role_id?: { ... } + } + }> + is_dummy?: boolean + is_v3_item?: boolean + published_revision_id?: string + _created_at?: string // date-time + _updated_at?: string // date-time } ``` -### `PortalConfigV3` +### `JuiceSettings` ```ts -type PortalConfigV3 = { +type JuiceSettings = { + is_dummy?: boolean + is_canary?: boolean + is_legacy_design?: boolean + redirect_to?: string + title?: string + prevent_indexing?: boolean + organization_id?: string + design_id?: string + design?: { + background: { + light: { ... } + dark: { ... } + } + accent: { + light: { ... } + dark: { ... } + } + last_modified_at: string + } +} +``` + +### `RevisionPageRequest` + +A page inside a revision snapshot. `additionalProperties` is true on purpose — a page carries fields this schema does not name and they must survive into the snapshot and back onto the live page when it is published. + + +```ts +type RevisionPageRequest = { + id: string // uuid + slug: string + order: number + blocks: Record +} +``` + +### `PortalRevisionRequest` + +```ts +type PortalRevisionRequest = { entity_actions?: Array<{ journey_id?: string // uuid slug?: string @@ -11104,59 +15538,313 @@ type PortalConfigV3 = { phone?: { ... } }> } - enabled?: boolean - name?: string - domain?: string - is_epilot_domain?: boolean - epilot_domain?: string - domain_settings?: { - is_custom_domain_enabled?: boolean - is_epilot_domain_enabled?: boolean - is_redirection_enabled?: boolean - } - design_id?: string // uuid - self_registration_setting?: "ALLOW_WITH_CONTACT_CREATION" | "ALLOW_WITHOUT_CONTACT_CREATION" | "DENY" | "ALWAYS_CREATE_CONTACT" | "DISALLOW_COMPLETELY" | "BLOCK_IF_PORTAL_USER_EXISTS" - user_account_self_management?: boolean - feature_settings?: { - start_page?: boolean - billing?: boolean - change_due_date?: boolean - new_design?: boolean - } - accessToken?: string - advanced_mfa?: { + identity_providers?: Array<{ + slug?: string + display_name: string + provider_type: "OIDC" + attribute_mappings?: { + contact: { ... } + account?: { ... } + portal_user?: { ... } + concession_attributes?: { ... } + } + entity_matching?: { + portal_user?: { ... } + contact?: { ... } + auto_create_cognito_user?: { ... } + } + oidc_config?: { + type?: { ... } + oidc_issuer: { ... } + redirect_uri?: { ... } + client_id: { ... } + client_secret?: { ... } + has_client_secret?: { ... } + scope: { ... } + metadata?: { ... } + prompt?: { ... } + } + mobile_oidc_config?: { + client_id?: { ... } + client_secret?: { ... } + } + expose_client_secret?: boolean + debug_mode_until?: string // date-time + }> + mobile_config?: { + portal_id?: string enabled?: boolean - } - auth_settings?: { - passwordless_login?: { + display_name?: string + app_host?: string + environment?: "prod" | "staging" | "dev" + branding?: { + app_icon?: { ... } + splash?: { ... } + splash_dark?: { ... } + icon_background_color?: { ... } + splash_background_color?: { ... } + splash_background_color_dark?: { ... } + } + ios?: { + bundle_id?: { ... } + team_id?: { ... } + credentials_status?: { ... } + app_store_id?: { ... } + store_url?: { ... } + last_build?: { ... } + } + android?: { + package_name?: { ... } + credentials_status?: { ... } + upload_key_status?: { ... } + store_url?: { ... } + last_build?: { ... } + } + ota?: { enabled?: { ... } + channel?: { ... } + auto_update?: { ... } + update_strategy?: { ... } + min_native_version?: { ... } } - entry_point?: "PASSWORD" | "SSO" - preferred_sso_providers?: string[] - auto_redirect_to_sso?: boolean } - cognito_details?: { - cognito_user_pool_client_id?: string - cognito_user_pool_arn?: string - cognito_user_pool_id?: string - password_policy?: { - minimum_length?: { ... } - maximum_length?: { ... } - require_lowercase?: { ... } - require_uppercase?: { ... } - require_numbers?: { ... } - require_symbols?: { ... } - } - } - config?: string - contact_identifiers?: string[] - approval_state_attributes?: Record + // ... +} +``` + +### `PublishRevisionRequest` + +```ts +type PublishRevisionRequest = { + revision_id: string + name?: string + description?: string + force?: boolean +} +``` + +### `UpdatePortalRevisionRequest` + +```ts +type UpdatePortalRevisionRequest = { + name: string +} +``` + +### `RevisionSource` + +Where a revision came from, when it was not saved in the builder. Not part of the portal config. The builder renders it in the viewer's language for an unnamed revision. + + +```ts +type RevisionSource = { + type: "blueprint_sync" + blueprint_title?: string +} +``` + +### `PortalRevisionSummary` + +```ts +type PortalRevisionSummary = { + revision_id: string + created_at: string // date-time + created_by?: string + name?: string + description?: string + source?: { + type: "blueprint_sync" + blueprint_title?: string + } + page_count: number + published_at?: string // date-time + published_by?: string + is_published: boolean +} +``` + +### `PortalRevisionList` + +```ts +type PortalRevisionList = { + results: Array<{ + revision_id: string + created_at: string // date-time + created_by?: string + name?: string + description?: string + source?: { + type: { ... } + blueprint_title?: { ... } + } + page_count: number + published_at?: string // date-time + published_by?: string + is_published: boolean + }> + next_cursor?: string +} +``` + +### `PortalRevisionCreated` + +```ts +type PortalRevisionCreated = { + revision_id: string + created_at: string // date-time + created_by?: string + name?: string + description?: string + source?: { + type: "blueprint_sync" + blueprint_title?: string + } + page_count: number + published_at?: string // date-time + published_by?: string + is_published: boolean + identity_providers?: Array<{ + slug?: string + display_name: string + provider_type: "OIDC" + attribute_mappings?: { + contact: { ... } + account?: { ... } + portal_user?: { ... } + concession_attributes?: { ... } + } + entity_matching?: { + portal_user?: { ... } + contact?: { ... } + auto_create_cognito_user?: { ... } + } + oidc_config?: { + type?: { ... } + oidc_issuer: { ... } + redirect_uri?: { ... } + client_id: { ... } + client_secret?: { ... } + has_client_secret?: { ... } + scope: { ... } + metadata?: { ... } + prompt?: { ... } + } + mobile_oidc_config?: { + client_id?: { ... } + client_secret?: { ... } + } + expose_client_secret?: boolean + debug_mode_until?: string // date-time + }> + published?: { + revision_id: string + published_at: string // date-time + published_by?: string + name?: string + post_publish_warnings: string[] + held_back?: Array<{ + page_id: { ... } + block_id?: { ... } + reason: { ... } + }> + } +} +``` + +### `RevisionPage` + +A page from a revision snapshot. Same shape as a live `Page`, without the server-managed fields (`past_routes`, `_created_at`, `_updated_at`, `is_deleted`), which publish re-derives from the live portal. + + +```ts +type RevisionPage = { + org_id?: string +} +``` + +### `PortalRevisionPreview` + +```ts +type PortalRevisionPreview = { + preview_token: string + expires_at: string // date-time + url: string +} +``` + +### `PreviewRevision` + +The revision a config response shows instead of the live portal config. + +```ts +type PreviewRevision = { + revision_id: string + name?: string + created_at: string // date-time +} +``` + +### `PortalRevision` + +```ts +type PortalRevision = { + revision_id: string + created_at: string // date-time + created_by?: string + name?: string + description?: string + source?: { + type: "blueprint_sync" + blueprint_title?: string + } + page_count: number + published_at?: string // date-time + published_by?: string + is_published: boolean + config: Record + pages: Array<{ + org_id?: string + }> + identity_providers?: Array<{ + slug?: string + display_name: string + provider_type: "OIDC" + attribute_mappings?: { + contact: { ... } + account?: { ... } + portal_user?: { ... } + concession_attributes?: { ... } + } + entity_matching?: { + portal_user?: { ... } + contact?: { ... } + auto_create_cognito_user?: { ... } + } + oidc_config?: { + type?: { ... } + oidc_issuer: { ... } + redirect_uri?: { ... } + client_id: { ... } + client_secret?: { ... } + has_client_secret?: { ... } + scope: { ... } + metadata?: { ... } + prompt?: { ... } + } + mobile_oidc_config?: { + client_id?: { ... } + client_secret?: { ... } + } + expose_client_secret?: boolean + debug_mode_until?: string // date-time + }> email_templates?: { confirmAccount?: string // uuid advancedAuth?: string // uuid advancedMFA?: string // uuid journeySignUp?: string // uuid journeySignInOneTimePassword?: string // uuid + passkeyVerificationCode?: string // uuid journeyLoginOTP?: string // uuid forgotPassword?: string // uuid invitation?: string // uuid @@ -11168,30 +15856,103 @@ type PortalConfigV3 = { confirmEmailUpdate?: string // uuid verifyCodeToSetPassword?: string // uuid } - images?: { - orderLeftTeaser?: string - orderRightTeaser?: string - welcomeBanner?: string - } - entity_identifiers?: { - // ... + email_template_settings?: Record } ``` -### `JuiceSettings` +### `PublishResult` ```ts -type JuiceSettings = { - is_dummy?: boolean - is_canary?: boolean - redirect_to?: string +type PublishResult = { + revision_id: string + published_at: string // date-time + published_by?: string + name?: string + post_publish_warnings: string[] + held_back?: Array<{ + page_id: string + block_id?: string + reason: "BLUEPRINT_MANAGED" + }> } ``` ### `SwappableConfig` +Optional configuration item that a portal swap can additionally include. The swap always transfers the pages and the functional experience config that keep the portal working. These items are opt-in on top of that and are OFF by default. Domain and access/security settings (domain, cognito_details, + +```ts +type SwappableConfig = "email_templates" | "portal_references" +``` + +### `SwapPortalReferencesResult` + +Outcome of the `portal_references` swap option. Only present when that option was requested. The swap itself has already succeeded when this is returned, so failures here do not undo it. + +```ts +type SwapPortalReferencesResult = { + journeys: { + updated: Array<{ + id: { ... } + name?: { ... } + paths?: { ... } + error?: { ... } + }> + failed: Array<{ + id: { ... } + name?: { ... } + paths?: { ... } + error?: { ... } + }> + list_error?: string + } + automation_flows: { + updated: Array<{ + id: { ... } + name?: { ... } + paths?: { ... } + error?: { ... } + }> + failed: Array<{ + id: { ... } + name?: { ... } + paths?: { ... } + error?: { ... } + }> + list_error?: string + } +} +``` + +### `SwapPortalReferenceGroup` + +```ts +type SwapPortalReferenceGroup = { + updated: Array<{ + id: string + name?: string + paths?: string[] + error?: string + }> + failed: Array<{ + id: string + name?: string + paths?: string[] + error?: string + }> + list_error?: string +} +``` + +### `SwapPortalReferenceItem` + ```ts -type SwappableConfig = "all" | "domain" | "users" | "email_templates" +type SwapPortalReferenceItem = { + id: string + name?: string + paths?: string[] + error?: string +} ``` ### `PortalUserRegistrationStatus` @@ -11214,3 +15975,80 @@ type BusinessPartnerItem = { access_status?: boolean } ``` + +### `SupportReportType` + +```ts +type SupportReportType = "bug" | "feedback" +``` + +### `SupportRequestAttachment` + +```ts +type SupportRequestAttachment = { + filename: string + mime_type: string + contents: string +} +``` + +### `CleverPvContext` + +```ts +type CleverPvContext = { + screen?: string + version?: string + connection_state?: string + locale?: string + timezone?: string + firmware_version?: string + build?: string + trace_id?: string + device?: Record + vendor?: { + id?: string + name?: string + } +} +``` + +### `CreateSupportRequest` + +```ts +type CreateSupportRequest = { + report_type: "bug" | "feedback" + description: string + submission_id: string + site_id?: string // uuid + device_id?: string // uuid + clever_pv?: { + screen?: string + version?: string + connection_state?: string + locale?: string + timezone?: string + firmware_version?: string + build?: string + trace_id?: string + device?: Record + vendor?: { + id?: { ... } + name?: { ... } + } + } + attachments?: Array<{ + filename: string + mime_type: string + contents: string + }> +} +``` + +### `SupportRequestResult` + +```ts +type SupportRequestResult = { + reference: string + status: string +} +``` diff --git a/docs/sdk/clients/dashboard.md b/docs/sdk/clients/dashboard.md index eb024b09..cf38c259 100644 --- a/docs/sdk/clients/dashboard.md +++ b/docs/sdk/clients/dashboard.md @@ -32,10 +32,23 @@ const { data } = await dashboardClient.listDashboards(...) **Dashboards** - [`listDashboards`](#listdashboards) - [`createDashboard`](#createdashboard) +- [`listFavoriteDashboardIds`](#listfavoritedashboardids) +- [`favoriteDashboard`](#favoritedashboard) +- [`unfavoriteDashboard`](#unfavoritedashboard) - [`getDashboard`](#getdashboard) - [`putDashboard`](#putdashboard) +- [`patchDashboard`](#patchdashboard) - [`deleteDashboard`](#deletedashboard) +**Insights** +- [`listInsights`](#listinsights) +- [`createInsight`](#createinsight) +- [`listInsightTags`](#listinsighttags) +- [`getInsight`](#getinsight) +- [`putInsight`](#putinsight) +- [`patchInsight`](#patchinsight) +- [`deleteInsight`](#deleteinsight) + **Visualisations** - [`listAvailableVisualisations`](#listavailablevisualisations) @@ -46,6 +59,17 @@ const { data } = await dashboardClient.listDashboards(...) - [`DashboardID`](#dashboardid) - [`Dashboard`](#dashboard) - [`DashboardTileID`](#dashboardtileid) +- [`SharePermission`](#sharepermission) +- [`ShareGrant`](#sharegrant) +- [`OrgAccess`](#orgaccess) +- [`AccessControl`](#accesscontrol) +- [`AccessControlUpdate`](#accesscontrolupdate) +- [`DashboardPatch`](#dashboardpatch) +- [`InsightID`](#insightid) +- [`Insight`](#insight) +- [`InsightPatch`](#insightpatch) +- [`Tags`](#tags) +- [`Pagination`](#pagination) - [`DashboardTile`](#dashboardtile) - [`VisualisationConfig`](#visualisationconfig) - [`timechartVisualisationConfig`](#timechartvisualisationconfig) @@ -62,7 +86,23 @@ List dashboards available to the user `GET /v1/dashboard/dashboards` ```ts -const { data } = await client.listDashboards() +const { data } = await client.listDashboards({ + q: 'example', + created_by: 'example', + created_after: 'example', + created_before: 'example', + updated_after: 'example', + updated_before: 'example', + shared_with: ['...'], + owner: ['...'], + accessible_to: 'example', + favorite: true, + favorites_first: true, + sort: 'example', + order: 'example', + limit: 1, + offset: 1, +}) ```
@@ -72,42 +112,37 @@ const { data } = await client.listDashboards() { "results": [ { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false } - ] + ], + "pagination": { + "total": 0, + "limit": 0, + "offset": 0, + "has_more": true + } } ``` @@ -125,40 +160,29 @@ Create new dashboard const { data } = await client.createDashboard( null, { + created_by: '10598', + created_at: '1970-01-01T00:00:00.000Z', + updated_by: '10598', + updated_at: '1970-01-01T00:00:00.000Z', + owner_org_id: '739224', + owners: ['10598'], + shared_with: [ + { + user_id: '10598', + permission: 'view' + } + ], + org_access: 'view', id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', title: 'Employee Dashboard', tiles: [ { id: 'e4af1297-1fd6-440f-9846-f475f580d40f', coordinates: {}, - visualisation: 'timechart', - visualisation_config: { - query: { - dataset: 'entity_operations', - measure: 'count_operations', - filters: [ - { - operation: ['createEntity'] - }, - { - entity_schema: ['opportunity'] - } - ], - dimensions: [ - { - time_with_granularity: 'month' - }, - { - entity_attribute: 'source.title' - } - ] - }, - options: { - type: 'line' - } - } + insight_id: '8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e' } - ] + ], + favorited: false }, ) ``` @@ -168,40 +192,55 @@ const { data } = await client.createDashboard( ```json { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false +} +``` + +
+ +--- + +### `listFavoriteDashboardIds` + +Returns the current user's favorited dashboard ids, with no dashboard metadata. Lets a +client decide whether to default to a favorites-only view without first fetching the full +dashboards list. + +`GET /v1/dashboard/dashboards/favorites` + +```ts +const { data } = await client.listFavoriteDashboardIds() +``` + +
+Response + +```json +{ + "dashboard_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"], + "total": 0 } ``` @@ -209,6 +248,38 @@ const { data } = await client.createDashboard( --- +### `favoriteDashboard` + +Marks the dashboard as favorited by the current user. Idempotent — favoriting an +already-favorited dashboard is not an error. Requires only view-level access to the +dashboard (unlike the edit-level ch + +`PUT /v1/dashboard/dashboards/{id}/favorite` + +```ts +const { data } = await client.favoriteDashboard({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `unfavoriteDashboard` + +Removes the current user's favorite for the dashboard. Idempotent — unfavoriting a +dashboard that was not favorited is not an error, and neither is unfavoriting one that no +longer exists or is no long + +`DELETE /v1/dashboard/dashboards/{id}/favorite` + +```ts +const { data } = await client.unfavoriteDashboard({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + ### `getDashboard` Get dashboard by ID @@ -226,40 +297,29 @@ const { data } = await client.getDashboard({ ```json { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false } ``` @@ -279,36 +339,115 @@ const { data } = await client.putDashboard( id: '123e4567-e89b-12d3-a456-426614174000', }, { + created_by: '10598', + created_at: '1970-01-01T00:00:00.000Z', + updated_by: '10598', + updated_at: '1970-01-01T00:00:00.000Z', + owner_org_id: '739224', + owners: ['10598'], + shared_with: [ + { + user_id: '10598', + permission: 'view' + } + ], + org_access: 'view', id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', title: 'Employee Dashboard', tiles: [ { id: 'e4af1297-1fd6-440f-9846-f475f580d40f', coordinates: {}, - visualisation: 'timechart', + insight_id: '8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e' + } + ], + favorited: false + }, +) +``` + +
+Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "Employee Dashboard", + "tiles": [ + { + "id": "e4af1297-1fd6-440f-9846-f475f580d40f", + "coordinates": {}, + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" + } + ], + "favorited": false +} +``` + +
+ +--- + +### `patchDashboard` + +Partially update a dashboard by ID. Update content (title/tiles) and/or manage sharing +(owners, shared_with, org_access) — only owners may change sharing. +`owners` and `shared_with` replace the whole + +`PATCH /v1/dashboard/dashboards/{id}` + +```ts +const { data } = await client.patchDashboard( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + owners: ['string'], + shared_with: [ + { + user_id: '10598', + permission: 'view' + } + ], + org_access: 'view', + title: 'Employee Dashboard', + tiles: [ + { + id: 'e4af1297-1fd6-440f-9846-f475f580d40f', + coordinates: {}, + title: 'Number of opportunities created by journeys every month', + insight_id: '8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e', + visualisation_id: 'timechart', visualisation_config: { query: { dataset: 'entity_operations', measure: 'count_operations', - filters: [ - { - operation: ['createEntity'] - }, + dimensions: [ { - entity_schema: ['opportunity'] + time_with_granularity: 'year-month' } ], - dimensions: [ - { - time_with_granularity: 'month' - }, + filters: [ { - entity_attribute: 'source.title' + entity_schema: 'opportunity' } ] }, options: { - type: 'line' + type: 'bar' } } } @@ -322,40 +461,29 @@ const { data } = await client.putDashboard( ```json { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", - "visualisation_config": { - "query": { - "dataset": "entity_operations", - "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, - { - "entity_schema": ["opportunity"] - } - ], - "dimensions": [ - { - "time_with_granularity": "month" - }, - { - "entity_attribute": "source.title" - } - ] - }, - "options": { - "type": "line" - } - } + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" } - ] + ], + "favorited": false } ``` @@ -380,40 +508,115 @@ const { data } = await client.deleteDashboard({ ```json { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Employee Dashboard", "tiles": [ { "id": "e4af1297-1fd6-440f-9846-f475f580d40f", "coordinates": {}, - "visualisation": "timechart", + "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e" + } + ], + "favorited": false +} +``` + +
+ +--- + +### `listInsights` + +List insights (saved charts) available to the user + +`GET /v1/dashboard/insights` + +```ts +const { data } = await client.listInsights({ + q: 'example', + visualisation_id: ['...'], + tags: ['...'], + tags_match: 'example', + created_by: 'example', + created_after: 'example', + created_before: 'example', + updated_after: 'example', + updated_before: 'example', + shared_with: ['...'], + owner: ['...'], + accessible_to: 'example', + sort: 'example', + order: 'example', + limit: 1, + offset: 1, +}) +``` + +
+Response + +```json +{ + "results": [ + { + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", "visualisation_config": { "query": { "dataset": "entity_operations", "measure": "count_operations", - "filters": [ - { - "operation": ["createEntity"] - }, + "dimensions": [ { - "entity_schema": ["opportunity"] + "time_with_granularity": "year-month" } ], - "dimensions": [ - { - "time_with_granularity": "month" - }, + "filters": [ { - "entity_attribute": "source.title" + "entity_schema": "opportunity" } ] }, "options": { - "type": "line" + "type": "bar" } - } + }, + "tags": ["revenue", "marketing"] } - ] + ], + "pagination": { + "total": 0, + "limit": 0, + "offset": 0, + "has_more": true + } } ``` @@ -421,14 +624,55 @@ const { data } = await client.deleteDashboard({ --- -### `listAvailableVisualisations` +### `createInsight` -Returns list of available Visualisations to configure new dashboard tiles +Create a new insight (saved chart). The caller becomes the owner. -`GET /v1/dashboard/visualisations` +`POST /v1/dashboard/insights` ```ts -const { data } = await client.listAvailableVisualisations() +const { data } = await client.createInsight( + null, + { + created_by: '10598', + created_at: '1970-01-01T00:00:00.000Z', + updated_by: '10598', + updated_at: '1970-01-01T00:00:00.000Z', + owner_org_id: '739224', + owners: ['10598'], + shared_with: [ + { + user_id: '10598', + permission: 'view' + } + ], + org_access: 'view', + id: '8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e', + name: 'Opportunities created by journeys every month', + description: 'Monthly count of opportunities grouped by source journey', + visualisation_id: 'timechart', + visualisation_config: { + query: { + dataset: 'entity_operations', + measure: 'count_operations', + dimensions: [ + { + time_with_granularity: 'year-month' + } + ], + filters: [ + { + entity_schema: 'opportunity' + } + ] + }, + options: { + type: 'bar' + } + }, + tags: ['revenue', 'marketing'] + }, +) ```
@@ -436,20 +680,43 @@ const { data } = await client.listAvailableVisualisations() ```json { - "results": [ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ { - "visualisation": "timechart", - "title": "Time Series Visualisation", - "description": "Visualise your metrics with respect to time series", - "package_name": "@epilot360/highcharts" + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] }, - { - "visualisation": "kpi", - "title": "KPI Visualisation", - "description": "Visualise your key performance indicators", - "package_name": "@epilot360/kpi" + "options": { + "type": "bar" } - ] + }, + "tags": ["revenue", "marketing"] } ``` @@ -457,7 +724,388 @@ const { data } = await client.listAvailableVisualisations() --- -### `listAvailableExamples` +### `listInsightTags` + +List the distinct tags used by insights in the organization (for filter facets) + +`GET /v1/dashboard/insights/tags` + +```ts +const { data } = await client.listInsightTags() +``` + +
+Response + +```json +{ + "results": ["string"] +} +``` + +
+ +--- + +### `getInsight` + +Get insight by ID + +`GET /v1/dashboard/insights/{id}` + +```ts +const { data } = await client.getInsight({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +} +``` + +
+ +--- + +### `putInsight` + +Replace an insight's content by ID. Sharing is managed via patchInsight. + +`PUT /v1/dashboard/insights/{id}` + +```ts +const { data } = await client.putInsight( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + created_by: '10598', + created_at: '1970-01-01T00:00:00.000Z', + updated_by: '10598', + updated_at: '1970-01-01T00:00:00.000Z', + owner_org_id: '739224', + owners: ['10598'], + shared_with: [ + { + user_id: '10598', + permission: 'view' + } + ], + org_access: 'view', + id: '8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e', + name: 'Opportunities created by journeys every month', + description: 'Monthly count of opportunities grouped by source journey', + visualisation_id: 'timechart', + visualisation_config: { + query: { + dataset: 'entity_operations', + measure: 'count_operations', + dimensions: [ + { + time_with_granularity: 'year-month' + } + ], + filters: [ + { + entity_schema: 'opportunity' + } + ] + }, + options: { + type: 'bar' + } + }, + tags: ['revenue', 'marketing'] + }, +) +``` + +
+Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +} +``` + +
+ +--- + +### `patchInsight` + +Partially update an insight by ID. Update content (name/description/visualisation/tags) and/or +manage sharing (owners, shared_with, org_access) — only owners may change sharing. +`owners` and `shared_w + +`PATCH /v1/dashboard/insights/{id}` + +```ts +const { data } = await client.patchInsight( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + owners: ['string'], + shared_with: [ + { + user_id: '10598', + permission: 'view' + } + ], + org_access: 'view', + name: 'string', + description: 'string', + visualisation_id: 'timechart', + visualisation_config: { + query: { + dataset: 'entity_operations', + measure: 'count_operations', + dimensions: [ + { + time_with_granularity: 'year-month' + } + ], + filters: [ + { + entity_schema: 'opportunity' + } + ] + }, + options: { + type: 'bar' + } + }, + tags: ['revenue', 'marketing'] + }, +) +``` + +
+Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +} +``` + +
+ +--- + +### `deleteInsight` + +Delete an insight by ID. Only owners may delete. + +`DELETE /v1/dashboard/insights/{id}` + +```ts +const { data } = await client.deleteInsight({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "created_by": "10598", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_by": "10598", + "updated_at": "1970-01-01T00:00:00.000Z", + "owner_org_id": "739224", + "owners": ["10598"], + "shared_with": [ + { + "user_id": "10598", + "permission": "view" + } + ], + "org_access": "view", + "id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e", + "name": "Opportunities created by journeys every month", + "description": "Monthly count of opportunities grouped by source journey", + "visualisation_id": "timechart", + "visualisation_config": { + "query": { + "dataset": "entity_operations", + "measure": "count_operations", + "dimensions": [ + { + "time_with_granularity": "year-month" + } + ], + "filters": [ + { + "entity_schema": "opportunity" + } + ] + }, + "options": { + "type": "bar" + } + }, + "tags": ["revenue", "marketing"] +} +``` + +
+ +--- + +### `listAvailableVisualisations` + +Returns list of available Visualisations to configure new dashboard tiles + +`GET /v1/dashboard/visualisations` + +```ts +const { data } = await client.listAvailableVisualisations() +``` + +
+Response + +```json +{ + "results": [ + { + "visualisation": "timechart", + "title": "Time Series Visualisation", + "description": "Visualise your metrics with respect to time series", + "package_name": "@epilot360/highcharts" + }, + { + "visualisation": "kpi", + "title": "KPI Visualisation", + "description": "Visualise your key performance indicators", + "package_name": "@epilot360/kpi" + } + ] +} +``` + +
+ +--- + +### `listAvailableExamples` Returns list of available exampless for visualisations to configure new dashboard tiles @@ -512,22 +1160,38 @@ type DashboardID = string // uuid ### `Dashboard` -Adashboard configuration with tiles +A dashboard configuration. A dashboard is a canvas whose tiles arrange and +position insights (saved charts). Tiles may reference an insight by `insight_id` +or, for backwards compatibility, embed a visualisation inline. + ```ts type Dashboard = { + created_by?: string + created_at?: string // date-time + updated_by?: string + updated_at?: string // date-time + owner_org_id?: string + owners?: string[] + shared_with?: Array<{ + user_id: string + permission: "view" | "edit" + }> + org_access?: "view" | "edit" | null id?: string // uuid title: string tiles: Array<{ id?: string // uuid coordinates?: object title?: string + insight_id?: string // uuid visualisation_id?: "kpi" | "funnel" | "toplist" | "timechart" | "pie" | "bar" | "entity_list" | "markdown" | "news_feed" | "workflow" visualisation_config?: { query?: { ... } options?: { ... } } }> + favorited?: boolean } ``` @@ -539,13 +1203,213 @@ Unique identifier for a tile in a dashboard type DashboardTileID = string // uuid ``` +### `SharePermission` + +Permission level granted to a user (or the whole organization) on a shared resource. +`view` allows read-only access; `edit` additionally allows updating the content. +Full control (delete and managing sharing) is reserved for owners. + + +```ts +type SharePermission = "view" | "edit" +``` + +### `ShareGrant` + +Grants a single user a permission level on a resource + +```ts +type ShareGrant = { + user_id: string + permission: "view" | "edit" +} +``` + +### `OrgAccess` + +Optional organization-wide grant. When set, every user in the resource's organization +is granted this permission level. `null` (or omitted) means the resource is not shared +org-wide. + + +```ts +type OrgAccess = "view" | "edit" | null +``` + +### `AccessControl` + +Ownership and sharing metadata common to dashboards and insights. `created_*`/`updated_*` +fields are managed by the server. `owners`, `shared_with` and `org_access` describe who +may access the resource. New resources are private to their creator until shared. + + +```ts +type AccessControl = { + created_by?: string + created_at?: string // date-time + updated_by?: string + updated_at?: string // date-time + owner_org_id?: string + owners?: string[] + shared_with?: Array<{ + user_id: string + permission: "view" | "edit" + }> + org_access?: "view" | "edit" | null +} +``` + +### `AccessControlUpdate` + +Sharing fields that can be mutated via PATCH (owners only). `owners` and `shared_with` are +full replacements of their arrays, not merges — omit a field to leave it unchanged. + + +```ts +type AccessControlUpdate = { + owners?: string[] + shared_with?: Array<{ + user_id: string + permission: "view" | "edit" + }> + org_access?: "view" | "edit" | null +} +``` + +### `DashboardPatch` + +Fields that can be partially updated on a dashboard + +```ts +type DashboardPatch = { + owners?: string[] + shared_with?: Array<{ + user_id: string + permission: "view" | "edit" + }> + org_access?: "view" | "edit" | null + title?: string + tiles?: Array<{ + id?: string // uuid + coordinates?: object + title?: string + insight_id?: string // uuid + visualisation_id?: "kpi" | "funnel" | "toplist" | "timechart" | "pie" | "bar" | "entity_list" | "markdown" | "news_feed" | "workflow" + visualisation_config?: { + query?: { ... } + options?: { ... } + } + }> +} +``` + +### `InsightID` + +Unique identifier for an insight (a saved chart / visualisation) + +```ts +type InsightID = string // uuid +``` + +### `Insight` + +An insight is a saved, reusable chart definition (a visualisation plus its query/options). +Insights exist independently of dashboards: they can be created, shared and edited on their +own, and referenced by one or more dashboard tiles via `insight_id`. + + +```ts +type Insight = { + created_by?: string + created_at?: string // date-time + updated_by?: string + updated_at?: string // date-time + owner_org_id?: string + owners?: string[] + shared_with?: Array<{ + user_id: string + permission: "view" | "edit" + }> + org_access?: "view" | "edit" | null + id?: string // uuid + name: string + description?: string + visualisation_id: "kpi" | "funnel" | "toplist" | "timechart" | "pie" | "bar" | "entity_list" | "markdown" | "news_feed" | "workflow" + visualisation_config?: { + query?: { + dataset?: { ... } + measure?: { ... } + dimensions?: { ... } + filters?: { ... } + } + options?: Record + } + tags?: string[] +} +``` + +### `InsightPatch` + +Fields that can be partially updated on an insight + +```ts +type InsightPatch = { + owners?: string[] + shared_with?: Array<{ + user_id: string + permission: "view" | "edit" + }> + org_access?: "view" | "edit" | null + name?: string + description?: string + visualisation_id?: "kpi" | "funnel" | "toplist" | "timechart" | "pie" | "bar" | "entity_list" | "markdown" | "news_feed" | "workflow" + visualisation_config?: { + query?: { + dataset?: { ... } + measure?: { ... } + dimensions?: { ... } + filters?: { ... } + } + options?: Record + } + tags?: string[] +} +``` + +### `Tags` + +Free-form labels for grouping and filtering insights + +```ts +type Tags = string[] +``` + +### `Pagination` + +Offset-based pagination metadata for list responses + +```ts +type Pagination = { + total: number + limit: number + offset: number + has_more: boolean +} +``` + ### `DashboardTile` +A positioned tile on a dashboard canvas. A tile references a saved insight via +`insight_id`. Inline `visualisation_id`/`visualisation_config` remain supported for +backwards compatibility (ad-hoc tiles that are not backed by a shared insight). + + ```ts type DashboardTile = { id?: string // uuid coordinates?: object title?: string + insight_id?: string // uuid visualisation_id?: "kpi" | "funnel" | "toplist" | "timechart" | "pie" | "bar" | "entity_list" | "markdown" | "news_feed" | "workflow" visualisation_config?: { query?: { diff --git a/docs/sdk/clients/data-governance.md b/docs/sdk/clients/data-governance.md index d41823bf..87c47c74 100644 --- a/docs/sdk/clients/data-governance.md +++ b/docs/sdk/clients/data-governance.md @@ -29,17 +29,21 @@ const { data } = await dataGovernanceClient.queryEntities(...) ## Operations -**Data Governance** +**Query** - [`queryEntities`](#queryentities) + +**Auditable Jobs** - [`createJob`](#createjob) - [`updateJob`](#updatejob) - [`getJob`](#getjob) - [`getJobReportUrl`](#getjobreporturl) -- [`getConfig`](#getconfig) - [`createJobForConfig`](#createjobforconfig) +- [`listJobs`](#listjobs) + +**Data Lifecycle Configs** +- [`getConfig`](#getconfig) - [`upsertConfig`](#upsertconfig) - [`listConfigs`](#listconfigs) -- [`listJobs`](#listjobs) **Schemas** - [`ConfigType`](#configtype) @@ -67,7 +71,7 @@ const { data } = await dataGovernanceClient.queryEntities(...) ### `queryEntities` -Query entities using a saved view with additional data filters +Query entities matching a data lifecycle config `POST /data-governance/v1/{entity_schema}/query` @@ -83,7 +87,9 @@ const { data } = await client.queryEntities( { type: 'entity_workflows_only_in_closed_or_cancelled_status', related_entity_schemas: ['string'], - lookback_period_days: 0 + lookback_period_days: 0, + message_type: ['SENT'], + workflow_status: ['CLOSED'] } ], from: 0, @@ -124,7 +130,7 @@ const { data } = await client.createJob( { type: 'deletion', config_id: 'string', - scheduled_for: 'string', + scheduled_for: '1970-01-01', status: 'in_progress', started_at: '1970-01-01T00:00:00.000Z' }, @@ -140,7 +146,7 @@ const { data } = await client.createJob( "type": "deletion", "config_id": "string", "entity_schema": "string", - "scheduled_for": "string", + "scheduled_for": "1970-01-01", "status": "in_progress", "details": {}, "started_at": "1970-01-01T00:00:00.000Z", @@ -197,7 +203,7 @@ const { data } = await client.updateJob( "type": "deletion", "config_id": "string", "entity_schema": "string", - "scheduled_for": "string", + "scheduled_for": "1970-01-01", "status": "in_progress", "details": {}, "started_at": "1970-01-01T00:00:00.000Z", @@ -221,7 +227,7 @@ const { data } = await client.updateJob( ### `getJob` -Get a job by id +Get a job by ID `GET /data-governance/v1/jobs/{job_id}` @@ -240,7 +246,7 @@ const { data } = await client.getJob({ "type": "deletion", "config_id": "string", "entity_schema": "string", - "scheduled_for": "string", + "scheduled_for": "1970-01-01", "status": "in_progress", "details": {}, "started_at": "1970-01-01T00:00:00.000Z", @@ -290,7 +296,7 @@ const { data } = await client.getJobReportUrl({ ### `getConfig` -Get a config by id +Get a config by ID `GET /data-governance/v1/configs/{config_id}` @@ -315,20 +321,22 @@ const { data } = await client.getConfig({ { "type": "entity_workflows_only_in_closed_or_cancelled_status", "related_entity_schemas": ["string"], - "lookback_period_days": 0 + "lookback_period_days": 0, + "message_type": ["SENT"], + "workflow_status": ["CLOSED"] } ] }, "schedule": { "frequency": "interval", "interval_days": 1, - "start_date": "string", - "end_date": "string" + "start_date": "1970-01-01", + "end_date": "1970-01-01" }, "enabled": true, "created_at": "1970-01-01T00:00:00.000Z", "last_updated_at": "1970-01-01T00:00:00.000Z", - "next_run_at": "string", + "next_run_at": "1970-01-01", "relations_for_deletion": ["contact"], "last_run_at": "1970-01-01T00:00:00.000Z" } @@ -359,7 +367,7 @@ const { data } = await client.createJobForConfig({ "type": "deletion", "config_id": "string", "entity_schema": "string", - "scheduled_for": "string", + "scheduled_for": "1970-01-01", "status": "in_progress", "details": {}, "started_at": "1970-01-01T00:00:00.000Z", @@ -383,7 +391,7 @@ const { data } = await client.createJobForConfig({ ### `upsertConfig` -Upsert config +Create or update a data lifecycle config `POST /data-governance/v1/{entity_schema}/configs` @@ -401,15 +409,17 @@ const { data } = await client.upsertConfig( { type: 'entity_workflows_only_in_closed_or_cancelled_status', related_entity_schemas: ['string'], - lookback_period_days: 0 + lookback_period_days: 0, + message_type: ['SENT'], + workflow_status: ['CLOSED'] } ] }, schedule: { frequency: 'interval', interval_days: 1, - start_date: 'string', - end_date: 'string' + start_date: '1970-01-01', + end_date: '1970-01-01' }, relations_for_deletion: ['contact'], enabled: true @@ -432,20 +442,22 @@ const { data } = await client.upsertConfig( { "type": "entity_workflows_only_in_closed_or_cancelled_status", "related_entity_schemas": ["string"], - "lookback_period_days": 0 + "lookback_period_days": 0, + "message_type": ["SENT"], + "workflow_status": ["CLOSED"] } ] }, "schedule": { "frequency": "interval", "interval_days": 1, - "start_date": "string", - "end_date": "string" + "start_date": "1970-01-01", + "end_date": "1970-01-01" }, "enabled": true, "created_at": "1970-01-01T00:00:00.000Z", "last_updated_at": "1970-01-01T00:00:00.000Z", - "next_run_at": "string", + "next_run_at": "1970-01-01", "relations_for_deletion": ["contact"], "last_run_at": "1970-01-01T00:00:00.000Z" } @@ -457,7 +469,7 @@ const { data } = await client.upsertConfig( ### `listConfigs` -List configs +List data lifecycle configs `GET /data-governance/v1/configs` @@ -489,20 +501,22 @@ const { data } = await client.listConfigs({ { "type": "entity_workflows_only_in_closed_or_cancelled_status", "related_entity_schemas": ["string"], - "lookback_period_days": 0 + "lookback_period_days": 0, + "message_type": ["SENT"], + "workflow_status": ["CLOSED"] } ] }, "schedule": { "frequency": "interval", "interval_days": 1, - "start_date": "string", - "end_date": "string" + "start_date": "1970-01-01", + "end_date": "1970-01-01" }, "enabled": true, "created_at": "1970-01-01T00:00:00.000Z", "last_updated_at": "1970-01-01T00:00:00.000Z", - "next_run_at": "string", + "next_run_at": "1970-01-01", "relations_for_deletion": ["contact"], "last_run_at": "1970-01-01T00:00:00.000Z" } @@ -517,7 +531,7 @@ const { data } = await client.listConfigs({ ### `listJobs` -List jobs +List job runs `GET /data-governance/v1/jobs` @@ -543,7 +557,7 @@ const { data } = await client.listJobs({ "type": "deletion", "config_id": "string", "entity_schema": "string", - "scheduled_for": "string", + "scheduled_for": "1970-01-01", "status": "in_progress", "details": {}, "started_at": "1970-01-01T00:00:00.000Z", @@ -572,7 +586,9 @@ const { data } = await client.listJobs({ ### `ConfigType` -Type of configuration (e.g. deletion) +The governance action type. Determines what operation is performed on +matched entities when a job runs. Currently only `deletion` is supported. + ```ts type ConfigType = "deletion" @@ -580,24 +596,41 @@ type ConfigType = "deletion" ### `JobStatus` +Current execution status of a job run. +- `in_progress` — the job is actively processing entities. +- `success` — the job completed without critical errors. +- `failed` — the job terminated due to an error. + + ```ts type JobStatus = "in_progress" | "success" | "failed" ``` ### `JobTrigger` +Indicates how the job was initiated. +- `schedule` — automatically created by the background scheduler. +- `manual` — explicitly triggered by a user via the API. + + ```ts type JobTrigger = "schedule" | "manual" ``` ### `JobReportFormat` +File format of the job report. Currently only CSV is supported. + ```ts type JobReportFormat = "csv" ``` ### `JobReport` +Reference to a report file stored in S3 that details the outcome of a +job run (e.g., which entities were deleted or failed). + + ```ts type JobReport = { bucket?: string @@ -608,6 +641,8 @@ type JobReport = { ### `CreateJobRequest` +Request payload for creating a new job run. + ```ts type CreateJobRequest = { type: "deletion" @@ -620,7 +655,12 @@ type CreateJobRequest = { ### `JobDetails` -Generic, type-specific job details payload (e.g. matched count, deleted count, failed count, etc.). +Type-specific job outcome payload. The shape depends on the config type. +For `deletion` jobs, typical fields include: +- `matched_count` — total entities matched by the query +- `deleted_count` — entities successfully deleted +- `failed_count` — entities that could not be deleted + ```ts type JobDetails = Record @@ -628,6 +668,10 @@ type JobDetails = Record ### `UpdateJobRequest` +Partial update payload for an existing job. Only the fields provided +will be merged into the job record. + + ```ts type UpdateJobRequest = { status?: "in_progress" | "success" | "failed" @@ -644,6 +688,11 @@ type UpdateJobRequest = { ### `Job` +Represents a single execution run of a data lifecycle config. Tracks the +full lifecycle from creation through completion, including outcome +details and an optional downloadable report. + + ```ts type Job = { id: string @@ -670,6 +719,8 @@ type Job = { ### `ListJobsResponse` +Paginated response containing a list of job runs. + ```ts type ListJobsResponse = { jobs?: Array<{ @@ -699,6 +750,8 @@ type ListJobsResponse = { ### `JobReportUrlResponse` +Contains a time-limited pre-signed URL to download a job report. + ```ts type JobReportUrlResponse = { url?: string @@ -708,22 +761,38 @@ type JobReportUrlResponse = { ### `QueryFilterType` +Predefined data governance filter types that can be layered on top of +a saved view to narrow down target entities: +- `entity_workflows_only_in_closed_or_cancelled_status` — include only + entities whose own workflows are all in a closed/cancelled state. +- `no_related_entities` — include only entitie + ```ts type QueryFilterType = "entity_workflows_only_in_closed_or_cancelled_status" | "no_related_entities" | "related_entities_all_in_closed_or_cancelled_status" | "related_entities_workflows_only_in_closed_or_cancelled_status" | "no_email_communication_since" ``` ### `QueryFilter` +A single governance filter condition applied during entity querying. +The required and optional fields depend on the `type`. + + ```ts type QueryFilter = { type: "entity_workflows_only_in_closed_or_cancelled_status" | "no_related_entities" | "related_entities_all_in_closed_or_cancelled_status" | "related_entities_workflows_only_in_closed_or_cancelled_status" | "no_email_communication_since" related_entity_schemas?: string[] lookback_period_days?: number + message_type?: "SENT" | "RECEIVED"[] + workflow_status?: "CLOSED" | "DONE"[] } ``` ### `QueryConfig` +Defines the query used by a data lifecycle config to identify target +entities. Combines a saved view with optional governance filters. + + ```ts type QueryConfig = { saved_view_id: string @@ -732,12 +801,18 @@ type QueryConfig = { type: "entity_workflows_only_in_closed_or_cancelled_status" | "no_related_entities" | "related_entities_all_in_closed_or_cancelled_status" | "related_entities_workflows_only_in_closed_or_cancelled_status" | "no_email_communication_since" related_entity_schemas?: string[] lookback_period_days?: number + message_type?: "SENT" | "RECEIVED"[] + workflow_status?: "CLOSED" | "DONE"[] }> } ``` ### `QueryEntitiesRequest` +Request body for the query endpoint. Extends `QueryConfig` with +pagination and projection options. + + ```ts type QueryEntitiesRequest = { saved_view_id: string @@ -746,6 +821,8 @@ type QueryEntitiesRequest = { type: "entity_workflows_only_in_closed_or_cancelled_status" | "no_related_entities" | "related_entities_all_in_closed_or_cancelled_status" | "related_entities_workflows_only_in_closed_or_cancelled_status" | "no_email_communication_since" related_entity_schemas?: string[] lookback_period_days?: number + message_type?: "SENT" | "RECEIVED"[] + workflow_status?: "CLOSED" | "DONE"[] }> from?: number size?: number @@ -756,6 +833,8 @@ type QueryEntitiesRequest = { ### `QueryEntitiesResult` +Response from the entity query endpoint. + ```ts type QueryEntitiesResult = { hits?: number @@ -765,6 +844,10 @@ type QueryEntitiesResult = { ### `ConfigSchedule` +Interval-based schedule. The governance engine will create a job every +`interval_days` days, optionally bounded by start and end dates. + + ```ts type ConfigSchedule = { frequency: "interval" @@ -776,6 +859,10 @@ type ConfigSchedule = { ### `IntervalConfigSchedule` +Interval-based schedule. The governance engine will create a job every +`interval_days` days, optionally bounded by start and end dates. + + ```ts type IntervalConfigSchedule = { frequency: "interval" @@ -787,6 +874,8 @@ type IntervalConfigSchedule = { ### `UpsertConfigRequest` +Request payload for creating or updating a data lifecycle config. + ```ts type UpsertConfigRequest = { type: "deletion" @@ -797,6 +886,8 @@ type UpsertConfigRequest = { type: { ... } related_entity_schemas?: { ... } lookback_period_days?: { ... } + message_type?: { ... } + workflow_status?: { ... } }> } schedule: { @@ -812,6 +903,10 @@ type UpsertConfigRequest = { ### `Config` +A data lifecycle config defining an automated policy (e.g., scheduled +entity deletion) for a specific entity schema. + + ```ts type Config = { id: string @@ -824,6 +919,8 @@ type Config = { type: { ... } related_entity_schemas?: { ... } lookback_period_days?: { ... } + message_type?: { ... } + workflow_status?: { ... } }> } schedule?: { @@ -843,12 +940,19 @@ type Config = { ### `DeletionRelationEntitySchema` +Entity schema slug that can be specified as a cascading deletion +target. When a primary entity is deleted, related entities of these +schemas are also removed. + + ```ts type DeletionRelationEntitySchema = "contact" | "file" | "opportunity" | "order" | "meter" | "ticket" | "message" | "account" | "submission" | "contract" ``` ### `ListConfigsResponse` +Paginated response containing a list of data lifecycle configs. + ```ts type ListConfigsResponse = { configs?: Array<{ diff --git a/docs/sdk/clients/deduplication.md b/docs/sdk/clients/deduplication.md index b22674dc..263af901 100644 --- a/docs/sdk/clients/deduplication.md +++ b/docs/sdk/clients/deduplication.md @@ -30,11 +30,34 @@ const { data } = await deduplicationClient.deduplicate(...) ## Operations - [`deduplicate`](#deduplicate) +- [`deduplicateAsync`](#deduplicateasync) +- [`getDeduplicationJob`](#getdeduplicationjob) +- [`detectDuplicates`](#detectduplicates) +- [`dismissDuplicates`](#dismissduplicates) +- [`listUniquenessCriteria`](#listuniquenesscriteria) +- [`createUniquenessCriteria`](#createuniquenesscriteria) +- [`getUniquenessCriteria`](#getuniquenesscriteria) +- [`updateUniquenessCriteria`](#updateuniquenesscriteria) +- [`deleteUniquenessCriteria`](#deleteuniquenesscriteria) **Schemas** - [`DeduplicateRequestBody`](#deduplicaterequestbody) - [`DeduplicateRequestResponse`](#deduplicaterequestresponse) - [`Entity`](#entity) +- [`DeduplicateAsyncResponse`](#deduplicateasyncresponse) +- [`JobStatus`](#jobstatus) +- [`DeduplicationJob`](#deduplicationjob) +- [`DetectDuplicatesRequestBody`](#detectduplicatesrequestbody) +- [`DetectDuplicatesResponse`](#detectduplicatesresponse) +- [`DetectedDuplicateMatch`](#detectedduplicatematch) +- [`DismissDuplicatesRequestBody`](#dismissduplicatesrequestbody) +- [`DismissDuplicatesResponse`](#dismissduplicatesresponse) +- [`UniquenessCriteriaListResponse`](#uniquenesscriterialistresponse) +- [`UniquenessCriteria`](#uniquenesscriteria) +- [`MatchRule`](#matchrule) +- [`MatchAttribute`](#matchattribute) +- [`UniquenessCriteriaCreateBody`](#uniquenesscriteriacreatebody) +- [`UniquenessCriteriaUpdateBody`](#uniquenesscriteriaupdatebody) ### `deduplicate` @@ -58,32 +81,391 @@ const { data } = await client.deduplicate( Response ```json -[ +{ + "deduplicatedEntities": [ + { + "_id": "string", + "_org": "string", + "_schema": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_created_by": "string", + "created_by": "string", + "_tags": ["string"], + "_acl": {}, + "_owners": [ + { + "org_id": "string", + "user_id": "string" + } + ], + "type": "string" + } + ] +} +``` + +
+ +--- + +### `deduplicateAsync` + +Submits an async deduplication job. Returns a job ID immediately. Poll GET /v1/deduplicate/jobs/{jobId} for status. + +`POST /v1/deduplicate/job` + +```ts +const { data } = await client.deduplicateAsync( + null, + [ + { + toKeep: 'string', + toDelete: ['string'] + } + ], +) +``` + +--- + +### `getDeduplicationJob` + +Returns the current status of an async deduplication job + +`GET /v1/deduplicate/jobs/{jobId}` + +```ts +const { data } = await client.getDeduplicationJob({ + jobId: 'example', +}) +``` + +
+Response + +```json +{ + "jobId": "string", + "status": "pending", + "message": "string", + "result": [ + { + "_id": "string", + "_org": "string", + "_schema": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_created_by": "string", + "created_by": "string", + "_tags": ["string"], + "_acl": {}, + "_owners": [ + { + "org_id": "string", + "user_id": "string" + } + ], + "type": "string" + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `detectDuplicates` + +Detects potential duplicate entities for the given entity using the schema's prioritized uniqueness rules. Returns matches with a confidence score. + +`POST /v1/detect-duplicates` + +```ts +const { data } = await client.detectDuplicates( + null, { - "_id": "string", - "_org": "string", - "_schema": "string", - "_created_at": "1970-01-01T00:00:00.000Z", - "_updated_at": "1970-01-01T00:00:00.000Z", - "_created_by": "string", - "created_by": "string", - "_tags": ["string"], - "_acl": {}, - "_owners": [ + schema: 'string', + entity: {} + }, +) +``` + +
+Response + +```json +{ + "matches": [ + { + "entity": { + "_id": "string", + "_org": "string", + "_schema": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_created_by": "string", + "created_by": "string", + "_tags": ["string"], + "_acl": {}, + "_owners": [ + { + "org_id": "string", + "user_id": "string" + } + ], + "type": "string" + }, + "confidence": 0, + "matched_attributes": ["string"] + } + ] +} +``` + +
+ +--- + +### `dismissDuplicates` + +Confirms entities as NOT duplicates: clears the internal duplicate-detection flags (_matching_entities) on each given entity, so they stop appearing as open duplicate sets. The records themselves are + +`POST /v1/duplicates/dismiss` + +```ts +const { data } = await client.dismissDuplicates( + null, + { + schema: 'string', + entityIds: ['string'] + }, +) +``` + +
+Response + +```json +{ + "dismissed": ["string"] +} +``` + +
+ +--- + +### `listUniquenessCriteria` + +Lists UniquenessCriteria for the requesting organization. Optionally filtered by schema. + +`GET /v1/uniqueness-criteria` + +```ts +const { data } = await client.listUniquenessCriteria({ + schema: 'example', +}) +``` + +
+Response + +```json +{ + "items": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "schema": "string", + "matchRules": [ + { + "name": "string", + "attributes": [ + { + "attribute": "string" + } + ], + "confidence": 0 + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `createUniquenessCriteria` + +Creates a new UniquenessCriteria record. + +`POST /v1/uniqueness-criteria` + +```ts +const { data } = await client.createUniquenessCriteria( + null, + { + schema: 'string', + matchRules: [ { - "org_id": "string", - "user_id": "string" + name: 'string', + attributes: [ + { + attribute: 'string' + } + ], + confidence: 0 } - ], - "type": "string" - } -] + ] + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "schema": "string", + "matchRules": [ + { + "name": "string", + "attributes": [ + { + "attribute": "string" + } + ], + "confidence": 0 + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getUniquenessCriteria` + +Fetch a single UniquenessCriteria record. + +`GET /v1/uniqueness-criteria/{schema}` + +```ts +const { data } = await client.getUniquenessCriteria({ + schema: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "schema": "string", + "matchRules": [ + { + "name": "string", + "attributes": [ + { + "attribute": "string" + } + ], + "confidence": 0 + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} ```
--- +### `updateUniquenessCriteria` + +Replace the matchRules on an existing UniquenessCriteria record. + +`PUT /v1/uniqueness-criteria/{schema}` + +```ts +const { data } = await client.updateUniquenessCriteria( + { + schema: 'example', + }, + { + matchRules: [ + { + name: 'string', + attributes: [ + { + attribute: 'string' + } + ], + confidence: 0 + } + ] + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "schema": "string", + "matchRules": [ + { + "name": "string", + "attributes": [ + { + "attribute": "string" + } + ], + "confidence": 0 + } + ], + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteUniquenessCriteria` + +Delete a UniquenessCriteria record. + +`DELETE /v1/uniqueness-criteria/{schema}` + +```ts +const { data } = await client.deleteUniquenessCriteria({ + schema: 'example', +}) +``` + +--- + ## Schemas ### `DeduplicateRequestBody` @@ -98,22 +480,24 @@ type DeduplicateRequestBody = Array<{ ### `DeduplicateRequestResponse` ```ts -type DeduplicateRequestResponse = Array<{ - _id: string - _org?: string - _schema?: string - _created_at?: string // date-time - _updated_at?: string // date-time - _created_by?: string | number - created_by?: string | number - _tags?: string[] - _acl?: Record - _owners?: Array<{ - org_id: string - user_id: string +type DeduplicateRequestResponse = { + deduplicatedEntities: Array<{ + _id: string + _org?: string + _schema?: string + _created_at?: string // date-time + _updated_at?: string // date-time + _created_by?: string | number + created_by?: string | number + _tags?: string[] + _acl?: Record + _owners?: Array<{ + org_id: { ... } + user_id: { ... } + }> + type?: string }> - type?: string -}> +} ``` ### `Entity` @@ -138,3 +522,219 @@ type Entity = { type?: string } ``` + +### `DeduplicateAsyncResponse` + +Response returned immediately when a deduplication job is submitted + +```ts +type DeduplicateAsyncResponse = { + jobId: string + status: "pending" | "processing" | "completed" | "failed" + message: string +} +``` + +### `JobStatus` + +```ts +type JobStatus = "pending" | "processing" | "completed" | "failed" +``` + +### `DeduplicationJob` + +Represents an async deduplication job + +```ts +type DeduplicationJob = { + jobId: string + status: "pending" | "processing" | "completed" | "failed" + message?: string + result?: Array<{ + _id: string + _org?: string + _schema?: string + _created_at?: string // date-time + _updated_at?: string // date-time + _created_by?: string | number + created_by?: string | number + _tags?: string[] + _acl?: Record + _owners?: Array<{ + org_id: { ... } + user_id: { ... } + }> + type?: string + }> + createdAt: string // date-time + updatedAt: string // date-time +} +``` + +### `DetectDuplicatesRequestBody` + +```ts +type DetectDuplicatesRequestBody = { + schema: string + entity: Record +} +``` + +### `DetectDuplicatesResponse` + +```ts +type DetectDuplicatesResponse = { + matches: Array<{ + entity: { + _id: { ... } + _org?: { ... } + _schema?: { ... } + _created_at?: { ... } + _updated_at?: { ... } + _created_by?: { ... } + created_by?: { ... } + _tags?: { ... } + _acl?: { ... } + _owners?: { ... } + type?: { ... } + } + confidence: number + matched_attributes: string[] + }> +} +``` + +### `DetectedDuplicateMatch` + +```ts +type DetectedDuplicateMatch = { + entity: { + _id: string + _org?: string + _schema?: string + _created_at?: string // date-time + _updated_at?: string // date-time + _created_by?: string | number + created_by?: string | number + _tags?: string[] + _acl?: Record + _owners?: Array<{ + org_id: { ... } + user_id: { ... } + }> + type?: string + } + confidence: number + matched_attributes: string[] +} +``` + +### `DismissDuplicatesRequestBody` + +```ts +type DismissDuplicatesRequestBody = { + schema: string + entityIds: string[] +} +``` + +### `DismissDuplicatesResponse` + +```ts +type DismissDuplicatesResponse = { + dismissed: string[] +} +``` + +### `UniquenessCriteriaListResponse` + +```ts +type UniquenessCriteriaListResponse = { + items: Array<{ + id: string // uuid + orgId: string + schema: string + matchRules: Array<{ + name?: { ... } + attributes: { ... } + confidence: { ... } + }> + createdAt: string // date-time + updatedAt: string // date-time + }> +} +``` + +### `UniquenessCriteria` + +Defines what makes an entity of a given schema unique within an organization. + +```ts +type UniquenessCriteria = { + id: string // uuid + orgId: string + schema: string + matchRules: Array<{ + name?: string + attributes: Array<{ + attribute: { ... } + }> + confidence: number + }> + createdAt: string // date-time + updatedAt: string // date-time +} +``` + +### `MatchRule` + +One way to identify the same entity. Evaluated in order; first rule whose attributes are all available and that returns hits wins. + +```ts +type MatchRule = { + name?: string + attributes: Array<{ + attribute: string + }> + confidence: number +} +``` + +### `MatchAttribute` + +One attribute participating in a match rule. Wrapped as an object so per-attribute options can be added later. + +```ts +type MatchAttribute = { + attribute: string +} +``` + +### `UniquenessCriteriaCreateBody` + +```ts +type UniquenessCriteriaCreateBody = { + schema: string + matchRules: Array<{ + name?: string + attributes: Array<{ + attribute: { ... } + }> + confidence: number + }> +} +``` + +### `UniquenessCriteriaUpdateBody` + +```ts +type UniquenessCriteriaUpdateBody = { + matchRules: Array<{ + name?: string + attributes: Array<{ + attribute: { ... } + }> + confidence: number + }> +} +``` diff --git a/docs/sdk/clients/design.md b/docs/sdk/clients/design.md index 51d7f941..a6ce1ad8 100644 --- a/docs/sdk/clients/design.md +++ b/docs/sdk/clients/design.md @@ -5,7 +5,7 @@ description: "TypeScript SDK client for the epilot Design Builder API v2: usage # Design Builder API v2 -- **Base URL:** `https://design-builder-api.epilot.io` +- **Base URL:** `https://design-builder-api.sls.epilot.io` - **Full API Docs:** [https://docs.epilot.io/api/design](https://docs.epilot.io/api/design) ## Usage @@ -35,27 +35,28 @@ const { data } = await designClient.getAllDesigns(...) - [`getDesign`](#getdesign) - [`deleteDesign`](#deletedesign) - [`updateDesign`](#updatedesign) -- [`getThemeFromDesign`](#getthemefromdesign) +- [`duplicateDesign`](#duplicatedesign) +- [`generateDesign`](#generatedesign) +- [`generateDesignDocument`](#generatedesigndocument) - [`uploadFile`](#uploadfile) - [`getFiles`](#getfiles) - [`getConsumerDesign`](#getconsumerdesign) -- [`addConsumer`](#addconsumer) -- [`removeConsumer`](#removeconsumer) **Schemas** - [`UploadFileReq`](#uploadfilereq) - [`UploadFileRes`](#uploadfileres) - [`GetFilesRes`](#getfilesres) - [`GetAllDesignsRes`](#getalldesignsres) -- [`GetBrandsRes`](#getbrandsres) - [`AddDesignReq`](#adddesignreq) - [`AddDesignRes`](#adddesignres) - [`GetDesignRes`](#getdesignres) - [`UpdateDesignReq`](#updatedesignreq) - [`ItemMetada`](#itemmetada) - [`AddConsumerReq`](#addconsumerreq) +- [`RemoveConsumerReq`](#removeconsumerreq) - [`DesignItem`](#designitem) -- [`BrandItem`](#branditem) +- [`Design_Document_V1`](#design_document_v1) +- [`UpdateDesignConflict`](#updatedesignconflict) - [`Custom_Style`](#custom_style) - [`Journey`](#journey) - [`ConsumerData`](#consumerdata) @@ -68,8 +69,22 @@ const { data } = await designClient.getAllDesigns(...) - [`FontData`](#fontdata) - [`FontResponseUrl`](#fontresponseurl) - [`WidgetPortalData`](#widgetportaldata) +- [`GenerateDesignReq`](#generatedesignreq) +- [`GenerateDesignRes`](#generatedesignres) +- [`GenerateDesignDocumentReq`](#generatedesigndocumentreq) +- [`FindingId`](#findingid) +- [`FindingStatus`](#findingstatus) +- [`FindingDetail`](#findingdetail) +- [`DesignFinding`](#designfinding) +- [`GenerateDesignDocumentRes`](#generatedesigndocumentres) +- [`GeneratedDesign`](#generateddesign) - [`ErrorResp`](#errorresp) - [`FileData`](#filedata) +- [`DesignId`](#designid) +- [`Theme`](#theme) +- [`Application`](#application) +- [`DesignParameters`](#designparameters) +- [`ParseThemeFromDesignResp`](#parsethemefromdesignresp) ### `getAllDesigns` @@ -85,91 +100,34 @@ const { data } = await client.getAllDesigns() Response ```json -[ - { - "designs": [ - { - "id": "string", - "created_at": "2021-01-30T08:30:00Z", - "created_by": "string", - "edited": true, - "last_modified_at": "string", - "brand_id": "string", - "brand_name": "string", - "user": { - "emailaddress": "string", - "fullname": "string", - "name": "string", - "userid": "string" - }, - "style_name": "string", - "style": { - "logo": { - "main": { - "name": "string", - "display_name": "string", - "file_type": "LOGO", - "s3_object_key": "string", - "url": "string" - } - }, - "palette": { - "primary": "string", - "secondary": "string", - "error": "string", - "background": "string", - "paper": "string", - "navbar": "string", - "portal_login_background": "string" - }, - "typography": { - "font": { - "font_id": "string", - "font_name": "string", - "font_family": "string", - "font_weight_regular": "string", - "font_weight_medium": "string", - "font_weight_bold": "string", - "urls": [ - { - "type": "WOFF2", - "url": "string" - } - ] - }, - "primary": "string", - "secondary": "string" - }, - "shape": { - "border_radius": 0 - }, - "consumer": { - "widgets": [ - { - "id": "string", - "name": "string" - } - ], - "customer_portals": [ - { - "id": "string", - "name": "string" - } - ] - } - }, - "is_default": true, - "custom_theme": "string", - "use_custom_theme": true, - "design_tokens": { - "coupon": "string", - "cashback": "string", - "custom_css": "string" - } - } - ] - } -] +{ + "designs": [ + { + "id": "string", + "created_at": "2021-01-30T08:30:00Z", + "created_by": "string", + "edited": true, + "last_modified_at": "string", + "brand_id": "string", + "brand_name": "string", + "user": {}, + "style_name": "string", + "style": {}, + "is_default": true, + "_manifest": ["string"], + "custom_theme": "string", + "use_custom_theme": true, + "design_tokens": {}, + "version": 1, + "colors": {}, + "typography": {}, + "shape": {}, + "components": {}, + "assets": {}, + "consumer": {} + } + ] +} ```
@@ -197,67 +155,87 @@ const { data } = await client.addDesign( }, style_name: 'string', style: { - logo: { - main: { - name: 'string', - display_name: 'string', - file_type: 'LOGO', - s3_object_key: 'string', - url: 'string' - } - }, - palette: { - primary: 'string', - secondary: 'string', - error: 'string', - background: 'string', - paper: 'string', - navbar: 'string', - portal_login_background: 'string' - }, - typography: { - font: { - font_id: 'string', - font_name: 'string', - font_family: 'string', - font_weight_regular: 'string', - font_weight_medium: 'string', - font_weight_bold: 'string', - urls: [ - { - type: 'WOFF2', - url: 'string' - } - ] - }, - primary: 'string', - secondary: 'string' - }, - shape: { - border_radius: 0 - }, - consumer: { - widgets: [ - { - id: 'string', - name: 'string' - } - ], - customer_portals: [ - { - id: 'string', - name: 'string' - } - ] - } + logo: { /* ... */ }, + palette: { /* ... */ }, + typography: { /* ... */ }, + shape: { /* ... */ }, + consumer: { /* ... */ } }, is_default: true, + _manifest: ['string'], custom_theme: 'string', use_custom_theme: true, design_tokens: { coupon: 'string', cashback: 'string', - custom_css: 'string' + custom_css: 'string', + accent_color: 'string', + outline_color: 'string', + divider_color: 'string', + link_color: 'string', + link_hover_color: 'string', + font_size_scale: 'xs', + topbar_height: 0, + topbar_logo_alignment: 'flex-start', + logo_size: 0, + input_background: 'string', + input_border_color: 'string', + input_text_color: 'string', + input_label_color: 'string', + input_border_radius: 0, + input_height: 0, + input_variant: 'outlined', + button_primary_bg: 'string', + button_primary_text: 'string', + button_primary_hover_bg: 'string', + button_primary_hover_text: 'string', + button_outlined_border: 'string', + button_outlined_text: 'string', + button_outlined_hover_bg: 'string', + button_outlined_hover_text: 'string', + button_ghost_bg: 'string', + button_ghost_text: 'string', + button_ghost_hover_bg: 'string', + button_ghost_hover_text: 'string', + button_border_radius: 0, + button_height: 0, + card_background: 'string', + card_border_color: 'string', + card_variant: 'shadow', + summary_card_background: 'string', + toggle_selected_bg: 'string', + toggle_selected_text: 'string', + toggle_hover_bg: 'string', + toggle_hover_text: 'string', + toggle_border_color: 'string', + dropdown_hover_bg: 'string', + dropdown_hover_text: 'string', + dropdown_selected_bg: 'string', + dropdown_selected_text: 'string', + switch_unchecked_color: 'string', + switch_unchecked_bg: 'string', + switch_border_radius: 0, + checkbox_unchecked_color: 'string', + checkbox_label_color: 'string', + radio_unchecked_color: 'string', + radio_label_color: 'string', + datepicker_selected_bg: 'string', + datepicker_selected_color: 'string', + datepicker_border_radius: 0, + chip_background: 'string', + chip_hover_background: 'string', + chip_text_color: 'string', + chip_hover_text_color: 'string' + }, + version: 1, + colors: {}, + typography: {}, + shape: {}, + components: {}, + assets: {}, + consumer: { + widgets: [ /* ... */ ], + customer_portals: [ /* ... */ ] } } }, @@ -285,67 +263,87 @@ const { data } = await client.addDesign( }, "style_name": "string", "style": { - "logo": { - "main": { - "name": "string", - "display_name": "string", - "file_type": "LOGO", - "s3_object_key": "string", - "url": "string" - } - }, - "palette": { - "primary": "string", - "secondary": "string", - "error": "string", - "background": "string", - "paper": "string", - "navbar": "string", - "portal_login_background": "string" - }, - "typography": { - "font": { - "font_id": "string", - "font_name": "string", - "font_family": "string", - "font_weight_regular": "string", - "font_weight_medium": "string", - "font_weight_bold": "string", - "urls": [ - { - "type": "WOFF2", - "url": "string" - } - ] - }, - "primary": "string", - "secondary": "string" - }, - "shape": { - "border_radius": 0 - }, - "consumer": { - "widgets": [ - { - "id": "string", - "name": "string" - } - ], - "customer_portals": [ - { - "id": "string", - "name": "string" - } - ] - } + "logo": {}, + "palette": {}, + "typography": {}, + "shape": {}, + "consumer": {} }, "is_default": true, + "_manifest": ["string"], "custom_theme": "string", "use_custom_theme": true, "design_tokens": { "coupon": "string", "cashback": "string", - "custom_css": "string" + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" + }, + "version": 1, + "colors": {}, + "typography": {}, + "shape": {}, + "components": {}, + "assets": {}, + "consumer": { + "widgets": [], + "customer_portals": [] } } } @@ -388,67 +386,87 @@ const { data } = await client.getDesign({ }, "style_name": "string", "style": { - "logo": { - "main": { - "name": "string", - "display_name": "string", - "file_type": "LOGO", - "s3_object_key": "string", - "url": "string" - } - }, - "palette": { - "primary": "string", - "secondary": "string", - "error": "string", - "background": "string", - "paper": "string", - "navbar": "string", - "portal_login_background": "string" - }, - "typography": { - "font": { - "font_id": "string", - "font_name": "string", - "font_family": "string", - "font_weight_regular": "string", - "font_weight_medium": "string", - "font_weight_bold": "string", - "urls": [ - { - "type": "WOFF2", - "url": "string" - } - ] - }, - "primary": "string", - "secondary": "string" - }, - "shape": { - "border_radius": 0 - }, - "consumer": { - "widgets": [ - { - "id": "string", - "name": "string" - } - ], - "customer_portals": [ - { - "id": "string", - "name": "string" - } - ] - } + "logo": {}, + "palette": {}, + "typography": {}, + "shape": {}, + "consumer": {} }, "is_default": true, + "_manifest": ["string"], "custom_theme": "string", "use_custom_theme": true, "design_tokens": { "coupon": "string", "cashback": "string", - "custom_css": "string" + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" + }, + "version": 1, + "colors": {}, + "typography": {}, + "shape": {}, + "components": {}, + "assets": {}, + "consumer": { + "widgets": [], + "customer_portals": [] } } } @@ -474,7 +492,7 @@ const { data } = await client.deleteDesign({ ### `updateDesign` -Update a especific design owned by user organization +Update a especific design owned by user organization. A body with `version: 1` is validated against the design document v1 schema and stored as v1. A v1 body leaves the stored `style`, `design_tokens` `PUT /v1/designs/{designId}` @@ -482,6 +500,7 @@ Update a especific design owned by user organization const { data } = await client.updateDesign( { designId: 'example', + If-Match: 'example', }, { design: { @@ -495,67 +514,87 @@ const { data } = await client.updateDesign( }, style_name: 'string', style: { - logo: { - main: { - name: 'string', - display_name: 'string', - file_type: 'LOGO', - s3_object_key: 'string', - url: 'string' - } - }, - palette: { - primary: 'string', - secondary: 'string', - error: 'string', - background: 'string', - paper: 'string', - navbar: 'string', - portal_login_background: 'string' - }, - typography: { - font: { - font_id: 'string', - font_name: 'string', - font_family: 'string', - font_weight_regular: 'string', - font_weight_medium: 'string', - font_weight_bold: 'string', - urls: [ - { - type: 'WOFF2', - url: 'string' - } - ] - }, - primary: 'string', - secondary: 'string' - }, - shape: { - border_radius: 0 - }, - consumer: { - widgets: [ - { - id: 'string', - name: 'string' - } - ], - customer_portals: [ - { - id: 'string', - name: 'string' - } - ] - } + logo: { /* ... */ }, + palette: { /* ... */ }, + typography: { /* ... */ }, + shape: { /* ... */ }, + consumer: { /* ... */ } }, is_default: true, + _manifest: ['string'], custom_theme: 'string', use_custom_theme: true, design_tokens: { coupon: 'string', cashback: 'string', - custom_css: 'string' + custom_css: 'string', + accent_color: 'string', + outline_color: 'string', + divider_color: 'string', + link_color: 'string', + link_hover_color: 'string', + font_size_scale: 'xs', + topbar_height: 0, + topbar_logo_alignment: 'flex-start', + logo_size: 0, + input_background: 'string', + input_border_color: 'string', + input_text_color: 'string', + input_label_color: 'string', + input_border_radius: 0, + input_height: 0, + input_variant: 'outlined', + button_primary_bg: 'string', + button_primary_text: 'string', + button_primary_hover_bg: 'string', + button_primary_hover_text: 'string', + button_outlined_border: 'string', + button_outlined_text: 'string', + button_outlined_hover_bg: 'string', + button_outlined_hover_text: 'string', + button_ghost_bg: 'string', + button_ghost_text: 'string', + button_ghost_hover_bg: 'string', + button_ghost_hover_text: 'string', + button_border_radius: 0, + button_height: 0, + card_background: 'string', + card_border_color: 'string', + card_variant: 'shadow', + summary_card_background: 'string', + toggle_selected_bg: 'string', + toggle_selected_text: 'string', + toggle_hover_bg: 'string', + toggle_hover_text: 'string', + toggle_border_color: 'string', + dropdown_hover_bg: 'string', + dropdown_hover_text: 'string', + dropdown_selected_bg: 'string', + dropdown_selected_text: 'string', + switch_unchecked_color: 'string', + switch_unchecked_bg: 'string', + switch_border_radius: 0, + checkbox_unchecked_color: 'string', + checkbox_label_color: 'string', + radio_unchecked_color: 'string', + radio_label_color: 'string', + datepicker_selected_bg: 'string', + datepicker_selected_color: 'string', + datepicker_border_radius: 0, + chip_background: 'string', + chip_hover_background: 'string', + chip_text_color: 'string', + chip_hover_text_color: 'string' + }, + version: 1, + colors: {}, + typography: {}, + shape: {}, + components: {}, + assets: {}, + consumer: { + widgets: [ /* ... */ ], + customer_portals: [ /* ... */ ] } } }, @@ -564,17 +603,15 @@ const { data } = await client.updateDesign( --- -### `getThemeFromDesign` +### `duplicateDesign` -Search for a especific design owned by user organization and parse them to a new or old theme +Duplicate an existing design owned by the user organization. The copy carries over the style, custom CSS and name (marked as a copy) but does NOT carry over journey/portal relations, so the new design -`GET /v1/designs/{designId}/parse` +`POST /v1/designs/{designId}/duplicate` ```ts -const { data } = await client.getThemeFromDesign({ +const { data } = await client.duplicateDesign({ designId: 'example', - orgId: 'example', - theme: 'example', }) ``` @@ -582,7 +619,251 @@ const { data } = await client.getThemeFromDesign({ Response ```json -{} +{ + "design": { + "id": "string", + "created_at": "2021-01-30T08:30:00Z", + "created_by": "string", + "edited": true, + "last_modified_at": "string", + "brand_id": "string", + "brand_name": "string", + "user": { + "emailaddress": "string", + "fullname": "string", + "name": "string", + "userid": "string" + }, + "style_name": "string", + "style": { + "logo": {}, + "palette": {}, + "typography": {}, + "shape": {}, + "consumer": {} + }, + "is_default": true, + "_manifest": ["string"], + "custom_theme": "string", + "use_custom_theme": true, + "design_tokens": { + "coupon": "string", + "cashback": "string", + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" + }, + "version": 1, + "colors": {}, + "typography": {}, + "shape": {}, + "components": {}, + "assets": {}, + "consumer": { + "widgets": [], + "customer_portals": [] + } + } +} +``` + +
+ +--- + +### `generateDesign` + +Generates a design (palette, text colours, font, logo and border radius) from a public +website with AI. The result is cached per organization and URL for 30 days. + +`POST /v1/designs/generate` + +```ts +const { data } = await client.generateDesign( + null, + { + url: 'https://www.twl.de' + }, +) +``` + +
+Response + +```json +{ + "design": { + "style": { + "logo": { + "main": { + "name": "string", + "display_name": "string", + "file_type": "LOGO", + "s3_object_key": "string", + "url": "string", + "file_id": "string" + } + }, + "palette": { + "primary": "string", + "secondary": "string", + "error": "string", + "background": "string", + "paper": "string", + "navbar": "string", + "portal_login_background": "string" + }, + "typography": { + "font": { + "font_id": "string", + "font_name": "string", + "font_family": "string", + "font_weight_regular": "string", + "font_weight_medium": "string", + "font_weight_bold": "string", + "urls": [ + { + "type": "WOFF2", + "url": "string" + } + ] + }, + "primary": "string", + "secondary": "string" + } + }, + "theme": { + "shape": { + "borderRadius": "8" + } + } + }, + "cached": true +} +``` + +
+ +--- + +### `generateDesignDocument` + +Reads a public website and returns a v1 design document plus one finding for each +id in fixed order. This version chooses the favicon in code and derives the site name. +The other findings are `not_fou + +`POST /v1/designs/document/generate` + +```ts +const { data } = await client.generateDesignDocument( + null, + { + url: 'https://www.stadtwerke-musterstadt.de' + }, +) +``` + +
+Response + +```json +{ + "document": { + "version": 1, + "colors": {}, + "typography": {}, + "shape": {}, + "components": {}, + "assets": {}, + "consumer": { + "widgets": [ + { + "id": "string", + "name": "string" + } + ], + "customer_portals": [ + { + "id": "string", + "name": "string" + } + ] + } + }, + "findings": [ + { + "id": "primary_color", + "status": "found", + "detail": { + "family": "string" + } + }, + { + "id": "primary_color", + "status": "found", + "detail": { + "family": "string" + } + } + ], + "site_name": "Stadtwerke Musterstadt", + "cached": true +} ```
@@ -608,7 +889,8 @@ const { data } = await client.uploadFile() "display_name": "string", "file_type": "LOGO", "s3_object_key": "string", - "url": "string" + "url": "string", + "file_id": "string" } ``` @@ -638,7 +920,8 @@ const { data } = await client.getFiles({ "display_name": "string", "file_type": "LOGO", "s3_object_key": "string", - "url": "string" + "url": "string", + "file_id": "string" } ] ``` @@ -681,67 +964,87 @@ const { data } = await client.getConsumerDesign({ }, "style_name": "string", "style": { - "logo": { - "main": { - "name": "string", - "display_name": "string", - "file_type": "LOGO", - "s3_object_key": "string", - "url": "string" - } - }, - "palette": { - "primary": "string", - "secondary": "string", - "error": "string", - "background": "string", - "paper": "string", - "navbar": "string", - "portal_login_background": "string" - }, - "typography": { - "font": { - "font_id": "string", - "font_name": "string", - "font_family": "string", - "font_weight_regular": "string", - "font_weight_medium": "string", - "font_weight_bold": "string", - "urls": [ - { - "type": "WOFF2", - "url": "string" - } - ] - }, - "primary": "string", - "secondary": "string" - }, - "shape": { - "border_radius": 0 - }, - "consumer": { - "widgets": [ - { - "id": "string", - "name": "string" - } - ], - "customer_portals": [ - { - "id": "string", - "name": "string" - } - ] - } + "logo": {}, + "palette": {}, + "typography": {}, + "shape": {}, + "consumer": {} }, "is_default": true, + "_manifest": ["string"], "custom_theme": "string", "use_custom_theme": true, "design_tokens": { "coupon": "string", "cashback": "string", - "custom_css": "string" + "custom_css": "string", + "accent_color": "string", + "outline_color": "string", + "divider_color": "string", + "link_color": "string", + "link_hover_color": "string", + "font_size_scale": "xs", + "topbar_height": 0, + "topbar_logo_alignment": "flex-start", + "logo_size": 0, + "input_background": "string", + "input_border_color": "string", + "input_text_color": "string", + "input_label_color": "string", + "input_border_radius": 0, + "input_height": 0, + "input_variant": "outlined", + "button_primary_bg": "string", + "button_primary_text": "string", + "button_primary_hover_bg": "string", + "button_primary_hover_text": "string", + "button_outlined_border": "string", + "button_outlined_text": "string", + "button_outlined_hover_bg": "string", + "button_outlined_hover_text": "string", + "button_ghost_bg": "string", + "button_ghost_text": "string", + "button_ghost_hover_bg": "string", + "button_ghost_hover_text": "string", + "button_border_radius": 0, + "button_height": 0, + "card_background": "string", + "card_border_color": "string", + "card_variant": "shadow", + "summary_card_background": "string", + "toggle_selected_bg": "string", + "toggle_selected_text": "string", + "toggle_hover_bg": "string", + "toggle_hover_text": "string", + "toggle_border_color": "string", + "dropdown_hover_bg": "string", + "dropdown_hover_text": "string", + "dropdown_selected_bg": "string", + "dropdown_selected_text": "string", + "switch_unchecked_color": "string", + "switch_unchecked_bg": "string", + "switch_border_radius": 0, + "checkbox_unchecked_color": "string", + "checkbox_label_color": "string", + "radio_unchecked_color": "string", + "radio_label_color": "string", + "datepicker_selected_bg": "string", + "datepicker_selected_color": "string", + "datepicker_border_radius": 0, + "chip_background": "string", + "chip_hover_background": "string", + "chip_text_color": "string", + "chip_hover_text_color": "string" + }, + "version": 1, + "colors": {}, + "typography": {}, + "shape": {}, + "components": {}, + "assets": {}, + "consumer": { + "widgets": [], + "customer_portals": [] } } } @@ -751,57 +1054,13 @@ const { data } = await client.getConsumerDesign({ --- -### `addConsumer` - -Add a consumer that uses a specific design - -`PUT /v1/designs/addConsumer/{application}/{designId}` - -```ts -const { data } = await client.addConsumer( - { - designId: 'example', - application: 'example', - }, - { - consumer_id: 'string', - consumer_name: 'string', - should_delete: 'string' - }, -) -``` - ---- - -### `removeConsumer` - -Remove a consumer that uses a specific design - -`PUT /v1/designs/removeConsumer/{application}/{designId}` - -```ts -const { data } = await client.removeConsumer( - { - designId: 'example', - application: 'example', - }, - { - consumer_id: 'string', - consumer_name: 'string', - should_delete: 'string' - }, -) -``` - ---- - ## Schemas ### `UploadFileReq` ```ts type UploadFileReq = { - file_type: "LOGO" | "FONT" + file_type: "LOGO" | "FONT" | "IMAGE" file_data: string // base64 display_name?: string file_name: string @@ -814,9 +1073,10 @@ type UploadFileReq = { type UploadFileRes = { name: string display_name?: string - file_type?: "LOGO" | "FONT" + file_type?: "LOGO" | "FONT" | "IMAGE" s3_object_key: string url: string + file_id?: string } ``` @@ -826,9 +1086,10 @@ type UploadFileRes = { type GetFilesRes = Array<{ name: string display_name?: string - file_type?: "LOGO" | "FONT" + file_type?: "LOGO" | "FONT" | "IMAGE" s3_object_key: string url: string + file_id?: string }> ``` @@ -859,32 +1120,83 @@ type GetAllDesignsRes = { consumer: { ... } } is_default?: boolean + _manifest?: string[] custom_theme?: string use_custom_theme?: boolean design_tokens?: { coupon?: { ... } cashback?: { ... } custom_css?: { ... } + accent_color?: { ... } + outline_color?: { ... } + divider_color?: { ... } + link_color?: { ... } + link_hover_color?: { ... } + font_size_scale?: { ... } + topbar_height?: { ... } + topbar_logo_alignment?: { ... } + logo_size?: { ... } + input_background?: { ... } + input_border_color?: { ... } + input_text_color?: { ... } + input_label_color?: { ... } + input_border_radius?: { ... } + input_height?: { ... } + input_variant?: { ... } + button_primary_bg?: { ... } + button_primary_text?: { ... } + button_primary_hover_bg?: { ... } + button_primary_hover_text?: { ... } + button_outlined_border?: { ... } + button_outlined_text?: { ... } + button_outlined_hover_bg?: { ... } + button_outlined_hover_text?: { ... } + button_ghost_bg?: { ... } + button_ghost_text?: { ... } + button_ghost_hover_bg?: { ... } + button_ghost_hover_text?: { ... } + button_border_radius?: { ... } + button_height?: { ... } + card_background?: { ... } + card_border_color?: { ... } + card_variant?: { ... } + summary_card_background?: { ... } + toggle_selected_bg?: { ... } + toggle_selected_text?: { ... } + toggle_hover_bg?: { ... } + toggle_hover_text?: { ... } + toggle_border_color?: { ... } + dropdown_hover_bg?: { ... } + dropdown_hover_text?: { ... } + dropdown_selected_bg?: { ... } + dropdown_selected_text?: { ... } + switch_unchecked_color?: { ... } + switch_unchecked_bg?: { ... } + switch_border_radius?: { ... } + checkbox_unchecked_color?: { ... } + checkbox_label_color?: { ... } + radio_unchecked_color?: { ... } + radio_label_color?: { ... } + datepicker_selected_bg?: { ... } + datepicker_selected_color?: { ... } + datepicker_border_radius?: { ... } + chip_background?: { ... } + chip_hover_background?: { ... } + chip_text_color?: { ... } + chip_hover_text_color?: { ... } + } + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + consumer?: { + widgets: { ... } + customer_portals: { ... } } }> -} -``` - -### `GetBrandsRes` - -```ts -type GetBrandsRes = { - brands?: Array<{ - id: string - name: string - created_by?: string - created_date?: string - main_brand?: string - organization_id?: string - updated_date?: string - updated_by?: string - status?: string - }> + // ... } ``` @@ -910,12 +1222,80 @@ type AddDesignReq = { consumer: { ... } } is_default?: boolean + _manifest?: string[] custom_theme?: string use_custom_theme?: boolean design_tokens?: { coupon?: { ... } cashback?: { ... } custom_css?: { ... } + accent_color?: { ... } + outline_color?: { ... } + divider_color?: { ... } + link_color?: { ... } + link_hover_color?: { ... } + font_size_scale?: { ... } + topbar_height?: { ... } + topbar_logo_alignment?: { ... } + logo_size?: { ... } + input_background?: { ... } + input_border_color?: { ... } + input_text_color?: { ... } + input_label_color?: { ... } + input_border_radius?: { ... } + input_height?: { ... } + input_variant?: { ... } + button_primary_bg?: { ... } + button_primary_text?: { ... } + button_primary_hover_bg?: { ... } + button_primary_hover_text?: { ... } + button_outlined_border?: { ... } + button_outlined_text?: { ... } + button_outlined_hover_bg?: { ... } + button_outlined_hover_text?: { ... } + button_ghost_bg?: { ... } + button_ghost_text?: { ... } + button_ghost_hover_bg?: { ... } + button_ghost_hover_text?: { ... } + button_border_radius?: { ... } + button_height?: { ... } + card_background?: { ... } + card_border_color?: { ... } + card_variant?: { ... } + summary_card_background?: { ... } + toggle_selected_bg?: { ... } + toggle_selected_text?: { ... } + toggle_hover_bg?: { ... } + toggle_hover_text?: { ... } + toggle_border_color?: { ... } + dropdown_hover_bg?: { ... } + dropdown_hover_text?: { ... } + dropdown_selected_bg?: { ... } + dropdown_selected_text?: { ... } + switch_unchecked_color?: { ... } + switch_unchecked_bg?: { ... } + switch_border_radius?: { ... } + checkbox_unchecked_color?: { ... } + checkbox_label_color?: { ... } + radio_unchecked_color?: { ... } + radio_label_color?: { ... } + datepicker_selected_bg?: { ... } + datepicker_selected_color?: { ... } + datepicker_border_radius?: { ... } + chip_background?: { ... } + chip_hover_background?: { ... } + chip_text_color?: { ... } + chip_hover_text_color?: { ... } + } + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + consumer?: { + widgets: { ... } + customer_portals: { ... } } } } @@ -948,14 +1328,83 @@ type AddDesignRes = { consumer: { ... } } is_default?: boolean + _manifest?: string[] custom_theme?: string use_custom_theme?: boolean design_tokens?: { coupon?: { ... } cashback?: { ... } custom_css?: { ... } + accent_color?: { ... } + outline_color?: { ... } + divider_color?: { ... } + link_color?: { ... } + link_hover_color?: { ... } + font_size_scale?: { ... } + topbar_height?: { ... } + topbar_logo_alignment?: { ... } + logo_size?: { ... } + input_background?: { ... } + input_border_color?: { ... } + input_text_color?: { ... } + input_label_color?: { ... } + input_border_radius?: { ... } + input_height?: { ... } + input_variant?: { ... } + button_primary_bg?: { ... } + button_primary_text?: { ... } + button_primary_hover_bg?: { ... } + button_primary_hover_text?: { ... } + button_outlined_border?: { ... } + button_outlined_text?: { ... } + button_outlined_hover_bg?: { ... } + button_outlined_hover_text?: { ... } + button_ghost_bg?: { ... } + button_ghost_text?: { ... } + button_ghost_hover_bg?: { ... } + button_ghost_hover_text?: { ... } + button_border_radius?: { ... } + button_height?: { ... } + card_background?: { ... } + card_border_color?: { ... } + card_variant?: { ... } + summary_card_background?: { ... } + toggle_selected_bg?: { ... } + toggle_selected_text?: { ... } + toggle_hover_bg?: { ... } + toggle_hover_text?: { ... } + toggle_border_color?: { ... } + dropdown_hover_bg?: { ... } + dropdown_hover_text?: { ... } + dropdown_selected_bg?: { ... } + dropdown_selected_text?: { ... } + switch_unchecked_color?: { ... } + switch_unchecked_bg?: { ... } + switch_border_radius?: { ... } + checkbox_unchecked_color?: { ... } + checkbox_label_color?: { ... } + radio_unchecked_color?: { ... } + radio_label_color?: { ... } + datepicker_selected_bg?: { ... } + datepicker_selected_color?: { ... } + datepicker_border_radius?: { ... } + chip_background?: { ... } + chip_hover_background?: { ... } + chip_text_color?: { ... } + chip_hover_text_color?: { ... } + } + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + consumer?: { + widgets: { ... } + customer_portals: { ... } } } + // ... } ``` @@ -986,14 +1435,83 @@ type GetDesignRes = { consumer: { ... } } is_default?: boolean + _manifest?: string[] custom_theme?: string use_custom_theme?: boolean design_tokens?: { coupon?: { ... } cashback?: { ... } custom_css?: { ... } + accent_color?: { ... } + outline_color?: { ... } + divider_color?: { ... } + link_color?: { ... } + link_hover_color?: { ... } + font_size_scale?: { ... } + topbar_height?: { ... } + topbar_logo_alignment?: { ... } + logo_size?: { ... } + input_background?: { ... } + input_border_color?: { ... } + input_text_color?: { ... } + input_label_color?: { ... } + input_border_radius?: { ... } + input_height?: { ... } + input_variant?: { ... } + button_primary_bg?: { ... } + button_primary_text?: { ... } + button_primary_hover_bg?: { ... } + button_primary_hover_text?: { ... } + button_outlined_border?: { ... } + button_outlined_text?: { ... } + button_outlined_hover_bg?: { ... } + button_outlined_hover_text?: { ... } + button_ghost_bg?: { ... } + button_ghost_text?: { ... } + button_ghost_hover_bg?: { ... } + button_ghost_hover_text?: { ... } + button_border_radius?: { ... } + button_height?: { ... } + card_background?: { ... } + card_border_color?: { ... } + card_variant?: { ... } + summary_card_background?: { ... } + toggle_selected_bg?: { ... } + toggle_selected_text?: { ... } + toggle_hover_bg?: { ... } + toggle_hover_text?: { ... } + toggle_border_color?: { ... } + dropdown_hover_bg?: { ... } + dropdown_hover_text?: { ... } + dropdown_selected_bg?: { ... } + dropdown_selected_text?: { ... } + switch_unchecked_color?: { ... } + switch_unchecked_bg?: { ... } + switch_border_radius?: { ... } + checkbox_unchecked_color?: { ... } + checkbox_label_color?: { ... } + radio_unchecked_color?: { ... } + radio_label_color?: { ... } + datepicker_selected_bg?: { ... } + datepicker_selected_color?: { ... } + datepicker_border_radius?: { ... } + chip_background?: { ... } + chip_hover_background?: { ... } + chip_text_color?: { ... } + chip_hover_text_color?: { ... } + } + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + consumer?: { + widgets: { ... } + customer_portals: { ... } } } + // ... } ``` @@ -1019,12 +1537,80 @@ type UpdateDesignReq = { consumer: { ... } } is_default?: boolean + _manifest?: string[] custom_theme?: string use_custom_theme?: boolean design_tokens?: { coupon?: { ... } cashback?: { ... } custom_css?: { ... } + accent_color?: { ... } + outline_color?: { ... } + divider_color?: { ... } + link_color?: { ... } + link_hover_color?: { ... } + font_size_scale?: { ... } + topbar_height?: { ... } + topbar_logo_alignment?: { ... } + logo_size?: { ... } + input_background?: { ... } + input_border_color?: { ... } + input_text_color?: { ... } + input_label_color?: { ... } + input_border_radius?: { ... } + input_height?: { ... } + input_variant?: { ... } + button_primary_bg?: { ... } + button_primary_text?: { ... } + button_primary_hover_bg?: { ... } + button_primary_hover_text?: { ... } + button_outlined_border?: { ... } + button_outlined_text?: { ... } + button_outlined_hover_bg?: { ... } + button_outlined_hover_text?: { ... } + button_ghost_bg?: { ... } + button_ghost_text?: { ... } + button_ghost_hover_bg?: { ... } + button_ghost_hover_text?: { ... } + button_border_radius?: { ... } + button_height?: { ... } + card_background?: { ... } + card_border_color?: { ... } + card_variant?: { ... } + summary_card_background?: { ... } + toggle_selected_bg?: { ... } + toggle_selected_text?: { ... } + toggle_hover_bg?: { ... } + toggle_hover_text?: { ... } + toggle_border_color?: { ... } + dropdown_hover_bg?: { ... } + dropdown_hover_text?: { ... } + dropdown_selected_bg?: { ... } + dropdown_selected_text?: { ... } + switch_unchecked_color?: { ... } + switch_unchecked_bg?: { ... } + switch_border_radius?: { ... } + checkbox_unchecked_color?: { ... } + checkbox_label_color?: { ... } + radio_unchecked_color?: { ... } + radio_label_color?: { ... } + datepicker_selected_bg?: { ... } + datepicker_selected_color?: { ... } + datepicker_border_radius?: { ... } + chip_background?: { ... } + chip_hover_background?: { ... } + chip_text_color?: { ... } + chip_hover_text_color?: { ... } + } + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + consumer?: { + widgets: { ... } + customer_portals: { ... } } } } @@ -1048,7 +1634,14 @@ type ItemMetada = { type AddConsumerReq = { consumer_id: string consumer_name: string - should_delete?: string +} +``` + +### `RemoveConsumerReq` + +```ts +type RemoveConsumerReq = { + consumer_id: string } ``` @@ -1092,22 +1685,139 @@ type DesignItem = { } } is_default?: boolean + _manifest?: string[] } ``` -### `BrandItem` +### `Design_Document_V1` + +Groups of the design document v1. A design is v1 when `version` is 1, otherwise it is the old shape (`style`, `design_tokens`, `custom_theme`). The authoritative contract for the groups is the schema exported by @epilot/design-document. A v1 design keeps `style`, `design_tokens`, `custom_theme` and ```ts -type BrandItem = { - id: string - name: string - created_by?: string - created_date?: string - main_brand?: string - organization_id?: string - updated_date?: string - updated_by?: string - status?: string +type Design_Document_V1 = { + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + consumer?: { + widgets: Array<{ + id: { ... } + name: { ... } + }> + customer_portals: Array<{ + id: { ... } + name: { ... } + }> + } +} +``` + +### `UpdateDesignConflict` + +```ts +type UpdateDesignConflict = { + message?: string + design?: { + id?: string + created_at?: string + created_by?: string + edited: boolean + last_modified_at?: string + brand_id?: string + brand_name?: string + user?: { + emailaddress?: { ... } + fullname?: { ... } + name?: { ... } + userid?: { ... } + } + style_name: string + style: { + logo?: { ... } + palette: { ... } + typography: { ... } + shape?: { ... } + consumer: { ... } + } + is_default?: boolean + _manifest?: string[] + custom_theme?: string + use_custom_theme?: boolean + design_tokens?: { + coupon?: { ... } + cashback?: { ... } + custom_css?: { ... } + accent_color?: { ... } + outline_color?: { ... } + divider_color?: { ... } + link_color?: { ... } + link_hover_color?: { ... } + font_size_scale?: { ... } + topbar_height?: { ... } + topbar_logo_alignment?: { ... } + logo_size?: { ... } + input_background?: { ... } + input_border_color?: { ... } + input_text_color?: { ... } + input_label_color?: { ... } + input_border_radius?: { ... } + input_height?: { ... } + input_variant?: { ... } + button_primary_bg?: { ... } + button_primary_text?: { ... } + button_primary_hover_bg?: { ... } + button_primary_hover_text?: { ... } + button_outlined_border?: { ... } + button_outlined_text?: { ... } + button_outlined_hover_bg?: { ... } + button_outlined_hover_text?: { ... } + button_ghost_bg?: { ... } + button_ghost_text?: { ... } + button_ghost_hover_bg?: { ... } + button_ghost_hover_text?: { ... } + button_border_radius?: { ... } + button_height?: { ... } + card_background?: { ... } + card_border_color?: { ... } + card_variant?: { ... } + summary_card_background?: { ... } + toggle_selected_bg?: { ... } + toggle_selected_text?: { ... } + toggle_hover_bg?: { ... } + toggle_hover_text?: { ... } + toggle_border_color?: { ... } + dropdown_hover_bg?: { ... } + dropdown_hover_text?: { ... } + dropdown_selected_bg?: { ... } + dropdown_selected_text?: { ... } + switch_unchecked_color?: { ... } + switch_unchecked_bg?: { ... } + switch_border_radius?: { ... } + checkbox_unchecked_color?: { ... } + checkbox_label_color?: { ... } + radio_unchecked_color?: { ... } + radio_label_color?: { ... } + datepicker_selected_bg?: { ... } + datepicker_selected_color?: { ... } + datepicker_border_radius?: { ... } + chip_background?: { ... } + chip_hover_background?: { ... } + chip_text_color?: { ... } + chip_hover_text_color?: { ... } + } + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + consumer?: { + widgets: { ... } + customer_portals: { ... } + } + // ... } ``` @@ -1128,6 +1838,63 @@ type Journey = { coupon?: string cashback?: string custom_css?: string + accent_color?: string + outline_color?: string + divider_color?: string + link_color?: string + link_hover_color?: string + font_size_scale?: "xs" | "sm" | "md" | "lg" | "xl" + topbar_height?: number + topbar_logo_alignment?: "flex-start" | "center" | "flex-end" + logo_size?: number + input_background?: string + input_border_color?: string + input_text_color?: string + input_label_color?: string + input_border_radius?: number + input_height?: number + input_variant?: "outlined" | "filled" | "underlined" + button_primary_bg?: string + button_primary_text?: string + button_primary_hover_bg?: string + button_primary_hover_text?: string + button_outlined_border?: string + button_outlined_text?: string + button_outlined_hover_bg?: string + button_outlined_hover_text?: string + button_ghost_bg?: string + button_ghost_text?: string + button_ghost_hover_bg?: string + button_ghost_hover_text?: string + button_border_radius?: number + button_height?: number + card_background?: string + card_border_color?: string + card_variant?: "shadow" | "outlined" + summary_card_background?: string + toggle_selected_bg?: string + toggle_selected_text?: string + toggle_hover_bg?: string + toggle_hover_text?: string + toggle_border_color?: string + dropdown_hover_bg?: string + dropdown_hover_text?: string + dropdown_selected_bg?: string + dropdown_selected_text?: string + switch_unchecked_color?: string + switch_unchecked_bg?: string + switch_border_radius?: number + checkbox_unchecked_color?: string + checkbox_label_color?: string + radio_unchecked_color?: string + radio_label_color?: string + datepicker_selected_bg?: string + datepicker_selected_color?: string + datepicker_border_radius?: number + chip_background?: string + chip_hover_background?: string + chip_text_color?: string + chip_hover_text_color?: string } } ``` @@ -1172,9 +1939,10 @@ type LogoData = { main?: { name: string display_name?: string - file_type?: "LOGO" | "FONT" + file_type?: "LOGO" | "FONT" | "IMAGE" s3_object_key: string url: string + file_id?: string } } ``` @@ -1257,11 +2025,140 @@ type WidgetPortalData = { } ``` +### `GenerateDesignReq` + +```ts +type GenerateDesignReq = { + url: string // uri +} +``` + +### `GenerateDesignRes` + +```ts +type GenerateDesignRes = { + design: { + style: { + logo: { ... } + palette: { ... } + typography: { ... } + } + theme: { + shape: { ... } + } + } + cached: boolean +} +``` + +### `GenerateDesignDocumentReq` + +```ts +type GenerateDesignDocumentReq = { + url: string // uri +} +``` + +### `FindingId` + +```ts +type FindingId = "primary_color" | "fonts" | "corners" | "primary_button" | "logo" | "favicon" +``` + +### `FindingStatus` + +```ts +type FindingStatus = "found" | "not_found" | "not_available" +``` + +### `FindingDetail` + +```ts +type FindingDetail = { + family: string +} +``` + +### `DesignFinding` + +```ts +type DesignFinding = { + id: "primary_color" | "fonts" | "corners" | "primary_button" | "logo" | "favicon" + status: "found" | "not_found" | "not_available" + detail?: { + family: string + } +} +``` + +### `GenerateDesignDocumentRes` + +```ts +type GenerateDesignDocumentRes = { + document: { + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + consumer?: { + widgets: { ... } + customer_portals: { ... } + } + } + findings: Array<{ + id: "primary_color" | "fonts" | "corners" | "primary_button" | "logo" | "favicon" + status: "found" | "not_found" | "not_available" + detail?: { + family: { ... } + } + }> + site_name: string + cached: boolean +} +``` + +### `GeneratedDesign` + +Partial design to merge into the design being edited + +```ts +type GeneratedDesign = { + style: { + logo: { + main?: { ... } + } + palette: { + primary: { ... } + secondary: { ... } + error: { ... } + background: { ... } + paper: { ... } + navbar: { ... } + portal_login_background?: { ... } + } + typography: { + font: { ... } + primary: { ... } + secondary: { ... } + } + } + theme: { + shape: { + borderRadius: { ... } + } + } +} +``` + ### `ErrorResp` ```ts type ErrorResp = { message?: string + code?: string + error?: object } ``` @@ -1271,8 +2168,71 @@ type ErrorResp = { type FileData = { name: string display_name?: string - file_type?: "LOGO" | "FONT" + file_type?: "LOGO" | "FONT" | "IMAGE" s3_object_key: string url: string + file_id?: string +} +``` + +### `DesignId` + +Id of the design + +```ts +type DesignId = string +``` + +### `Theme` + +Type of theme to be parsed and returned + +```ts +type Theme = "NEW" | "OLD" +``` + +### `Application` + +Type of application that uses the design + +```ts +type Application = string +``` + +### `DesignParameters` + +```ts +type DesignParameters = { + designId?: string + theme?: "NEW" | "OLD" + application?: string +} +``` + +### `ParseThemeFromDesignResp` + +```ts +type ParseThemeFromDesignResp = { + theme?: "NEW" | "OLD" + design?: { + id?: string + last_modified_at?: string + style_name?: string + style?: { + logo?: { ... } + palette?: { ... } + typography?: { ... } + } + custom_theme?: string + use_custom_theme?: boolean + journey_design_tokens?: object + version?: 1 + colors?: Record + typography?: Record + shape?: Record + components?: Record + assets?: Record + journey?: Record + } } ``` diff --git a/docs/sdk/clients/document.md b/docs/sdk/clients/document.md index f4b54099..00a89dbe 100644 --- a/docs/sdk/clients/document.md +++ b/docs/sdk/clients/document.md @@ -33,6 +33,7 @@ const { data } = await documentClient.getTemplateMeta(...) - [`getTemplateMeta`](#gettemplatemeta) - [`generateDocumentV2`](#generatedocumentv2) - [`convertDocument`](#convertdocument) +- [`validateTemplate`](#validatetemplate) **Schemas** - [`S3Reference`](#s3reference) @@ -44,6 +45,9 @@ const { data } = await documentClient.getTemplateMeta(...) - [`DocxTemplaterErrorDetails`](#docxtemplatererrordetails) - [`DocxTemplaterErrorDetail`](#docxtemplatererrordetail) - [`ErrorCode`](#errorcode) +- [`TemplateValidationRequest`](#templatevalidationrequest) +- [`TemplateValidationResponse`](#templatevalidationresponse) +- [`TemplateIssue`](#templateissue) - [`TemplateSettings`](#templatesettings) - [`DocumentMetaRequest`](#documentmetarequest) - [`DocumentMetaResponse`](#documentmetaresponse) @@ -115,7 +119,7 @@ const { data } = await client.generateDocumentV2( } }, context_entity_id: 'bcd0aab9-b544-42b0-8bfb-6d449d02eacc', - user_id: 100321, + user_id: '100321', language: 'de', variable_payload: { additionalProperties: 'string' @@ -137,7 +141,7 @@ const { data } = await client.generateDocumentV2( template_with_datatable: false, enabled_template_settings_persistence: false, misconfigured_margins: false, - file_entity_id: '1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p' + file_entity_id: '123e4567-e89b-12d3-a456-426614174000' } }, ) @@ -220,7 +224,7 @@ const { data } = await client.generateDocumentV2( "template_with_datatable": false, "enabled_template_settings_persistence": false, "misconfigured_margins": false, - "file_entity_id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p" + "file_entity_id": "123e4567-e89b-12d3-a456-426614174000" } } ``` @@ -271,6 +275,72 @@ const { data } = await client.convertDocument( --- +### `validateTemplate` + +Validates a document template's variable syntax and, optionally, proposes a hotfixed copy of it. + +`POST /v2/templates:validate` + +```ts +const { data } = await client.validateTemplate( + null, + { + template_document: { + filename: 'Umzugsmeldung.xlsx', + s3ref: { + bucket: 'document-api-prod', + key: 'uploads/my-template.pdf' + } + }, + fix: true, + fix_level: 'safe' + }, +) +``` + +
+Response + +```json +{ + "valid": false, + "fixed": true, + "issues": [ + { + "id": "unopened_tag", + "file": "xl/sharedStrings.xml", + "location": "Tabelle1!N4", + "context": "…Datum: {system.date}} Unterschrift…", + "explanation": "The tag is missing an opening brace.", + "fixable": true, + "confidence": "high", + "rule": "balance_opening_delimiter", + "before": "{system.date}}", + "after": "{{system.date}}" + } + ], + "unresolved_errors": [ + { + "id": "string", + "context": "string", + "explanation": "string" + } + ], + "fixed_document": { + "s3ref": { + "bucket": "document-api-prod", + "key": "uploads/my-template.pdf" + }, + "filename": "Umzugsmeldung (fixed).xlsx", + "preview_url": "https://example.com/path" + } +} +``` + +
+ +--- + ## Schemas ### `S3Reference` @@ -287,7 +357,7 @@ type S3Reference = { ```ts type ErrorOutput = { error_message?: string - error_code?: "PARSE_ERROR" | "DOC_TO_PDF_CONVERT_ERROR" | "INTERNAL_ERROR" | "INVALID_TEMPLATE_FORMAT" + error_code?: "PARSE_ERROR" | "DOC_TO_PDF_CONVERT_ERROR" | "INTERNAL_ERROR" | "INVALID_TEMPLATE_FORMAT" | "TEMPLATE_NOT_FOUND" error_details?: Array<{ explanation?: string context?: { @@ -400,7 +470,76 @@ Error codes for document generation: - INTERNAL_ERROR - In ```ts -type ErrorCode = "PARSE_ERROR" | "DOC_TO_PDF_CONVERT_ERROR" | "INTERNAL_ERROR" | "INVALID_TEMPLATE_FORMAT" +type ErrorCode = "PARSE_ERROR" | "DOC_TO_PDF_CONVERT_ERROR" | "INTERNAL_ERROR" | "INVALID_TEMPLATE_FORMAT" | "TEMPLATE_NOT_FOUND" +``` + +### `TemplateValidationRequest` + +```ts +type TemplateValidationRequest = { + template_document: { + filename?: string + s3ref: { + bucket: { ... } + key: { ... } + } + } + fix?: boolean + fix_level?: "safe" | "aggressive" +} +``` + +### `TemplateValidationResponse` + +```ts +type TemplateValidationResponse = { + valid?: boolean + fixed?: boolean + issues?: Array<{ + id?: string + file?: string + location?: string + context?: string + explanation?: string + fixable?: boolean + confidence?: "high" | "medium" | "low" + rule?: string + before?: string + after?: string + }> + unresolved_errors?: Array<{ + id?: string + context?: string + explanation?: string + }> + fixed_document?: { + s3ref?: { + bucket: { ... } + key: { ... } + } + filename?: string + preview_url?: string // uri + } +} +``` + +### `TemplateIssue` + +A single template syntax problem, and the repair proposed for it + +```ts +type TemplateIssue = { + id?: string + file?: string + location?: string + context?: string + explanation?: string + fixable?: boolean + confidence?: "high" | "medium" | "low" + rule?: string + before?: string + after?: string +} ``` ### `TemplateSettings` @@ -530,7 +669,7 @@ type DocumentGenerationV2Response = { } error_output?: { error_message?: string - error_code?: "PARSE_ERROR" | "DOC_TO_PDF_CONVERT_ERROR" | "INTERNAL_ERROR" | "INVALID_TEMPLATE_FORMAT" + error_code?: "PARSE_ERROR" | "DOC_TO_PDF_CONVERT_ERROR" | "INTERNAL_ERROR" | "INVALID_TEMPLATE_FORMAT" | "TEMPLATE_NOT_FOUND" error_details?: Array<{ explanation?: { ... } context?: { ... } diff --git a/docs/sdk/clients/email-settings.md b/docs/sdk/clients/email-settings.md index ad20706b..116fd6a6 100644 --- a/docs/sdk/clients/email-settings.md +++ b/docs/sdk/clients/email-settings.md @@ -51,15 +51,36 @@ const { data } = await emailSettingsClient.provisionEpilotEmailAddress(...) **O365 Outlook Connection** - [`connectOutlook`](#connectoutlook) - [`getOutlookConnectionStatus`](#getoutlookconnectionstatus) +- [`getCalendarAdminConsentStatus`](#getcalendaradminconsentstatus) +- [`getMyCalendarConnection`](#getmycalendarconnection) +- [`disconnectMyCalendar`](#disconnectmycalendar) - [`disconnectOutlook`](#disconnectoutlook) - [`connectOutlookMailbox`](#connectoutlookmailbox) - [`disconnectOutlookMailbox`](#disconnectoutlookmailbox) - [`startMailboxSync`](#startmailboxsync) - [`getMailboxSyncStatus`](#getmailboxsyncstatus) +- [`getMailboxSyncEstimate`](#getmailboxsyncestimate) - [`retryMailboxSync`](#retrymailboxsync) +- [`cancelMailboxSync`](#cancelmailboxsync) - [`getConnectedOutlookEmails`](#getconnectedoutlookemails) - [`outlookOAuthCallback`](#outlookoauthcallback) +**Channels** +- [`connectMsTeams`](#connectmsteams) +- [`disconnectMsTeams`](#disconnectmsteams) +- [`getMsTeamsStatus`](#getmsteamsstatus) + +**Custom SMTP** +- [`listSmtpConnections`](#listsmtpconnections) +- [`createSmtpConnection`](#createsmtpconnection) +- [`getSmtpConnection`](#getsmtpconnection) +- [`updateSmtpConnection`](#updatesmtpconnection) +- [`deleteSmtpConnection`](#deletesmtpconnection) +- [`testSmtpConnection`](#testsmtpconnection) +- [`listSmtpSenders`](#listsmtpsenders) +- [`connectSmtpSender`](#connectsmtpsender) +- [`disconnectSmtpSender`](#disconnectsmtpsender) + **Settings** - [`getSettings`](#getsettings) - [`addSetting`](#addsetting) @@ -69,13 +90,17 @@ const { data } = await emailSettingsClient.provisionEpilotEmailAddress(...) **Domains** - [`addDomain`](#adddomain) - [`deleteDomain`](#deletedomain) +- [`getDomains`](#getdomains) - [`verifyNameServers`](#verifynameservers) +- [`verifyDnsRecords`](#verifydnsrecords) - [`verifyDomain`](#verifydomain) **Schemas** +- [`ConnectOutlookRequest`](#connectoutlookrequest) - [`MailboxSyncStatus`](#mailboxsyncstatus) - [`MailboxSyncStatuses`](#mailboxsyncstatuses) - [`MailboxSyncFolderStatuses`](#mailboxsyncfolderstatuses) +- [`MailboxSyncEstimate`](#mailboxsyncestimate) - [`MailboxSyncTimeframePeriods`](#mailboxsynctimeframeperiods) - [`InboxBucketResponse`](#inboxbucketresponse) - [`ProvisionEpilotEmailAddressPayload`](#provisionepilotemailaddresspayload) @@ -83,6 +108,7 @@ const { data } = await emailSettingsClient.provisionEpilotEmailAddress(...) - [`UpdateEmailAddressPayload`](#updateemailaddresspayload) - [`CreateEmailAddressPayload`](#createemailaddresspayload) - [`EmailAddressResponse`](#emailaddressresponse) +- [`OutlookDisconnectError`](#outlookdisconnecterror) - [`ErrorResponse`](#errorresponse) - [`SettingMeta`](#settingmeta) - [`UpdateSharedInboxPayload`](#updatesharedinboxpayload) @@ -91,12 +117,24 @@ const { data } = await emailSettingsClient.provisionEpilotEmailAddress(...) - [`SettingsResponse`](#settingsresponse) - [`ConnectedOutlookEmail`](#connectedoutlookemail) - [`OutlookConnectionError`](#outlookconnectionerror) +- [`CalendarAdminConsentStatus`](#calendaradminconsentstatus) +- [`MyCalendarConnectionResponse`](#mycalendarconnectionresponse) +- [`CalendarConnectionInfo`](#calendarconnectioninfo) - [`OutlookConnectionStatus`](#outlookconnectionstatus) +- [`SmtpConnection`](#smtpconnection) +- [`CreateSmtpConnectionRequest`](#createsmtpconnectionrequest) +- [`UpdateSmtpConnectionRequest`](#updatesmtpconnectionrequest) +- [`SmtpSender`](#smtpsender) +- [`ConnectSmtpSenderRequest`](#connectsmtpsenderrequest) +- [`SmtpTestResult`](#smtptestresult) - [`SignatureSetting`](#signaturesetting) - [`EmailDomainSetting`](#emaildomainsetting) - [`EmailAddressSetting`](#emailaddresssetting) - [`WhitelistEmailAddressSetting`](#whitelistemailaddresssetting) - [`RestrictDuplicatesWithinSetting`](#restrictduplicateswithinsetting) +- [`AllowedRecipientDomainsSetting`](#allowedrecipientdomainssetting) +- [`AutoLinkIdentifierAttributesSetting`](#autolinkidentifierattributessetting) +- [`AutoLinkIdentifierAttribute`](#autolinkidentifierattribute) - [`SettingType`](#settingtype) - [`Setting`](#setting) - [`Domain`](#domain) @@ -134,7 +172,8 @@ const { data } = await client.provisionEpilotEmailAddress( "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -175,7 +214,8 @@ const { data } = await client.setEmailAddressPrimary( "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -213,7 +253,8 @@ const { data } = await client.getEmailAddress({ "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -275,7 +316,8 @@ const { data } = await client.updateEmailAddress( "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -312,7 +354,8 @@ const { data } = await client.listEmailAddresses() "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ] ``` @@ -359,7 +402,8 @@ const { data } = await client.addEmailAddress( "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" } ``` @@ -561,12 +605,19 @@ const { data } = await client.listInboxBuckets() ### `connectOutlook` -Returns Microsoft authorization URL for Outlook OAuth. +Returns the Microsoft authorization URL for Outlook OAuth. -`GET /v2/outlook/connect` +`POST /v2/outlook/connect` ```ts -const { data } = await client.connectOutlook() +const { data } = await client.connectOutlook( + null, + { + mail: true, + calendar: true, + return_to: 'string' + }, +) ```
@@ -602,6 +653,7 @@ const { data } = await client.getOutlookConnectionStatus() { "status": "connected", "action": "connect", + "action_reason": "expired", "connected_by_display_name": "string", "connected_by_email": "user@example.com", "connected_by_user_id": "string", @@ -613,7 +665,67 @@ const { data } = await client.getOutlookConnectionStatus() "is_token_valid": true } ], - "has_connections": true + "has_connections": true, + "teams_enabled": true +} +``` + +
+ +--- + +### `getCalendarAdminConsentStatus` + +Reports whether the caller's organization can connect personal Outlook +calendars. + +`GET /v2/outlook/calendar/admin-consent-status` + +```ts +const { data } = await client.getCalendarAdminConsentStatus() +``` + +
+Response + +```json +{ + "admin_consented": true, + "admin_consent_url": "https://example.com/path" +} +``` + +
+ +--- + +### `getMyCalendarConnection` + +Returns the calling user's personal Outlook calendar connection, +or null when the user hasn't connected yet. + +`GET /v2/outlook/calendar/me` + +```ts +const { data } = await client.getMyCalendarConnection() +``` + +
+Response + +```json +{ + "connection": { + "user_id": "string", + "tenant_id": "string", + "status": "connected", + "scopes": ["string"], + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z" + } } ``` @@ -621,6 +733,18 @@ const { data } = await client.getOutlookConnectionStatus() --- +### `disconnectMyCalendar` + +Removes the calling user's personal calendar connection. + +`DELETE /v2/outlook/calendar/me` + +```ts +const { data } = await client.disconnectMyCalendar() +``` + +--- + ### `disconnectOutlook` Removes the Microsoft 365 / Outlook connection for a specific tenant. @@ -652,6 +776,79 @@ const { data } = await client.disconnectOutlook( --- +### `connectMsTeams` + +Connects Microsoft Teams channel (click-to-call deep links, meetings) for the organization. +Independent of the Microsoft 365 / Outlook connection. + +`POST /v2/channels/msteams/connect` + +```ts +const { data } = await client.connectMsTeams() +``` + +
+Response + +```json +{ + "connected": true, + "connected_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `disconnectMsTeams` + +Disconnects Microsoft Teams channel for the organization. + +`POST /v2/channels/msteams/disconnect` + +```ts +const { data } = await client.disconnectMsTeams() +``` + +
+Response + +```json +{ + "connected": true +} +``` + +
+ +--- + +### `getMsTeamsStatus` + +Returns the connection status of the Microsoft Teams channel for the organization. + +`GET /v2/channels/msteams/status` + +```ts +const { data } = await client.getMsTeamsStatus() +``` + +
+Response + +```json +{ + "connected": true, + "connected_at": "1970-01-01T00:00:00.000Z", + "connected_by_user_id": "string" +} +``` + +
+ +--- + ### `connectOutlookMailbox` Connects an Outlook mailbox: @@ -667,6 +864,10 @@ const { data } = await client.connectOutlookMailbox( { email: 'user@example.com', shared_inbox_id: 'default', + name: 'string', + user_ids: ['string'], + group_ids: ['string'], + default_signature_id: 'string', mailboxSyncTimeframe: '5m' }, ) @@ -691,7 +892,8 @@ const { data } = await client.connectOutlookMailbox( "shared_inbox_id": "inbox-xyz", "is_active": true, "is_primary": false, - "is_epilot_email_address": false + "is_epilot_email_address": false, + "provider": "outlook" }, "outlook_email": "user@example.com", "tenant_id": "string", @@ -741,7 +943,8 @@ const { data } = await client.startMailboxSync( email: 'example', }, { - timeframe: '5m' + timeframe: '5m', + since: '1970-01-01T00:00:00.000Z' }, ) ``` @@ -768,6 +971,7 @@ const { data } = await client.getMailboxSyncStatus({ "execution_id": "string", "status": "RUNNING", "timeframe": "5m", + "timeframe_start": "1970-01-01T00:00:00.000Z", "started_at": "1970-01-01T00:00:00.000Z", "completed_at": "1970-01-01T00:00:00.000Z", "inbox": { @@ -789,6 +993,42 @@ const { data } = await client.getMailboxSyncStatus({ --- +### `getMailboxSyncEstimate` + +Estimate Mailbox Sync + +`GET /v2/outlook/mailbox/{email}/sync/estimate` + +```ts +const { data } = await client.getMailboxSyncEstimate({ + email: 'example', + timeframes: 'example', + since: 'example', +}) +``` + +
+Response + +```json +{ + "estimates": [ + { + "timeframe": "5m", + "since": "1970-01-01T00:00:00.000Z", + "inbox_messages": 0, + "sent_messages": 0, + "total_messages": 0, + "estimated_duration_seconds": 0 + } + ] +} +``` + +
+ +--- + ### `retryMailboxSync` Retry Failed Messages @@ -810,6 +1050,32 @@ const { data } = await client.retryMailboxSync( --- +### `cancelMailboxSync` + +Stop Mailbox Sync + +`POST /v2/outlook/mailbox/{email}/sync/cancel` + +```ts +const { data } = await client.cancelMailboxSync({ + email: 'example', +}) +``` + +
+Response + +```json +{ + "execution_id": "string", + "status": "RUNNING" +} +``` + +
+ +--- + ### `getConnectedOutlookEmails` Returns all Outlook email addresses connected to the organization. @@ -842,25 +1108,15 @@ const { data } = await client.getConnectedOutlookEmails() --- -### `outlookOAuthCallback` +### `listSmtpConnections` -Exchanges authorization code for tokens and stores them. +Returns all custom SMTP connections configured for the organization. +Passwords are never returned. -`GET /v2/outlook/oauth/callback` +`GET /v2/smtp/connections` ```ts -const { data } = await client.outlookOAuthCallback({ - code: 'example', - state: 'example', - session_state: 'example', - error: 'example', - error_description: 'example', - error_subcode: 'example', - client_info: 'example', - error_uri: 'example', - admin_consent: 'example', - tenant: 'example', -}) +const { data } = await client.listSmtpConnections() ```
@@ -868,9 +1124,25 @@ const { data } = await client.outlookOAuthCallback({ ```json { - "connected": true, - "expires_at": "1970-01-01T00:00:00.000Z", - "scope": "string" + "connections": [ + { + "connection_id": "string", + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "string", + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_by_user_id": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "last_tested_at": "1970-01-01T00:00:00.000Z", + "last_test_status": "ok", + "last_test_error": "string" + } + ], + "has_connections": true } ``` @@ -878,103 +1150,113 @@ const { data } = await client.outlookOAuthCallback({ --- -### `getSettings` +### `createSmtpConnection` -Retrieves settings of a specific type for the organization. +Creates a new custom SMTP connection. Runs a live verify against the SMTP server +before persisting; on failure the request is rejected and nothing is saved. Pass +`skip_test=true` to store the configur -`GET /v1/email-settings` +`POST /v2/smtp/connections` ```ts -const { data } = await client.getSettings({ - type: 'example', - id: '123e4567-e89b-12d3-a456-426614174000', -}) +const { data } = await client.createSmtpConnection( + { + skip_test: true, + }, + { + smtp_host: 'string', + smtp_port: 'string', + smtp_secure: 'tls', + smtp_username: 'string', + smtp_password: '{{ env.smtp_password }}' + }, +) ```
Response ```json -[ - { - "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", - "name": "Default Signature", - "org_id": "org-123", - "type": "signature", - "value": "Best regards, The Team", - "html": "

Best regards,
The Team

", - "created_at": "2024-01-15T10:30:00Z", - "updated_at": "2024-01-20T14:45:00Z", - "created_by": "user-123", - "updated_by": "user-456" - } -] +{ + "connection_id": "string", + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "string", + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_by_user_id": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "last_tested_at": "1970-01-01T00:00:00.000Z", + "last_test_status": "ok", + "last_test_error": "string" +} ```
--- -### `addSetting` +### `getSmtpConnection` -Creates a new setting of the specified type. +Returns a single custom SMTP connection by id. The password is never returned. -`POST /v1/email-settings` +`GET /v2/smtp/connections/{connectionId}` ```ts -const { data } = await client.addSetting( - null, - { - id: 'a10bd0ff-4391-4cfc-88ee-b19d718a9bf7', - name: 'Default Signature', - org_id: 'org-123', - type: 'signature', - value: 'Best regards, The Team', - html: '

Best regards,
The Team

', - created_at: '2024-01-15T10:30:00Z', - updated_at: '2024-01-20T14:45:00Z', - created_by: 'user-123', - updated_by: 'user-456' - }, -) +const { data } = await client.getSmtpConnection({ + connectionId: 'example', +}) ```
Response ```json -[ - { - "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", - "name": "Default Signature", - "org_id": "org-123", - "type": "signature", - "value": "Best regards, The Team", - "html": "

Best regards,
The Team

", - "created_at": "2024-01-15T10:30:00Z", - "updated_at": "2024-01-20T14:45:00Z", - "created_by": "user-123", - "updated_by": "user-456" - } -] +{ + "connection_id": "string", + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "string", + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_by_user_id": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "last_tested_at": "1970-01-01T00:00:00.000Z", + "last_test_status": "ok", + "last_test_error": "string" +} ```
--- -### `deleteSetting` +### `updateSmtpConnection` -Deletes a setting by its ID and type. +Partial update; omitted fields keep their existing values. The merged +configuration is verified against the SMTP server before persisting. Pass +`skip_test=true` to store it untested instead, which als -`DELETE /v1/email-settings` +`PUT /v2/smtp/connections/{connectionId}` ```ts -const { data } = await client.deleteSetting( - null, +const { data } = await client.updateSmtpConnection( { - type: 'signature', - id: 'a10bd0ff-4391-4cfc-88ee-b19d718a9bf7' + connectionId: 'example', + skip_test: true, + }, + { + smtp_host: 'string', + smtp_port: 'string', + smtp_secure: 'tls', + smtp_username: 'string', + smtp_password: 'string' }, ) ``` @@ -984,16 +1266,165 @@ const { data } = await client.deleteSetting( ```json { - "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", - "name": "Default Signature", - "org_id": "org-123", - "type": "signature", - "value": "Best regards, The Team", - "html": "

Best regards,
The Team

", - "created_at": "2024-01-15T10:30:00Z", - "updated_at": "2024-01-20T14:45:00Z", - "created_by": "user-123", - "updated_by": "user-456" + "connection_id": "string", + "smtp_host": "string", + "smtp_port": "string", + "smtp_secure": "tls", + "smtp_username": "string", + "smtp_password": "string", + "connected_by_display_name": "string", + "connected_by_email": "user@example.com", + "connected_by_user_id": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "last_tested_at": "1970-01-01T00:00:00.000Z", + "last_test_status": "ok", + "last_test_error": "string" +} +``` + +
+ +--- + +### `deleteSmtpConnection` + +Deletes a custom SMTP connection. Messages already sent are unaffected. + +`DELETE /v2/smtp/connections/{connectionId}` + +```ts +const { data } = await client.deleteSmtpConnection({ + connectionId: 'example', +}) +``` + +
+Response + +```json +{ + "success": true, + "connection_id": "string" +} +``` + +
+ +--- + +### `testSmtpConnection` + +Re-runs a live SMTP verify against the saved configuration (EHLO + AUTH + NOOP + QUIT) +and updates `last_test_status` / `last_tested_at` on the connection. + +`POST /v2/smtp/connections/{connectionId}/test` + +```ts +const { data } = await client.testSmtpConnection({ + connectionId: 'example', +}) +``` + +
+Response + +```json +{ + "status": "ok", + "error": "string", + "tested_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `listSmtpSenders` + +Returns every address registered to send through a custom SMTP connection. + +`GET /v2/smtp/senders` + +```ts +const { data } = await client.listSmtpSenders() +``` + +
+Response + +```json +{ + "senders": [ + { + "email": "user@example.com", + "connection_id": "string", + "reply_to_email": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "connected_by_user_id": "string" + } + ] +} +``` + +
+ +--- + +### `connectSmtpSender` + +Registers an address as a sender on a custom SMTP connection: + 1. Creates the email address so it can be picked in the composer + 2. Binds it to the connection, so outgoing mail from it is routed the + +`POST /v2/smtp/senders` + +```ts +const { data } = await client.connectSmtpSender( + null, + { + email: 'user@example.com', + connection_id: 'string', + name: 'string', + reply_to_email: 'string', + shared_inbox_id: 'default', + user_ids: ['string'], + group_ids: ['string'], + default_signature_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "email_address": { + "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-20T14:45:00Z", + "created_by": "user-123", + "updated_by": "user-456", + "address": "sales@yourcompany.com", + "name": "Sales Team", + "user_ids": ["user-123", "user-456"], + "group_ids": ["group-789"], + "default_signature_id": "sig-abc", + "shared_inbox_id": "inbox-xyz", + "is_active": true, + "is_primary": false, + "is_epilot_email_address": false, + "provider": "outlook" + }, + "sender": { + "email": "user@example.com", + "connection_id": "string", + "reply_to_email": "string", + "connected_at": "1970-01-01T00:00:00.000Z", + "connected_by_user_id": "string" + } } ``` @@ -1001,6 +1432,179 @@ const { data } = await client.deleteSetting( --- +### `disconnectSmtpSender` + +Removes a sender address: deletes the email address and its binding to the SMTP +connection. The connection itself and messages already sent are unaffected. + +`DELETE /v2/smtp/senders/{email}` + +```ts +const { data } = await client.disconnectSmtpSender({ + email: 'example', +}) +``` + +
+Response + +```json +{ + "success": true, + "email": "user@example.com" +} +``` + +
+ +--- + +### `outlookOAuthCallback` + +Exchanges authorization code for tokens and stores them. + +`GET /v2/outlook/oauth/callback` + +```ts +const { data } = await client.outlookOAuthCallback({ + code: 'example', + state: 'example', + session_state: 'example', + error: 'example', + error_description: 'example', + error_subcode: 'example', + client_info: 'example', + error_uri: 'example', + admin_consent: 'example', + tenant: 'example', + clientdata: 'example', +}) +``` + +
+Response + +```json +{ + "connected": true, + "expires_at": "1970-01-01T00:00:00.000Z", + "scope": "string" +} +``` + +
+ +--- + +### `getSettings` + +Retrieves settings of a specific type for the organization. + +`GET /v1/email-settings` + +```ts +const { data } = await client.getSettings({ + type: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +[ + { + "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", + "name": "Default Signature", + "org_id": "org-123", + "type": "signature", + "value": "Best regards, The Team", + "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-20T14:45:00Z", + "created_by": "user-123", + "updated_by": "user-456" + } +] +``` + +
+ +--- + +### `addSetting` + +Creates a new setting of the specified type. + +`POST /v1/email-settings` + +```ts +const { data } = await client.addSetting( + null, + { + id: 'a10bd0ff-4391-4cfc-88ee-b19d718a9bf7', + name: 'Default Signature', + org_id: 'org-123', + type: 'signature', + value: 'Best regards, The Team', + html: '

Best regards,
The Team

', + schemas: {}, + excluded_senders: ['newsletter@partner.de', '@noreply.example.com'], + created_at: '2024-01-15T10:30:00Z', + updated_at: '2024-01-20T14:45:00Z', + created_by: 'user-123', + updated_by: 'user-456' + }, +) +``` + +
+Response + +```json +[ + { + "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", + "name": "Default Signature", + "org_id": "org-123", + "type": "signature", + "value": "Best regards, The Team", + "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-20T14:45:00Z", + "created_by": "user-123", + "updated_by": "user-456" + } +] +``` + +
+ +--- + +### `deleteSetting` + +Deletes a setting by its ID and type. + +`DELETE /v1/email-settings` + +```ts +const { data } = await client.deleteSetting( + null, + { + type: 'signature', + id: 'a10bd0ff-4391-4cfc-88ee-b19d718a9bf7' + }, +) +``` + +--- + ### `updateSetting` Updates an existing setting identified by its ID. @@ -1019,6 +1623,8 @@ const { data } = await client.updateSetting( type: 'signature', value: 'Best regards, The Team', html: '

Best regards,
The Team

', + schemas: {}, + excluded_senders: ['newsletter@partner.de', '@noreply.example.com'], created_at: '2024-01-15T10:30:00Z', updated_at: '2024-01-20T14:45:00Z', created_by: 'user-123', @@ -1038,6 +1644,8 @@ const { data } = await client.updateSetting( "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1076,6 +1684,8 @@ const { data } = await client.addDomain( "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1105,6 +1715,27 @@ const { data } = await client.deleteDomain( --- +### `getDomains` + +Retrieves all custom email domains for the organization. + +`GET /v1/email-settings/domain` + +```ts +const { data } = await client.getDomains() +``` + +
+Response + +```json +["string"] +``` + +
+ +--- + ### `verifyNameServers` Verifies that the domain's name server (NS) records are correctly configured. @@ -1132,6 +1763,50 @@ const { data } = await client.verifyNameServers( "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-20T14:45:00Z", + "created_by": "user-123", + "updated_by": "user-456" + } +] +``` + +
+ +--- + +### `verifyDnsRecords` + +Verifies that the domain's DNS records (MX, TXT, CNAME) are correctly configured +in the customer's DNS provider. + +`POST /v1/email-settings/domain/dns-records:verify` + +```ts +const { data } = await client.verifyDnsRecords( + null, + { + domain: 'mail.yourcompany.com' + }, +) +``` + +
+Response + +```json +[ + { + "id": "a10bd0ff-4391-4cfc-88ee-b19d718a9bf7", + "name": "Default Signature", + "org_id": "org-123", + "type": "signature", + "value": "Best regards, The Team", + "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1171,6 +1846,8 @@ const { data } = await client.verifyDomain( "type": "signature", "value": "Best regards, The Team", "html": "

Best regards,
The Team

", + "schemas": {}, + "excluded_senders": ["newsletter@partner.de", "@noreply.example.com"], "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:45:00Z", "created_by": "user-123", @@ -1185,13 +1862,29 @@ const { data } = await client.verifyDomain( ## Schemas +### `ConnectOutlookRequest` + +Feature flags selecting which Microsoft Graph scopes to request. +At least one flag must be true. Passing a superset of previously +granted features triggers incremental consent for the delta only. + + +```ts +type ConnectOutlookRequest = { + mail?: boolean + calendar?: boolean + return_to?: string +} +``` + ### `MailboxSyncStatus` ```ts type MailboxSyncStatus = { execution_id: string status: "RUNNING" | "COMPLETED" | "COMPLETED_WITH_ERRORS" | "FAILED" | "CANCELLED" - timeframe: "5m" | "1w" | "2w" | "1m" + timeframe: "5m" | "1d" | "1w" | "2w" | "1m" | "3m" | "6m" | "1y" | "2y" | "custom" + timeframe_start?: string // date-time started_at: string // date-time completed_at?: string // date-time inbox?: { @@ -1221,10 +1914,25 @@ type MailboxSyncStatuses = "RUNNING" | "COMPLETED" | "COMPLETED_WITH_ERRORS" | " type MailboxSyncFolderStatuses = "PENDING" | "RUNNING" | "COMPLETED" | "FAILED" | "SKIPPED" ``` +### `MailboxSyncEstimate` + +```ts +type MailboxSyncEstimate = { + timeframe: "5m" | "1d" | "1w" | "2w" | "1m" | "3m" | "6m" | "1y" | "2y" | "custom" + since: string // date-time + inbox_messages: number + sent_messages: number + total_messages: number + estimated_duration_seconds: number +} +``` + ### `MailboxSyncTimeframePeriods` +Mailbox sync period. `custom` is a sync started with an explicit `since`. + ```ts -type MailboxSyncTimeframePeriods = "5m" | "1w" | "2w" | "1m" +type MailboxSyncTimeframePeriods = "5m" | "1d" | "1w" | "2w" | "1m" | "3m" | "6m" | "1y" | "2y" | "custom" ``` ### `InboxBucketResponse` @@ -1310,6 +2018,19 @@ type EmailAddressResponse = { is_active?: boolean is_primary?: boolean is_epilot_email_address?: boolean + provider?: "outlook" | "smtp" +} +``` + +### `OutlookDisconnectError` + +Why an Outlook mailbox or connection was not disconnected. Nothing was removed. + +```ts +type OutlookDisconnectError = { + error: "email_address_in_use" | "email_address_deletion_failed" + message: string + email_addresses?: string // email[] } ``` @@ -1393,9 +2114,14 @@ type SettingsResponse = Array<{ id?: string name?: string org_id?: string - type: "signature" | "email_domain" | "email_address" | "whitelist_email_address" | "restrict_duplicates_within" + type: "signature" | "email_domain" | "email_address" | "whitelist_email_address" | "restrict_duplicates_within" | "allowed_recipient_domains" | "auto_link_identifier_attributes" value?: string html?: string + schemas?: Record> + excluded_senders?: string[] created_at?: string updated_at?: string created_by?: string @@ -1404,9 +2130,14 @@ type SettingsResponse = Array<{ id?: string name?: string org_id?: string - type: "signature" | "email_domain" | "email_address" | "whitelist_email_address" | "restrict_duplicates_within" + type: "signature" | "email_domain" | "email_address" | "whitelist_email_address" | "restrict_duplicates_within" | "allowed_recipient_domains" | "auto_link_identifier_attributes" value?: string html?: string + schemas?: Record> + excluded_senders?: string[] created_at?: string updated_at?: string created_by?: string @@ -1440,12 +2171,60 @@ type OutlookConnectionError = { } ``` +### `CalendarAdminConsentStatus` + +```ts +type CalendarAdminConsentStatus = { + admin_consented: boolean + admin_consent_url?: string // uri +} +``` + +### `MyCalendarConnectionResponse` + +Per-user calendar connection metadata, or null when the caller has +not connected their personal calendar yet. + + +```ts +type MyCalendarConnectionResponse = { + connection?: { + user_id: string + tenant_id: string + status: "connected" | "expired" + scopes?: string[] + connected_by_display_name?: string + connected_by_email?: string // email + connected_at?: string // date-time + updated_at?: string // date-time + expires_at?: string // date-time + } +} +``` + +### `CalendarConnectionInfo` + +```ts +type CalendarConnectionInfo = { + user_id: string + tenant_id: string + status: "connected" | "expired" + scopes?: string[] + connected_by_display_name?: string + connected_by_email?: string // email + connected_at?: string // date-time + updated_at?: string // date-time + expires_at?: string // date-time +} +``` + ### `OutlookConnectionStatus` ```ts type OutlookConnectionStatus = { status: "connected" | "expired" | "pending_auth" | "not_connected" action: "connect" | "authorize" | "reconnect" | "none" + action_reason?: "expired" | "permission_update" connected_by_display_name?: string connected_by_email?: string // email connected_by_user_id?: string @@ -1458,6 +2237,95 @@ type OutlookConnectionStatus = { } ``` +### `SmtpConnection` + +```ts +type SmtpConnection = { + connection_id: string + smtp_host: string + smtp_port: string + smtp_secure: "tls" | "starttls" + smtp_username: string + smtp_password?: string + connected_by_display_name?: string + connected_by_email?: string // email + connected_by_user_id?: string + connected_at?: string // date-time + updated_at?: string // date-time + last_tested_at?: string // date-time + last_test_status?: "ok" | "auth_failed" | "tls_failed" | "host_unreachable" | "timeout" | "secret_missing" | "unknown" + last_test_error?: string +} +``` + +### `CreateSmtpConnectionRequest` + +```ts +type CreateSmtpConnectionRequest = { + smtp_host: string + smtp_port: string | number + smtp_secure: "tls" | "starttls" + smtp_username: string + smtp_password: string +} +``` + +### `UpdateSmtpConnectionRequest` + +Partial update; omitted fields keep their existing values. + +```ts +type UpdateSmtpConnectionRequest = { + smtp_host?: string + smtp_port?: string | number + smtp_secure?: "tls" | "starttls" + smtp_username?: string + smtp_password?: string +} +``` + +### `SmtpSender` + +An address allowed to send through a custom SMTP connection. Mirrors an Outlook +mailbox: the address, its display name and its assignees live on the shared +email-address record, while this row binds it to a set of SMTP credentials. + + +```ts +type SmtpSender = { + email: string // email + connection_id: string + reply_to_email?: string + connected_at?: string // date-time + connected_by_user_id?: string +} +``` + +### `ConnectSmtpSenderRequest` + +```ts +type ConnectSmtpSenderRequest = { + email: string // email + connection_id: string + name?: string + reply_to_email?: string + shared_inbox_id?: string + user_ids?: string[] + group_ids?: string[] + default_signature_id?: string +} +``` + +### `SmtpTestResult` + +```ts +type SmtpTestResult = { + status: "ok" | "auth_failed" | "tls_failed" | "host_unreachable" | "timeout" | "secret_missing" | "unknown" + error?: string + tested_at: string // date-time +} +``` + ### `SignatureSetting` Setting that allows to add a signature. @@ -1508,10 +2376,41 @@ type WhitelistEmailAddressSetting = "whitelist_email_address" type RestrictDuplicatesWithinSetting = "restrict_duplicates_within" ``` +### `AllowedRecipientDomainsSetting` + +- Extra recipient domain allowed for outbound email from a sandbox organization. +- Sandbox orgs (organization_use) with the sandbox recipient allowlist enabled may only + send unattended emails (workflow/automation/bulk/system) to epilot domains, the + verified sending domains of the org and its par + +```ts +type AllowedRecipientDomainsSetting = "allowed_recipient_domains" +``` + +### `AutoLinkIdentifierAttributesSetting` + +- Extra attributes, per entity schema, that inbound email auto-linking treats as identifiers, + on top of the built-in ones (e.g. `contract_number`). +- Stored in `schemas`: entity schema slug → attributes of that schema. +- Only one value per organization: posting again replaces it, and listing retur + +```ts +type AutoLinkIdentifierAttributesSetting = "auto_link_identifier_attributes" +``` + +### `AutoLinkIdentifierAttribute` + +```ts +type AutoLinkIdentifierAttribute = { + name: string + labels?: string[] +} +``` + ### `SettingType` ```ts -type SettingType = "signature" | "email_domain" | "email_address" | "whitelist_email_address" | "restrict_duplicates_within" +type SettingType = "signature" | "email_domain" | "email_address" | "whitelist_email_address" | "restrict_duplicates_within" | "allowed_recipient_domains" | "auto_link_identifier_attributes" ``` ### `Setting` @@ -1528,9 +2427,14 @@ type Setting = { id?: string name?: string org_id?: string - type: "signature" | "email_domain" | "email_address" | "whitelist_email_address" | "restrict_duplicates_within" + type: "signature" | "email_domain" | "email_address" | "whitelist_email_address" | "restrict_duplicates_within" | "allowed_recipient_domains" | "auto_link_identifier_attributes" value?: string html?: string + schemas?: Record> + excluded_senders?: string[] created_at?: string updated_at?: string created_by?: string diff --git a/docs/sdk/clients/email-template.md b/docs/sdk/clients/email-template.md index 2b84b1ba..d5d87f28 100644 --- a/docs/sdk/clients/email-template.md +++ b/docs/sdk/clients/email-template.md @@ -55,6 +55,7 @@ const { data } = await emailTemplateClient.saveTemplate(...) - [`EmailTemplateResponse`](#emailtemplateresponse) - [`AsyncEmailTemplateResponse`](#asyncemailtemplateresponse) - [`SkipCreatingEntities`](#skipcreatingentities) +- [`CompleteThread`](#completethread) - [`BulkSendMessageRequest`](#bulksendmessagerequest) - [`BulkSendMessageRequestWithQuery`](#bulksendmessagerequestwithquery) - [`CustomVariables`](#customvariables) @@ -131,7 +132,8 @@ const { data } = await client.saveTemplate( }, system_template: false, created_by: 1234, - updated_by: 1234 + updated_by: 1234, + json_template: 'string' }, ) ``` @@ -198,6 +200,7 @@ const { data } = await client.saveTemplate( }, "created_by": 1234, "updated_by": 1234, + "json_template": "string", "system_template": false } ``` @@ -281,6 +284,7 @@ const { data } = await client.getTemplateDetail({ }, "created_by": 1234, "updated_by": 1234, + "json_template": "string", "system_template": false }, "relations": [ @@ -357,7 +361,8 @@ const { data } = await client.updateTemplateDetail( }, system_template: false, created_by: 1234, - updated_by: 1234 + updated_by: 1234, + json_template: 'string' }, ) ``` @@ -424,6 +429,7 @@ const { data } = await client.updateTemplateDetail( }, "created_by": 1234, "updated_by": 1234, + "json_template": "string", "system_template": false } ``` @@ -535,6 +541,7 @@ const { data } = await client.replaceVariablesAsync( }, "created_by": 1234, "updated_by": 1234, + "json_template": "string", "system_template": false }, "relations": [ @@ -559,8 +566,9 @@ const { data } = await client.bulkSendMessage( null, { skip_creating_entities: true, + complete_thread: false, email_template_id: '511ceb90-f738-47aa-8b1e-915ace0ae13c', - must_include_unsubscribe_link: true, + must_include_unsubscribe_link: false, recipient_query: '_schema:contact AND consent_email_marketing:active', custom_variables: [ { @@ -580,11 +588,13 @@ const { data } = await client.bulkSendMessage( "org_id": "206801", "job_id": "8c086140-f33e-4bb7-a993-50c0f2402c7b", "skip_creating_entities": true, + "complete_thread": false, "status": "PROCESSING", "request": { "skip_creating_entities": true, + "complete_thread": false, "email_template_id": "511ceb90-f738-47aa-8b1e-915ace0ae13c", - "must_include_unsubscribe_link": true, + "must_include_unsubscribe_link": false, "recipient_ids": ["3fa85f64-5717-4562-b3fc-2c963f66afa6", "3fa85f64-5717-4562-b3fc-2c963f66afa7", "3fa85f64-5717-4562-b3fc-2c963f66afa8"], "custom_variables": [ { @@ -710,6 +720,7 @@ type EmailTemplateRequest = { system_template?: boolean created_by?: string updated_by?: string + json_template?: string } ``` @@ -764,6 +775,7 @@ type EmailTemplateEntity = { } created_by?: string updated_by?: string + json_template?: string system_template?: boolean } ``` @@ -935,6 +947,7 @@ type EmailTemplateResponse = { } created_by?: string updated_by?: string + json_template?: string system_template?: boolean } relations?: object[] @@ -975,6 +988,7 @@ type AsyncEmailTemplateResponse = { file?: { ... } created_by?: { ... } updated_by?: { ... } + json_template?: { ... } system_template?: { ... } } relations?: object[] @@ -990,6 +1004,14 @@ When true, it lets to send only the email by skip creating the thread & message type SkipCreatingEntities = boolean ``` +### `CompleteThread` + +Whether the thread is marked as Done immediately after sending the message + +```ts +type CompleteThread = boolean +``` + ### `BulkSendMessageRequest` It takes a list of entity ids, treating each as a separate mainEntity to construct individual messages. @@ -999,6 +1021,7 @@ For e.g; if there some opportunityIds are provided, then each opportunityId is t ```ts type BulkSendMessageRequest = { skip_creating_entities?: boolean + complete_thread?: boolean email_template_id: string must_include_unsubscribe_link?: boolean recipient_ids: string[] @@ -1018,6 +1041,7 @@ For e.g; if the query is provided as `_schema:opportunity AND status:PENDING`, ```ts type BulkSendMessageRequestWithQuery = { skip_creating_entities?: boolean + complete_thread?: boolean email_template_id: string must_include_unsubscribe_link?: boolean recipient_query: string @@ -1046,9 +1070,11 @@ type BulkSendMessageJob = { org_id?: string job_id: string skip_creating_entities?: boolean + complete_thread?: boolean status: "PROCESSING" | "QUEUEING" | "APPROVAL" | "SENDING" | "SUCCESS" | "FAILED" | "CANCELLED" request: { skip_creating_entities?: boolean + complete_thread?: boolean email_template_id: string must_include_unsubscribe_link?: boolean recipient_ids: string[] @@ -1058,6 +1084,7 @@ type BulkSendMessageJob = { }> } | { skip_creating_entities?: boolean + complete_thread?: boolean email_template_id: string must_include_unsubscribe_link?: boolean recipient_query: string diff --git a/docs/sdk/clients/entity-mapping.md b/docs/sdk/clients/entity-mapping.md index 5fd958cd..2e10494e 100644 --- a/docs/sdk/clients/entity-mapping.md +++ b/docs/sdk/clients/entity-mapping.md @@ -68,6 +68,12 @@ const { data } = await entityMappingClient.storeConfig(...) - [`MapCondition`](#mapcondition) - [`ConditionNode`](#conditionnode) - [`RelationAttribute`](#relationattribute) +- [`GraphContextEntry`](#graphcontextentry) +- [`GraphSeed`](#graphseed) +- [`GraphDefinition`](#graphdefinition) +- [`GraphNode`](#graphnode) +- [`GraphNodeFilter`](#graphnodefilter) +- [`GraphEdge`](#graphedge) - [`MappingAttributeV2`](#mappingattributev2) - [`AttributeOrigin`](#attributeorigin) - [`OperationNode`](#operationnode) @@ -111,66 +117,15 @@ const { data } = await client.storeConfig( allow_failure: true, target_schema: 'string', target_unique: ['string'], - loop_config: { - source_path: 'string', - length: 'the length of the array' - }, + use_uniqueness_criteria: false, + loop_config: { /* ... */ }, conditionMode: 'oneOf', - conditions: [ - { - _exists: { - source: 'string', - value: 'string' - }, - _equals: { - source: 'string', - value: 'string' - }, - _not_exists: { - source: 'string', - value: 'string' - }, - _any_of: { - source: 'string', - value: 'string' - } - } - ], - mapping_attributes: [ - { - target: '_tags', - operation: { - _append: ['new', 'tags'], - _uniq: true - } - }, - { - mode: 'copy_if_exists', - target: 'string', - value: {} - } - ], - relation_attributes: [ - { - target: 'string', - target_tags: ['string'], - target_tags_include_source: false, - override_with_source_filter: false, - source_filter: { - limit: 0, - schema: 'string', - attribute: 'string', - relation_tag: 'string', - tag: 'string', - self: false - }, - related_to: {}, - mode: 'append', - origin: 'system_recommendation' - } - ], + conditions: [ /* ... */ ], + mapping_attributes: [ /* ... */ ], + relation_attributes: [ /* ... */ ], linkback_relation_attribute: 'mapped_entities', - linkback_relation_tags: ['string'] + linkback_relation_tags: ['string'], + graph_context: [ /* ... */ ] } ], created_at: '1970-01-01T00:00:00.000Z', @@ -210,66 +165,15 @@ const { data } = await client.storeConfig( "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -324,66 +228,15 @@ const { data } = await client.getConfig({ "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -438,66 +291,15 @@ const { data } = await client.deleteConfig({ "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -541,93 +343,12 @@ const { data } = await client.getAllVersions({ "configs": [ { "id": "string", - "source": { - "type": "journey", - "config": { - "journey_id": "string" - } - }, - "targets": [ - { - "id": "string", - "name": "string", - "allow_failure": true, - "target_schema": "string", - "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, - "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], - "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] - } - ], + "source": {}, + "targets": [], "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", - "created_by": { - "type": "user", - "org_id": "string", - "user_id": "string" - }, - "last_updated_by": { - "type": "user", - "org_id": "string", - "user_id": "string" - }, + "created_by": {}, + "last_updated_by": {}, "org_id": "66", "version": 2 } @@ -665,66 +386,15 @@ const { data } = await client.storeNewVersion( allow_failure: true, target_schema: 'string', target_unique: ['string'], - loop_config: { - source_path: 'string', - length: 'the length of the array' - }, + use_uniqueness_criteria: false, + loop_config: { /* ... */ }, conditionMode: 'oneOf', - conditions: [ - { - _exists: { - source: 'string', - value: 'string' - }, - _equals: { - source: 'string', - value: 'string' - }, - _not_exists: { - source: 'string', - value: 'string' - }, - _any_of: { - source: 'string', - value: 'string' - } - } - ], - mapping_attributes: [ - { - target: '_tags', - operation: { - _append: ['new', 'tags'], - _uniq: true - } - }, - { - mode: 'copy_if_exists', - target: 'string', - value: {} - } - ], - relation_attributes: [ - { - target: 'string', - target_tags: ['string'], - target_tags_include_source: false, - override_with_source_filter: false, - source_filter: { - limit: 0, - schema: 'string', - attribute: 'string', - relation_tag: 'string', - tag: 'string', - self: false - }, - related_to: {}, - mode: 'append', - origin: 'system_recommendation' - } - ], + conditions: [ /* ... */ ], + mapping_attributes: [ /* ... */ ], + relation_attributes: [ /* ... */ ], linkback_relation_attribute: 'mapped_entities', - linkback_relation_tags: ['string'] + linkback_relation_tags: ['string'], + graph_context: [ /* ... */ ] } ], created_at: '1970-01-01T00:00:00.000Z', @@ -764,66 +434,15 @@ const { data } = await client.storeNewVersion( "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -879,66 +498,15 @@ const { data } = await client.getConfigVersion({ "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -978,6 +546,10 @@ const { data } = await client.executeMapping( entity_id: 'string', entity_schema: 'submission' }, + loop_ref: { + entity_id: 'string', + entity_schema: 'submission' + }, targets: [ { id: 'string', @@ -985,66 +557,15 @@ const { data } = await client.executeMapping( allow_failure: true, target_schema: 'string', target_unique: ['string'], - loop_config: { - source_path: 'string', - length: 'the length of the array' - }, + use_uniqueness_criteria: false, + loop_config: { /* ... */ }, conditionMode: 'oneOf', - conditions: [ - { - _exists: { - source: 'string', - value: 'string' - }, - _equals: { - source: 'string', - value: 'string' - }, - _not_exists: { - source: 'string', - value: 'string' - }, - _any_of: { - source: 'string', - value: 'string' - } - } - ], - mapping_attributes: [ - { - target: '_tags', - operation: { - _append: ['new', 'tags'], - _uniq: true - } - }, - { - mode: 'copy_if_exists', - target: 'string', - value: {} - } - ], - relation_attributes: [ - { - target: 'string', - target_tags: ['string'], - target_tags_include_source: false, - override_with_source_filter: false, - source_filter: { - limit: 0, - schema: 'string', - attribute: 'string', - relation_tag: 'string', - tag: 'string', - self: false - }, - related_to: {}, - mode: 'append', - origin: 'system_recommendation' - } - ], + conditions: [ /* ... */ ], + mapping_attributes: [ /* ... */ ], + relation_attributes: [ /* ... */ ], linkback_relation_attribute: 'mapped_entities', - linkback_relation_tags: ['string'] + linkback_relation_tags: ['string'], + graph_context: [ /* ... */ ] } ] }, @@ -1070,77 +591,8 @@ const { data } = await client.executeMapping( ], "failures": [ { - "target": { - "id": "string", - "name": "string", - "allow_failure": true, - "target_schema": "string", - "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, - "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], - "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] - }, - "error": { - "isSilent": true, - "message": "string" - } + "target": {}, + "error": {} } ], "warnings": [ @@ -1196,66 +648,15 @@ const { data } = await client.searchConfigs( "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -1329,6 +730,7 @@ const { data } = await client.executeRelations( target: 'string', target_tags: ['string'], target_tags_include_source: false, + target_entity_tags: ['string'], override_with_source_filter: false, source_filter: { limit: 0, @@ -1409,66 +811,15 @@ const { data } = await client.getMappingConfig({ "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -1518,66 +869,15 @@ const { data } = await client.putMappingConfig( allow_failure: true, target_schema: 'string', target_unique: ['string'], - loop_config: { - source_path: 'string', - length: 'the length of the array' - }, + use_uniqueness_criteria: false, + loop_config: { /* ... */ }, conditionMode: 'oneOf', - conditions: [ - { - _exists: { - source: 'string', - value: 'string' - }, - _equals: { - source: 'string', - value: 'string' - }, - _not_exists: { - source: 'string', - value: 'string' - }, - _any_of: { - source: 'string', - value: 'string' - } - } - ], - mapping_attributes: [ - { - target: '_tags', - operation: { - _append: ['new', 'tags'], - _uniq: true - } - }, - { - mode: 'copy_if_exists', - target: 'string', - value: {} - } - ], - relation_attributes: [ - { - target: 'string', - target_tags: ['string'], - target_tags_include_source: false, - override_with_source_filter: false, - source_filter: { - limit: 0, - schema: 'string', - attribute: 'string', - relation_tag: 'string', - tag: 'string', - self: false - }, - related_to: {}, - mode: 'append', - origin: 'system_recommendation' - } - ], + conditions: [ /* ... */ ], + mapping_attributes: [ /* ... */ ], + relation_attributes: [ /* ... */ ], linkback_relation_attribute: 'mapped_entities', - linkback_relation_tags: ['string'] + linkback_relation_tags: ['string'], + graph_context: [ /* ... */ ] } ], created_at: '1970-01-01T00:00:00.000Z', @@ -1617,66 +917,15 @@ const { data } = await client.putMappingConfig( "allow_failure": true, "target_schema": "string", "target_unique": ["string"], - "loop_config": { - "source_path": "string", - "length": "the length of the array" - }, + "use_uniqueness_criteria": false, + "loop_config": {}, "conditionMode": "oneOf", - "conditions": [ - { - "_exists": { - "source": "string", - "value": "string" - }, - "_equals": { - "source": "string", - "value": "string" - }, - "_not_exists": { - "source": "string", - "value": "string" - }, - "_any_of": { - "source": "string", - "value": "string" - } - } - ], - "mapping_attributes": [ - { - "target": "_tags", - "operation": { - "_append": ["new", "tags"], - "_uniq": true - } - }, - { - "mode": "copy_if_exists", - "target": "string", - "value": {} - } - ], - "relation_attributes": [ - { - "target": "string", - "target_tags": ["string"], - "target_tags_include_source": false, - "override_with_source_filter": false, - "source_filter": { - "limit": 0, - "schema": "string", - "attribute": "string", - "relation_tag": "string", - "tag": "string", - "self": false - }, - "related_to": {}, - "mode": "append", - "origin": "system_recommendation" - } - ], + "conditions": [], + "mapping_attributes": [], + "relation_attributes": [], "linkback_relation_attribute": "mapped_entities", - "linkback_relation_tags": ["string"] + "linkback_relation_tags": ["string"], + "graph_context": [] } ], "created_at": "1970-01-01T00:00:00.000Z", @@ -1734,6 +983,7 @@ type MappingConfigsResp = { allow_failure?: { ... } target_schema: { ... } target_unique?: { ... } + use_uniqueness_criteria?: { ... } loop_config?: { ... } conditionMode?: { ... } conditions?: { ... } @@ -1741,6 +991,7 @@ type MappingConfigsResp = { relation_attributes?: { ... } linkback_relation_attribute?: { ... } linkback_relation_tags?: { ... } + graph_context?: { ... } }> created_at?: string // date-time updated_at?: string // date-time @@ -1780,8 +1031,11 @@ type MappingConfigs = Array<{ allow_failure?: boolean target_schema: string target_unique?: string[] + use_uniqueness_criteria?: boolean loop_config?: { source_path?: { ... } + source_type?: { ... } + filter_tags?: { ... } length?: { ... } } conditionMode?: "oneOf" | "anyOf" | "allOf" @@ -1814,6 +1068,7 @@ type MappingConfigs = Array<{ target: { ... } target_tags?: { ... } target_tags_include_source?: { ... } + target_entity_tags?: { ... } override_with_source_filter?: { ... } source_filter?: { ... } related_to?: { ... } @@ -1822,6 +1077,10 @@ type MappingConfigs = Array<{ }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> }> created_at?: string // date-time updated_at?: string // date-time @@ -1860,8 +1119,11 @@ type MappingConfig = { allow_failure?: boolean target_schema: string target_unique?: string[] + use_uniqueness_criteria?: boolean loop_config?: { source_path?: { ... } + source_type?: { ... } + filter_tags?: { ... } length?: { ... } } conditionMode?: "oneOf" | "anyOf" | "allOf" @@ -1894,6 +1156,7 @@ type MappingConfig = { target: { ... } target_tags?: { ... } target_tags_include_source?: { ... } + target_entity_tags?: { ... } override_with_source_filter?: { ... } source_filter?: { ... } related_to?: { ... } @@ -1902,6 +1165,10 @@ type MappingConfig = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> }> created_at?: string // date-time updated_at?: string // date-time @@ -1940,8 +1207,11 @@ type MappingConfigV2 = { allow_failure?: boolean target_schema: string target_unique?: string[] + use_uniqueness_criteria?: boolean loop_config?: { source_path?: { ... } + source_type?: { ... } + filter_tags?: { ... } length?: { ... } } conditionMode?: "oneOf" | "anyOf" | "allOf" @@ -1974,6 +1244,7 @@ type MappingConfigV2 = { target: { ... } target_tags?: { ... } target_tags_include_source?: { ... } + target_entity_tags?: { ... } override_with_source_filter?: { ... } source_filter?: { ... } related_to?: { ... } @@ -1982,6 +1253,10 @@ type MappingConfigV2 = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> }> created_at?: string // date-time updated_at?: string // date-time @@ -2020,8 +1295,11 @@ type MappingConfigCommonFields = { allow_failure?: boolean target_schema: string target_unique?: string[] + use_uniqueness_criteria?: boolean loop_config?: { source_path?: { ... } + source_type?: { ... } + filter_tags?: { ... } length?: { ... } } conditionMode?: "oneOf" | "anyOf" | "allOf" @@ -2054,6 +1332,7 @@ type MappingConfigCommonFields = { target: { ... } target_tags?: { ... } target_tags_include_source?: { ... } + target_entity_tags?: { ... } override_with_source_filter?: { ... } source_filter?: { ... } related_to?: { ... } @@ -2062,6 +1341,10 @@ type MappingConfigCommonFields = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> }> created_at?: string // date-time updated_at?: string // date-time @@ -2107,6 +1390,7 @@ type ExecuteRelationsReq = { target: { ... } target_tags?: { ... } target_tags_include_source?: { ... } + target_entity_tags?: { ... } override_with_source_filter?: { ... } source_filter?: { ... } related_to?: { ... } @@ -2168,14 +1452,21 @@ type ExecuteMappingReq = { entity_id: string entity_schema?: string } + loop_ref?: { + entity_id: string + entity_schema?: string + } targets: Array<{ id?: string name?: string allow_failure?: boolean target_schema: string target_unique?: string[] + use_uniqueness_criteria?: boolean loop_config?: { source_path?: { ... } + source_type?: { ... } + filter_tags?: { ... } length?: { ... } } conditionMode?: "oneOf" | "anyOf" | "allOf" @@ -2208,6 +1499,7 @@ type ExecuteMappingReq = { target: { ... } target_tags?: { ... } target_tags_include_source?: { ... } + target_entity_tags?: { ... } override_with_source_filter?: { ... } source_filter?: { ... } related_to?: { ... } @@ -2216,6 +1508,10 @@ type ExecuteMappingReq = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> }> } ``` @@ -2241,6 +1537,7 @@ type ExecuteMappingResp = { allow_failure?: { ... } target_schema: { ... } target_unique?: { ... } + use_uniqueness_criteria?: { ... } loop_config?: { ... } conditionMode?: { ... } conditions?: { ... } @@ -2248,6 +1545,7 @@ type ExecuteMappingResp = { relation_attributes?: { ... } linkback_relation_attribute?: { ... } linkback_relation_tags?: { ... } + graph_context?: { ... } } error?: { isSilent?: { ... } @@ -2272,8 +1570,11 @@ type MappingFailure = { allow_failure?: boolean target_schema: string target_unique?: string[] + use_uniqueness_criteria?: boolean loop_config?: { source_path?: { ... } + source_type?: { ... } + filter_tags?: { ... } length?: { ... } } conditionMode?: "oneOf" | "anyOf" | "allOf" @@ -2306,6 +1607,7 @@ type MappingFailure = { target: { ... } target_tags?: { ... } target_tags_include_source?: { ... } + target_entity_tags?: { ... } override_with_source_filter?: { ... } source_filter?: { ... } related_to?: { ... } @@ -2314,6 +1616,10 @@ type MappingFailure = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> } error?: { isSilent?: boolean @@ -2395,8 +1701,11 @@ type TargetConfig = { allow_failure?: boolean target_schema: string target_unique?: string[] + use_uniqueness_criteria?: boolean loop_config?: { source_path?: string + source_type?: "journey-multi-select" | "journey-file-upload" + filter_tags?: string[] length?: number } conditionMode?: "oneOf" | "anyOf" | "allOf" @@ -2429,6 +1738,9 @@ type TargetConfig = { _copy?: { ... } _template?: { ... } _random?: { ... } + _each?: { ... } + _as?: { ... } + _map?: { ... } } | string | boolean | number | Record | unknown[] origin?: "system_recommendation" | "user_manually" | "entity_updating_system_recommendation" } | { @@ -2450,6 +1762,7 @@ type TargetConfig = { target: string target_tags?: string[] target_tags_include_source?: boolean + target_entity_tags?: string[] override_with_source_filter?: boolean source_filter?: { limit?: { ... } @@ -2465,6 +1778,16 @@ type TargetConfig = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { + entity_id: { ... } + node_id: { ... } + } + graph: { + nodes: { ... } + edges: { ... } + } + }> } ``` @@ -2507,6 +1830,7 @@ type RelationAttribute = { target: string target_tags?: string[] target_tags_include_source?: boolean + target_entity_tags?: string[] override_with_source_filter?: boolean source_filter?: { limit?: number @@ -2522,6 +1846,111 @@ type RelationAttribute = { } ``` +### `GraphContextEntry` + +One multi-hop graph lookup against entity-api's `POST /v1/entity:graph`, resolved during +graph_context enrichment (before mapping_attributes are evaluated). Every node in `graph.nodes` +is merged into sourceContext under its own `id`, so listing several nodes here costs one +entity-api call, not one p + +```ts +type GraphContextEntry = { + seed: { + entity_id: string + node_id: string + } + graph: { + nodes: Array<{ + id: { ... } + schema: { ... } + cardinality?: { ... } + fields?: { ... } + filter?: { ... } + optional?: { ... } + }> + edges: Array<{ + from: { ... } + to: { ... } + }> + } +} +``` + +### `GraphSeed` + +Mirrors entity-api's GraphSeed (see entity-api openapi.yml) - the entity the graph traversal starts from. + +```ts +type GraphSeed = { + entity_id: string + node_id: string +} +``` + +### `GraphDefinition` + +Mirrors entity-api's GraphDefinition (see entity-api openapi.yml) - the shape of the graph to traverse. + +```ts +type GraphDefinition = { + nodes: Array<{ + id: string + schema: string + cardinality?: "one" | "many" + fields?: string[] + filter?: Array<{ + attribute: { ... } + value: { ... } + }> + optional?: boolean + }> + edges: Array<{ + from: string + to: string + }> +} +``` + +### `GraphNode` + +Mirrors entity-api's GraphNode (see entity-api openapi.yml). + +```ts +type GraphNode = { + id: string + schema: string + cardinality?: "one" | "many" + fields?: string[] + filter?: Array<{ + attribute: string + value: string | number | boolean + }> + optional?: boolean +} +``` + +### `GraphNodeFilter` + +Mirrors entity-api's GraphNodeFilter (see entity-api openapi.yml). + +```ts +type GraphNodeFilter = { + attribute: string + value: string | number | boolean +} +``` + +### `GraphEdge` + +Mirrors entity-api's GraphEdge (see entity-api openapi.yml). + +```ts +type GraphEdge = { + from: string + to: string +} +``` + ### `MappingAttributeV2` ```ts @@ -2542,6 +1971,9 @@ type MappingAttributeV2 = { min?: { ... } max?: { ... } } + _each?: string + _as?: string + _map?: { ... } } | string | boolean | number | Record | unknown[] origin?: "system_recommendation" | "user_manually" | "entity_updating_system_recommendation" } @@ -2575,6 +2007,9 @@ type OperationNode = { min?: number max?: number } + _each?: string + _as?: string + _map?: { ... } } | string | boolean | number | Record | unknown[] ``` @@ -2596,6 +2031,9 @@ type OperationObjectNode = { min?: number max?: number } + _each?: string + _as?: string + _map?: { ... } | string | boolean | number | Record | unknown[] } ``` @@ -2712,6 +2150,7 @@ type MappingHistoryResp = { allow_failure?: { ... } target_schema: { ... } target_unique?: { ... } + use_uniqueness_criteria?: { ... } loop_config?: { ... } conditionMode?: { ... } conditions?: { ... } @@ -2719,6 +2158,7 @@ type MappingHistoryResp = { relation_attributes?: { ... } linkback_relation_attribute?: { ... } linkback_relation_tags?: { ... } + graph_context?: { ... } }> }> } @@ -2756,8 +2196,11 @@ type MappingHistoryEntry = { allow_failure?: boolean target_schema: string target_unique?: string[] + use_uniqueness_criteria?: boolean loop_config?: { source_path?: { ... } + source_type?: { ... } + filter_tags?: { ... } length?: { ... } } conditionMode?: "oneOf" | "anyOf" | "allOf" @@ -2790,6 +2233,7 @@ type MappingHistoryEntry = { target: { ... } target_tags?: { ... } target_tags_include_source?: { ... } + target_entity_tags?: { ... } override_with_source_filter?: { ... } source_filter?: { ... } related_to?: { ... } @@ -2798,6 +2242,10 @@ type MappingHistoryEntry = { }> linkback_relation_attribute?: string linkback_relation_tags?: string[] + graph_context?: Array<{ + seed: { ... } + graph: { ... } + }> }> } ``` @@ -2821,6 +2269,7 @@ type MappingSource = { target: string target_tags?: string[] target_tags_include_source?: boolean + target_entity_tags?: string[] override_with_source_filter?: boolean source_filter?: { limit?: { ... } diff --git a/docs/sdk/clients/entity-ui.md b/docs/sdk/clients/entity-ui.md new file mode 100644 index 00000000..47876475 --- /dev/null +++ b/docs/sdk/clients/entity-ui.md @@ -0,0 +1,313 @@ +--- +title: "Entity UI API" +description: "TypeScript SDK client for the epilot Entity UI API: usage with @epilot/sdk, all operations and schemas." +--- + +# Entity UI API + +- **Base URL:** `https://entity-ui.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/entity-ui](https://docs.epilot.io/api/entity-ui) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.entityUi.putWidgetDefinition(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/entity-ui' + +const entityUiClient = getClient() +authorize(entityUiClient, () => '') +const { data } = await entityUiClient.putWidgetDefinition(...) +``` + +## Operations + +**Widget Definitions** +- [`putWidgetDefinition`](#putwidgetdefinition) +- [`getWidgetDefinition`](#getwidgetdefinition) +- [`batchGetWidgetDefinitions`](#batchgetwidgetdefinitions) + +**Schemas** +- [`WidgetDefinitionRef`](#widgetdefinitionref) +- [`WidgetDefinitionRefResponse`](#widgetdefinitionrefresponse) +- [`WidgetDefinition`](#widgetdefinition) +- [`WidgetManifest`](#widgetmanifest) +- [`WidgetRelations`](#widgetrelations) +- [`WidgetStrings`](#widgetstrings) +- [`WidgetStringTable`](#widgetstringtable) +- [`WidgetSuggestions`](#widgetsuggestions) +- [`BatchGetWidgetDefinitionsRequest`](#batchgetwidgetdefinitionsrequest) +- [`BatchGetWidgetDefinitionsResponse`](#batchgetwidgetdefinitionsresponse) +- [`ErrorResponse`](#errorresponse) + +### `putWidgetDefinition` + +Stores a widget definition and returns its `ref`. + +`PUT /v1/entity-ui/widget-definitions` + +```ts +const { data } = await client.putWidgetDefinition( + null, + { + version: 1, + prompt: 'string', + manifest: { + relations: {}, + libs: ['echarts'], + icons: ['string'] + }, + html: 'string', + strings: { + de: {}, + en: {} + }, + suggestions: { + de: ['string'], + en: ['string'] + } + }, +) +``` + +
+Response + +```json +{ + "ref": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" +} +``` + +
+ +--- + +### `getWidgetDefinition` + +Returns a stored widget definition in its canonical form. + +`GET /v1/entity-ui/widget-definitions/{ref}` + +```ts +const { data } = await client.getWidgetDefinition({ + ref: 'example', +}) +``` + +
+Response + +```json +{ + "version": 1, + "prompt": "string", + "manifest": { + "relations": {}, + "libs": ["echarts"], + "icons": ["string"] + }, + "html": "string", + "strings": { + "de": {}, + "en": {} + }, + "suggestions": { + "de": ["string"], + "en": ["string"] + } +} +``` + +
+ +--- + +### `batchGetWidgetDefinitions` + +Returns up to 20 stored widget definitions by `ref`. Refs that are not stored in the organization are +listed in `missing`. + +`POST /v1/entity-ui/widget-definitions/batch-get` + +```ts +const { data } = await client.batchGetWidgetDefinitions( + null, + { + refs: ['9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'] + }, +) +``` + +
+Response + +```json +{ + "definitions": {}, + "missing": ["9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"] +} +``` + +
+ +--- + +## Schemas + +### `WidgetDefinitionRef` + +Lowercase hex SHA-256 of the definition's RFC 8785 canonical JSON + +```ts +type WidgetDefinitionRef = string +``` + +### `WidgetDefinitionRefResponse` + +```ts +type WidgetDefinitionRefResponse = { + ref: string +} +``` + +### `WidgetDefinition` + +Version 1 of an AI widget definition. Unknown keys are rejected at every level, because any extra key would +produce a different `ref` for an otherwise identical definition. + + +```ts +type WidgetDefinition = { + version: 1 + prompt: string + manifest: { + relations: { + mode?: { ... } + } | { + mode?: { ... } + schemas?: { ... } + } + libs: "echarts"[] + icons?: string[] + } + html: string + strings: { + de: Record + en: Record + } + suggestions?: { + de: string[] + en: string[] + } +} +``` + +### `WidgetManifest` + +```ts +type WidgetManifest = { + relations: { + mode?: "direct" | "reverse" | "both" + } | { + mode?: "none" + schemas?: unknown + } + libs: "echarts"[] + icons?: string[] +} +``` + +### `WidgetRelations` + +```ts +type WidgetRelations = { + mode?: "direct" | "reverse" | "both" +} | { + mode?: "none" + schemas?: unknown +} +``` + +### `WidgetStrings` + +Localized string tables; both include `title` + +```ts +type WidgetStrings = { + de: Record + en: Record +} +``` + +### `WidgetStringTable` + +String table of one locale. Keys are what the widget passes to `t()`; both tables include `title`. + +Every key must match `^[a-z0-9_]{1,64}$` (snake_case, at most 64 characters) and may not be `__proto__`. The +server enforces this and answers `400` naming the offending key; OpenAPI 3.0 has no keyword + +```ts +type WidgetStringTable = Record +``` + +### `WidgetSuggestions` + +```ts +type WidgetSuggestions = { + de: string[] + en: string[] +} +``` + +### `BatchGetWidgetDefinitionsRequest` + +```ts +type BatchGetWidgetDefinitionsRequest = { + refs: string[] +} +``` + +### `BatchGetWidgetDefinitionsResponse` + +```ts +type BatchGetWidgetDefinitionsResponse = { + definitions: Record + missing: string[] +} +``` + +### `ErrorResponse` + +Standard error response format for all API errors + +```ts +type ErrorResponse = { + error: string | object[] + status: number +} +``` diff --git a/docs/sdk/clients/entity.md b/docs/sdk/clients/entity.md index 031c7894..51eaa181 100644 --- a/docs/sdk/clients/entity.md +++ b/docs/sdk/clients/entity.md @@ -31,9 +31,11 @@ const { data } = await entityClient.listSchemas(...) **Schemas** - [`listSchemas`](#listschemas) +- [`listSchemasV2`](#listschemasv2) - [`getSchema`](#getschema) - [`putSchema`](#putschema) - [`deleteSchema`](#deleteschema) +- [`getSchemaHead`](#getschemahead) - [`getJsonSchema`](#getjsonschema) - [`getSchemaExample`](#getschemaexample) - [`getSchemaVersions`](#getschemaversions) @@ -74,6 +76,10 @@ const { data } = await entityClient.listSchemas(...) - [`deleteEntity`](#deleteentity) - [`autocomplete`](#autocomplete) - [`wipeAllEntities`](#wipeallentities) +- [`listWipeJobs`](#listwipejobs) +- [`applyChangeset`](#applychangeset) +- [`dismissChangeset`](#dismisschangeset) +- [`listChangesets`](#listchangesets) **Activity** - [`createActivity`](#createactivity) @@ -81,6 +87,9 @@ const { data } = await entityClient.listSchemas(...) - [`attachActivity`](#attachactivity) - [`getEntityActivityFeed`](#getentityactivityfeed) +**AI** +- [`getEntitySummary`](#getentitysummary) + **Relations** - [`getRelations`](#getrelations) - [`addRelations`](#addrelations) @@ -94,6 +103,10 @@ const { data } = await entityClient.listSchemas(...) **Import-Export** - [`exportEntities`](#exportentities) - [`importEntities`](#importentities) +- [`getLatestEntityImport`](#getlatestentityimport) +- [`getEntityImportHistory`](#getentityimporthistory) +- [`abortEntityImport`](#abortentityimport) +- [`discardEntityImport`](#discardentityimport) **Saved Views** - [`listSavedViews`](#listsavedviews) @@ -130,6 +143,10 @@ const { data } = await entityClient.listSchemas(...) - [`IsTemplate`](#istemplate) - [`SchemaId`](#schemaid) - [`EntitySchema`](#entityschema) +- [`SchemaHead`](#schemahead) +- [`WipeJob`](#wipejob) +- [`WipeJobConflictError`](#wipejobconflicterror) +- [`SchemaVersionConflictError`](#schemaversionconflicterror) - [`EntitySchemaItem`](#entityschemaitem) - [`GenerateEntityTableAIFiltersRequest`](#generateentitytableaifiltersrequest) - [`GenerateEntityTableAIFiltersResponse`](#generateentitytableaifiltersresponse) @@ -158,6 +175,7 @@ const { data } = await entityClient.listSchemas(...) - [`UserRelationAttribute`](#userrelationattribute) - [`PartnerOrganisationAttribute`](#partnerorganisationattribute) - [`PortalAccessAttribute`](#portalaccessattribute) +- [`PortalRoleAttribute`](#portalroleattribute) - [`DefaultAddressFields`](#defaultaddressfields) - [`AddressAttribute`](#addressattribute) - [`AddressRelationAttribute`](#addressrelationattribute) @@ -170,6 +188,7 @@ const { data } = await entityClient.listSchemas(...) - [`TagsAttribute`](#tagsattribute) - [`MessageEmailAddressAttribute`](#messageemailaddressattribute) - [`NumberAttribute`](#numberattribute) +- [`TableAttribute`](#tableattribute) - [`ConsentAttribute`](#consentattribute) - [`OrderedListAttribute`](#orderedlistattribute) - [`EmailAttribute`](#emailattribute) @@ -181,7 +200,13 @@ const { data } = await entityClient.listSchemas(...) - [`SummaryAttribute`](#summaryattribute) - [`GroupHeadline`](#groupheadline) - [`GroupHeadlineWithCompositeID`](#groupheadlinewithcompositeid) +- [`BaseConditionDefinition`](#baseconditiondefinition) +- [`ScalarConditionDefinition`](#scalarconditiondefinition) +- [`SelectConditionDefinition`](#selectconditiondefinition) +- [`LocationConditionDefinition`](#locationconditiondefinition) +- [`ConditionDefinition`](#conditiondefinition) - [`EntitySlug`](#entityslug) +- [`AdjustInstallmentCapabilityConfig`](#adjustinstallmentcapabilityconfig) - [`EntityCapability`](#entitycapability) - [`EntityCapabilityWithCompositeID`](#entitycapabilitywithcompositeid) - [`EntityViewDisabled`](#entityviewdisabled) @@ -219,10 +244,16 @@ const { data } = await entityClient.listSchemas(...) - [`EntitySearchOptions`](#entitysearchoptions) - [`FieldsParam`](#fieldsparam) - [`EntityImportParams`](#entityimportparams) +- [`ImportRowOutcomeCounts`](#importrowoutcomecounts) +- [`ImportJobSummary`](#importjobsummary) +- [`ImportIssue`](#importissue) +- [`ImportFailureCode`](#importfailurecode) +- [`ImportProgress`](#importprogress) - [`GraphQueryRequest`](#graphqueryrequest) - [`GraphSeed`](#graphseed) - [`GraphDefinition`](#graphdefinition) - [`GraphNode`](#graphnode) +- [`GraphNodeFilter`](#graphnodefilter) - [`GraphEdge`](#graphedge) - [`GraphQueryResponse`](#graphqueryresponse) - [`EntitySearchResults`](#entitysearchresults) @@ -232,8 +263,10 @@ const { data } = await entityClient.listSchemas(...) - [`ActivityType`](#activitytype) - [`Activity`](#activity) - [`EntityOperation`](#entityoperation) +- [`EntityOperationSourceContext`](#entityoperationsourcecontext) - [`BaseActivityItem`](#baseactivityitem) - [`ActivityItem`](#activityitem) +- [`EntitySummary`](#entitysummary) - [`BlueprintEntityId`](#blueprintentityid) - [`ListSavedViewsResults`](#listsavedviewsresults) - [`SavedViewId`](#savedviewid) @@ -256,6 +289,14 @@ const { data } = await entityClient.listSchemas(...) - [`ESClusterAssignment`](#esclusterassignment) - [`SettingFlag`](#settingflag) - [`ErrorObject`](#errorobject) +- [`ChangesetCreator`](#changesetcreator) +- [`Changeset`](#changeset) +- [`ChangesetMap`](#changesetmap) +- [`MeterReadingChangesetEntry`](#meterreadingchangesetentry) +- [`EditMode`](#editmode) +- [`EditModeConfig`](#editmodeconfig) +- [`FuzzyConfig`](#fuzzyconfig) +- [`MatchStrategy`](#matchstrategy) ### `listSchemas` @@ -266,7 +307,77 @@ Get the latest versions of all schemas ```ts const { data } = await client.listSchemas({ unpublished: true, + latest: true, + exclude: ['...'], + include: ['...'], +}) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "created_at": "string", + "updated_at": "string", + "comment": "string", + "source": {}, + "frozen": true, + "latest": true, + "_summary": true, + "slug": "contact", + "version": 1, + "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "feature_flag": "FF_MY_FEATURE_FLAG", + "enable_setting": ["360_features"], + "name": "Contact", + "plural": "Contacts", + "description": "Example description", + "docs_url": "https://docs.epilot.io/docs/pricing/entities", + "category": "customer_relations", + "published": false, + "draft": false, + "require_change_comment": false, + "icon": "person", + "title_template": "{{first_name}} {{last_name}}", + "ui_config": {}, + "capabilities": [], + "group_settings": [], + "layout_settings": {}, + "dialog_config": {}, + "attributes": [], + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "explicit_search_mappings": {}, + "group_headlines": [], + "conditions": [] + } + ] +} +``` + +
+ +--- + +### `listSchemasV2` + +Get the latest versions of all schemas. +Returns summary schemas by default (only summary attributes, no capabilities). +Use ?full=true for complete schemas. + +`GET /v2/entity/schemas` + +```ts +const { data } = await client.listSchemasV2({ + full: true, + unpublished: true, + latest: true, exclude: ['...'], + include: ['...'], }) ``` @@ -282,6 +393,9 @@ const { data } = await client.listSchemas({ "updated_at": "string", "comment": "string", "source": {}, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -294,6 +408,7 @@ const { data } = await client.listSchemas({ "category": "customer_relations", "published": false, "draft": false, + "require_change_comment": false, "icon": "person", "title_template": "{{first_name}} {{last_name}}", "ui_config": {}, @@ -303,8 +418,10 @@ const { data } = await client.listSchemas({ "dialog_config": {}, "attributes": [], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": {}, - "group_headlines": [] + "group_headlines": [], + "conditions": [] } ] } @@ -316,7 +433,8 @@ const { data } = await client.listSchemas({ ### `getSchema` -By default gets the latest version of the Schema and to get the specific version of schema pass the id. +Gets the latest version of the Schema. +Pass ?id= to get a specific version by ID. `GET /v1/entity/schemas/{slug}` @@ -324,6 +442,7 @@ By default gets the latest version of the Schema and to get the specific version const { data } = await client.getSchema({ slug: 'example', id: '123e4567-e89b-12d3-a456-426614174000', + latest: true, }) ``` @@ -340,6 +459,9 @@ const { data } = await client.getSchema({ "id": "string", "type": "string" }, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -352,6 +474,7 @@ const { data } = await client.getSchema({ "category": "customer_relations", "published": false, "draft": false, + "require_change_comment": false, "icon": "person", "title_template": "{{first_name}} {{last_name}}", "ui_config": { @@ -383,7 +506,24 @@ const { data } = await client.getSchema({ }, "sharing": { "show_sharing_button": true - } + }, + "grid_layout": { + "id": "string", + "columns": 0, + "cells": [0] + }, + "widget_order": ["string"], + "widget_visibility": { + "next_best_action": true, + "address_map": false + }, + "widget_widths": { + "address_map": "full_width", + "recent_communications": "one_third_width" + }, + "custom_tabs": [ + {} + ] }, "capabilities": [ { @@ -391,13 +531,17 @@ const { data } = await client.getSchema({ "name": "customer_messaging", "title": "Messaging", "attributes": [], + "overridable_attribute": false, + "managed_fields": ["status"], "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": {}, "ui_config": {}, "ui_hooks": [], "feature_flag": "FF_MY_FEATURE_FLAG", - "settings_flag": [] + "settings_flag": [], + "schemas": [] } ], "group_settings": [ @@ -434,6 +578,7 @@ const { data } = await client.getSchema({ } ], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": { "image": { "type": "keyword", @@ -454,6 +599,14 @@ const { data } = await client.getSchema({ "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } + ], + "conditions": [ + { + "id": "d5839b94-ba20-4225-a78e-76951d352bd6", + "name": "delivery_area", + "label": "Delivery Area", + "type": "string" + } ] } ``` @@ -464,7 +617,7 @@ const { data } = await client.getSchema({ ### `putSchema` -Create or update a schema with a new version +Create or update a schema with a new version. `PUT /v1/entity/schemas/{slug}` @@ -473,6 +626,8 @@ const { data } = await client.putSchema( { slug: 'example', draft: true, + base_version: 1, + base_updated_at: 'example', }, { slug: 'contact', @@ -487,6 +642,7 @@ const { data } = await client.putSchema( category: 'customer_relations', published: false, draft: false, + require_change_comment: false, icon: 'person', title_template: '{{first_name}} {{last_name}}', ui_config: { @@ -518,7 +674,24 @@ const { data } = await client.putSchema( }, sharing: { show_sharing_button: true - } + }, + grid_layout: { + id: 'string', + columns: 0, + cells: [0] + }, + widget_order: ['string'], + widget_visibility: { + next_best_action: true, + address_map: false + }, + widget_widths: { + address_map: 'full_width', + recent_communications: 'one_third_width' + }, + custom_tabs: [ + { /* ... */ } + ] }, capabilities: [ { @@ -526,13 +699,17 @@ const { data } = await client.putSchema( name: 'customer_messaging', title: 'Messaging', attributes: [ /* ... */ ], + overridable_attribute: false, + managed_fields: ['status'], _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], app_id: '123e4567-e89b-12d3-a456-426614174000', + adjust_installment: { /* ... */ }, ui_config: { /* ... */ }, ui_hooks: [ /* ... */ ], feature_flag: 'FF_MY_FEATURE_FLAG', - settings_flag: [ /* ... */ ] + settings_flag: [ /* ... */ ], + schemas: [ /* ... */ ] } ], group_settings: [ @@ -570,6 +747,7 @@ const { data } = await client.putSchema( /* ... 5 more */ ], _purpose: ['string'], + _manifest: ['123e4567-e89b-12d3-a456-426614174000'], explicit_search_mappings: { image: { type: 'keyword', @@ -590,6 +768,14 @@ const { data } = await client.putSchema( _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'] } + ], + conditions: [ + { + id: 'd5839b94-ba20-4225-a78e-76951d352bd6', + name: 'delivery_area', + label: 'Delivery Area', + type: 'string' + } ] }, ) @@ -608,6 +794,9 @@ const { data } = await client.putSchema( "id": "string", "type": "string" }, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -620,6 +809,7 @@ const { data } = await client.putSchema( "category": "customer_relations", "published": false, "draft": false, + "require_change_comment": false, "icon": "person", "title_template": "{{first_name}} {{last_name}}", "ui_config": { @@ -651,7 +841,24 @@ const { data } = await client.putSchema( }, "sharing": { "show_sharing_button": true - } + }, + "grid_layout": { + "id": "string", + "columns": 0, + "cells": [0] + }, + "widget_order": ["string"], + "widget_visibility": { + "next_best_action": true, + "address_map": false + }, + "widget_widths": { + "address_map": "full_width", + "recent_communications": "one_third_width" + }, + "custom_tabs": [ + {} + ] }, "capabilities": [ { @@ -659,13 +866,17 @@ const { data } = await client.putSchema( "name": "customer_messaging", "title": "Messaging", "attributes": [], + "overridable_attribute": false, + "managed_fields": ["status"], "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": {}, "ui_config": {}, "ui_hooks": [], "feature_flag": "FF_MY_FEATURE_FLAG", - "settings_flag": [] + "settings_flag": [], + "schemas": [] } ], "group_settings": [ @@ -702,6 +913,7 @@ const { data } = await client.putSchema( } ], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": { "image": { "type": "keyword", @@ -722,6 +934,14 @@ const { data } = await client.putSchema( "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } + ], + "conditions": [ + { + "id": "d5839b94-ba20-4225-a78e-76951d352bd6", + "name": "delivery_area", + "label": "Delivery Area", + "type": "string" + } ] } ``` @@ -744,6 +964,36 @@ const { data } = await client.deleteSchema({ --- +### `getSchemaHead` + +Lightweight lookup of the schema version saves currently land on top of. Meant for editors +to detect that someone else saved while they were editing, without fetching the schema. + +`GET /v1/entity/schemas/{slug}/head` + +```ts +const { data } = await client.getSchemaHead({ + slug: 'example', +}) +``` + +
+Response + +```json +{ + "slug": "contact", + "id": "string", + "version": 0, + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string" +} +``` + +
+ +--- + ### `getJsonSchema` Get formal JSON schema definition draft 2020-12 for the given epilot schema @@ -924,6 +1174,9 @@ const { data } = await client.getSchemaVersions({ "updated_at": "string", "comment": "string", "source": {}, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -936,6 +1189,7 @@ const { data } = await client.getSchemaVersions({ "category": "customer_relations", "published": false, "draft": false, + "require_change_comment": false, "icon": "person", "title_template": "{{first_name}} {{last_name}}", "ui_config": {}, @@ -945,8 +1199,10 @@ const { data } = await client.getSchemaVersions({ "dialog_config": {}, "attributes": [], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": {}, - "group_headlines": [] + "group_headlines": [], + "conditions": [] } ], "drafts": [ @@ -956,6 +1212,9 @@ const { data } = await client.getSchemaVersions({ "updated_at": "string", "comment": "string", "source": {}, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -968,6 +1227,7 @@ const { data } = await client.getSchemaVersions({ "category": "customer_relations", "published": false, "draft": false, + "require_change_comment": false, "icon": "person", "title_template": "{{first_name}} {{last_name}}", "ui_config": {}, @@ -977,12 +1237,15 @@ const { data } = await client.getSchemaVersions({ "dialog_config": {}, "attributes": [], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": {}, - "group_headlines": [] + "group_headlines": [], + "conditions": [] } ], "versions_more": true, - "drafts_more": true + "drafts_more": true, + "frozen_version": "3fa85f64-5717-4562-b3fc-2c963f66afa6" } ``` @@ -1013,13 +1276,17 @@ const { data } = await client.listAvailableCapabilities({ "name": "customer_messaging", "title": "Messaging", "attributes": [], + "overridable_attribute": false, + "managed_fields": ["status"], "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": {}, "ui_config": {}, "ui_hooks": [], "feature_flag": "FF_MY_FEATURE_FLAG", - "settings_flag": [] + "settings_flag": [], + "schemas": [] } ] } @@ -1051,6 +1318,9 @@ const { data } = await client.listSchemaBlueprints() "updated_at": "string", "comment": "string", "source": {}, + "frozen": true, + "latest": true, + "_summary": true, "slug": "contact", "version": 1, "blueprint": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -1063,6 +1333,7 @@ const { data } = await client.listSchemaBlueprints() "category": "customer_relations", "published": false, "draft": false, + "require_change_comment": false, "icon": "person", "title_template": "{{first_name}} {{last_name}}", "ui_config": {}, @@ -1072,8 +1343,10 @@ const { data } = await client.listSchemaBlueprints() "dialog_config": {}, "attributes": [], "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "explicit_search_mappings": {}, - "group_headlines": [] + "group_headlines": [], + "conditions": [] } ] } @@ -1099,6 +1372,7 @@ const { data } = await client.searchEntities( from: 0, size: 10, hydrate: false, + anonymize: false, fields: ['_id', '_title', 'first_name', 'account', '!account.*._files', '**._product'], aggs: { 'contact-count-per-tag': { @@ -1204,6 +1478,7 @@ const { data } = await client.listEntities( from: 0, size: 10, hydrate: false, + anonymize: false, fields: ['_id', '_title', 'first_name', 'account', '!account.*._files', '**._product'], aggs: { 'contact-count-per-tag': { @@ -1314,7 +1589,8 @@ const { data } = await client.queryEntityGraph( } ] }, - hydrate: false + hydrate: false, + apply_changesets: false }, ) ``` @@ -1635,7 +1911,9 @@ const { data } = await client.getEntityV2({ id: '123e4567-e89b-12d3-a456-426614174000', slug: 'example', hydrate: true, + anonymize: true, fields: ['...'], + apply_changesets: true, }) ``` @@ -1773,6 +2051,7 @@ const { data } = await client.getEntity({ id: '123e4567-e89b-12d3-a456-426614174000', slug: 'example', hydrate: true, + anonymize: true, }) ``` @@ -1845,6 +2124,7 @@ const { data } = await client.updateEntity( fill_activity: true, async: true, validate: true, + direct: true, }, { _id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', @@ -1915,6 +2195,7 @@ const { data } = await client.patchEntity( dry_run: true, async: true, validate: true, + direct: true, }, { _id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', @@ -1988,16 +2269,18 @@ const { data } = await client.deleteEntity({ ### `autocomplete` -Autocomplete entity attributes +Autocomplete entity attributes. `GET /v1/entity:autocomplete` ```ts const { data } = await client.autocomplete({ + anonymize: true, input: 'example', attribute: 'example', slug: 'example', size: 1, + from: 1, }) ``` @@ -2030,6 +2313,86 @@ const { data } = await client.wipeAllEntities( ) ``` +
+Response + +```json +{ + "id": "string", + "schemas": ["contact"], + "status": "running", + "current_step": "SANITY_CHECK", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "user_id": "string", + "email": "string", + "display_name": "string" + }, + "entity_totals": {}, + "total_entities": 0, + "progress": { + "indices_deleted": 0, + "entities_deleted": 0, + "relations_deleted": 0, + "activities_deleted": 0 + }, + "error": "string" +} +``` + +
+ +--- + +### `listWipeJobs` + +Lists the most recent wipe jobs of the organization, newest first. + +`GET /v1/entity:wipeJobs` + +```ts +const { data } = await client.listWipeJobs({ + limit: 1, +}) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "string", + "schemas": ["contact"], + "status": "running", + "current_step": "SANITY_CHECK", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "user_id": "string", + "email": "string", + "display_name": "string" + }, + "entity_totals": {}, + "total_entities": 0, + "progress": { + "indices_deleted": 0, + "entities_deleted": 0, + "relations_deleted": 0, + "activities_deleted": 0 + }, + "error": "string" + } + ] +} +``` + +
+ --- ### `createActivity` @@ -2111,6 +2474,7 @@ Get activity by id ```ts const { data } = await client.getActivity({ + anonymize: true, id: '123e4567-e89b-12d3-a456-426614174000', operations_size: 1, operations_from: 1, @@ -2149,7 +2513,10 @@ const { data } = await client.getActivity({ "operation": "createEntity", "params": {}, "payload": {}, - "diff": {} + "diff": {}, + "source_context": {}, + "_workflow_origin": {}, + "_automation_chain": ["string"] } ] } @@ -2217,26 +2584,18 @@ const { data } = await client.attachActivity({ --- -### `getEntityActivityFeed` +### `applyChangeset` -Get activity feed for an entity +Applies the proposed value from a pending changeset to the entity attribute +and removes the changeset. Used for human approval of pending changes. -`GET /v1/entity/{slug}/{id}/activity` +`POST /v1/entity/{slug}/{id}/changesets/{attribute}:apply` ```ts -const { data } = await client.getEntityActivityFeed({ +const { data } = await client.applyChangeset({ slug: 'example', id: '123e4567-e89b-12d3-a456-426614174000', - after: 'example', - before: 'example', - start_date: 'example', - end_date: 'example', - preset_range: 'example', - from: 1, - size: 1, - type: ['...'], - include_relations: true, - exclude_activity_groups: 'example', + attribute: 'example', }) ``` @@ -2245,21 +2604,24 @@ const { data } = await client.getEntityActivityFeed({ ```json { - "total": 1, - "results": [ + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_owners": [ { - "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", - "timestamp": "1970-01-01T00:00:00.000Z", - "type": "string", - "title": "My custom activity", - "message": "{{caller}} did something with {{entity payload.entity.id}}.", - "payload": {}, - "pending": false, - "caller": {}, - "operations_total": 1, - "operations": [] + "org_id": "123", + "user_id": "123" } - ] + ], + "_schema": "contact", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "_acl": { + "view": ["org:456", "org:789"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } ``` @@ -2267,40 +2629,196 @@ const { data } = await client.getEntityActivityFeed({ --- -### `getRelations` +### `dismissChangeset` -Returns 1st level direct relations for an entity. +Removes a pending changeset without applying it. The attribute value remains unchanged. -`GET /v1/entity/{slug}/{id}/relations` +`POST /v1/entity/{slug}/{id}/changesets/{attribute}:dismiss` ```ts -const { data } = await client.getRelations({ - slug: 'example', - id: '123e4567-e89b-12d3-a456-426614174000', - hydrate: true, - include_reverse: true, - from: 1, - size: 1, - include_schemas: ['...'], - exclude_schemas: ['...'], -}) +const { data } = await client.dismissChangeset( + { + slug: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', + attribute: 'example', + }, + { + reason: 'string' + }, +) ```
Response ```json -[ - { - "entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "org_id": "string", - "_schema": "contact", - "attribute": "string", - "_tags": ["string"], - "reverse": true +{ + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_schema": "contact", + "_tags": ["example", "mock"], + "_created_at": "2021-02-09T12:41:43.662Z", + "_updated_at": "2021-02-09T12:41:43.662Z", + "_acl": { + "view": ["org:456", "org:789"], + "edit": ["org:456"], + "delete": ["org:456"] }, - { - "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] +} +``` + +
+ +--- + +### `listChangesets` + +Returns all pending changesets for an entity. + +`GET /v1/entity/{slug}/{id}/changesets` + +```ts +const { data } = await client.listChangesets({ + anonymize: true, + slug: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{} +``` + +
+ +--- + +### `getEntityActivityFeed` + +Get activity feed for an entity + +`GET /v1/entity/{slug}/{id}/activity` + +```ts +const { data } = await client.getEntityActivityFeed({ + anonymize: true, + slug: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', + after: 'example', + before: 'example', + start_date: 'example', + end_date: 'example', + preset_range: 'example', + from: 1, + size: 1, + type: ['...'], + include_relations: true, + exclude_activity_groups: 'example', +}) +``` + +
+Response + +```json +{ + "total": 1, + "results": [ + { + "_id": "01F130Q52Q6MWSNS8N2AVXV4JN", + "timestamp": "1970-01-01T00:00:00.000Z", + "type": "string", + "title": "My custom activity", + "message": "{{caller}} did something with {{entity payload.entity.id}}.", + "payload": {}, + "pending": false, + "caller": {}, + "operations_total": 1, + "operations": [] + } + ] +} +``` + +
+ +--- + +### `getEntitySummary` + +Get the latest AI generated summary of an entity. Summaries are generated by the +ai-agents-api `skill:entity-summary` and stored here when the execution completes. + +`GET /v1/entity/{slug}/{id}/summary` + +```ts +const { data } = await client.getEntitySummary({ + slug: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "summary": "string", + "variant": "short", + "execution_id": "7b4cfc0f-1d5e-4f3a-9b4a-2c7d1f9e8a10", + "created_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getRelations` + +Returns 1st level direct relations for an entity. + +`GET /v1/entity/{slug}/{id}/relations` + +```ts +const { data } = await client.getRelations({ + slug: 'example', + id: '123e4567-e89b-12d3-a456-426614174000', + hydrate: true, + anonymize: true, + include_reverse: true, + from: 1, + size: 1, + include_schemas: ['...'], + exclude_schemas: ['...'], +}) +``` + +
+Response + +```json +[ + { + "entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "_schema": "contact", + "attribute": "string", + "_tags": ["string"], + "reverse": true + }, + { + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "_org": "123", "_owners": [ { @@ -2411,6 +2929,7 @@ const { data } = await client.getRelationsV2({ slug: 'example', id: '123e4567-e89b-12d3-a456-426614174000', hydrate: true, + anonymize: true, query: 'example', include_reverse: true, from: 1, @@ -2473,6 +2992,7 @@ const { data } = await client.getRelationsV3({ slug: 'example', id: '123e4567-e89b-12d3-a456-426614174000', hydrate: true, + anonymize: true, include_reverse: true, from: 1, size: 1, @@ -2634,6 +3154,7 @@ const { data } = await client.exportEntities( from: 0, size: 10, hydrate: false, + anonymize: false, fields: ['_id', '_title', 'first_name', 'account', '!account.*._files', '**._product'], aggs: { 'contact-count-per-tag': { @@ -2669,11 +3190,230 @@ const { data } = await client.importEntities( bucket: 'my-bucket', key: 'imports/my-import.json' }, - schema: 'contact' + schema: 'contact', + unique_key: ['email'], + dry_run: false, + dry_run_job_id: 'string', + trigger_automations: false }, ) ``` +
+Response + +```json +{ + "jobPollId": "string", + "trigger_automations": true, + "started_by": "string", + "status": "PROCESSING", + "total": 0, + "importedEntitiesCount": 0, + "failedEntitiesCount": 0, + "importedEntitiesUrl": "string", + "failedEntitiesUrl": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "failure_reason": "string", + "failure_code": "invalid_csv_bad_headers", + "abortable": true, + "dry_run": true, + "unique_key": ["string"], + "outcome_counts": { + "error": 0, + "skipped_empty_key": 0, + "skipped_duplicate_in_file": 0, + "skipped_id_not_found": 0, + "skipped_ambiguous": 0, + "create": 0, + "unchanged": 0, + "update": 0 + }, + "report_url": "string", + "S3Reference": { + "bucket": "string", + "key": "string" + }, + "issues": [ + { + "severity": "blocking", + "reason": "string", + "column": "string", + "count": 0, + "example_rows": [0] + } + ], + "phase": "scanning", + "heartbeat_at": "1970-01-01T00:00:00.000Z", + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getLatestEntityImport` + +Get the latest import job of a schema + +`GET /v1/entity:import:latest` + +```ts +const { data } = await client.getLatestEntityImport({ + schema: 'example', +}) +``` + +
+Response + +```json +{ + "jobPollId": "string", + "trigger_automations": true, + "started_by": "string", + "status": "PROCESSING", + "total": 0, + "importedEntitiesCount": 0, + "failedEntitiesCount": 0, + "importedEntitiesUrl": "string", + "failedEntitiesUrl": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "failure_reason": "string", + "failure_code": "invalid_csv_bad_headers", + "abortable": true, + "dry_run": true, + "unique_key": ["string"], + "outcome_counts": { + "error": 0, + "skipped_empty_key": 0, + "skipped_duplicate_in_file": 0, + "skipped_id_not_found": 0, + "skipped_ambiguous": 0, + "create": 0, + "unchanged": 0, + "update": 0 + }, + "report_url": "string", + "S3Reference": { + "bucket": "string", + "key": "string" + }, + "issues": [ + { + "severity": "blocking", + "reason": "string", + "column": "string", + "count": 0, + "example_rows": [0] + } + ], + "phase": "scanning", + "heartbeat_at": "1970-01-01T00:00:00.000Z", + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getEntityImportHistory` + +List the import jobs of a schema + +`GET /v1/entity:importHistory` + +```ts +const { data } = await client.getEntityImportHistory({ + schema: 'example', + limit: 1, +}) +``` + +
+Response + +```json +{ + "jobs": [ + { + "job_id": "string", + "schema": "string", + "status": "PROCESSING", + "dry_run": true, + "trigger_automations": true, + "started_by": "string", + "started_at": "1970-01-01T00:00:00.000Z", + "finished_at": "1970-01-01T00:00:00.000Z", + "file_name": "string", + "total": 0, + "importedEntitiesCount": 0, + "failedEntitiesCount": 0, + "outcome_counts": { + "error": 0, + "skipped_empty_key": 0, + "skipped_duplicate_in_file": 0, + "skipped_id_not_found": 0, + "skipped_ambiguous": 0, + "create": 0, + "unchanged": 0, + "update": 0 + }, + "failure_code": "invalid_csv_bad_headers", + "unique_key": ["string"] + } + ] +} +``` + +
+ +--- + +### `abortEntityImport` + +Abort a running entity import + +`POST /v1/entity:abortImport` + +```ts +const { data } = await client.abortEntityImport({ + job_id: 'example', + schema: 'example', +}) +``` + +--- + +### `discardEntityImport` + +Discard a finished dry run + +`POST /v1/entity:discardImport` + +```ts +const { data } = await client.discardEntityImport({ + job_id: 'example', + schema: 'example', +}) +``` + +
+Response + +```json +{ + "status": "string", + "jobPollId": "string" +} +``` + +
+ --- ### `listSavedViews` @@ -2688,6 +3428,7 @@ const { data } = await client.listSavedViews({ sort: 'example', from: 1, size: 1, + q: 'example', fields: ['...'], }) ``` @@ -2709,7 +3450,8 @@ const { data } = await client.listSavedViews({ "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -2751,7 +3493,8 @@ const { data } = await client.createSavedView( shared: true, isFavoritedBy: ['11701'], created_by: { - user_id: '10598' + user_id: '10598', + org_id: '739224' }, ui_config: { filters: { @@ -2786,7 +3529,8 @@ const { data } = await client.createSavedView( "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -2836,7 +3580,8 @@ const { data } = await client.getSavedView({ "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -2881,7 +3626,8 @@ const { data } = await client.updateSavedView( shared: true, isFavoritedBy: ['11701'], created_by: { - user_id: '10598' + user_id: '10598', + org_id: '739224' }, ui_config: { filters: { @@ -2916,7 +3662,8 @@ const { data } = await client.updateSavedView( "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -2958,7 +3705,8 @@ const { data } = await client.patchSavedView( shared: true, isFavoritedBy: ['11701'], created_by: { - user_id: '10598' + user_id: '10598', + org_id: '739224' }, ui_config: { filters: { @@ -2993,7 +3741,8 @@ const { data } = await client.patchSavedView( "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3057,7 +3806,8 @@ const { data } = await client.listFavoriteViewsForUser() "shared": true, "isFavoritedBy": ["11701"], "created_by": { - "user_id": "10598" + "user_id": "10598", + "org_id": "739224" }, "ui_config": { "filters": { @@ -3375,7 +4125,7 @@ const { data } = await client.updateClassificationsForTaxonomy( "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] } ], - "deleted": {} + "deleted": ["taxonomy-slug:classification-slug"] } ``` @@ -3612,6 +4362,7 @@ const { data } = await client.taxonomiesClassificationsSearch( query: 'example', archived: true, include_archived: 'example', + exclude_types: ['...'], }, { classificationIds: [ @@ -3916,6 +4667,7 @@ const { data } = await client.createSchemaAttribute( required: false, readonly: false, deprecated: false, + overridable_attribute: false, default_value: {}, group: 'string', order: 0, @@ -3923,6 +4675,7 @@ const { data } = await client.createSchemaAttribute( hide_label: true, icon: 'string', render_condition: 'string', + data_classification: 'public', _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], constraints: { @@ -3949,6 +4702,23 @@ const { data } = await client.createSchemaAttribute( exclude_from_search: false, repeatable: true, has_primary: true, + edit_mode: 'direct', + edit_mode_config: { + match_strategy: 'exact', + fuzzy_config: { + type: 'suffix', + suffix_length: 0, + fields_to_ignore: ['string'], + regex_flags: 'string', + country_code: 'string', + match_on: 'string', + key: 'string', + mode: 'subset', + ordered: true, + require_tags_match: true, + pattern: 'string' + } + }, type: 'string', multiline: true, rich_text: true, @@ -3972,6 +4742,7 @@ const { data } = await client.createSchemaAttribute( "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -3979,6 +4750,7 @@ const { data } = await client.createSchemaAttribute( "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -4005,6 +4777,23 @@ const { data } = await client.createSchemaAttribute( "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -4043,6 +4832,7 @@ const { data } = await client.getSchemaAttribute({ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4050,6 +4840,7 @@ const { data } = await client.getSchemaAttribute({ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -4076,6 +4867,23 @@ const { data } = await client.getSchemaAttribute({ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -4109,6 +4917,7 @@ const { data } = await client.putSchemaAttribute( required: false, readonly: false, deprecated: false, + overridable_attribute: false, default_value: {}, group: 'string', order: 0, @@ -4116,6 +4925,7 @@ const { data } = await client.putSchemaAttribute( hide_label: true, icon: 'string', render_condition: 'string', + data_classification: 'public', _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], constraints: { @@ -4142,6 +4952,23 @@ const { data } = await client.putSchemaAttribute( exclude_from_search: false, repeatable: true, has_primary: true, + edit_mode: 'direct', + edit_mode_config: { + match_strategy: 'exact', + fuzzy_config: { + type: 'suffix', + suffix_length: 0, + fields_to_ignore: ['string'], + regex_flags: 'string', + country_code: 'string', + match_on: 'string', + key: 'string', + mode: 'subset', + ordered: true, + require_tags_match: true, + pattern: 'string' + } + }, type: 'string', multiline: true, rich_text: true, @@ -4165,6 +4992,7 @@ const { data } = await client.putSchemaAttribute( "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4172,6 +5000,7 @@ const { data } = await client.putSchemaAttribute( "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -4198,6 +5027,23 @@ const { data } = await client.putSchemaAttribute( "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -4236,6 +5082,7 @@ const { data } = await client.deleteSchemaAttribute({ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4243,6 +5090,7 @@ const { data } = await client.deleteSchemaAttribute({ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": { @@ -4269,6 +5117,23 @@ const { data } = await client.deleteSchemaAttribute({ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": { + "match_strategy": "exact", + "fuzzy_config": { + "type": "suffix", + "suffix_length": 0, + "fields_to_ignore": ["string"], + "regex_flags": "string", + "country_code": "string", + "match_on": "string", + "key": "string", + "mode": "subset", + "ordered": true, + "require_tags_match": true, + "pattern": "string" + } + }, "type": "string", "multiline": true, "rich_text": true, @@ -4305,6 +5170,7 @@ const { data } = await client.createSchemaCapability( required: false, readonly: false, deprecated: false, + overridable_attribute: false, default_value: {}, group: 'string', order: 0, @@ -4312,6 +5178,7 @@ const { data } = await client.createSchemaCapability( hide_label: true, icon: 'string', render_condition: 'string', + data_classification: 'public', _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], constraints: { /* ... */ }, @@ -4326,6 +5193,8 @@ const { data } = await client.createSchemaCapability( exclude_from_search: false, repeatable: true, has_primary: true, + edit_mode: 'direct', + edit_mode_config: { /* ... */ }, type: 'string', multiline: true, rich_text: true, @@ -4342,6 +5211,7 @@ const { data } = await client.createSchemaCapability( required: false, readonly: false, deprecated: false, + overridable_attribute: false, default_value: {}, group: 'string', order: 0, @@ -4349,6 +5219,7 @@ const { data } = await client.createSchemaCapability( hide_label: true, icon: 'string', render_condition: 'string', + data_classification: 'public', _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], constraints: { /* ... */ }, @@ -4363,13 +5234,20 @@ const { data } = await client.createSchemaCapability( exclude_from_search: false, repeatable: true, has_primary: true, + edit_mode: 'direct', + edit_mode_config: { /* ... */ }, type: 'link' }, - /* ... 32 more */ + /* ... 34 more */ ], + overridable_attribute: false, + managed_fields: ['status'], _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], app_id: '123e4567-e89b-12d3-a456-426614174000', + adjust_installment: { + journey_id: 'adjust-installment-flow' + }, ui_config: { is_filterable: true }, @@ -4386,7 +5264,10 @@ const { data } = await client.createSchemaCapability( icon: 'email', disabled: true, header: true, - requiredPermission: { /* ... */ } + requiredPermission: { /* ... */ }, + default_visible: false, + default_width: 'half_width', + pricing_tier_setting: 'entity_address_maps' } ], feature_flag: 'FF_MY_FEATURE_FLAG', @@ -4396,6 +5277,11 @@ const { data } = await client.createSchemaCapability( enabled: true } ], + schemas: [ + { + schema: 'contact' + } + ], composite_id: 'contact:97644baa-083f-4e49-9188-fcff2ecaad7d', schema: 'contact' }, @@ -4422,6 +5308,7 @@ const { data } = await client.createSchemaCapability( "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4429,6 +5316,7 @@ const { data } = await client.createSchemaCapability( "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -4443,6 +5331,8 @@ const { data } = await client.createSchemaCapability( "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -4459,6 +5349,7 @@ const { data } = await client.createSchemaCapability( "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4466,6 +5357,7 @@ const { data } = await client.createSchemaCapability( "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -4480,12 +5372,19 @@ const { data } = await client.createSchemaCapability( "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, + "managed_fields": ["status"], "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -4502,7 +5401,10 @@ const { data } = await client.createSchemaCapability( "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -4512,6 +5414,11 @@ const { data } = await client.createSchemaCapability( "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" } @@ -4553,6 +5460,7 @@ const { data } = await client.getSchemaCapability({ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4560,6 +5468,7 @@ const { data } = await client.getSchemaCapability({ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -4574,6 +5483,8 @@ const { data } = await client.getSchemaCapability({ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -4590,6 +5501,7 @@ const { data } = await client.getSchemaCapability({ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4597,6 +5509,7 @@ const { data } = await client.getSchemaCapability({ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -4611,12 +5524,19 @@ const { data } = await client.getSchemaCapability({ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, + "managed_fields": ["status"], "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -4633,7 +5553,10 @@ const { data } = await client.getSchemaCapability({ "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -4643,6 +5566,11 @@ const { data } = await client.getSchemaCapability({ "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" } @@ -4679,6 +5607,7 @@ const { data } = await client.putSchemaCapability( required: false, readonly: false, deprecated: false, + overridable_attribute: false, default_value: {}, group: 'string', order: 0, @@ -4686,6 +5615,7 @@ const { data } = await client.putSchemaCapability( hide_label: true, icon: 'string', render_condition: 'string', + data_classification: 'public', _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], constraints: { /* ... */ }, @@ -4700,6 +5630,8 @@ const { data } = await client.putSchemaCapability( exclude_from_search: false, repeatable: true, has_primary: true, + edit_mode: 'direct', + edit_mode_config: { /* ... */ }, type: 'string', multiline: true, rich_text: true, @@ -4716,6 +5648,7 @@ const { data } = await client.putSchemaCapability( required: false, readonly: false, deprecated: false, + overridable_attribute: false, default_value: {}, group: 'string', order: 0, @@ -4723,6 +5656,7 @@ const { data } = await client.putSchemaCapability( hide_label: true, icon: 'string', render_condition: 'string', + data_classification: 'public', _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], constraints: { /* ... */ }, @@ -4737,13 +5671,20 @@ const { data } = await client.putSchemaCapability( exclude_from_search: false, repeatable: true, has_primary: true, + edit_mode: 'direct', + edit_mode_config: { /* ... */ }, type: 'link' }, - /* ... 32 more */ + /* ... 34 more */ ], + overridable_attribute: false, + managed_fields: ['status'], _purpose: ['taxonomy-slug:classification-slug'], _manifest: ['123e4567-e89b-12d3-a456-426614174000'], app_id: '123e4567-e89b-12d3-a456-426614174000', + adjust_installment: { + journey_id: 'adjust-installment-flow' + }, ui_config: { is_filterable: true }, @@ -4760,7 +5701,10 @@ const { data } = await client.putSchemaCapability( icon: 'email', disabled: true, header: true, - requiredPermission: { /* ... */ } + requiredPermission: { /* ... */ }, + default_visible: false, + default_width: 'half_width', + pricing_tier_setting: 'entity_address_maps' } ], feature_flag: 'FF_MY_FEATURE_FLAG', @@ -4770,6 +5714,11 @@ const { data } = await client.putSchemaCapability( enabled: true } ], + schemas: [ + { + schema: 'contact' + } + ], composite_id: 'contact:97644baa-083f-4e49-9188-fcff2ecaad7d', schema: 'contact' }, @@ -4796,6 +5745,7 @@ const { data } = await client.putSchemaCapability( "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4803,6 +5753,7 @@ const { data } = await client.putSchemaCapability( "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -4817,6 +5768,8 @@ const { data } = await client.putSchemaCapability( "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -4833,6 +5786,7 @@ const { data } = await client.putSchemaCapability( "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4840,6 +5794,7 @@ const { data } = await client.putSchemaCapability( "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -4854,12 +5809,19 @@ const { data } = await client.putSchemaCapability( "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, + "managed_fields": ["status"], "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -4876,7 +5838,10 @@ const { data } = await client.putSchemaCapability( "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -4886,6 +5851,11 @@ const { data } = await client.putSchemaCapability( "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" } @@ -4927,6 +5897,7 @@ const { data } = await client.deleteSchemaCapability({ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4934,6 +5905,7 @@ const { data } = await client.deleteSchemaCapability({ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -4948,6 +5920,8 @@ const { data } = await client.deleteSchemaCapability({ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "string", "multiline": true, "rich_text": true, @@ -4964,6 +5938,7 @@ const { data } = await client.deleteSchemaCapability({ "required": false, "readonly": false, "deprecated": false, + "overridable_attribute": false, "default_value": {}, "group": "string", "order": 0, @@ -4971,6 +5946,7 @@ const { data } = await client.deleteSchemaCapability({ "hide_label": true, "icon": "string", "render_condition": "string", + "data_classification": "public", "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "constraints": {}, @@ -4985,12 +5961,19 @@ const { data } = await client.deleteSchemaCapability({ "exclude_from_search": false, "repeatable": true, "has_primary": true, + "edit_mode": "direct", + "edit_mode_config": {}, "type": "link" } ], + "overridable_attribute": false, + "managed_fields": ["status"], "_purpose": ["taxonomy-slug:classification-slug"], "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "app_id": "123e4567-e89b-12d3-a456-426614174000", + "adjust_installment": { + "journey_id": "adjust-installment-flow" + }, "ui_config": { "is_filterable": true }, @@ -5007,7 +5990,10 @@ const { data } = await client.deleteSchemaCapability({ "icon": "email", "disabled": true, "header": true, - "requiredPermission": {} + "requiredPermission": {}, + "default_visible": false, + "default_width": "half_width", + "pricing_tier_setting": "entity_address_maps" } ], "feature_flag": "FF_MY_FEATURE_FLAG", @@ -5017,6 +6003,11 @@ const { data } = await client.deleteSchemaCapability({ "enabled": true } ], + "schemas": [ + { + "schema": "contact" + } + ], "composite_id": "contact:97644baa-083f-4e49-9188-fcff2ecaad7d", "schema": "contact" } @@ -5480,6 +6471,7 @@ type EntitySchema = { category?: string published?: boolean draft?: boolean + require_change_comment?: boolean icon?: string title_template?: string ui_config?: { @@ -5532,6 +6524,23 @@ type EntitySchema = { sharing?: { show_sharing_button?: { ... } } + grid_layout?: { + id?: { ... } + columns?: { ... } + cells?: { ... } + } + widget_order?: string[] + widget_visibility?: Record + widget_widths?: Record + custom_tabs?: Array<{ + id: { ... } + slug: { ... } + title: { ... } + order: { ... } + icon?: { ... } + type: { ... } + widgets?: { ... } + }> } capabilities: Array<{ id?: string @@ -5548,29 +6557,78 @@ type EntitySchema = { required?: { ... } readonly?: { ... } deprecated?: { ... } - default_value?: { ... } - group?: { ... } - order?: { ... } - layout?: { ... } - hide_label?: { ... } - icon?: { ... } - render_condition?: { ... } - _purpose?: { ... } - _manifest?: { ... } - constraints?: { ... } - feature_flag?: { ... } - settings_flag?: { ... } - value_formatter?: { ... } - preview_value_formatter?: { ... } - entity_builder_disable_edit?: { ... } - protected?: { ... } - info_helpers?: { ... } - explicit_searchable?: { ... } - exclude_from_search?: { ... } + overridable_attribute?: { ... } // ... } ``` +### `SchemaHead` + +```ts +type SchemaHead = { + slug: string + id?: string + version: number + updated_at?: string // date-time + created_by?: string +} +``` + +### `WipeJob` + +A request to wipe entity data of an organization, and its progress + +```ts +type WipeJob = { + id: string + schemas: string[] + status: "running" | "succeeded" | "failed" + current_step: "SANITY_CHECK" | "DELETE_ELASTIC_INDICES" | "DELETE_DYNAMODB_ENTITIES" | "DELETE_DYNAMODB_RELATIONS" | "DELETE_DYNAMODB_ACTIVITIES" | "DELETE_CLICKHOUSE_ENTITIES" | "DELETE_CLICKHOUSE_ENTITY_OPERATIONS" | "DELETE_S3_FILES" | "SUCCESS" | "FAIL" + created_at: string // date-time + updated_at: string // date-time + finished_at?: string // date-time + created_by?: { + user_id?: string + email?: string + display_name?: string + } + entity_totals: Record + total_entities: number + progress: { + indices_deleted?: number + entities_deleted?: number + relations_deleted?: number + activities_deleted?: number + } + error?: string +} +``` + +### `WipeJobConflictError` + +```ts +type WipeJobConflictError = { + status?: number + error?: string + message: string + conflicting_schemas: string[] +} +``` + +### `SchemaVersionConflictError` + +```ts +type SchemaVersionConflictError = { + status?: number + error?: string + message?: string + base_version?: number + current_version?: number + current_updated_at?: string // date-time + current_created_by?: string +} +``` + ### `EntitySchemaItem` ```ts @@ -5583,6 +6641,9 @@ type EntitySchemaItem = { id?: string type?: string } + frozen?: boolean + latest?: boolean + _summary?: boolean slug: string version?: number blueprint?: string // uuid @@ -5595,6 +6656,7 @@ type EntitySchemaItem = { category?: string published?: boolean draft?: boolean + require_change_comment?: boolean icon?: string title_template?: string ui_config?: { @@ -5647,33 +6709,29 @@ type EntitySchemaItem = { sharing?: { show_sharing_button?: { ... } } + grid_layout?: { + id?: { ... } + columns?: { ... } + cells?: { ... } + } + widget_order?: string[] + widget_visibility?: Record + widget_widths?: Record + custom_tabs?: Array<{ + id: { ... } + slug: { ... } + title: { ... } + order: { ... } + icon?: { ... } + type: { ... } + widgets?: { ... } + }> } capabilities: Array<{ id?: string name: string title?: string attributes?: Array<{ - id?: { ... } - name: { ... } - label: { ... } - placeholder?: { ... } - hidden?: { ... } - show_in_table?: { ... } - sortable?: { ... } - required?: { ... } - readonly?: { ... } - deprecated?: { ... } - default_value?: { ... } - group?: { ... } - order?: { ... } - layout?: { ... } - hide_label?: { ... } - icon?: { ... } - render_condition?: { ... } - _purpose?: { ... } - _manifest?: { ... } - constraints?: { ... } - feature_flag?: { ... } // ... } ``` @@ -5691,15 +6749,7 @@ type GenerateEntityTableAIFiltersRequest = { name?: string group?: string allowedSchemas?: string[] - relatedOptions?: Array<{ - type?: { ... } - label: { ... } - label_type?: { ... } - name?: { ... } - group?: { ... } - allowedSchemas?: { ... } - relatedOptions?: { ... } - }> + relatedOptions?: { ... }[] }> } ``` @@ -5734,23 +6784,7 @@ type EntityTableFilterOption = { name?: string group?: string allowedSchemas?: string[] - relatedOptions?: Array<{ - type?: "search" | "filter" - label: string - label_type?: string - name?: string - group?: string - allowedSchemas?: string[] - relatedOptions?: Array<{ - type?: { ... } - label: { ... } - label_type?: { ... } - name?: { ... } - group?: { ... } - allowedSchemas?: { ... } - relatedOptions?: { ... } - }> - }> + relatedOptions?: { ... }[] } ``` @@ -5816,6 +6850,7 @@ type Attribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -5823,6 +6858,7 @@ type Attribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -5845,6 +6881,23 @@ type Attribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "string" multiline?: boolean rich_text?: boolean @@ -5860,6 +6913,7 @@ type Attribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -5867,6 +6921,7 @@ type Attribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -5884,27 +6939,6 @@ type Attribute = { hint_text_key?: string hint_custom_component?: string hint_tooltip_placement?: string - } - explicit_searchable?: boolean - exclude_from_search?: boolean - repeatable?: boolean - has_primary?: boolean - type: "link" -} | { - id?: string - name: string - label: string - placeholder?: string - hidden?: boolean - show_in_table?: boolean - sortable?: boolean - required?: boolean - readonly?: boolean - deprecated?: boolean - default_value?: unknown - group?: string - order?: number - layout?: string // ... } ``` @@ -5932,6 +6966,7 @@ type BaseAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -5939,6 +6974,7 @@ type BaseAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -5961,6 +6997,23 @@ type BaseAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } } ``` @@ -5978,6 +7031,7 @@ type TextAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -5985,6 +7039,7 @@ type TextAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6007,6 +7062,23 @@ type TextAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "string" multiline?: boolean rich_text?: boolean @@ -6028,6 +7100,7 @@ type LinkAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6035,6 +7108,7 @@ type LinkAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6057,6 +7131,23 @@ type LinkAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "link" } ``` @@ -6075,6 +7166,7 @@ type InternalAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6082,6 +7174,7 @@ type InternalAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6104,6 +7197,23 @@ type InternalAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "internal" } ``` @@ -6122,6 +7232,7 @@ type BooleanAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6129,6 +7240,7 @@ type BooleanAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6151,6 +7263,23 @@ type BooleanAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "boolean" display_type?: "switch" | "checkbox" } @@ -6170,6 +7299,7 @@ type DateAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6177,6 +7307,7 @@ type DateAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6199,6 +7330,23 @@ type DateAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "date" | "datetime" } ``` @@ -6217,6 +7365,7 @@ type CountryAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6224,6 +7373,7 @@ type CountryAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6246,6 +7396,23 @@ type CountryAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "country" } ``` @@ -6264,6 +7431,7 @@ type SelectAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6271,6 +7439,7 @@ type SelectAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6293,6 +7462,23 @@ type SelectAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "select" | "radio" options?: Array<{ value: string @@ -6316,6 +7502,7 @@ type MultiSelectAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6323,6 +7510,7 @@ type MultiSelectAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6345,6 +7533,23 @@ type MultiSelectAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "multiselect" | "checkbox" disable_case_sensitive?: boolean allow_extra_options?: boolean @@ -6370,6 +7575,7 @@ type StatusAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6377,6 +7583,7 @@ type StatusAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6399,6 +7606,23 @@ type StatusAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "status" options?: Array relation_affinity_mode?: "weak" | "strong" enable_relation_picker?: boolean - edit_mode?: "list-view" details_view_mode_enabled?: boolean relation_picker_filter?: { q: string @@ -6676,6 +7976,7 @@ type UserRelationAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6683,6 +7984,7 @@ type UserRelationAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6705,6 +8007,23 @@ type UserRelationAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "relation_user" multiple?: boolean } @@ -6724,6 +8043,7 @@ type PartnerOrganisationAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6731,6 +8051,7 @@ type PartnerOrganisationAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6753,6 +8074,23 @@ type PartnerOrganisationAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "partner_organisation" } ``` @@ -6771,6 +8109,7 @@ type PortalAccessAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6778,6 +8117,7 @@ type PortalAccessAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6800,10 +8140,93 @@ type PortalAccessAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "portal_access" } ``` +### `PortalRoleAttribute` + +```ts +type PortalRoleAttribute = { + id?: string + name: string + label: string + placeholder?: string + hidden?: boolean + show_in_table?: boolean + sortable?: boolean + required?: boolean + readonly?: boolean + deprecated?: boolean + overridable_attribute?: boolean + default_value?: unknown + group?: string + order?: number + layout?: string + hide_label?: boolean + icon?: string + render_condition?: string + data_classification?: "public" | "pii" + _purpose?: string[] + _manifest?: string // uuid[] + constraints?: object + feature_flag?: string + settings_flag?: Array<{ + name?: string + enabled?: boolean + }> + value_formatter?: string + preview_value_formatter?: string + entity_builder_disable_edit?: boolean + protected?: boolean + info_helpers?: { + hint_text?: string + hint_text_key?: string + hint_custom_component?: string + hint_tooltip_placement?: string + } + explicit_searchable?: boolean + exclude_from_search?: boolean + repeatable?: boolean + has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } + type: "portal_role" +} +``` + ### `DefaultAddressFields` Default fields visible on addresses @@ -6843,6 +8266,7 @@ type AddressAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6850,6 +8274,7 @@ type AddressAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6872,6 +8297,23 @@ type AddressAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "address" default_address_fields?: string[] } @@ -6891,6 +8333,7 @@ type AddressRelationAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6898,6 +8341,7 @@ type AddressRelationAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6920,6 +8364,23 @@ type AddressRelationAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "relation_address" default_address_fields?: string[] } @@ -6939,6 +8400,7 @@ type PaymentMethodRelationAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6946,6 +8408,7 @@ type PaymentMethodRelationAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -6968,6 +8431,23 @@ type PaymentMethodRelationAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "relation_payment_method" } ``` @@ -6986,6 +8466,7 @@ type InvitationEmailAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -6993,6 +8474,7 @@ type InvitationEmailAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7015,6 +8497,23 @@ type InvitationEmailAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "invitation_email" } ``` @@ -7033,6 +8532,7 @@ type AutomationAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7040,6 +8540,7 @@ type AutomationAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7062,6 +8563,23 @@ type AutomationAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "automation" } ``` @@ -7080,6 +8598,7 @@ type InternalUserAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7087,6 +8606,7 @@ type InternalUserAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7109,6 +8629,23 @@ type InternalUserAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "internal_user" } ``` @@ -7127,6 +8664,7 @@ type PurposeAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7134,6 +8672,7 @@ type PurposeAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7156,6 +8695,23 @@ type PurposeAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "purpose" } ``` @@ -7174,6 +8730,7 @@ type RepeatableAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7181,6 +8738,7 @@ type RepeatableAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7203,6 +8761,23 @@ type RepeatableAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } } ``` @@ -7220,6 +8795,7 @@ type TagsAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7227,6 +8803,7 @@ type TagsAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7249,6 +8826,23 @@ type TagsAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "tags" options?: string[] suggestions?: string[] @@ -7269,6 +8863,7 @@ type MessageEmailAddressAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7276,6 +8871,7 @@ type MessageEmailAddressAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7298,6 +8894,23 @@ type MessageEmailAddressAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "message_email_address" address?: string send_status?: string @@ -7319,6 +8932,7 @@ type NumberAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7326,6 +8940,7 @@ type NumberAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7348,6 +8963,23 @@ type NumberAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "number" data_type?: "number" | "string" format?: string @@ -7355,10 +8987,10 @@ type NumberAttribute = { } ``` -### `ConsentAttribute` +### `TableAttribute` ```ts -type ConsentAttribute = { +type TableAttribute = { id?: string name: string label: string @@ -7369,6 +9001,7 @@ type ConsentAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7376,6 +9009,7 @@ type ConsentAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7398,16 +9032,46 @@ type ConsentAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean - type: "consent" - topic: string - identifiers?: string[] + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } + type: "table" + columns?: Array<{ + name: string + label: string + type?: "string" | "number" | "date" | "boolean" + width?: string + required?: boolean + bold?: boolean + }> + min_rows?: number + max_rows?: number + transposed?: boolean + column_header?: { + template?: string + start?: number + } } ``` -### `OrderedListAttribute` +### `ConsentAttribute` ```ts -type OrderedListAttribute = { +type ConsentAttribute = { id?: string name: string label: string @@ -7418,6 +9082,7 @@ type OrderedListAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7425,6 +9090,7 @@ type OrderedListAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7447,14 +9113,33 @@ type OrderedListAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean - type: "ordered_list" + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } + type: "consent" + topic: string + identifiers?: string[] } ``` -### `EmailAttribute` +### `OrderedListAttribute` ```ts -type EmailAttribute = { +type OrderedListAttribute = { id?: string name: string label: string @@ -7465,6 +9150,7 @@ type EmailAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7472,6 +9158,7 @@ type EmailAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7494,14 +9181,31 @@ type EmailAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean - type: "email" + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } + type: "ordered_list" } ``` -### `PhoneAttribute` +### `EmailAttribute` ```ts -type PhoneAttribute = { +type EmailAttribute = { id?: string name: string label: string @@ -7512,6 +9216,7 @@ type PhoneAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7519,6 +9224,7 @@ type PhoneAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7541,9 +9247,92 @@ type PhoneAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean - type: "phone" -} -``` + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } + type: "email" +} +``` + +### `PhoneAttribute` + +```ts +type PhoneAttribute = { + id?: string + name: string + label: string + placeholder?: string + hidden?: boolean + show_in_table?: boolean + sortable?: boolean + required?: boolean + readonly?: boolean + deprecated?: boolean + overridable_attribute?: boolean + default_value?: unknown + group?: string + order?: number + layout?: string + hide_label?: boolean + icon?: string + render_condition?: string + data_classification?: "public" | "pii" + _purpose?: string[] + _manifest?: string // uuid[] + constraints?: object + feature_flag?: string + settings_flag?: Array<{ + name?: string + enabled?: boolean + }> + value_formatter?: string + preview_value_formatter?: string + entity_builder_disable_edit?: boolean + protected?: boolean + info_helpers?: { + hint_text?: string + hint_text_key?: string + hint_custom_component?: string + hint_tooltip_placement?: string + } + explicit_searchable?: boolean + exclude_from_search?: boolean + repeatable?: boolean + has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } + type: "phone" +} +``` ### `PaymentAttribute` @@ -7559,6 +9348,7 @@ type PaymentAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7566,6 +9356,7 @@ type PaymentAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7588,6 +9379,23 @@ type PaymentAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "payment" } ``` @@ -7606,6 +9414,7 @@ type PriceComponentAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7613,6 +9422,7 @@ type PriceComponentAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7635,6 +9445,23 @@ type PriceComponentAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "price_component" } ``` @@ -7653,6 +9480,7 @@ type ComputedAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7660,6 +9488,7 @@ type ComputedAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7682,6 +9511,23 @@ type ComputedAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "computed" computed?: boolean amount_field?: string @@ -7703,6 +9549,7 @@ type PartnerStatusAttribute = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7710,6 +9557,7 @@ type PartnerStatusAttribute = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7732,6 +9580,23 @@ type PartnerStatusAttribute = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: { ... } + suffix_length?: { ... } + fields_to_ignore?: { ... } + regex_flags?: { ... } + country_code?: { ... } + match_on?: { ... } + key?: { ... } + mode?: { ... } + ordered?: { ... } + require_tags_match?: { ... } + pattern?: { ... } + } + } type: "partner_status" } ``` @@ -7805,6 +9670,85 @@ type GroupHeadlineWithCompositeID = { } ``` +### `BaseConditionDefinition` + +```ts +type BaseConditionDefinition = { + id: string // uuid + name: string + label: string +} +``` + +### `ScalarConditionDefinition` + +```ts +type ScalarConditionDefinition = { + id: string // uuid + name: string + label: string + type: "string" | "number" | "date" | "daterange" | "boolean" +} +``` + +### `SelectConditionDefinition` + +```ts +type SelectConditionDefinition = { + id: string // uuid + name: string + label: string + type: "select" + options?: Array +} +``` + +### `LocationConditionDefinition` + +```ts +type LocationConditionDefinition = { + id: string // uuid + name: string + label: string + type: "location" + format?: "postal_code" | "postal_code_city" | "power_grid_operator" | "gas_grid_operator" +} +``` + +### `ConditionDefinition` + +One dimension that conditional variants of an entity type are keyed by. `type` +discriminates the variants: only a `select` condition carries `options`, and only a +`location` condition carries `format`. + + +```ts +type ConditionDefinition = { + id: string // uuid + name: string + label: string + type: "string" | "number" | "date" | "daterange" | "boolean" +} | { + id: string // uuid + name: string + label: string + type: "select" + options?: Array +} | { + id: string // uuid + name: string + label: string + type: "location" + format?: "postal_code" | "postal_code_city" | "power_grid_operator" | "gas_grid_operator" +} +``` + ### `EntitySlug` URL-friendly identifier for the entity schema @@ -7813,6 +9757,16 @@ URL-friendly identifier for the entity schema type EntitySlug = string ``` +### `AdjustInstallmentCapabilityConfig` + +Configuration for adjusting a contract installment through a Journey. + +```ts +type AdjustInstallmentCapabilityConfig = { + journey_id: string +} +``` + ### `EntityCapability` Capabilities the Entity has. Turn features on/off for entities. @@ -7833,6 +9787,7 @@ type EntityCapability = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7840,6 +9795,7 @@ type EntityCapability = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7862,6 +9818,11 @@ type EntityCapability = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: { ... } + fuzzy_config?: { ... } + } type: "string" multiline?: boolean rich_text?: boolean @@ -7877,6 +9838,7 @@ type EntityCapability = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7884,6 +9846,7 @@ type EntityCapability = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7906,18 +9869,9 @@ type EntityCapability = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean - type: "link" - } | { - id?: string - name: string - label: string - placeholder?: string - hidden?: boolean - show_in_table?: boolean - sortable?: boolean - required?: boolean - readonly?: boolean - deprecated?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: { ... } // ... } ``` @@ -7940,6 +9894,7 @@ type EntityCapabilityWithCompositeID = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7947,6 +9902,7 @@ type EntityCapabilityWithCompositeID = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -7969,6 +9925,11 @@ type EntityCapabilityWithCompositeID = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: { ... } + fuzzy_config?: { ... } + } type: "string" multiline?: boolean rich_text?: boolean @@ -7984,6 +9945,7 @@ type EntityCapabilityWithCompositeID = { required?: boolean readonly?: boolean deprecated?: boolean + overridable_attribute?: boolean default_value?: unknown group?: string order?: number @@ -7991,6 +9953,7 @@ type EntityCapabilityWithCompositeID = { hide_label?: boolean icon?: string render_condition?: string + data_classification?: "public" | "pii" _purpose?: string[] _manifest?: string // uuid[] constraints?: object @@ -8013,18 +9976,9 @@ type EntityCapabilityWithCompositeID = { exclude_from_search?: boolean repeatable?: boolean has_primary?: boolean - type: "link" - } | { - id?: string - name: string - label: string - placeholder?: string - hidden?: boolean - show_in_table?: boolean - sortable?: boolean - required?: boolean - readonly?: boolean - deprecated?: boolean + edit_mode?: "direct" | "external" | "approval" + edit_mode_config?: { + match_strategy?: { ... } // ... } ``` @@ -8123,6 +10077,22 @@ type BaseEntity = { _purpose?: string[] _purpose_name?: string[] _manifest?: string // uuid[] + _changesets?: Record + }> } ``` @@ -8150,6 +10120,22 @@ type Entity = { _purpose?: string[] _purpose_name?: string[] _manifest?: string // uuid[] + _changesets?: Record + }> } ``` @@ -8177,6 +10163,22 @@ type NullableEntity = { _purpose?: string[] _purpose_name?: string[] _manifest?: string // uuid[] + _changesets?: Record + }> } ``` @@ -8242,6 +10244,22 @@ type EntityItem = { _purpose?: string[] _purpose_name?: string[] _manifest?: string // uuid[] + _changesets?: Record + }> } ``` @@ -8529,6 +10547,7 @@ type EntitySearchParams = { from?: number size?: number hydrate?: boolean + anonymize?: boolean fields?: string[] aggs?: object include_deleted?: "true" | "false" | "only" @@ -8569,42 +10588,16 @@ type EntityListParams = { exists?: { field: { ... } } - $and?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $or?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $not?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> + $and?: { ... } + $or?: { ... } + $not?: { ... } }> allow_targeting_all_schemas?: boolean sort?: string | string[] from?: number size?: number hydrate?: boolean + anonymize?: boolean fields?: string[] aggs?: object include_deleted?: "true" | "false" | "only" @@ -8639,90 +10632,10 @@ type SearchFilter = Array<{ exists?: { field: string } - $and?: Array<{ - term?: Record - terms?: Record - ids?: { - values?: { ... } - } - range?: Record - exists?: { - field: { ... } - } - $and?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $or?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $not?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - }> - $or?: Array<{ - term?: Record - terms?: Record - ids?: { - values?: { ... } - } - range?: Record - exists?: { - field: { ... } - } - $and?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - exists?: { ... } - $and?: { ... } - $or?: { ... } - $not?: { ... } - }> - $or?: Array<{ - term?: { ... } - terms?: { ... } - ids?: { ... } - range?: { ... } - // ... -} + $and?: { ... } + $or?: { ... } + $not?: { ... } +}> ``` ### `SearchFilterValue` @@ -8741,6 +10654,7 @@ type EntitySearchOptions = { from?: number size?: number hydrate?: boolean + anonymize?: boolean fields?: string[] aggs?: object include_deleted?: "true" | "false" | "only" @@ -8775,6 +10689,137 @@ type EntityImportParams = { key: string } schema: string + unique_key?: string[] + dry_run?: boolean + dry_run_job_id?: string + trigger_automations?: boolean +} +``` + +### `ImportRowOutcomeCounts` + +Number of rows per outcome, in the order the outcomes are evaluated. + +```ts +type ImportRowOutcomeCounts = { + error?: number + skipped_empty_key?: number + skipped_duplicate_in_file?: number + skipped_id_not_found?: number + skipped_ambiguous?: number + create?: number + unchanged?: number + update?: number +} +``` + +### `ImportJobSummary` + +One import job (import or dry run) in the import history of a schema. + +```ts +type ImportJobSummary = { + job_id: string + schema: string + status: "PROCESSING" | "COMPLETED" | "FAILED" | "CANCELLED" + dry_run: boolean + trigger_automations?: boolean + started_by?: string + started_at: string // date-time + finished_at?: string // date-time + file_name?: string + total?: number + importedEntitiesCount?: number + failedEntitiesCount?: number + outcome_counts?: { + error?: number + skipped_empty_key?: number + skipped_duplicate_in_file?: number + skipped_id_not_found?: number + skipped_ambiguous?: number + create?: number + unchanged?: number + update?: number + } + failure_code?: "invalid_csv_bad_headers" | "dry_run_required" | "dry_run_mismatch" | "dry_run_expired" | "import_file_changed" | "prescan_missing" | "import_too_large" | "token_expired" | "max_duration_exceeded" | "no_progress" | "internal_error" + unique_key?: string[] +} +``` + +### `ImportIssue` + +Rows of an import job that share one reason not to be written. + +```ts +type ImportIssue = { + severity: "blocking" | "warning" + reason: string + column?: string + count: number + example_rows: number[] +} +``` + +### `ImportFailureCode` + +Machine readable reason of a failed job. `failure_reason` holds the human text. +- `invalid_csv_bad_headers`: the file has neither a `_schema` nor an `_id` column +- `dry_run_required`, `dry_run_mismatch`, `dry_run_expired`: the dry-run rule rejected the commit before any row +- `import_file_changed`: + +```ts +type ImportFailureCode = "invalid_csv_bad_headers" | "dry_run_required" | "dry_run_mismatch" | "dry_run_expired" | "import_file_changed" | "prescan_missing" | "import_too_large" | "token_expired" | "max_duration_exceeded" | "no_progress" | "internal_error" +``` + +### `ImportProgress` + +Progress of an import job. The fields `dry_run`, `unique_key`, `outcome_counts`, `report_url`, +`S3Reference` and `started_by` are only set for jobs started with `unique_key`, `dry_run` or `dry_run_job_id`. For those, +`importedEntitiesCount` is `create` plus `update` and `failedEntitiesCount` counts + +```ts +type ImportProgress = { + jobPollId?: string + trigger_automations?: boolean + started_by?: string + status?: "PROCESSING" | "COMPLETED" | "FAILED" | "CANCELLED" + total?: number + importedEntitiesCount?: number + failedEntitiesCount?: number + importedEntitiesUrl?: string + failedEntitiesUrl?: string + updated_at?: string // date-time + failure_reason?: string + failure_code?: "invalid_csv_bad_headers" | "dry_run_required" | "dry_run_mismatch" | "dry_run_expired" | "import_file_changed" | "prescan_missing" | "import_too_large" | "token_expired" | "max_duration_exceeded" | "no_progress" | "internal_error" + abortable?: boolean + dry_run?: boolean + unique_key?: string[] + outcome_counts?: { + error?: number + skipped_empty_key?: number + skipped_duplicate_in_file?: number + skipped_id_not_found?: number + skipped_ambiguous?: number + create?: number + unchanged?: number + update?: number + } + report_url?: string + S3Reference?: { + bucket?: string + key?: string + } + issues?: Array<{ + severity: "blocking" | "warning" + reason: string + column?: string + count: number + example_rows: number[] + }> + phase?: "scanning" | "dry_run" | "importing" | "finalizing" | "done" + heartbeat_at?: string // date-time + started_at?: string // date-time + finished_at?: string // date-time } ``` @@ -8792,6 +10837,7 @@ type GraphQueryRequest = { schema: { ... } cardinality?: { ... } fields?: { ... } + filter?: { ... } }> edges: Array<{ from: { ... } @@ -8799,6 +10845,7 @@ type GraphQueryRequest = { }> } hydrate?: boolean + apply_changesets?: boolean } ``` @@ -8820,6 +10867,10 @@ type GraphDefinition = { schema: string cardinality?: "one" | "many" fields?: object + filter?: Array<{ + attribute: { ... } + value: { ... } + }> }> edges: Array<{ from: string @@ -8836,6 +10887,21 @@ type GraphNode = { schema: string cardinality?: "one" | "many" fields?: object + filter?: Array<{ + attribute: string + value: object + }> +} +``` + +### `GraphNodeFilter` + +Entities are included in this node's result only if `attribute` exactly equals the literal `value`. + +```ts +type GraphNodeFilter = { + attribute: string + value: object } ``` @@ -8874,6 +10940,16 @@ type GraphQueryResponse = { _purpose?: string[] _purpose_name?: string[] _manifest?: string // uuid[] + _changesets?: Record } | Array<{ _id?: object _org?: string @@ -8895,6 +10971,16 @@ type GraphQueryResponse = { _purpose?: string[] _purpose_name?: string[] _manifest?: string // uuid[] + _changesets?: Record }>> edges: Array<{ from: string @@ -8929,6 +11015,16 @@ type EntitySearchResults = { _purpose?: string[] _purpose_name?: string[] _manifest?: string // uuid[] + _changesets?: Record }> aggregations?: object stable_query_id?: string @@ -8944,8 +11040,9 @@ Advanced: explicit Elasticsearch index mapping definitions for entity data ```ts type SearchMappings = Record ``` @@ -9035,6 +11132,16 @@ type EntityOperation = { _purpose?: string[] _purpose_name?: string[] _manifest?: string // uuid[] + _changesets?: Record } diff?: { added?: { @@ -9051,6 +11158,7 @@ type EntityOperation = { _purpose?: { ... } _purpose_name?: { ... } _manifest?: { ... } + _changesets?: { ... } } updated?: { _id?: { ... } @@ -9066,6 +11174,7 @@ type EntityOperation = { _purpose?: { ... } _purpose_name?: { ... } _manifest?: { ... } + _changesets?: { ... } } deleted?: { _id?: { ... } @@ -9081,8 +11190,34 @@ type EntityOperation = { _purpose?: { ... } _purpose_name?: { ... } _manifest?: { ... } + _changesets?: { ... } } } + source_context?: { + source: "portal" | "epilot" | "erp" | "system" | "api" | "external" | "journey" | "automation" | "unknown" + source_label?: string + source_system?: string + source_reference?: string + actor_type?: "user" | "portal_user" | "api_client" | "automation" | "system" + actor_id?: string + effective_at?: string // date-time + // ... +} +``` + +### `EntityOperationSourceContext` + +Billing and audit source context for the operation event. + +```ts +type EntityOperationSourceContext = { + source: "portal" | "epilot" | "erp" | "system" | "api" | "external" | "journey" | "automation" | "unknown" + source_label?: string + source_system?: string + source_reference?: string + actor_type?: "user" | "portal_user" | "api_client" | "automation" | "system" + actor_id?: string + effective_at?: string // date-time } ``` @@ -9134,16 +11269,44 @@ type ActivityItem = { _purpose?: { ... } _purpose_name?: { ... } _manifest?: { ... } + _changesets?: { ... } } diff?: { added?: { ... } updated?: { ... } deleted?: { ... } } + source_context?: { + source: { ... } + source_label?: { ... } + source_system?: { ... } + source_reference?: { ... } + actor_type?: { ... } + actor_id?: { ... } + effective_at?: { ... } + } + _workflow_origin?: { + workflow_exec_id?: { ... } + flow_template_id?: { ... } + } + _automation_chain?: string[] }> } ``` +### `EntitySummary` + +Latest AI generated summary of an entity + +```ts +type EntitySummary = { + summary: string + variant: "short" | "detailed" | "action_points" + execution_id: string + created_at: string // date-time +} +``` + ### `BlueprintEntityId` Reference to blueprint @@ -9196,6 +11359,7 @@ type SavedViewPartial = { isFavoritedBy?: string[] created_by?: { user_id?: string + org_id?: string } | { source?: "SYSTEM" | "BLUEPRINT" } @@ -9217,6 +11381,7 @@ type SavedView = { isFavoritedBy?: string[] created_by?: { user_id?: string + org_id?: string } | { source?: "SYSTEM" | "BLUEPRINT" } @@ -9242,14 +11407,14 @@ type Taxonomy = { created_by?: string enabled?: boolean order?: number - enabled_locations?: "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | string[] + enabled_locations?: "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | "user" | string[] } ``` ### `TaxonomyLocationId` ```ts -type TaxonomyLocationId = "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" +type TaxonomyLocationId = "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | "user" ``` ### `TaxonomySearchIncludeArchivedParam` @@ -9279,7 +11444,7 @@ type TaxonomyClassification = { updated_at?: string // date-time archived?: boolean starred?: boolean - enabled_locations?: "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | string[] + enabled_locations?: "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | "user" | string[] enabled_purposes?: string[] _manifest?: string // uuid[] } @@ -9329,7 +11494,7 @@ type ClassificationsUpdate = { updated_at?: string // date-time archived?: boolean starred?: boolean - enabled_locations?: "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | string[] + enabled_locations?: "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | "user" | string[] enabled_purposes?: string[] _manifest?: string // uuid[] }> @@ -9343,7 +11508,7 @@ type ClassificationsUpdate = { updated_at?: string // date-time archived?: boolean starred?: boolean - enabled_locations?: "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | string[] + enabled_locations?: "account" | "contact" | "contract" | "email_template" | "file" | "journey" | "meter_counter" | "meter" | "opportunity" | "order" | "partner" | "price" | "product" | "submission" | "tax" | "message" | "portal_user" | "request" | "comment" | "user" | string[] enabled_purposes?: string[] _manifest?: string // uuid[] }> @@ -9428,3 +11593,187 @@ type ErrorObject = { error?: string } ``` + +### `ChangesetCreator` + +Identifies the actor that created the changeset. + +```ts +type ChangesetCreator = { + type?: "user" | "portal_user" | "api_client" | "automation" + id?: string +} +``` + +### `Changeset` + +A pending proposed change for a single entity attribute, awaiting external confirmation or human approval. + +```ts +type Changeset = { + proposed_value: unknown + previous_value?: unknown + created_at: string // date-time + created_by?: { + type?: "user" | "portal_user" | "api_client" | "automation" + id?: string + } + edit_mode: "external" | "approval" + match_strategy?: "exact" | "fuzzy" | "any" + source?: string + related_values?: Record +} +``` + +### `ChangesetMap` + +Map of attribute name to pending changeset. At most one changeset per attribute. + +```ts +type ChangesetMap = Record +}> +``` + +### `MeterReadingChangesetEntry` + +A meter readings changeset entry — service-managed by metering-api. +Stored on `Meter._meter_readings_changeset` array attribute. Each entry mirrors a +ClickHouse meter reading row plus a changeset metadata overlay. + +Note: `org_id` is NOT stored on the entry. The entries live on the Meter entity, +whic + +```ts +type MeterReadingChangesetEntry = { + value: number + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + meter_id: string // uuid + counter_id: string // uuid + source?: string + reason?: string + read_by?: string + status?: "valid" | "in-validation" | "implausible" + external_id?: string + remark?: string + metadata?: Record + changeset_id: string + edit_mode: "external" | "approval" + match_strategy?: "exact" | "fuzzy" + timestamp_tolerance?: "exact" | { + type: "same-day" + timezone?: string + } | { + type: "within-seconds" + seconds: number + } + fuzzy_config?: { + percentage_threshold?: number + absolute_threshold?: number + } + created_at: string // date-time + created_by?: { + type?: "user" | "portal_user" | "api_client" | "automation" + id?: string + } + previous?: { + value?: number + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + } +} +``` + +### `EditMode` + +Controls whether a write goes through immediately or is held as a pending entry +on the parent entity's `_changesets` map. + +- `direct`: write applied immediately. No changeset created. +- `external`: write held as a pending changeset; auto-cleared on a matching direct/ERP write. +- `approval`: write he + +```ts +type EditMode = "direct" | "external" | "approval" +``` + +### `EditModeConfig` + +Configuration for `edit_mode: external` auto-clear matching. +Fields here (`match_strategy`, `fuzzy_config`) only take effect when +`edit_mode` is `external`. They are ignored for `edit_mode: approval`, +which never auto-clears and is resolved exclusively via the +`:apply` / `:dismiss` changeset endpoin + +```ts +type EditModeConfig = { + match_strategy?: "exact" | "fuzzy" | "any" + fuzzy_config?: { + type: "suffix" | "digits_only" | "normalize_phone" | "ignore_fields" | "set_equivalent" | "entry_match" | "relation_set" | "regex" + suffix_length?: number + fields_to_ignore?: string[] + regex_flags?: string + country_code?: string + match_on?: string + key?: string | string[] + mode?: "subset" | "exact_set" + ordered?: boolean + require_tags_match?: boolean + pattern?: string + } +} +``` + +### `FuzzyConfig` + +Configuration for fuzzy auto-clear matching on `edit_mode: external` attributes. +Not used for `edit_mode: approval`. + +Type compatibility with attribute shape is enforced at schema save time: +- scalar string attributes: `suffix`, `digits_only`, `regex` +- repeatable attributes: `set_equivalent`, `entr + +```ts +type FuzzyConfig = { + type: "suffix" | "digits_only" | "normalize_phone" | "ignore_fields" | "set_equivalent" | "entry_match" | "relation_set" | "regex" + suffix_length?: number + fields_to_ignore?: string[] + regex_flags?: string + country_code?: string + match_on?: string + key?: string | string[] + mode?: "subset" | "exact_set" + ordered?: boolean + require_tags_match?: boolean + pattern?: string +} +``` + +### `MatchStrategy` + +Strategy for auto-clearing a changeset on an `edit_mode: external` attribute +when a direct write (`?direct=true`) arrives — typically an ERP inbound sync. +Ignored for `edit_mode: approval`, which does not auto-clear and is resolved +exclusively via the `:apply` / `:dismiss` changeset endpoints. +- `ex + +```ts +type MatchStrategy = "exact" | "fuzzy" | "any" +``` diff --git a/docs/sdk/clients/environments.md b/docs/sdk/clients/environments.md index daebd8ee..b3ec6444 100644 --- a/docs/sdk/clients/environments.md +++ b/docs/sdk/clients/environments.md @@ -32,21 +32,43 @@ const { data } = await environmentsClient.listEnvironmentVariables(...) **environments** - [`listEnvironmentVariables`](#listenvironmentvariables) - [`createEnvironmentVariable`](#createenvironmentvariable) +- [`listEnvironmentGroups`](#listenvironmentgroups) +- [`putEnvironmentGroup`](#putenvironmentgroup) +- [`deleteEnvironmentGroup`](#deleteenvironmentgroup) - [`getEnvironmentVariable`](#getenvironmentvariable) - [`updateEnvironmentVariable`](#updateenvironmentvariable) - [`deleteEnvironmentVariable`](#deleteenvironmentvariable) **Schemas** - [`EnvironmentValueType`](#environmentvaluetype) +- [`StringTranslations`](#stringtranslations) +- [`MapEntry`](#mapentry) +- [`MapValue`](#mapvalue) +- [`JsonValue`](#jsonvalue) +- [`LinkValue`](#linkvalue) +- [`LinkFields`](#linkfields) +- [`ListItemType`](#listitemtype) +- [`ListOfText`](#listoftext) +- [`ListOfString`](#listofstring) +- [`ListOfSecretString`](#listofsecretstring) +- [`ListOfNumber`](#listofnumber) +- [`ListOfBoolean`](#listofboolean) +- [`ListOfJson`](#listofjson) +- [`ListOfLink`](#listoflink) +- [`ListValue`](#listvalue) +- [`EnvironmentValue`](#environmentvalue) - [`EnvironmentVariable`](#environmentvariable) - [`EnvironmentVariableListItem`](#environmentvariablelistitem) - [`EnvironmentVariableList`](#environmentvariablelist) - [`EnvironmentVariableCreateRequest`](#environmentvariablecreaterequest) - [`EnvironmentVariableUpdateRequest`](#environmentvariableupdaterequest) +- [`EnvironmentGroup`](#environmentgroup) +- [`EnvironmentGroupList`](#environmentgrouplist) +- [`EnvironmentGroupUpsertRequest`](#environmentgroupupsertrequest) ### `listEnvironmentVariables` -List environment variables +List all environment variables for the organization. Returns metadata only, no secret values. `GET /v1/environments` @@ -63,8 +85,11 @@ const { data } = await client.listEnvironmentVariables() { "key": "string", "type": "String", + "item_type": "String", "description": "string", + "group": "string", "value": "string", + "protected": true, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z" } @@ -78,7 +103,7 @@ const { data } = await client.listEnvironmentVariables() ### `createEnvironmentVariable` -Create environment variable +Create a new environment variable or secret for the organization. If `group` is provided and the group does not yet exist, it is created automatically. `POST /v1/environments` @@ -89,7 +114,9 @@ const { data } = await client.createEnvironmentVariable( key: 'string', type: 'String', description: 'string', - value: 'string' + group: 'string', + value: 'string', + protected: true }, ) ``` @@ -101,8 +128,11 @@ const { data } = await client.createEnvironmentVariable( { "key": "string", "type": "String", + "item_type": "String", "description": "string", + "group": "string", "value": "string", + "protected": true, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z" } @@ -112,9 +142,86 @@ const { data } = await client.createEnvironmentVariable( --- +### `listEnvironmentGroups` + +List all environment groups for the organization. + +`GET /v1/environments/groups` + +```ts +const { data } = await client.listEnvironmentGroups() +``` + +
+Response + +```json +{ + "items": [ + { + "name": "string", + "description": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `putEnvironmentGroup` + +Create or update an environment group by name. Acts as an upsert — creates the group if it does not exist. + +`PUT /v1/environments/groups/{name}` + +```ts +const { data } = await client.putEnvironmentGroup( + { + name: 'example', + }, + { + description: 'string' + }, +) +``` + +
+Response + +```json +{ + "name": "string", + "description": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteEnvironmentGroup` + +Deletes a group. Variables assigned to this group become ungrouped. + +`DELETE /v1/environments/groups/{name}` + +```ts +const { data } = await client.deleteEnvironmentGroup({ + name: 'example', +}) +``` + +--- + ### `getEnvironmentVariable` -Get environment variable +Get an environment variable by key. Returns value for non-secret types, omitted for SecretString. `GET /v1/environments/{key}` @@ -131,8 +238,11 @@ const { data } = await client.getEnvironmentVariable({ { "key": "string", "type": "String", + "item_type": "String", "description": "string", + "group": "string", "value": "string", + "protected": true, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z" } @@ -144,7 +254,7 @@ const { data } = await client.getEnvironmentVariable({ ### `updateEnvironmentVariable` -Update environment variable +Create or update an environment variable. Acts as an upsert — creates the variable if it does not exist. If `group` is provided and the group does not yet exist, it is created automatically. `PUT /v1/environments/{key}` @@ -156,7 +266,9 @@ const { data } = await client.updateEnvironmentVariable( { type: 'String', value: 'string', - description: 'string' + description: 'string', + group: 'string', + protected: true }, ) ``` @@ -168,8 +280,11 @@ const { data } = await client.updateEnvironmentVariable( { "key": "string", "type": "String", + "item_type": "String", "description": "string", + "group": "string", "value": "string", + "protected": true, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z" } @@ -181,7 +296,7 @@ const { data } = await client.updateEnvironmentVariable( ### `deleteEnvironmentVariable` -Delete environment variable +Delete an environment variable by key. `DELETE /v1/environments/{key}` @@ -197,8 +312,277 @@ const { data } = await client.deleteEnvironmentVariable({ ### `EnvironmentValueType` +The structure a variable's value holds. `SecretString` is encrypted at rest and +its value is never returned. Every other type +may be served to browser-facing consumers. A `List` inherits this from its element +type: a `List``` is never served. + + +```ts +type EnvironmentValueType = "String" | "SecretString" | "Text" | "Number" | "Boolean" | "Map" | "JSON" | "Link" | "List" +``` + +### `StringTranslations` + +A string translated per language. Keys are language codes (e.g. `de`, +`en-US`), matching the hyphen-only BCP-47 form epilot's i18n stack uses +everywhere else: `^[a-z]{2,3}(-[A-Za-z0-9]+)*$`. The server enforces +that with LANGUAGE_KEY_PATTERN in src/core/value-types.ts — the two are +not otherwise lin + ```ts -type EnvironmentValueType = "String" | "SecretString" +type StringTranslations = Record +``` + +### `MapEntry` + +One entry of a Map. `key` is the token a journey submits; `value` is +what the customer reads — either one string, or one string per +language. Every entry of a Map must agree on which of the two it uses. + + +```ts +type MapEntry = { + key: string + value: string | Record +} +``` + +### `MapValue` + +```ts +type MapValue = { + fallbackLanguage?: string + options: Array<{ + key: string + value: string | Record + }> +} +``` + +### `JsonValue` + +Arbitrary JSON object, e.g. a flat key/value map used by integrations for +enum translation: {"Mr.": 1, "Ms. / Mrs.": 2}. Max 32 KB serialised. + + +```ts +type JsonValue = Record +``` + +### `LinkValue` + +One URL with a label and description a customer reads. `label` and +`description` are each either a plain string or one string per language; +the two fields decide that independently — a plain string means "the +same in every language". A translated field must carry the fallback +language. + +The URL must + +```ts +type LinkValue = { + url: string + label: string | Record + description?: string | Record + fallbackLanguage?: string +} +``` + +### `LinkFields` + +The fields of a link, without a fallback language — the shape a `List` +item carries. Inside a list the fallback belongs to the wrapper, which +owns the language tabs for every row. + +Restated rather than composed with `LinkValue`: `allOf` plus +`additionalProperties: false` is rejected by most validato + +```ts +type LinkFields = { + url: string + label: string | Record + description?: string | Record +} +``` + +### `ListItemType` + +The element type a `List` holds — every value type except the +containers. `Map` is already a keyed collection and a list of lists has +no consumer. A list is exactly as client-safe and exactly as secret as +its element type: a list of `SecretString` is encrypted per item and its +value is never returne + +```ts +type ListItemType = "String" | "SecretString" | "Text" | "Number" | "Boolean" | "JSON" | "Link" +``` + +### `ListOfText` + +```ts +type ListOfText = { + itemType: "Text" + items: string[] +} +``` + +### `ListOfString` + +```ts +type ListOfString = { + itemType: "String" + items: string[] +} +``` + +### `ListOfSecretString` + +Write-only in effect: the items are encrypted per item at rest and the +whole value is omitted from every read response, exactly as a +`SecretString` variable's value is. Read `item_type` to learn what a +list holds when its value is withheld. + + +```ts +type ListOfSecretString = { + itemType: "SecretString" + items: string[] +} +``` + +### `ListOfNumber` + +```ts +type ListOfNumber = { + itemType: "Number" + items: number[] +} +``` + +### `ListOfBoolean` + +```ts +type ListOfBoolean = { + itemType: "Boolean" + items: boolean[] +} +``` + +### `ListOfJson` + +```ts +type ListOfJson = { + itemType: "JSON" + items: Record[] +} +``` + +### `ListOfLink` + +A list of links. `fallbackLanguage` applies to every item's translated +`label` and `description`; items may mix plain and translated fields +freely, since a plain string is a complete answer for any language. + + +```ts +type ListOfLink = { + itemType: "Link" + fallbackLanguage?: string + items: Array<{ + url: string + label: string | Record + description?: string | Record + }> +} +``` + +### `ListValue` + +An ordered collection of one declared element type. Items round-trip in +the order written; nothing sorts them. Holds at most 100 items. + +The whole value is limited to 32768 characters when serialised — the +server enforces this, and it is not expressible per-property here. + + +```ts +type ListValue = { + itemType: "Text" + items: string[] +} | { + itemType: "Number" + items: number[] +} | { + itemType: "Boolean" + items: boolean[] +} | { + itemType: "JSON" + items: Record[] +} | { + itemType: "Link" + fallbackLanguage?: string + items: Array<{ + url: string + label: string | Record + description?: string | Record + }> +} | { + itemType: "String" + items: string[] +} | { + itemType: "SecretString" + items: string[] +} +``` + +### `EnvironmentValue` + +A variable's value. The JSON type corresponds to the variable's `type`: +`String`, `SecretString` and `Text` are strings, `Number` is a number, +`Boolean` is a boolean, and `Map`, `JSON`, `Link` and `List` are objects. +Numbers are IEEE 754 doubles; integers above 2^53 may lose precision on +round-trip. + +```ts +type EnvironmentValue = string | number | boolean | { + fallbackLanguage?: string + options: Array<{ + key: string + value: string | Record + }> +} | Record | { + url: string + label: string | Record + description?: string | Record + fallbackLanguage?: string +} | { + itemType: "Text" + items: string[] +} | { + itemType: "Number" + items: number[] +} | { + itemType: "Boolean" + items: boolean[] +} | { + itemType: "JSON" + items: Record[] +} | { + itemType: "Link" + fallbackLanguage?: string + items: Array<{ + url: string + label: string | Record + description?: string | Record + }> +} | { + itemType: "String" + items: string[] +} | { + itemType: "SecretString" + items: string[] +} ``` ### `EnvironmentVariable` @@ -206,9 +590,49 @@ type EnvironmentValueType = "String" | "SecretString" ```ts type EnvironmentVariable = { key: string - type: "String" | "SecretString" + type: "String" | "SecretString" | "Text" | "Number" | "Boolean" | "Map" | "JSON" | "Link" | "List" + item_type?: "String" | "SecretString" | "Text" | "Number" | "Boolean" | "JSON" | "Link" description?: string - value?: string + group?: string + value?: string | number | boolean | { + fallbackLanguage?: string + options: Array<{ + key: { ... } + value: { ... } + }> + } | Record | { + url: string + label: string | Record + description?: string | Record + fallbackLanguage?: string + } | { + itemType: "Text" + items: string[] + } | { + itemType: "Number" + items: number[] + } | { + itemType: "Boolean" + items: boolean[] + } | { + itemType: "JSON" + items: Record[] + } | { + itemType: "Link" + fallbackLanguage?: string + items: Array<{ + url: { ... } + label: { ... } + description?: { ... } + }> + } | { + itemType: "String" + items: string[] + } | { + itemType: "SecretString" + items: string[] + } + protected?: boolean created_at: string // date-time updated_at: string // date-time } @@ -219,9 +643,49 @@ type EnvironmentVariable = { ```ts type EnvironmentVariableListItem = { key: string - type: "String" | "SecretString" + type: "String" | "SecretString" | "Text" | "Number" | "Boolean" | "Map" | "JSON" | "Link" | "List" + item_type?: "String" | "SecretString" | "Text" | "Number" | "Boolean" | "JSON" | "Link" description?: string - value?: string + group?: string + value?: string | number | boolean | { + fallbackLanguage?: string + options: Array<{ + key: { ... } + value: { ... } + }> + } | Record | { + url: string + label: string | Record + description?: string | Record + fallbackLanguage?: string + } | { + itemType: "Text" + items: string[] + } | { + itemType: "Number" + items: number[] + } | { + itemType: "Boolean" + items: boolean[] + } | { + itemType: "JSON" + items: Record[] + } | { + itemType: "Link" + fallbackLanguage?: string + items: Array<{ + url: { ... } + label: { ... } + description?: { ... } + }> + } | { + itemType: "String" + items: string[] + } | { + itemType: "SecretString" + items: string[] + } + protected?: boolean created_at: string // date-time updated_at: string // date-time } @@ -233,9 +697,42 @@ type EnvironmentVariableListItem = { type EnvironmentVariableList = { items: Array<{ key: string - type: "String" | "SecretString" + type: "String" | "SecretString" | "Text" | "Number" | "Boolean" | "Map" | "JSON" | "Link" | "List" + item_type?: "String" | "SecretString" | "Text" | "Number" | "Boolean" | "JSON" | "Link" description?: string - value?: string + group?: string + value?: string | number | boolean | { + fallbackLanguage?: { ... } + options: { ... } + } | Record | { + url: { ... } + label: { ... } + description?: { ... } + fallbackLanguage?: { ... } + } | { + itemType: { ... } + items: { ... } + } | { + itemType: { ... } + items: { ... } + } | { + itemType: { ... } + items: { ... } + } | { + itemType: { ... } + items: { ... } + } | { + itemType: { ... } + fallbackLanguage?: { ... } + items: { ... } + } | { + itemType: { ... } + items: { ... } + } | { + itemType: { ... } + items: { ... } + } + protected?: boolean created_at: string // date-time updated_at: string // date-time }> @@ -247,9 +744,48 @@ type EnvironmentVariableList = { ```ts type EnvironmentVariableCreateRequest = { key: string - type: "String" | "SecretString" + type: "String" | "SecretString" | "Text" | "Number" | "Boolean" | "Map" | "JSON" | "Link" | "List" description?: string - value: string + group?: string + value?: string | number | boolean | { + fallbackLanguage?: string + options: Array<{ + key: { ... } + value: { ... } + }> + } | Record | { + url: string + label: string | Record + description?: string | Record + fallbackLanguage?: string + } | { + itemType: "Text" + items: string[] + } | { + itemType: "Number" + items: number[] + } | { + itemType: "Boolean" + items: boolean[] + } | { + itemType: "JSON" + items: Record[] + } | { + itemType: "Link" + fallbackLanguage?: string + items: Array<{ + url: { ... } + label: { ... } + description?: { ... } + }> + } | { + itemType: "String" + items: string[] + } | { + itemType: "SecretString" + items: string[] + } + protected?: boolean } ``` @@ -257,8 +793,79 @@ type EnvironmentVariableCreateRequest = { ```ts type EnvironmentVariableUpdateRequest = { - type?: "String" | "SecretString" - value: string + type?: "String" | "SecretString" | "Text" | "Number" | "Boolean" | "Map" | "JSON" | "Link" | "List" + value?: string | number | boolean | { + fallbackLanguage?: string + options: Array<{ + key: { ... } + value: { ... } + }> + } | Record | { + url: string + label: string | Record + description?: string | Record + fallbackLanguage?: string + } | { + itemType: "Text" + items: string[] + } | { + itemType: "Number" + items: number[] + } | { + itemType: "Boolean" + items: boolean[] + } | { + itemType: "JSON" + items: Record[] + } | { + itemType: "Link" + fallbackLanguage?: string + items: Array<{ + url: { ... } + label: { ... } + description?: { ... } + }> + } | { + itemType: "String" + items: string[] + } | { + itemType: "SecretString" + items: string[] + } + description?: string + group?: string + protected?: boolean +} +``` + +### `EnvironmentGroup` + +```ts +type EnvironmentGroup = { + name: string + description?: string + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `EnvironmentGroupList` + +```ts +type EnvironmentGroupList = { + items: Array<{ + name: string + description?: string + created_at: string // date-time + updated_at: string // date-time + }> +} +``` + +### `EnvironmentGroupUpsertRequest` + +```ts +type EnvironmentGroupUpsertRequest = { description?: string } ``` diff --git a/docs/sdk/clients/erp-integration.md b/docs/sdk/clients/erp-integration.md deleted file mode 100644 index 000ef823..00000000 --- a/docs/sdk/clients/erp-integration.md +++ /dev/null @@ -1,4160 +0,0 @@ ---- -title: "ERP Integration API" -description: "TypeScript SDK client for the epilot ERP Integration API: usage with @epilot/sdk, all operations and schemas." ---- - -# ERP Integration API - -- **Base URL:** `https://erp-integration-api.sls.epilot.io` -- **Full API Docs:** [https://docs.epilot.io/api/erp-integration](https://docs.epilot.io/api/erp-integration) - -## Usage - -```ts -import { epilot } from '@epilot/sdk' - -epilot.authorize(() => '') -const { data } = await epilot.erpIntegration.acknowledgeTracking(...) -``` - -### Tree-shakeable import - -```ts -import { getClient, authorize } from '@epilot/sdk/erp-integration' - -const erpIntegrationClient = getClient() -authorize(erpIntegrationClient, () => '') -const { data } = await erpIntegrationClient.acknowledgeTracking(...) -``` - -## Operations - -**erp** -- [`acknowledgeTracking`](#acknowledgetracking) -- [`triggerErp`](#triggererp) -- [`processErpUpdatesEventsV3`](#processerpupdateseventsv3) -- [`simulateMappingV2`](#simulatemappingv2) -- [`simulateMapping`](#simulatemapping) - -**integrations** -- [`listIntegrations`](#listintegrations) -- [`createIntegration`](#createintegration) -- [`getIntegration`](#getintegration) -- [`updateIntegration`](#updateintegration) -- [`deleteIntegration`](#deleteintegration) -- [`queryEvents`](#queryevents) -- [`replayEvents`](#replayevents) -- [`listUseCases`](#listusecases) -- [`createUseCase`](#createusecase) -- [`getUseCase`](#getusecase) -- [`updateUseCase`](#updateusecase) -- [`deleteUseCase`](#deleteusecase) -- [`listUseCaseHistory`](#listusecasehistory) -- [`listIntegrationsV2`](#listintegrationsv2) -- [`createIntegrationV2`](#createintegrationv2) -- [`getIntegrationV2`](#getintegrationv2) -- [`updateIntegrationV2`](#updateintegrationv2) -- [`deleteIntegrationV2`](#deleteintegrationv2) -- [`setIntegrationAppMapping`](#setintegrationappmapping) -- [`deleteIntegrationAppMapping`](#deleteintegrationappmapping) -- [`getOutboundStatus`](#getoutboundstatus) - -**monitoring** -- [`queryInboundMonitoringEvents`](#queryinboundmonitoringevents) -- [`getMonitoringStats`](#getmonitoringstats) -- [`getMonitoringTimeSeries`](#getmonitoringtimeseries) -- [`queryAccessLogs`](#queryaccesslogs) -- [`queryOutboundMonitoringEvents`](#queryoutboundmonitoringevents) - -**Schemas** -- [`ErrorResponseBase`](#errorresponsebase) -- [`ErpEvent`](#erpevent) -- [`ErpUpdatesEventsV2Request`](#erpupdateseventsv2request) -- [`ErpEventV3`](#erpeventv3) -- [`ErpUpdatesEventsV3Request`](#erpupdateseventsv3request) -- [`TriggerErpActionRequest`](#triggererpactionrequest) -- [`TriggerWebhookResp`](#triggerwebhookresp) -- [`IntegrationEditableFields`](#integrationeditablefields) -- [`Integration`](#integration) -- [`CreateIntegrationRequest`](#createintegrationrequest) -- [`UpdateIntegrationRequest`](#updateintegrationrequest) -- [`EnvironmentFieldConfig`](#environmentfieldconfig) -- [`IntegrationSettings`](#integrationsettings) -- [`AutoRefreshSettings`](#autorefreshsettings) -- [`SetIntegrationAppMappingRequest`](#setintegrationappmappingrequest) -- [`DeleteIntegrationAppMappingRequest`](#deleteintegrationappmappingrequest) -- [`IntegrationAppMapping`](#integrationappmapping) -- [`IntegrationWithUseCases`](#integrationwithusecases) -- [`UpsertIntegrationWithUseCasesRequest`](#upsertintegrationwithusecasesrequest) -- [`InboundIntegrationEventConfiguration`](#inboundintegrationeventconfiguration) -- [`OutboundIntegrationEventConfiguration`](#outboundintegrationeventconfiguration) -- [`IntegrationEntity`](#integrationentity) -- [`IntegrationMeterReading`](#integrationmeterreading) -- [`PruneScopeConfig`](#prunescopeconfig) -- [`MeterReadingPruneScopeConfig`](#meterreadingprunescopeconfig) -- [`MeterUniqueIdsConfig`](#meteruniqueidsconfig) -- [`IntegrationEntityField`](#integrationentityfield) -- [`FileProxyUrlParam`](#fileproxyurlparam) -- [`FileProxyUrlParams`](#fileproxyurlparams) -- [`FileProxyUrlConfig`](#fileproxyurlconfig) -- [`EmbeddedUseCaseRequest`](#embeddedusecaserequest) -- [`EmbeddedUseCaseRequestBase`](#embeddedusecaserequestbase) -- [`EmbeddedInboundUseCaseRequest`](#embeddedinboundusecaserequest) -- [`EmbeddedOutboundUseCaseRequest`](#embeddedoutboundusecaserequest) -- [`UseCaseBase`](#usecasebase) -- [`InboundUseCase`](#inboundusecase) -- [`OutboundUseCase`](#outboundusecase) -- [`FileProxyUseCase`](#fileproxyusecase) -- [`UseCase`](#usecase) -- [`CreateUseCaseRequest`](#createusecaserequest) -- [`CreateUseCaseRequestBase`](#createusecaserequestbase) -- [`CreateInboundUseCaseRequest`](#createinboundusecaserequest) -- [`CreateOutboundUseCaseRequest`](#createoutboundusecaserequest) -- [`CreateFileProxyUseCaseRequest`](#createfileproxyusecaserequest) -- [`UpdateUseCaseRequest`](#updateusecaserequest) -- [`UpdateUseCaseRequestBase`](#updateusecaserequestbase) -- [`UpdateInboundUseCaseRequest`](#updateinboundusecaserequest) -- [`UpdateOutboundUseCaseRequest`](#updateoutboundusecaserequest) -- [`UpdateFileProxyUseCaseRequest`](#updatefileproxyusecaserequest) -- [`UseCaseHistoryEntry`](#usecasehistoryentry) -- [`UseCaseHistoryEntryBase`](#usecasehistoryentrybase) -- [`InboundUseCaseHistoryEntry`](#inboundusecasehistoryentry) -- [`OutboundUseCaseHistoryEntry`](#outboundusecasehistoryentry) -- [`FileProxyUseCaseHistoryEntry`](#fileproxyusecasehistoryentry) -- [`FileProxyUseCaseConfiguration`](#fileproxyusecaseconfiguration) -- [`FileProxyAuth`](#fileproxyauth) -- [`FileProxyParam`](#fileproxyparam) -- [`FileProxyStep`](#fileproxystep) -- [`FileProxyResponseConfig`](#fileproxyresponseconfig) -- [`MappingSimulationRequest`](#mappingsimulationrequest) -- [`MappingSimulationV2Request`](#mappingsimulationv2request) -- [`MappingSimulationResponse`](#mappingsimulationresponse) -- [`MappingSimulationWarning`](#mappingsimulationwarning) -- [`EntityUpdate`](#entityupdate) -- [`MeterReadingUpdate`](#meterreadingupdate) -- [`IntegrationConfigurationV1`](#integrationconfigurationv1) -- [`IntegrationObjectV1`](#integrationobjectv1) -- [`IntegrationFieldV1`](#integrationfieldv1) -- [`IntegrationConfigurationV2`](#integrationconfigurationv2) -- [`OutboundMapping`](#outboundmapping) -- [`DeliveryConfig`](#deliveryconfig) -- [`OutboundStatusResponse`](#outboundstatusresponse) -- [`OutboundUseCaseStatus`](#outboundusecasestatus) -- [`WebhookStatus`](#webhookstatus) -- [`OutboundConflict`](#outboundconflict) -- [`RelationConfig`](#relationconfig) -- [`RelationItemConfig`](#relationitemconfig) -- [`RelationUniqueIdField`](#relationuniqueidfield) -- [`RelationRefsConfig`](#relationrefsconfig) -- [`RelationRefItemConfig`](#relationrefitemconfig) -- [`RelationRefValueConfig`](#relationrefvalueconfig) -- [`RepeatableFieldType`](#repeatablefieldtype) -- [`ReplayEventsRequest`](#replayeventsrequest) -- [`QueryEventsRequest`](#queryeventsrequest) -- [`QueryInboundMonitoringEventsRequest`](#queryinboundmonitoringeventsrequest) -- [`QueryAccessLogsRequest`](#queryaccesslogsrequest) -- [`AccessLogEntry`](#accesslogentry) -- [`GetMonitoringStatsRequest`](#getmonitoringstatsrequest) -- [`GetMonitoringTimeSeriesRequest`](#getmonitoringtimeseriesrequest) -- [`TimeSeriesBucket`](#timeseriesbucket) -- [`QueryOutboundMonitoringEventsRequest`](#queryoutboundmonitoringeventsrequest) -- [`OutboundMonitoringEvent`](#outboundmonitoringevent) -- [`MonitoringStats`](#monitoringstats) -- [`InboundMonitoringEvent`](#inboundmonitoringevent) - -### `acknowledgeTracking` - -Acknowledges an ERP tracking record by removing it from the tracking table, requires public authentication - -`POST /v1/erp/tracking/acknowledgement` - -```ts -const { data } = await client.acknowledgeTracking( - null, - { - ack_id: 'string' - }, -) -``` - -
-Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `triggerErp` - -Triggers the ERP integration process - -`POST /v1/erp/trigger` - -```ts -const { data } = await client.triggerErp( - null, - { - execution_id: 'string', - org_id: 'string', - webhook_id: 'string', - flow_id: 'string', - created_at: '1970-01-01T00:00:00.000Z', - action_id: 'string', - flow_action_id: 'string', - flow_name: 'string', - activity_id: 'string', - entity_id: 'string' - }, -) -``` - -
-Response - -```json -{ - "status_code": "string", - "message": "string", - "body": {}, - "code": "string", - "status": "succeeded", - "start_date": "string", - "end_date": "string", - "event_id": "string" -} -``` - -
- ---- - -### `processErpUpdatesEventsV3` - -Handles updates from ERP systems using integration_id directly. -This is the v3 version that removes the unused event_type field and renames object_type to event_name -to align with the integration UI n - -`POST /v3/erp/updates/events` - -```ts -const { data } = await client.processErpUpdatesEventsV3( - null, - { - integration_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - correlation_id: 'string', - events: [ - {}, - {} - ] - }, -) -``` - -
-Response - -```json -{ - "results": [ - { - "event_id": "string", - "status": "success", - "message": "string" - } - ] -} -``` - -
- ---- - -### `simulateMappingV2` - -Test v2.0 mapping configuration by transforming a payload using the provided mapping rules without persisting data. - -`POST /v2/erp/updates/mapping_simulation` - -```ts -const { data } = await client.simulateMappingV2( - null, - { - event_configuration: { - entities: [ - { /* ... */ } - ], - meter_readings: [ - { /* ... */ } - ] - }, - format: 'json', - payload: 'string' - }, -) -``` - -
-Response - -```json -{ - "entity_updates": [ - { - "entity_slug": "string", - "unique_identifiers": {}, - "attributes": {} - } - ], - "meter_readings_updates": [ - { - "meter": { - "$entity_unique_ids": {} - }, - "meter_counter": { - "$entity_unique_ids": {} - }, - "attributes": {} - } - ], - "warnings": [ - { - "entity_schema": "string", - "field": "string", - "message": "string" - } - ] -} -``` - -
- ---- - -### `simulateMapping` - -Test mapping configuration by transforming a payload using the provided mapping rules without persisting data. - -`POST /v1/erp/updates/mapping_simulation` - -```ts -const { data } = await client.simulateMapping( - null, - { - mapping_configuration: { - version: '1.0', - mapping: { - objects: {} - } - }, - object_type: 'string', - format: 'json', - payload: 'string' - }, -) -``` - -
-Response - -```json -{ - "entity_updates": [ - { - "entity_slug": "string", - "unique_identifiers": {}, - "attributes": {} - } - ], - "meter_readings_updates": [ - { - "meter": { - "$entity_unique_ids": {} - }, - "meter_counter": { - "$entity_unique_ids": {} - }, - "attributes": {} - } - ], - "warnings": [ - { - "entity_schema": "string", - "field": "string", - "message": "string" - } - ] -} -``` - -
- ---- - -### `listIntegrations` - -Retrieve all integrations for the authenticated organization - -`GET /v1/integrations` - -```ts -const { data } = await client.listIntegrations() -``` - -
-Response - -```json -{ - "integrations": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } - } - ] -} -``` - -
- ---- - -### `createIntegration` - -Create a new integration configuration - -`POST /v1/integrations` - -```ts -const { data } = await client.createIntegration( - null, - { - name: 'string', - description: 'string', - access_token_ids: ['string'], - app_ids: ['string'], - environment_config: [ - { - key: 'string', - label: 'string', - type: 'String', - description: 'string', - required: false, - order: 0 - } - ], - settings: { - autoRefresh: { - enabled: false, - freshnessThresholdMinutes: 1 - } - } - }, -) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } -} -``` - -
- ---- - -### `getIntegration` - -Retrieve a specific integration by its ID - -`GET /v1/integrations/{integrationId}` - -```ts -const { data } = await client.getIntegration({ - integrationId: 'example', -}) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } -} -``` - -
- ---- - -### `updateIntegration` - -Update an existing integration configuration - -`PUT /v1/integrations/{integrationId}` - -```ts -const { data } = await client.updateIntegration( - { - integrationId: 'example', - }, - {}, -) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - } -} -``` - -
- ---- - -### `deleteIntegration` - -Delete an integration and all its use cases - -`DELETE /v1/integrations/{integrationId}` - -```ts -const { data } = await client.deleteIntegration({ - integrationId: 'example', -}) -``` - -
-Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `queryEvents` - -Query events for a specific integration - -`POST /v1/integrations/{integrationId}/events` - -```ts -const { data } = await client.queryEvents( - { - integrationId: 'example', - }, - { - event_id: 'string', - event_type: 'CREATE', - correlation_id: 'string', - object_type: 'string', - event_name: 'string', - limit: 25, - cursor: { - event_time: '2025-10-31T12:34:56Z', - event_id: 'evt_1234567890abcdef' - } - }, -) -``` - -
-Response - -```json -{ - "data": [ - { - "event_type": "CREATE", - "object_type": "string", - "timestamp": "1970-01-01T00:00:00.000Z", - "format": "json", - "payload": "string", - "deduplication_id": "evt-2025-05-01-12345-create-bp" - } - ], - "next_cursor": { - "event_time": "2025-10-31T12:34:56Z", - "event_id": "evt_1234567890abcdef" - }, - "has_more": true -} -``` - -
- ---- - -### `replayEvents` - -Replay one or more events for a specific integration. Events will be re-processed with their original payloads but with a new correlation ID for traceability. - -`POST /v1/integrations/{integrationId}/events/replay` - -```ts -const { data } = await client.replayEvents( - { - integrationId: 'example', - }, - { - event_ids: ['string'] - }, -) -``` - -
-Response - -```json -{ - "event_ids": ["string"] -} -``` - -
- ---- - -### `listUseCases` - -Retrieve all use cases for a specific integration - -`GET /v1/integrations/{integrationId}/use-cases` - -```ts -const { data } = await client.listUseCases({ - integrationId: 'example', -}) -``` - -
-Response - -```json -{ - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": {} - } - ] -} -``` - -
- ---- - -### `createUseCase` - -Create a new use case for an integration - -`POST /v1/integrations/{integrationId}/use-cases` - -```ts -const { data } = await client.createUseCase( - { - integrationId: 'example', - }, - { - name: 'string', - slug: 'string', - enabled: true, - type: 'inbound', - configuration: { - entities: [ - { /* ... */ } - ], - meter_readings: [ - { /* ... */ } - ] - } - }, -) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - } -} -``` - -
- ---- - -### `getUseCase` - -Retrieve a specific use case by its ID - -`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}` - -```ts -const { data } = await client.getUseCase({ - integrationId: 'example', - useCaseId: 'example', -}) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - } -} -``` - -
- ---- - -### `updateUseCase` - -Update an existing use case configuration - -`PUT /v1/integrations/{integrationId}/use-cases/{useCaseId}` - -```ts -const { data } = await client.updateUseCase( - { - integrationId: 'example', - useCaseId: 'example', - }, - { - name: 'string', - slug: 'string', - enabled: true, - change_description: 'string', - type: 'inbound', - configuration: { - entities: [ - { /* ... */ } - ], - meter_readings: [ - { /* ... */ } - ] - } - }, -) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": { - "entities": [ - {} - ], - "meter_readings": [ - {} - ] - } -} -``` - -
- ---- - -### `deleteUseCase` - -Delete a use case from an integration - -`DELETE /v1/integrations/{integrationId}/use-cases/{useCaseId}` - -```ts -const { data } = await client.deleteUseCase({ - integrationId: 'example', - useCaseId: 'example', -}) -``` - -
-Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `listUseCaseHistory` - -Retrieve historical versions of a use case's configuration. -History entries are returned in reverse chronological order (newest first). -Use the 'cursor' parameter for pagination to fetch additional en - -`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}/history` - -```ts -const { data } = await client.listUseCaseHistory({ - integrationId: 'example', - useCaseId: 'example', - cursor: 'example', -}) -``` - -
-Response - -```json -{ - "history": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "history_created_at": "1970-01-01T00:00:00.000Z", - "type": "inbound", - "configuration": {} - } - ], - "next_cursor": "string" -} -``` - -
- ---- - -### `listIntegrationsV2` - -Retrieve all integrations with embedded use cases for the authenticated organization - -`GET /v2/integrations` - -```ts -const { data } = await client.listIntegrationsV2() -``` - -
-Response - -```json -{ - "integrations": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [], - "settings": {}, - "use_cases": [] - } - ] -} -``` - -
- ---- - -### `createIntegrationV2` - -Create a new integration with embedded use cases. - -`POST /v2/integrations` - -```ts -const { data } = await client.createIntegrationV2( - null, - { - name: 'string', - description: 'string', - access_token_ids: ['string'], - app_ids: ['string'], - environment_config: [ - { - key: 'string', - label: 'string', - type: 'String', - description: 'string', - required: false, - order: 0 - } - ], - settings: { - autoRefresh: { - enabled: false, - freshnessThresholdMinutes: 1 - } - }, - use_cases: [ - { - id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - name: 'string', - slug: 'string', - enabled: true, - change_description: 'string', - type: 'inbound', - configuration: { /* ... */ } - } - ] - }, -) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - }, - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": {} - } - ] -} -``` - -
- ---- - -### `getIntegrationV2` - -Retrieve a specific integration with all its embedded use cases - -`GET /v2/integrations/{integrationId}` - -```ts -const { data } = await client.getIntegrationV2({ - integrationId: 'example', -}) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - }, - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": {} - } - ] -} -``` - -
- ---- - -### `updateIntegrationV2` - -Update an existing integration with embedded use cases. -The integration must already exist. -Use cases are updated declaratively: -- Use cases in the request with matching IDs are updated -- Use cases in - -`PUT /v2/integrations/{integrationId}` - -```ts -const { data } = await client.updateIntegrationV2( - { - integrationId: 'example', - }, - { - name: 'string', - description: 'string', - access_token_ids: ['string'], - app_ids: ['string'], - environment_config: [ - { - key: 'string', - label: 'string', - type: 'String', - description: 'string', - required: false, - order: 0 - } - ], - settings: { - autoRefresh: { - enabled: false, - freshnessThresholdMinutes: 1 - } - }, - use_cases: [ - { - id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - name: 'string', - slug: 'string', - enabled: true, - change_description: 'string', - type: 'inbound', - configuration: { /* ... */ } - } - ] - }, -) -``` - -
-Response - -```json -{ - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "orgId": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "name": "string", - "description": "string", - "access_token_ids": ["string"], - "app_ids": ["string"], - "environment_config": [ - { - "key": "string", - "label": "string", - "type": "String", - "description": "string", - "required": false, - "order": 0 - } - ], - "settings": { - "autoRefresh": { - "enabled": false, - "freshnessThresholdMinutes": 1 - } - }, - "use_cases": [ - { - "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "slug": "string", - "type": "inbound", - "enabled": true, - "change_description": "string", - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "configuration": {} - } - ] -} -``` - -
- ---- - -### `deleteIntegrationV2` - -Delete an integration and all its use cases - -`DELETE /v2/integrations/{integrationId}` - -```ts -const { data } = await client.deleteIntegrationV2({ - integrationId: 'example', -}) -``` - -
-Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `setIntegrationAppMapping` - -Creates or updates a mapping from an app/component to an integration. -This allows ERP updates sent via app_id and component_id to be associated -with a specific integration configuration. - -`PUT /v1/integrations/{integrationId}/app-mapping` - -```ts -const { data } = await client.setIntegrationAppMapping( - { - integrationId: 'example', - }, - { - app_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - component_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - overwrite: false - }, -) -``` - -
-Response - -```json -{ - "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" -} -``` - -
- ---- - -### `deleteIntegrationAppMapping` - -Removes a mapping from an app/component to an integration. - -`DELETE /v1/integrations/{integrationId}/app-mapping` - -```ts -const { data } = await client.deleteIntegrationAppMapping( - { - integrationId: 'example', - }, - { - app_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - component_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' - }, -) -``` - -
-Response - -```json -{ - "message": "string" -} -``` - -
- ---- - -### `queryInboundMonitoringEvents` - -Query inbound monitoring events for a specific integration. -Returns detailed information about inbound sync events from ERP systems, -including success rates, error breakdowns, and processing metrics. - -`POST /v1/integrations/{integrationId}/monitoring/inbound-events` - -```ts -const { data } = await client.queryInboundMonitoringEvents( - { - integrationId: 'example', - }, - { - use_case_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - event_type: 'CREATE', - sync_type: 'entity', - status: 'success', - error_category: 'validation', - correlation_id: 'string', - object_type: 'string', - event_name: 'string', - event_id: 'string', - from_date: '2025-01-01T00:00:00Z', - to_date: '2025-01-31T23:59:59Z', - limit: 50, - cursor: { - completed_at: '1970-01-01T00:00:00.000Z', - event_id: 'string' - } - }, -) -``` - -
-Response - -```json -{ - "data": [ - { - "org_id": "string", - "event_id": "string", - "correlation_id": "string", - "integration_id": "string", - "use_case_id": "string", - "event_type": "CREATE", - "object_type": "string", - "sync_type": "entity", - "status": "success", - "error_code": "string", - "error_message": "string", - "error_category": "validation", - "processing_duration_ms": 0, - "received_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z" - } - ], - "next_cursor": { - "completed_at": "1970-01-01T00:00:00.000Z", - "event_id": "string" - }, - "has_more": true -} -``` - -
- ---- - -### `getMonitoringStats` - -Get aggregated statistics for both inbound and outbound monitoring events for a specific integration. -Returns summary metrics for inbound (ERP sync) and outbound (webhook delivery) events, -including s - -`POST /v1/integrations/{integrationId}/monitoring/stats` - -```ts -const { data } = await client.getMonitoringStats( - { - integrationId: 'example', - }, - { - from_date: '2025-01-01T00:00:00Z', - to_date: '2025-01-31T23:59:59Z', - inbound_group_by: ['use_case_id', 'status'], - outbound_group_by: ['event_name', 'status'] - }, -) -``` - -
-Response - -```json -{ - "inbound": { - "total_events": 0, - "total_correlations": 0, - "success_count": 0, - "error_count": 0, - "skipped_count": 0, - "warning_count": 0, - "success_rate": 0, - "last_error_at": "1970-01-01T00:00:00.000Z", - "breakdown": [ - {} - ] - }, - "outbound": { - "total_events": 0, - "success_count": 0, - "error_count": 0, - "pending_count": 0, - "success_rate": 0, - "last_error_at": "1970-01-01T00:00:00.000Z", - "breakdown": [ - {} - ] - } -} -``` - -
- ---- - -### `getMonitoringTimeSeries` - -Get time-series aggregated event counts for monitoring charts. -Returns pre-bucketed counts at configurable intervals for both inbound and outbound events. -Maximum of 200 buckets per request. Returns 4 - -`POST /v1/integrations/{integrationId}/monitoring/timeseries` - -```ts -const { data } = await client.getMonitoringTimeSeries( - { - integrationId: 'example', - }, - { - from_date: '2025-01-01T00:00:00Z', - to_date: '2025-01-31T23:59:59Z', - interval: '1h', - direction: 'both' - }, -) -``` - -
-Response - -```json -{ - "interval": "5m", - "from_date": "1970-01-01T00:00:00.000Z", - "to_date": "1970-01-01T00:00:00.000Z", - "buckets": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "inbound": { - "success_count": 0, - "error_count": 0, - "warning_count": 0, - "skipped_count": 0, - "total_count": 0 - }, - "outbound": { - "success_count": 0, - "error_count": 0, - "pending_count": 0, - "total_count": 0 - } - } - ] -} -``` - -
- ---- - -### `getOutboundStatus` - -Get the status of all outbound use cases for a specific integration. -Returns conflict information when events or webhooks are disabled but the use case is enabled. - -`GET /v1/integrations/{integrationId}/outbound-status` - -```ts -const { data } = await client.getOutboundStatus({ - integrationId: 'example', -}) -``` - -
-Response - -```json -{ - "useCases": [ - { - "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "name": "string", - "useCaseEnabled": true, - "eventCatalogEvent": "contract.created", - "eventEnabled": true, - "webhooks": [ - { - "webhookId": "string", - "webhookName": "string", - "enabled": true - } - ], - "status": "ok", - "conflicts": [ - { - "type": "event_disabled", - "webhookId": "string", - "message": "string" - } - ] - } - ] -} -``` - -
- ---- - -### `queryAccessLogs` - -Query API access logs for a specific integration's organization. -Returns access token usage analytics filtered by user_id (access token). -Supports infinite scroll pagination with cursor-based navigati - -`POST /v1/integrations/{integrationId}/monitoring/access-logs` - -```ts -const { data } = await client.queryAccessLogs( - { - integrationId: 'example', - }, - { - token_id: 'api_5ZugdRXasLfWBypHi93Fk', - service: 'entity', - method: 'GET', - path: '/v1/entity', - status: 200, - from_date: '2025-01-01T00:00:00Z', - to_date: '2025-01-31T23:59:59Z', - limit: 50, - cursor: { - timestamp: '1970-01-01T00:00:00.000Z', - request_id: 'string' - } - }, -) -``` - -
-Response - -```json -{ - "data": [ - { - "timestamp": "1970-01-01T00:00:00.000Z", - "environment": "string", - "service": "string", - "request_id": "string", - "method": "string", - "path": "string", - "status": 0, - "response_latency_ms": 0, - "response_length": 0, - "token_id": "string", - "org_id": "string", - "origin": "string", - "source_ip": "string" - } - ], - "next_cursor": { - "timestamp": "1970-01-01T00:00:00.000Z", - "request_id": "string" - }, - "has_more": true -} -``` - -
- ---- - -### `queryOutboundMonitoringEvents` - -Query outbound monitoring events for a specific integration. -Returns detailed information about outbound event deliveries, -filtered by event_name (event_catalog_event) linked to the integration's outb - -`POST /v1/integrations/{integrationId}/monitoring/outbound-events` - -```ts -const { data } = await client.queryOutboundMonitoringEvents( - { - integrationId: 'example', - }, - { - event_name: 'automation_flow_target', - status: 'succeeded', - webhook_config_id: 'string', - from_date: '2025-01-01T00:00:00Z', - to_date: '2025-01-31T23:59:59Z', - limit: 50, - cursor: { - created_at: '1970-01-01T00:00:00.000Z', - event_id: 'string' - } - }, -) -``` - -
-Response - -```json -{ - "data": [ - { - "org_id": "string", - "event_id": "string", - "event_name": "string", - "status": "succeeded", - "url": "string", - "http_method": "string", - "http_response": {}, - "webhook_config_id": "string", - "metadata": {}, - "execution_context": {}, - "payload": {}, - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z" - } - ], - "next_cursor": { - "created_at": "1970-01-01T00:00:00.000Z", - "event_id": "string" - }, - "has_more": true -} -``` - -
- ---- - -## Schemas - -### `ErrorResponseBase` - -```ts -type ErrorResponseBase = { - code?: string - message?: string -} -``` - -### `ErpEvent` - -```ts -type ErpEvent = { - event_type: "CREATE" | "UPDATE" | "DELETE" - object_type: string - timestamp: string // date-time - format: "json" | "xml" - payload: string | Record - deduplication_id?: string -} -``` - -### `ErpUpdatesEventsV2Request` - -```ts -type ErpUpdatesEventsV2Request = { - integration_id: string // uuid - correlation_id?: string - events: Array<{ - event_type: "CREATE" | "UPDATE" | "DELETE" - object_type: string - timestamp: string // date-time - format: "json" | "xml" - payload: string | Record - deduplication_id?: string - }> -} -``` - -### `ErpEventV3` - -```ts -type ErpEventV3 = unknown | unknown -``` - -### `ErpUpdatesEventsV3Request` - -```ts -type ErpUpdatesEventsV3Request = { - integration_id: string // uuid - correlation_id?: string - events: unknown | unknown[] -} -``` - -### `TriggerErpActionRequest` - -```ts -type TriggerErpActionRequest = { - execution_id: string - org_id: string - webhook_id: string - flow_id: string - created_at: string // date-time - action_id: string - flow_action_id: string - flow_name: string - activity_id: string - entity_id: string -} -``` - -### `TriggerWebhookResp` - -```ts -type TriggerWebhookResp = { - status_code?: string - message?: string - body?: object - code?: string - status?: "succeeded" | "failed" - start_date?: string - end_date?: string - event_id?: string -} -``` - -### `IntegrationEditableFields` - -```ts -type IntegrationEditableFields = { - name?: string - description?: string - access_token_ids?: string[] - app_ids?: string[] - environment_config?: Array<{ - key: string - label: string - type: "String" | "SecretString" - description?: string - required?: boolean - order?: number - }> - settings?: { - autoRefresh?: { - enabled?: { ... } - freshnessThresholdMinutes?: { ... } - } - } -} -``` - -### `Integration` - -```ts -type Integration = { - id: string // uuid - orgId: string - created_at: string // date-time - updated_at: string // date-time - name: string - description?: string - access_token_ids?: string[] - app_ids?: string[] - environment_config?: Array<{ - key: string - label: string - type: "String" | "SecretString" - description?: string - required?: boolean - order?: number - }> - settings?: { - autoRefresh?: { - enabled?: { ... } - freshnessThresholdMinutes?: { ... } - } - } -} -``` - -### `CreateIntegrationRequest` - -```ts -type CreateIntegrationRequest = { - name: string - description?: string - access_token_ids?: string[] - app_ids?: string[] - environment_config?: Array<{ - key: string - label: string - type: "String" | "SecretString" - description?: string - required?: boolean - order?: number - }> - settings?: { - autoRefresh?: { - enabled?: { ... } - freshnessThresholdMinutes?: { ... } - } - } -} -``` - -### `UpdateIntegrationRequest` - -```ts -type UpdateIntegrationRequest = { - name?: string - description?: string - access_token_ids?: string[] - app_ids?: string[] - environment_config?: Array<{ - key: string - label: string - type: "String" | "SecretString" - description?: string - required?: boolean - order?: number - }> - settings?: { - autoRefresh?: { - enabled?: { ... } - freshnessThresholdMinutes?: { ... } - } - } -} -``` - -### `EnvironmentFieldConfig` - -```ts -type EnvironmentFieldConfig = { - key: string - label: string - type: "String" | "SecretString" - description?: string - required?: boolean - order?: number -} -``` - -### `IntegrationSettings` - -Settings for the integration - -```ts -type IntegrationSettings = { - autoRefresh?: { - enabled?: boolean - freshnessThresholdMinutes?: number - } -} -``` - -### `AutoRefreshSettings` - -Auto-refresh settings for keeping integration data fresh - -```ts -type AutoRefreshSettings = { - enabled?: boolean - freshnessThresholdMinutes?: number -} -``` - -### `SetIntegrationAppMappingRequest` - -```ts -type SetIntegrationAppMappingRequest = { - app_id: string // uuid - component_id: string // uuid - overwrite?: boolean -} -``` - -### `DeleteIntegrationAppMappingRequest` - -```ts -type DeleteIntegrationAppMappingRequest = { - app_id: string // uuid - component_id: string // uuid -} -``` - -### `IntegrationAppMapping` - -```ts -type IntegrationAppMapping = { - integration_id: string // uuid -} -``` - -### `IntegrationWithUseCases` - -```ts -type IntegrationWithUseCases = { - use_cases: Array<{ - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "inbound" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - entities?: { ... } - meter_readings?: { ... } - } - } | { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "outbound" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - event_catalog_event: { ... } - mappings: { ... } - } - } | { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "file_proxy" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - requires_vpc?: { ... } - auth?: { ... } - params?: { ... } - steps: { ... } - response: { ... } - } - }> -} -``` - -### `UpsertIntegrationWithUseCasesRequest` - -```ts -type UpsertIntegrationWithUseCasesRequest = { - name: string - description?: string - access_token_ids?: string[] - app_ids?: string[] - environment_config?: Array<{ - key: string - label: string - type: "String" | "SecretString" - description?: string - required?: boolean - order?: number - }> - settings?: { - autoRefresh?: { - enabled?: { ... } - freshnessThresholdMinutes?: { ... } - } - } - use_cases?: Array<{ - id?: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - type: "inbound" - configuration?: { - entities?: { ... } - meter_readings?: { ... } - } - } | { - id?: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - type: "outbound" - configuration?: { - event_catalog_event: { ... } - mappings: { ... } - } - }> -} -``` - -### `InboundIntegrationEventConfiguration` - -Configuration for inbound use cases (ERP to epilot) - -```ts -type InboundIntegrationEventConfiguration = { - entities?: Array<{ - entity_schema: string - unique_ids: string[] - jsonataExpression?: string - enabled?: boolean | string - mode?: "upsert" | "delete" | "purge" | "upsert-prune-scope-purge" | "upsert-prune-scope-delete" - scope?: { - scope_mode: { ... } - schema?: { ... } - unique_ids?: { ... } - query?: { ... } - } - fields: Array<{ - attribute: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - _type?: { ... } - enabled?: { ... } - relations?: { ... } - relation_refs?: { ... } - file_proxy_url?: { ... } - }> - }> - meter_readings?: Array<{ - jsonataExpression?: string - reading_matching?: "external_id" | "strict-date" - mode?: "upsert" | "delete" | "upsert-prune-scope" - scope?: { - source?: { ... } - } - meter: { - unique_ids: { ... } - } - meter_counter?: { - unique_ids: { ... } - } - fields: Array<{ - attribute: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - _type?: { ... } - enabled?: { ... } - relations?: { ... } - relation_refs?: { ... } - file_proxy_url?: { ... } - }> - }> -} -``` - -### `OutboundIntegrationEventConfiguration` - -Configuration for outbound use cases. Defines the event that triggers the flow and the webhook mappings. - -```ts -type OutboundIntegrationEventConfiguration = { - event_catalog_event: string - mappings: Array<{ - id: string // uuid - name: string - jsonata_expression: string - enabled: boolean - delivery: { - type: { ... } - webhook_id: { ... } - webhook_name?: { ... } - webhook_url?: { ... } - } - created_at?: string // date-time - updated_at?: string // date-time - }> -} -``` - -### `IntegrationEntity` - -```ts -type IntegrationEntity = { - entity_schema: string - unique_ids: string[] - jsonataExpression?: string - enabled?: boolean | string - mode?: "upsert" | "delete" | "purge" | "upsert-prune-scope-purge" | "upsert-prune-scope-delete" - scope?: { - scope_mode: "relations" | "query" - schema?: string - unique_ids?: Array<{ - attribute: { ... } - _type?: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - }> - query?: Array<{ - attribute: { ... } - _type?: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - }> - } - fields: Array<{ - attribute: string - field?: string - jsonataExpression?: string - constant?: unknown - _type?: "email" | "phone" - enabled?: boolean | string - relations?: { - operation: { ... } - items?: { ... } - jsonataExpression?: { ... } - } - relation_refs?: { - operation: { ... } - items?: { ... } - jsonataExpression?: { ... } - } - file_proxy_url?: { - use_case_slug: { ... } - params?: { ... } - } | { - use_case_id: { ... } - params?: { ... } - } - }> -} -``` - -### `IntegrationMeterReading` - -```ts -type IntegrationMeterReading = { - jsonataExpression?: string - reading_matching?: "external_id" | "strict-date" - mode?: "upsert" | "delete" | "upsert-prune-scope" - scope?: { - source?: string - } - meter: { - unique_ids: Array<{ - attribute: { ... } - _type?: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - }> - } - meter_counter?: { - unique_ids: Array<{ - attribute: { ... } - _type?: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - }> - } - fields: Array<{ - attribute: string - field?: string - jsonataExpression?: string - constant?: unknown - _type?: "email" | "phone" - enabled?: boolean | string - relations?: { - operation: { ... } - items?: { ... } - jsonataExpression?: { ... } - } - relation_refs?: { - operation: { ... } - items?: { ... } - jsonataExpression?: { ... } - } - file_proxy_url?: { - use_case_slug: { ... } - params?: { ... } - } | { - use_case_id: { ... } - params?: { ... } - } - }> -} -``` - -### `PruneScopeConfig` - -Scope configuration for upsert-prune-scope modes. -Defines how to find entities that should be pruned if not in the upsert payload. -The scope is resolved against the original event payload (not individual array items). - - -```ts -type PruneScopeConfig = { - scope_mode: "relations" | "query" - schema?: string - unique_ids?: Array<{ - attribute: string - _type?: "email" | "phone" - field?: string - jsonataExpression?: string - constant?: unknown - }> - query?: Array<{ - attribute: string - _type?: "email" | "phone" - field?: string - jsonataExpression?: string - constant?: unknown - }> -} -``` - -### `MeterReadingPruneScopeConfig` - -Scope configuration for meter reading upsert-prune-scope mode. -The scope is all readings for the same meter + counter. - - -```ts -type MeterReadingPruneScopeConfig = { - source?: string -} -``` - -### `MeterUniqueIdsConfig` - -```ts -type MeterUniqueIdsConfig = { - unique_ids: Array<{ - attribute: string - _type?: "email" | "phone" - field?: string - jsonataExpression?: string - constant?: unknown - }> -} -``` - -### `IntegrationEntityField` - -```ts -type IntegrationEntityField = { - attribute: string - field?: string - jsonataExpression?: string - constant?: unknown - _type?: "email" | "phone" - enabled?: boolean | string - relations?: { - operation: "_set" | "_append" | "_append_all" - items?: Array<{ - entity_schema: { ... } - _tags?: { ... } - unique_ids: { ... } - }> - jsonataExpression?: string - } - relation_refs?: { - operation: "_set" | "_append" | "_append_all" - items?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - path: { ... } - value: { ... } - }> - jsonataExpression?: string - } - file_proxy_url?: { - use_case_slug: string - params?: Record - } | { - use_case_id: string - params?: Record - } -} -``` - -### `FileProxyUrlParam` - -Parameter for file proxy URL. Exactly one of field, constant, or jsonataExpression must be set. - -```ts -type FileProxyUrlParam = { - field: string -} | { - constant: unknown -} | { - jsonataExpression: string -} -``` - -### `FileProxyUrlParams` - -Custom query parameters. Keys become URL param names, values resolved from payload. - -```ts -type FileProxyUrlParams = Record -``` - -### `FileProxyUrlConfig` - -Auto-constructs a file proxy download URL. orgId and integrationId are injected from context. Exactly one of use_case_id or use_case_slug must be provided. Using use_case_slug is recommended as it is portable across environments. - - -```ts -type FileProxyUrlConfig = { - use_case_slug: string - params?: Record -} | { - use_case_id: string - params?: Record -} -``` - -### `EmbeddedUseCaseRequest` - -```ts -type EmbeddedUseCaseRequest = { - id?: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - type: "inbound" - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} | { - id?: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - type: "outbound" - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} -``` - -### `EmbeddedUseCaseRequestBase` - -```ts -type EmbeddedUseCaseRequestBase = { - id?: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string -} -``` - -### `EmbeddedInboundUseCaseRequest` - -```ts -type EmbeddedInboundUseCaseRequest = { - id?: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - type: "inbound" - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} -``` - -### `EmbeddedOutboundUseCaseRequest` - -```ts -type EmbeddedOutboundUseCaseRequest = { - id?: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - type: "outbound" - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} -``` - -### `UseCaseBase` - -```ts -type UseCaseBase = { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "inbound" | "outbound" | "file_proxy" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time -} -``` - -### `InboundUseCase` - -```ts -type InboundUseCase = { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "inbound" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} -``` - -### `OutboundUseCase` - -```ts -type OutboundUseCase = { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "outbound" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} -``` - -### `FileProxyUseCase` - -```ts -type FileProxyUseCase = { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "file_proxy" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - requires_vpc?: boolean - auth?: { - type: { ... } - token_url: { ... } - client_id: { ... } - client_secret: { ... } - scope?: { ... } - audience?: { ... } - resource?: { ... } - username?: { ... } - password?: { ... } - body_params?: { ... } - headers?: { ... } - query_params?: { ... } - } - params?: Array<{ - name: { ... } - required: { ... } - description?: { ... } - }> - steps: Array<{ - url: { ... } - method: { ... } - headers?: { ... } - body?: { ... } - response_type: { ... } - }> - response: { - body: { ... } - encoding: { ... } - filename?: { ... } - content_type?: { ... } - } - } -} -``` - -### `UseCase` - -```ts -type UseCase = { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "inbound" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} | { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "outbound" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} | { - id: string // uuid - integrationId: string // uuid - name: string - slug?: string - type: "file_proxy" - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - configuration?: { - requires_vpc?: boolean - auth?: { - type: { ... } - token_url: { ... } - client_id: { ... } - client_secret: { ... } - scope?: { ... } - audience?: { ... } - resource?: { ... } - username?: { ... } - password?: { ... } - body_params?: { ... } - headers?: { ... } - query_params?: { ... } - } - params?: Array<{ - name: { ... } - required: { ... } - description?: { ... } - }> - steps: Array<{ - url: { ... } - method: { ... } - headers?: { ... } - body?: { ... } - response_type: { ... } - }> - response: { - body: { ... } - encoding: { ... } - filename?: { ... } - content_type?: { ... } - } - } -} -``` - -### `CreateUseCaseRequest` - -```ts -type CreateUseCaseRequest = { - name: string - slug?: string - enabled: boolean - type: "inbound" - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} | { - name: string - slug?: string - enabled: boolean - type: "outbound" - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} | { - name: string - slug?: string - enabled: boolean - type: "file_proxy" - configuration?: { - requires_vpc?: boolean - auth?: { - type: { ... } - token_url: { ... } - client_id: { ... } - client_secret: { ... } - scope?: { ... } - audience?: { ... } - resource?: { ... } - username?: { ... } - password?: { ... } - body_params?: { ... } - headers?: { ... } - query_params?: { ... } - } - params?: Array<{ - name: { ... } - required: { ... } - description?: { ... } - }> - steps: Array<{ - url: { ... } - method: { ... } - headers?: { ... } - body?: { ... } - response_type: { ... } - }> - response: { - body: { ... } - encoding: { ... } - filename?: { ... } - content_type?: { ... } - } - } -} -``` - -### `CreateUseCaseRequestBase` - -```ts -type CreateUseCaseRequestBase = { - name: string - slug?: string - enabled: boolean -} -``` - -### `CreateInboundUseCaseRequest` - -```ts -type CreateInboundUseCaseRequest = { - name: string - slug?: string - enabled: boolean - type: "inbound" - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} -``` - -### `CreateOutboundUseCaseRequest` - -```ts -type CreateOutboundUseCaseRequest = { - name: string - slug?: string - enabled: boolean - type: "outbound" - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} -``` - -### `CreateFileProxyUseCaseRequest` - -```ts -type CreateFileProxyUseCaseRequest = { - name: string - slug?: string - enabled: boolean - type: "file_proxy" - configuration?: { - requires_vpc?: boolean - auth?: { - type: { ... } - token_url: { ... } - client_id: { ... } - client_secret: { ... } - scope?: { ... } - audience?: { ... } - resource?: { ... } - username?: { ... } - password?: { ... } - body_params?: { ... } - headers?: { ... } - query_params?: { ... } - } - params?: Array<{ - name: { ... } - required: { ... } - description?: { ... } - }> - steps: Array<{ - url: { ... } - method: { ... } - headers?: { ... } - body?: { ... } - response_type: { ... } - }> - response: { - body: { ... } - encoding: { ... } - filename?: { ... } - content_type?: { ... } - } - } -} -``` - -### `UpdateUseCaseRequest` - -```ts -type UpdateUseCaseRequest = { - name?: string - slug?: string - enabled?: boolean - change_description?: string - type?: "inbound" - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} | { - name?: string - slug?: string - enabled?: boolean - change_description?: string - type?: "outbound" - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} | { - name?: string - slug?: string - enabled?: boolean - change_description?: string - type?: "file_proxy" - configuration?: { - requires_vpc?: boolean - auth?: { - type: { ... } - token_url: { ... } - client_id: { ... } - client_secret: { ... } - scope?: { ... } - audience?: { ... } - resource?: { ... } - username?: { ... } - password?: { ... } - body_params?: { ... } - headers?: { ... } - query_params?: { ... } - } - params?: Array<{ - name: { ... } - required: { ... } - description?: { ... } - }> - steps: Array<{ - url: { ... } - method: { ... } - headers?: { ... } - body?: { ... } - response_type: { ... } - }> - response: { - body: { ... } - encoding: { ... } - filename?: { ... } - content_type?: { ... } - } - } -} -``` - -### `UpdateUseCaseRequestBase` - -```ts -type UpdateUseCaseRequestBase = { - name?: string - slug?: string - enabled?: boolean - change_description?: string -} -``` - -### `UpdateInboundUseCaseRequest` - -```ts -type UpdateInboundUseCaseRequest = { - name?: string - slug?: string - enabled?: boolean - change_description?: string - type?: "inbound" - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} -``` - -### `UpdateOutboundUseCaseRequest` - -```ts -type UpdateOutboundUseCaseRequest = { - name?: string - slug?: string - enabled?: boolean - change_description?: string - type?: "outbound" - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} -``` - -### `UpdateFileProxyUseCaseRequest` - -```ts -type UpdateFileProxyUseCaseRequest = { - name?: string - slug?: string - enabled?: boolean - change_description?: string - type?: "file_proxy" - configuration?: { - requires_vpc?: boolean - auth?: { - type: { ... } - token_url: { ... } - client_id: { ... } - client_secret: { ... } - scope?: { ... } - audience?: { ... } - resource?: { ... } - username?: { ... } - password?: { ... } - body_params?: { ... } - headers?: { ... } - query_params?: { ... } - } - params?: Array<{ - name: { ... } - required: { ... } - description?: { ... } - }> - steps: Array<{ - url: { ... } - method: { ... } - headers?: { ... } - body?: { ... } - response_type: { ... } - }> - response: { - body: { ... } - encoding: { ... } - filename?: { ... } - content_type?: { ... } - } - } -} -``` - -### `UseCaseHistoryEntry` - -```ts -type UseCaseHistoryEntry = { - id: string // uuid - useCaseId: string // uuid - integrationId: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - history_created_at: string // date-time - type: "inbound" - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} | { - id: string // uuid - useCaseId: string // uuid - integrationId: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - history_created_at: string // date-time - type: "outbound" - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} | { - id: string // uuid - useCaseId: string // uuid - integrationId: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - history_created_at: string // date-time - type: "file_proxy" - configuration?: { - requires_vpc?: boolean - auth?: { - type: { ... } - token_url: { ... } - client_id: { ... } - client_secret: { ... } - scope?: { ... } - audience?: { ... } - resource?: { ... } - username?: { ... } - password?: { ... } - body_params?: { ... } - headers?: { ... } - query_params?: { ... } - } - params?: Array<{ - name: { ... } - required: { ... } - description?: { ... } - }> - steps: Array<{ - url: { ... } - method: { ... } - headers?: { ... } - body?: { ... } - response_type: { ... } - }> - response: { - body: { ... } - encoding: { ... } - filename?: { ... } - // ... -} -``` - -### `UseCaseHistoryEntryBase` - -```ts -type UseCaseHistoryEntryBase = { - id: string // uuid - useCaseId: string // uuid - integrationId: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - history_created_at: string // date-time -} -``` - -### `InboundUseCaseHistoryEntry` - -```ts -type InboundUseCaseHistoryEntry = { - id: string // uuid - useCaseId: string // uuid - integrationId: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - history_created_at: string // date-time - type: "inbound" - configuration?: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } -} -``` - -### `OutboundUseCaseHistoryEntry` - -```ts -type OutboundUseCaseHistoryEntry = { - id: string // uuid - useCaseId: string // uuid - integrationId: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - history_created_at: string // date-time - type: "outbound" - configuration?: { - event_catalog_event: string - mappings: Array<{ - id: { ... } - name: { ... } - jsonata_expression: { ... } - enabled: { ... } - delivery: { ... } - created_at?: { ... } - updated_at?: { ... } - }> - } -} -``` - -### `FileProxyUseCaseHistoryEntry` - -```ts -type FileProxyUseCaseHistoryEntry = { - id: string // uuid - useCaseId: string // uuid - integrationId: string // uuid - name: string - slug?: string - enabled: boolean - change_description?: string - created_at: string // date-time - updated_at: string // date-time - history_created_at: string // date-time - type: "file_proxy" - configuration?: { - requires_vpc?: boolean - auth?: { - type: { ... } - token_url: { ... } - client_id: { ... } - client_secret: { ... } - scope?: { ... } - audience?: { ... } - resource?: { ... } - username?: { ... } - password?: { ... } - body_params?: { ... } - headers?: { ... } - query_params?: { ... } - } - params?: Array<{ - name: { ... } - required: { ... } - description?: { ... } - }> - steps: Array<{ - url: { ... } - method: { ... } - headers?: { ... } - body?: { ... } - response_type: { ... } - }> - response: { - body: { ... } - encoding: { ... } - filename?: { ... } - content_type?: { ... } - } - } -} -``` - -### `FileProxyUseCaseConfiguration` - -Configuration for file_proxy use cases. Defines how to authenticate and fetch files from external document systems. - -The file proxy download URL always requires `orgId`, `integrationId`, and either `useCaseSlug` (recommended) or `useCaseId` (legacy UUID) as query parameters. -The `orgId` is included - -```ts -type FileProxyUseCaseConfiguration = { - requires_vpc?: boolean - auth?: { - type: "oauth2_client_credentials" | "oauth2_password" - token_url: string - client_id: string - client_secret: string - scope?: string - audience?: string - resource?: string - username?: string - password?: string - body_params?: Record - headers?: Record - query_params?: Record - } - params?: Array<{ - name: string - required: boolean - description?: string - }> - steps: Array<{ - url: string - method: "GET" | "POST" - headers?: Record - body?: string - response_type: "json" | "binary" - }> - response: { - body: string - encoding: "base64" | "binary" - filename?: string - content_type?: string - } -} -``` - -### `FileProxyAuth` - -```ts -type FileProxyAuth = { - type: "oauth2_client_credentials" | "oauth2_password" - token_url: string - client_id: string - client_secret: string - scope?: string - audience?: string - resource?: string - username?: string - password?: string - body_params?: Record - headers?: Record - query_params?: Record -} -``` - -### `FileProxyParam` - -```ts -type FileProxyParam = { - name: string - required: boolean - description?: string -} -``` - -### `FileProxyStep` - -```ts -type FileProxyStep = { - url: string - method: "GET" | "POST" - headers?: Record - body?: string - response_type: "json" | "binary" -} -``` - -### `FileProxyResponseConfig` - -```ts -type FileProxyResponseConfig = { - body: string - encoding: "base64" | "binary" - filename?: string - content_type?: string -} -``` - -### `MappingSimulationRequest` - -```ts -type MappingSimulationRequest = { - mapping_configuration: { - version?: "1.0" - mapping: { - objects: { ... } - } - } | { - version: "2.0" - mapping: { - events: { ... } - } - } - object_type: string - format: "json" | "xml" - payload: string | Record -} -``` - -### `MappingSimulationV2Request` - -Request for v2 mapping simulation. Uses the same configuration format stored in integration use case resources, -making it easier to test configurations before saving them. - - -```ts -type MappingSimulationV2Request = { - event_configuration: { - entities?: Array<{ - entity_schema: { ... } - unique_ids: { ... } - jsonataExpression?: { ... } - enabled?: { ... } - mode?: { ... } - scope?: { ... } - fields: { ... } - }> - meter_readings?: Array<{ - jsonataExpression?: { ... } - reading_matching?: { ... } - mode?: { ... } - scope?: { ... } - meter: { ... } - meter_counter?: { ... } - fields: { ... } - }> - } - format: "json" | "xml" - payload: string | Record -} -``` - -### `MappingSimulationResponse` - -```ts -type MappingSimulationResponse = { - entity_updates: Array<{ - entity_slug: string - unique_identifiers: Record - attributes: Record - }> - meter_readings_updates?: Array<{ - meter: { - $entity_unique_ids: { ... } - } - meter_counter?: { - $entity_unique_ids?: { ... } - } - attributes: Record - }> - warnings?: Array<{ - entity_schema: string - field: string - message: string - }> -} -``` - -### `MappingSimulationWarning` - -```ts -type MappingSimulationWarning = { - entity_schema: string - field: string - message: string -} -``` - -### `EntityUpdate` - -```ts -type EntityUpdate = { - entity_slug: string - unique_identifiers: Record - attributes: Record -} -``` - -### `MeterReadingUpdate` - -```ts -type MeterReadingUpdate = { - meter: { - $entity_unique_ids: Record - } - meter_counter?: { - $entity_unique_ids?: Record - } - attributes: Record -} -``` - -### `IntegrationConfigurationV1` - -```ts -type IntegrationConfigurationV1 = { - version?: "1.0" - mapping: { - objects: Record - } -} -``` - -### `IntegrationObjectV1` - -```ts -type IntegrationObjectV1 = { - unique_ids: Record> - fields: Array<{ - entity: string - attribute: string - field?: string - jsonataExpression?: string - }> -} -``` - -### `IntegrationFieldV1` - -```ts -type IntegrationFieldV1 = { - entity: string - attribute: string - field?: string - jsonataExpression?: string -} -``` - -### `IntegrationConfigurationV2` - -```ts -type IntegrationConfigurationV2 = { - version: "2.0" - mapping: { - events: Record - } -} -``` - -### `OutboundMapping` - -A mapping that transforms an event and delivers it to a webhook - -```ts -type OutboundMapping = { - id: string // uuid - name: string - jsonata_expression: string - enabled: boolean - delivery: { - type: "webhook" - webhook_id: string - webhook_name?: string - webhook_url?: string - } - created_at?: string // date-time - updated_at?: string // date-time -} -``` - -### `DeliveryConfig` - -Configuration for how the transformed event should be delivered - -```ts -type DeliveryConfig = { - type: "webhook" - webhook_id: string - webhook_name?: string - webhook_url?: string -} -``` - -### `OutboundStatusResponse` - -```ts -type OutboundStatusResponse = { - useCases: Array<{ - useCaseId: string // uuid - name: string - useCaseEnabled: boolean - eventCatalogEvent?: string - eventEnabled?: boolean - webhooks?: Array<{ - webhookId: { ... } - webhookName?: { ... } - enabled?: { ... } - }> - status: "ok" | "conflict" | "disabled" - conflicts?: Array<{ - type: { ... } - webhookId?: { ... } - message: { ... } - }> - }> -} -``` - -### `OutboundUseCaseStatus` - -```ts -type OutboundUseCaseStatus = { - useCaseId: string // uuid - name: string - useCaseEnabled: boolean - eventCatalogEvent?: string - eventEnabled?: boolean - webhooks?: Array<{ - webhookId: string - webhookName?: string - enabled?: boolean - }> - status: "ok" | "conflict" | "disabled" - conflicts?: Array<{ - type: "event_disabled" | "all_webhooks_disabled" | "event_enabled_while_disabled" | "webhook_enabled_while_disabled" - webhookId?: string - message: string - }> -} -``` - -### `WebhookStatus` - -```ts -type WebhookStatus = { - webhookId: string - webhookName?: string - enabled?: boolean -} -``` - -### `OutboundConflict` - -```ts -type OutboundConflict = { - type: "event_disabled" | "all_webhooks_disabled" | "event_enabled_while_disabled" | "webhook_enabled_while_disabled" - webhookId?: string - message: string -} -``` - -### `RelationConfig` - -```ts -type RelationConfig = { - operation: "_set" | "_append" | "_append_all" - items?: Array<{ - entity_schema: string - _tags?: string[] - unique_ids: Array<{ - attribute: { ... } - _type?: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - }> - }> - jsonataExpression?: string -} -``` - -### `RelationItemConfig` - -```ts -type RelationItemConfig = { - entity_schema: string - _tags?: string[] - unique_ids: Array<{ - attribute: string - _type?: "email" | "phone" - field?: string - jsonataExpression?: string - constant?: unknown - }> -} -``` - -### `RelationUniqueIdField` - -```ts -type RelationUniqueIdField = { - attribute: string - _type?: "email" | "phone" - field?: string - jsonataExpression?: string - constant?: unknown -} -``` - -### `RelationRefsConfig` - -Configuration for relation references ($relation_ref). -Relation references link to a specific item within a repeatable attribute on a related entity. -Common use case: referencing a specific address within a contact's address list. - - -```ts -type RelationRefsConfig = { - operation: "_set" | "_append" | "_append_all" - items?: Array<{ - entity_schema: string - unique_ids: Array<{ - attribute: { ... } - _type?: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - }> - path: string - value: { - attribute: { ... } - operation?: { ... } - field?: { ... } - jsonataExpression?: { ... } - constant?: { ... } - } - }> - jsonataExpression?: string -} -``` - -### `RelationRefItemConfig` - -Configuration for a single relation reference item - -```ts -type RelationRefItemConfig = { - entity_schema: string - unique_ids: Array<{ - attribute: string - _type?: "email" | "phone" - field?: string - jsonataExpression?: string - constant?: unknown - }> - path: string - value: { - attribute: string - operation?: "_set" | "_append" | "_append_all" - field?: string - jsonataExpression?: string - constant?: unknown - } -} -``` - -### `RelationRefValueConfig` - -Configuration for the value to set on the related entity's attribute - -```ts -type RelationRefValueConfig = { - attribute: string - operation?: "_set" | "_append" | "_append_all" - field?: string - jsonataExpression?: string - constant?: unknown -} -``` - -### `RepeatableFieldType` - -Type hint for repeatable fields that require special search handling. -These fields are stored as arrays of objects (e.g., email: [{ email: "value" }]). - - -```ts -type RepeatableFieldType = "email" | "phone" -``` - -### `ReplayEventsRequest` - -```ts -type ReplayEventsRequest = { - event_ids: string[] -} -``` - -### `QueryEventsRequest` - -```ts -type QueryEventsRequest = { - event_id?: string - event_type?: "CREATE" | "UPDATE" | "DELETE" - correlation_id?: string - object_type?: string - event_name?: string - limit?: number - cursor?: { - event_time?: string // date-time - event_id?: string - } -} -``` - -### `QueryInboundMonitoringEventsRequest` - -```ts -type QueryInboundMonitoringEventsRequest = { - use_case_id?: string // uuid - event_type?: "CREATE" | "UPDATE" | "DELETE" | "TRIGGER" - sync_type?: "entity" | "meter_reading" | "webhook" | "api_deprecation" - status?: "success" | "error" | "skipped" | "warning" - error_category?: "validation" | "configuration" | "downstream_api" | "timeout" | "system" - correlation_id?: string - object_type?: string - event_name?: string - event_id?: string - from_date?: string // date-time - to_date?: string // date-time - limit?: number - cursor?: { - completed_at?: string // date-time - event_id?: string - } -} -``` - -### `QueryAccessLogsRequest` - -```ts -type QueryAccessLogsRequest = { - token_id?: string - service?: string - method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD" - path?: string - status?: number - from_date?: string // date-time - to_date?: string // date-time - limit?: number - cursor?: { - timestamp?: string // date-time - request_id?: string - } -} -``` - -### `AccessLogEntry` - -```ts -type AccessLogEntry = { - timestamp?: string // date-time - environment?: string - service?: string - request_id?: string - method?: string - path?: string - status?: number - response_latency_ms?: number - response_length?: number - token_id?: string - org_id?: string - origin?: string - source_ip?: string -} -``` - -### `GetMonitoringStatsRequest` - -```ts -type GetMonitoringStatsRequest = { - from_date?: string // date-time - to_date?: string // date-time - inbound_group_by?: "use_case_id" | "sync_type" | "status" | "error_category" | "object_type" | "event_name" | "date"[] - outbound_group_by?: "event_name" | "status" | "webhook_config_id" | "date"[] -} -``` - -### `GetMonitoringTimeSeriesRequest` - -```ts -type GetMonitoringTimeSeriesRequest = { - from_date: string // date-time - to_date?: string // date-time - interval: "5m" | "10m" | "30m" | "1h" | "3h" | "1d" - direction?: "inbound" | "outbound" | "both" -} -``` - -### `TimeSeriesBucket` - -```ts -type TimeSeriesBucket = { - timestamp: string // date-time - inbound?: { - success_count?: number - error_count?: number - warning_count?: number - skipped_count?: number - total_count?: number - } - outbound?: { - success_count?: number - error_count?: number - pending_count?: number - total_count?: number - } -} -``` - -### `QueryOutboundMonitoringEventsRequest` - -```ts -type QueryOutboundMonitoringEventsRequest = { - event_name?: string - status?: "succeeded" | "failed" | "pending" - webhook_config_id?: string - from_date?: string // date-time - to_date?: string // date-time - limit?: number - cursor?: { - created_at?: string // date-time - event_id?: string - } -} -``` - -### `OutboundMonitoringEvent` - -```ts -type OutboundMonitoringEvent = { - org_id: string - event_id: string - event_name: string - status: "succeeded" | "failed" | "pending" - url?: string - http_method?: string - http_response?: Record - webhook_config_id?: string - metadata?: Record - execution_context?: Record - payload?: Record - created_at: string // date-time - updated_at?: string // date-time -} -``` - -### `MonitoringStats` - -```ts -type MonitoringStats = { - inbound: { - total_events: number - total_correlations?: number - success_count: number - error_count: number - skipped_count: number - warning_count?: number - success_rate?: number - last_error_at?: string // date-time - breakdown?: Record[] - } - outbound: { - total_events: number - success_count: number - error_count: number - pending_count?: number - success_rate?: number - last_error_at?: string // date-time - breakdown?: Record[] - } -} -``` - -### `InboundMonitoringEvent` - -```ts -type InboundMonitoringEvent = { - org_id: string - event_id: string - correlation_id?: string - integration_id?: string - use_case_id?: string - event_type?: "CREATE" | "UPDATE" | "DELETE" | "TRIGGER" - object_type: string - sync_type: "entity" | "meter_reading" | "webhook" | "api_deprecation" - status: "success" | "error" | "skipped" | "warning" - error_code?: string - error_message?: string - error_category?: "validation" | "configuration" | "downstream_api" | "timeout" | "system" - processing_duration_ms?: number - received_at: string // date-time - completed_at: string // date-time -} -``` diff --git a/docs/sdk/clients/event-catalog.md b/docs/sdk/clients/event-catalog.md index db31de78..9768ea3c 100644 --- a/docs/sdk/clients/event-catalog.md +++ b/docs/sdk/clients/event-catalog.md @@ -1,6 +1,6 @@ --- -title: " Event Catalog API" -description: "TypeScript SDK client for the epilot Event Catalog API: usage with @epilot/sdk, all operations and schemas." +title: "Event Catalog API" +description: "TypeScript SDK client for the epilot Event Catalog API: usage with @epilot/sdk, all operations and schemas." --- # Event Catalog API @@ -38,6 +38,10 @@ const { data } = await eventCatalogClient.listEvents(...) - [`deprecateCustomEvent`](#deprecatecustomevent) - [`previewCustomEvent`](#previewcustomevent) - [`publishCustomEventDefinition`](#publishcustomeventdefinition) +- [`getCustomEventVersionDraft`](#getcustomeventversiondraft) +- [`putCustomEventVersionDraft`](#putcustomeventversiondraft) +- [`deleteCustomEventVersionDraft`](#deletecustomeventversiondraft) +- [`publishCustomEventVersion`](#publishcustomeventversion) - [`getEventJSONSchema`](#geteventjsonschema) - [`getEventExample`](#geteventexample) - [`listEventVersions`](#listeventversions) @@ -54,6 +58,8 @@ const { data } = await eventCatalogClient.listEvents(...) - [`CustomEventLineage`](#customeventlineage) - [`PurposeFilterSnapshot`](#purposefiltersnapshot) - [`PublishCustomEventPayload`](#publishcustomeventpayload) +- [`CustomEventVersionDraft`](#customeventversiondraft) +- [`PublishCustomEventVersionPayload`](#publishcustomeventversionpayload) - [`ValidationIssue`](#validationissue) - [`PreviewEventResponse`](#previeweventresponse) - [`UpdateEventPayload`](#updateeventpayload) @@ -104,6 +110,7 @@ const { data } = await client.listEvents() "event_description": "Triggered when a new meter reading is added", "event_version": "1.0", "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", "event_tags": ["builtin", "metering", "erp"], "schema_fields": {}, "entity_graph": { @@ -143,7 +150,8 @@ const { data } = await client.listEvents() "event_origin": "builtin", "mapping": { "mode": "guided", - "jsonata": "string" + "jsonata": "string", + "payload": "extend" }, "lineage": { "base_event_name": "string", @@ -217,7 +225,8 @@ const { data } = await client.createCustomEvent( automation_trigger_seed_node: 'string', mapping: { mode: 'guided', - jsonata: 'string' + jsonata: 'string', + payload: 'extend' }, lineage: { base_event_name: 'string', @@ -238,6 +247,7 @@ const { data } = await client.createCustomEvent( "event_description": "Triggered when a new meter reading is added", "event_version": "1.0", "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", "event_tags": ["builtin", "metering", "erp"], "schema_fields": {}, "entity_graph": { @@ -277,7 +287,8 @@ const { data } = await client.createCustomEvent( "event_origin": "builtin", "mapping": { "mode": "guided", - "jsonata": "string" + "jsonata": "string", + "payload": "extend" }, "lineage": { "base_event_name": "string", @@ -322,6 +333,7 @@ const { data } = await client.getEvent({ "event_description": "Triggered when a new meter reading is added", "event_version": "1.0", "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", "event_tags": ["builtin", "metering", "erp"], "schema_fields": {}, "entity_graph": { @@ -361,7 +373,8 @@ const { data } = await client.getEvent({ "event_origin": "builtin", "mapping": { "mode": "guided", - "jsonata": "string" + "jsonata": "string", + "payload": "extend" }, "lineage": { "base_event_name": "string", @@ -418,6 +431,7 @@ const { data } = await client.patchEvent( "event_description": "Triggered when a new meter reading is added", "event_version": "1.0", "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", "event_tags": ["builtin", "metering", "erp"], "schema_fields": {}, "entity_graph": { @@ -457,7 +471,8 @@ const { data } = await client.patchEvent( "event_origin": "builtin", "mapping": { "mode": "guided", - "jsonata": "string" + "jsonata": "string", + "payload": "extend" }, "lineage": { "base_event_name": "string", @@ -533,7 +548,8 @@ const { data } = await client.replaceCustomEventDraft( automation_trigger_seed_node: 'string', mapping: { mode: 'guided', - jsonata: 'string' + jsonata: 'string', + payload: 'extend' }, lineage: { base_event_name: 'string', @@ -554,6 +570,7 @@ const { data } = await client.replaceCustomEventDraft( "event_description": "Triggered when a new meter reading is added", "event_version": "1.0", "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", "event_tags": ["builtin", "metering", "erp"], "schema_fields": {}, "entity_graph": { @@ -593,7 +610,8 @@ const { data } = await client.replaceCustomEventDraft( "event_origin": "builtin", "mapping": { "mode": "guided", - "jsonata": "string" + "jsonata": "string", + "payload": "extend" }, "lineage": { "base_event_name": "string", @@ -700,6 +718,7 @@ const { data } = await client.publishCustomEventDefinition( "event_description": "Triggered when a new meter reading is added", "event_version": "1.0", "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", "event_tags": ["builtin", "metering", "erp"], "schema_fields": {}, "entity_graph": { @@ -739,7 +758,369 @@ const { data } = await client.publishCustomEventDefinition( "event_origin": "builtin", "mapping": { "mode": "guided", - "jsonata": "string" + "jsonata": "string", + "payload": "extend" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" + } + ] +} +``` + +
+ +--- + +### `getCustomEventVersionDraft` + +Read the in-progress successor of a published custom event, together with the version it +would be published as. The live version keeps firing while the successor is authored. + +`GET /v1/events/{event_name}/version_draft` + +```ts +const { data } = await client.getCustomEventVersionDraft({ + event_name: 'example', +}) +``` + +
+Response + +```json +{ + "config": { + "event_name": "AddMeterReading", + "event_title": "Add Meter Reading", + "event_description": "Triggered when a new meter reading is added", + "event_version": "1.0", + "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", + "event_tags": ["builtin", "metering", "erp"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "enabled": true, + "auto_trigger": true, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string", + "payload": "extend" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" + } + ] + }, + "change_class": "none", + "next_version": "1.1", + "changes": [ + { + "field": "reading", + "op": "added", + "type_old": "string", + "type_new": "string" + } + ], + "remapped_fields": ["string"], + "added_nodes": ["string"], + "blocked_reason": "string" +} +``` + +
+ +--- + +### `putCustomEventVersionDraft` + +Create or replace the successor of a published custom event. The published definition stays +immutable and keeps firing; only publishing the draft promotes it. + +`PUT /v1/events/{event_name}/version_draft` + +```ts +const { data } = await client.putCustomEventVersionDraft( + { + event_name: 'example', + }, + { + event_name: 'string', + event_title: 'string', + event_description: 'string', + event_tags: ['string'], + schema_fields: {}, + entity_graph: { + nodes: [ + { + id: 'contact', + schema: 'contact', + cardinality: 'one', + fields: ['_id', '_title', 'first_name', 'account', '!account.*._files', '**._product'] + } + ], + edges: [ + { + from: 'contact', + to: 'billing_account' + } + ] + }, + entity_operation: { + operation: ['createEntity', 'updateEntity'], + schema: ['contact', 'contract', 'order'], + attribute: ['email', 'phone', 'status'], + purpose: ['Kündigung', 'Umzug/Auszug'], + purpose_filters: [ + { + id: 'string', + display_name: 'string' + } + ] + }, + automation_trigger: true, + api_trigger: true, + automation_trigger_only: false, + automation_trigger_seed_node: 'string', + mapping: { + mode: 'guided', + jsonata: 'string', + payload: 'extend' + }, + lineage: { + base_event_name: 'string', + base_event_version: 'string' + }, + example: {} + }, +) +``` + +
+Response + +```json +{ + "config": { + "event_name": "AddMeterReading", + "event_title": "Add Meter Reading", + "event_description": "Triggered when a new meter reading is added", + "event_version": "1.0", + "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", + "event_tags": ["builtin", "metering", "erp"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "enabled": true, + "auto_trigger": true, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string", + "payload": "extend" + }, + "lineage": { + "base_event_name": "string", + "base_event_version": "string" + }, + "success_criteria": [ + { + "entity_schema": "contract", + "attribute": "installment_amount" + }, + { + "entity_schema": "billing_account", + "attribute": "due_date" + } + ] + }, + "change_class": "none", + "next_version": "1.1", + "changes": [ + { + "field": "reading", + "op": "added", + "type_old": "string", + "type_new": "string" + } + ], + "remapped_fields": ["string"], + "added_nodes": ["string"], + "blocked_reason": "string" +} +``` + +
+ +--- + +### `deleteCustomEventVersionDraft` + +Discard the next-version draft. The published version is untouched. + +`DELETE /v1/events/{event_name}/version_draft` + +```ts +const { data } = await client.deleteCustomEventVersionDraft({ + event_name: 'example', +}) +``` + +--- + +### `publishCustomEventVersion` + +Publish the next-version draft as the event's new live version. + +`POST /v1/events/{event_name}/version_draft:publish` + +```ts +const { data } = await client.publishCustomEventVersion( + { + event_name: 'example', + }, + { + change_summary: 'string', + change_notes: 'string' + }, +) +``` + +
+Response + +```json +{ + "event_name": "AddMeterReading", + "event_title": "Add Meter Reading", + "event_description": "Triggered when a new meter reading is added", + "event_version": "1.0", + "event_status": "active", + "deprecated_at": "2026-09-30T12:00:00.000Z", + "event_tags": ["builtin", "metering", "erp"], + "schema_fields": {}, + "entity_graph": { + "nodes": [ + { + "id": "contact", + "schema": "contact", + "cardinality": "one", + "fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"] + } + ], + "edges": [ + { + "from": "contact", + "to": "billing_account" + } + ] + }, + "entity_operation": { + "operation": ["createEntity", "updateEntity"], + "schema": ["contact", "contract", "order"], + "attribute": ["email", "phone", "status"], + "purpose": ["Kündigung", "Umzug/Auszug"], + "purpose_filters": [ + { + "id": "string", + "display_name": "string" + } + ] + }, + "enabled": true, + "auto_trigger": true, + "automation_trigger": true, + "api_trigger": true, + "automation_trigger_only": true, + "automation_trigger_seed_node": "ticket", + "event_origin": "builtin", + "mapping": { + "mode": "guided", + "jsonata": "string", + "payload": "extend" }, "lineage": { "base_event_name": "string", @@ -1177,6 +1558,7 @@ type EventConfigBase = { event_description?: string event_version?: string event_status?: "active" | "deprecated" | "draft" | "disabled" + deprecated_at?: string // date-time event_tags?: string[] schema_fields?: Record + entity_graph?: { + nodes: { ... } + edges: { ... } + } + entity_operation?: { + operation: { ... } + schema: { ... } + attribute?: { ... } + purpose?: { ... } + purpose_filters?: { ... } + } + enabled?: boolean + auto_trigger?: boolean + automation_trigger?: boolean + api_trigger?: boolean + automation_trigger_only?: boolean + automation_trigger_seed_node?: string + event_origin?: "builtin" | "custom" + mapping?: { + mode: { ... } + jsonata?: { ... } + payload?: { ... } + } + lineage?: { + base_event_name: { ... } + base_event_version: { ... } + } + success_criteria?: Array<{ + entity_schema: { ... } + attribute: { ... } + }> + } + change_class: "none" | "minor" | "major" | "blocked" + next_version?: string + changes: Array<{ + field: string + op: "added" | "removed" | "type-changed" + type_old?: string + type_new?: string + }> + remapped_fields: string[] + added_nodes: string[] + blocked_reason?: string +} +``` + +### `PublishCustomEventVersionPayload` + +```ts +type PublishCustomEventVersionPayload = { + change_summary?: string + change_notes?: string +} +``` + ### `ValidationIssue` ```ts diff --git a/docs/sdk/clients/external-values.md b/docs/sdk/clients/external-values.md new file mode 100644 index 00000000..ac5c8879 --- /dev/null +++ b/docs/sdk/clients/external-values.md @@ -0,0 +1,411 @@ +--- +title: "External Values API" +description: "TypeScript SDK client for the epilot External Values API: usage with @epilot/sdk, all operations and schemas." +--- + +# External Values API + +- **Base URL:** `https://external-values.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/external-values](https://docs.epilot.io/api/external-values) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.externalValues.listExternalValues(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/external-values' + +const externalValuesClient = getClient() +authorize(externalValuesClient, () => '') +const { data } = await externalValuesClient.listExternalValues(...) +``` + +## Operations + +**external-values** +- [`listExternalValues`](#listexternalvalues) +- [`resolveExternalValue`](#resolveexternalvalue) +- [`resolvePortalExternalValue`](#resolveportalexternalvalue) + +**Schemas** +- [`TranslatedString`](#translatedstring) +- [`ExternalValueType`](#externalvaluetype) +- [`ResolveExternalValueRequest`](#resolveexternalvaluerequest) +- [`ExternalValueErrorCode`](#externalvalueerrorcode) +- [`ExternalValueError`](#externalvalueerror) +- [`ResolveExternalValueResponse`](#resolveexternalvalueresponse) +- [`ExternalValueResultSummary`](#externalvalueresultsummary) +- [`ExternalValueHookSummary`](#externalvaluehooksummary) +- [`ContextRequirement`](#contextrequirement) +- [`EntityContextRequirement`](#entitycontextrequirement) +- [`ValueContextRequirement`](#valuecontextrequirement) +- [`ExternalValueHookList`](#externalvaluehooklist) + +### `listExternalValues` + +List hooks and their results of all enabled installed apps that declare an +`EXTERNAL_VALUES` component. Intended for pickers (e.g. the validation-rules builder). + +`GET /v1/external-values` + +```ts +const { data } = await client.listExternalValues() +``` + +
+Response + +```json +{ + "hooks": [ + { + "app_id": "string", + "app_name": "string", + "hook_id": "string", + "name": { + "de": "string", + "en": "string" + }, + "description": { + "de": "string", + "en": "string" + }, + "results": [ + { + "id": "string", + "type": "number", + "name": { + "de": "string", + "en": "string" + } + } + ], + "contexts": [ + { + "type": "entity", + "schema": "contract" + } + ] + } + ] +} +``` + +
+ +--- + +### `resolveExternalValue` + +Resolve an external value hook for an epilot 360 user (builder preview, entity-attribute +rules). The organization is taken from the caller's token. + +`POST /v1/external-values/{app_id}/hooks/{hook_id}:resolve` + +```ts +const { data } = await client.resolveExternalValue( + { + app_id: 'example', + hook_id: 'example', + }, + { + context: { + contract: [ + { + _id: '8a7e3f5e-9c0c-4c74-8d4a-1a1a1a1a1a1a', + external_id: 'C-1001', + installment_amount: 110 + } + ] + }, + consumer: { + type: 'validation_rule', + rule_id: '6c0a9e1e-2f4b-4e6a-8f8e-2b2b2b2b2b2b' + } + }, +) +``` + +
+Response + +```json +{ + "values": { + "predicted": 132 + }, + "errors": [ + { + "result_id": "limit", + "code": "coercion_failed", + "message": "Cannot coerce \"n/a\" to number" + } + ], + "policy": { + "on_unavailable": "skip" + } +} +``` + +
+ +--- + +### `resolvePortalExternalValue` + +Resolve an external value hook for a portal end customer (private journeys, portal). +The organization is taken from the portal token claims. + +`POST /v1/portal/external-values/{app_id}/hooks/{hook_id}:resolve` + +```ts +const { data } = await client.resolvePortalExternalValue( + { + app_id: 'example', + hook_id: 'example', + }, + { + context: { + contract: [ + { + _id: '8a7e3f5e-9c0c-4c74-8d4a-1a1a1a1a1a1a', + external_id: 'C-1001', + installment_amount: 110 + } + ] + }, + consumer: { + type: 'validation_rule', + rule_id: '6c0a9e1e-2f4b-4e6a-8f8e-2b2b2b2b2b2b' + } + }, +) +``` + +
+Response + +```json +{ + "values": { + "predicted": 132 + }, + "errors": [ + { + "result_id": "limit", + "code": "coercion_failed", + "message": "Cannot coerce \"n/a\" to number" + } + ], + "policy": { + "on_unavailable": "skip" + } +} +``` + +
+ +--- + +## Schemas + +### `TranslatedString` + +```ts +type TranslatedString = { + de: string + en?: string +} +``` + +### `ExternalValueType` + +```ts +type ExternalValueType = "number" | "text" | "date" | "boolean" +``` + +### `ResolveExternalValueRequest` + +```ts +type ResolveExternalValueRequest = { + context: Record + consumer?: { + type?: string + rule_id?: string + journey_id?: string + } +} +``` + +### `ExternalValueErrorCode` + +- `timeout`: the third-party call exceeded `timeout_ms` +- `upstream_error`: the third-party call failed or returned a non-2xx status +- `auth_failed`: the `auth` pre-call failed +- `extraction_failed`: template/path/jsonata threw or yielded null / empty +- `coercion_failed`: the extracted value could n + +```ts +type ExternalValueErrorCode = "timeout" | "upstream_error" | "auth_failed" | "extraction_failed" | "coercion_failed" +``` + +### `ExternalValueError` + +```ts +type ExternalValueError = { + result_id?: string + code: "timeout" | "upstream_error" | "auth_failed" | "extraction_failed" | "coercion_failed" + message: string +} +``` + +### `ResolveExternalValueResponse` + +```ts +type ResolveExternalValueResponse = { + values: Record + errors: Array<{ + result_id?: string + code: "timeout" | "upstream_error" | "auth_failed" | "extraction_failed" | "coercion_failed" + message: string + }> + policy: { + on_unavailable: "skip" | "block" + } + cached?: boolean +} +``` + +### `ExternalValueResultSummary` + +```ts +type ExternalValueResultSummary = { + id: string + type: "number" | "text" | "date" | "boolean" + name: { + de: string + en?: string + } +} +``` + +### `ExternalValueHookSummary` + +```ts +type ExternalValueHookSummary = { + app_id: string + app_name: string + hook_id: string + name: { + de: string + en?: string + } + description?: { + de: string + en?: string + } + results: Array<{ + id: string + type: "number" | "text" | "date" | "boolean" + name: { + de: { ... } + en?: { ... } + } + }> + contexts?: Array<{ + type: "entity" + schema: string + } | { + type: "value" + name: string + value_type: "number" | "text" | "date" | "boolean" + }> +} +``` + +### `ContextRequirement` + +Something a hook needs the consumer to supply in `context`, discriminated by `type`: +bound entities (`entity`) or an optional scalar input (`value`). More types may follow; +consumers ignore types they do not know. + + +```ts +type ContextRequirement = { + type: "entity" + schema: string +} | { + type: "value" + name: string + value_type: "number" | "text" | "date" | "boolean" +} +``` + +### `EntityContextRequirement` + +The consumer supplies the bound entities of `schema` under `Context.```, e.g. a hook +interpolating `{{ Context.contract[0].external_id }}` declares +`{ type: entity, schema: contract }`. + + +```ts +type EntityContextRequirement = { + type: "entity" + schema: string +} +``` + +### `ValueContextRequirement` + +An optional scalar input. When the consumer has a value it supplies it under +`Context.``` (dates as ISO 8601 strings, `YYYY-MM-DD` or a date-time); otherwise the +key is absent, so the hook template must provide a fallback, e.g. +`{{ Context.reading_date | default: "now" | date: "%Y-%m-%d" }}` dec + +```ts +type ValueContextRequirement = { + type: "value" + name: string + value_type: "number" | "text" | "date" | "boolean" +} +``` + +### `ExternalValueHookList` + +```ts +type ExternalValueHookList = { + hooks: Array<{ + app_id: string + app_name: string + hook_id: string + name: { + de: { ... } + en?: { ... } + } + description?: { + de: { ... } + en?: { ... } + } + results: Array<{ + id: { ... } + type: { ... } + name: { ... } + }> + contexts?: Array<{ + type: { ... } + schema: { ... } + } | { + type: { ... } + name: { ... } + value_type: { ... } + }> + }> +} +``` diff --git a/docs/sdk/clients/file.md b/docs/sdk/clients/file.md index 6f7463f0..d584f51f 100644 --- a/docs/sdk/clients/file.md +++ b/docs/sdk/clients/file.md @@ -37,6 +37,21 @@ const { data } = await fileClient.uploadFileV2(...) - [`downloadFile`](#downloadfile) - [`downloadS3File`](#downloads3file) - [`downloadFiles`](#downloadfiles) +- [`createZipJob`](#createzipjob) +- [`getZipJob`](#getzipjob) +- [`getFileSummary`](#getfilesummary) +- [`getFileSummaryFeedback`](#getfilesummaryfeedback) +- [`putFileSummaryFeedback`](#putfilesummaryfeedback) +- [`createFileSummaryJob`](#createfilesummaryjob) +- [`getCurrentFileSummaryJob`](#getcurrentfilesummaryjob) +- [`getFileSummaryJob`](#getfilesummaryjob) +- [`generateFileSummary`](#generatefilesummary) +- [`createFileAttributeSuggestionJob`](#createfileattributesuggestionjob) +- [`getLatestFileAttributeSuggestions`](#getlatestfileattributesuggestions) +- [`getFileAttributeSuggestionJob`](#getfileattributesuggestionjob) +- [`updateFileAttributeSuggestionStatus`](#updatefileattributesuggestionstatus) +- [`getFileText`](#getfiletext) +- [`validateFile`](#validatefile) - [`verifyCustomDownloadUrl`](#verifycustomdownloadurl) - [`uploadFilePublic`](#uploadfilepublic) @@ -71,7 +86,35 @@ const { data } = await fileClient.uploadFileV2(...) - [`FileEntityId`](#fileentityid) - [`FileAttributes`](#fileattributes) - [`FileType`](#filetype) +- [`FileSummaryJobStatus`](#filesummaryjobstatus) +- [`FileSummaryJob`](#filesummaryjob) +- [`FileSummary`](#filesummary) +- [`FileSummaryFeedback`](#filesummaryfeedback) +- [`FileSummaryFeedbackResponse`](#filesummaryfeedbackresponse) +- [`PutFileSummaryFeedbackRequest`](#putfilesummaryfeedbackrequest) +- [`FileAttributeSuggestionJobStatus`](#fileattributesuggestionjobstatus) +- [`FileAttributeSuggestion`](#fileattributesuggestion) +- [`FileAttributeSuggestionsPayload`](#fileattributesuggestionspayload) +- [`FileAttributeSuggestionJob`](#fileattributesuggestionjob) +- [`CreateFileAttributeSuggestionJobRequest`](#createfileattributesuggestionjobrequest) +- [`UpdateFileAttributeSuggestionStatusRequest`](#updatefileattributesuggestionstatusrequest) +- [`FileAttributeSuggestionError`](#fileattributesuggestionerror) +- [`FileTextStatus`](#filetextstatus) +- [`FileValidationRequest`](#filevalidationrequest) +- [`FileValidationFileReference`](#filevalidationfilereference) +- [`FileValidation`](#filevalidation) +- [`FileValidationFile`](#filevalidationfile) +- [`FileValidationObservation`](#filevalidationobservation) +- [`FileValidationJudgement`](#filevalidationjudgement) +- [`FileValidationFacts`](#filevalidationfacts) +- [`FileValidationRuleResult`](#filevalidationruleresult) +- [`FileValidationConditionResult`](#filevalidationconditionresult) +- [`FileText`](#filetext) +- [`FileTextReady`](#filetextready) +- [`FileTextNotReady`](#filetextnotready) +- [`FileTextUnsupported`](#filetextunsupported) - [`CustomDownloadUrl`](#customdownloadurl) +- [`CustomDownloadUrlAuth`](#customdownloadurlauth) - [`FileEntity`](#fileentity) - [`CommonSaveFilePayload`](#commonsavefilepayload) - [`SaveS3FilePayload`](#saves3filepayload) @@ -83,6 +126,8 @@ const { data } = await fileClient.uploadFileV2(...) - [`UploadFilePayload`](#uploadfilepayload) - [`FileUpload`](#fileupload) - [`DownloadFilesPayload`](#downloadfilespayload) +- [`CreateZipJobPayload`](#createzipjobpayload) +- [`ZipJob`](#zipjob) - [`VerifyCustomDownloadUrlPayload`](#verifycustomdownloadurlpayload) - [`S3Reference`](#s3reference) - [`S3Ref`](#s3ref) @@ -171,9 +216,16 @@ const { data } = await client.saveFileV2( mime_type: 'application/pdf', size_bytes: 1234, readable_size: '1.2 MB', + etag: '9bb58f26192e4ba00f01e2e7b136bbd8', access_control: 'private', public_url: 'https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf', custom_download_url: 'https://some-api-url.com/download?file_id=123', + custom_download_url_auth: 'token', + preview_summary_de: 'string', + short_summary_de: 'string', + preview_summary_en: 'string', + short_summary_en: 'string', + file_summary_execution_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', s3ref: {} }, ) @@ -196,9 +248,16 @@ const { data } = await client.saveFileV2( "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "source_url": "https://productengineer-content.s3.eu-west-1.amazonaws.com/product-engineer-checklist.pdf", "s3ref": {}, "versions": [ @@ -207,7 +266,8 @@ const { data } = await client.saveFileV2( "filename": "document.pdf", "size_bytes": 1234, "readable_size": "1.2 MB", - "mime_type": "image/jpeg" + "mime_type": "image/jpeg", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8" } ], "_updated_at": "1970-01-01T00:00:00.000Z", @@ -263,9 +323,16 @@ const { data } = await client.getFile({ "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "source_url": "https://productengineer-content.s3.eu-west-1.amazonaws.com/product-engineer-checklist.pdf", "s3ref": {}, "versions": [ @@ -274,7 +341,8 @@ const { data } = await client.getFile({ "filename": "document.pdf", "size_bytes": 1234, "readable_size": "1.2 MB", - "mime_type": "image/jpeg" + "mime_type": "image/jpeg", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8" } ], "_updated_at": "1970-01-01T00:00:00.000Z", @@ -330,9 +398,16 @@ const { data } = await client.deleteFile({ "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "source_url": "https://productengineer-content.s3.eu-west-1.amazonaws.com/product-engineer-checklist.pdf", "s3ref": {}, "versions": [ @@ -341,7 +416,8 @@ const { data } = await client.deleteFile({ "filename": "document.pdf", "size_bytes": 1234, "readable_size": "1.2 MB", - "mime_type": "image/jpeg" + "mime_type": "image/jpeg", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8" } ], "_updated_at": "1970-01-01T00:00:00.000Z", @@ -376,6 +452,7 @@ const { data } = await client.downloadFile({ id: '123e4567-e89b-12d3-a456-426614174000', version: 1, attachment: true, + x-track: 'example', }) ``` @@ -453,6 +530,561 @@ const { data } = await client.downloadFiles( --- +### `createZipJob` + +Create a background job to ZIP multiple files and send a download link via email. + +`POST /v1/files:zipJob` + +```ts +const { data } = await client.createZipJob( + null, + {}, +) +``` + +--- + +### `getZipJob` + +Get the status of a ZIP job + +`GET /v1/files:zipJob/{job_id}` + +```ts +const { data } = await client.getZipJob({ + job_id: 'example', +}) +``` + +
+Response + +```json +{ + "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "completed", + "progress": { + "total_files": 100, + "downloaded_files": 75, + "failed_files": 2 + }, + "result": { + "file_entity_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8", + "download_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/files.zip?X-Amz-...", + "expires_at": "2024-01-02T12:00:00Z", + "zip_size_bytes": 104857600 + }, + "error": "Failed to download file: access denied", + "created_at": "2024-01-01T12:00:00Z", + "created_by": "10234", + "org_id": "123", + "updated_at": "2024-01-01T12:05:00Z" +} +``` + +
+ +--- + +### `getFileSummary` + +Get summary text for a file entity together with the current summary job status when available. + +`GET /v1/files/{id}/summary` + +```ts +const { data } = await client.getFileSummary({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "status": "queued", + "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "feedback_available": true, + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string" +} +``` + +
+ +--- + +### `getFileSummaryFeedback` + +Get file summary feedback + +`GET /v1/files/{id}/summary/feedback` + +```ts +const { data } = await client.getFileSummaryFeedback({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +### `putFileSummaryFeedback` + +Submit file summary feedback + +`PUT /v1/files/{id}/summary/feedback` + +```ts +const { data } = await client.putFileSummaryFeedback( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + rating: 'up', + comment: 'string' + }, +) +``` + +
+Response + +```json +{ + "feedback": { + "rating": "up", + "comment": "string", + "user_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +### `createFileSummaryJob` + +Create or return the current AI summary job for a file entity. + +`POST /v1/files/{id}/summary-jobs` + +```ts +const { data } = await client.createFileSummaryJob({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `getCurrentFileSummaryJob` + +Get the latest AI summary job for the file entity's current source. + +`GET /v1/files/{id}/summary-jobs/current` + +```ts +const { data } = await client.getCurrentFileSummaryJob({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "file_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8", + "status": "queued", + "error": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `getFileSummaryJob` + +Get an AI summary job by id. + +`GET /v1/files/{id}/summary-jobs/{job_id}` + +```ts +const { data } = await client.getFileSummaryJob({ + id: '123e4567-e89b-12d3-a456-426614174000', + job_id: 'example', +}) +``` + +
+Response + +```json +{ + "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "file_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8", + "status": "queued", + "error": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `generateFileSummary` + +Compatibility alias for creating or returning the current AI summary job for a file entity. + +`POST /v1/files/{id}/summary:generate` + +```ts +const { data } = await client.generateFileSummary({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `createFileAttributeSuggestionJob` + +Start an auto-fill job that reads the file's extracted text and suggests values for the related entity's attributes. Requires `entity:view` on the file and on the related entity. Returns 404 with `err + +`POST /v1/files/{id}/attribute-suggestion-jobs` + +```ts +const { data } = await client.createFileAttributeSuggestionJob( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + entity_slug: 'opportunity', + entity_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + }, +) +``` + +--- + +### `getLatestFileAttributeSuggestions` + +Get the most recent attribute suggestion job of any status for the file and the given entity. Returns 404 with `error_code: no_file_attribute_suggestions_job` when auto-fill has not run yet. + +`GET /v1/files/{id}/attribute-suggestion-jobs/latest` + +```ts +const { data } = await client.getLatestFileAttributeSuggestions({ + id: '123e4567-e89b-12d3-a456-426614174000', + entity_id: 'example', +}) +``` + +
+Response + +```json +{ + "jobId": "string", + "jobStatus": { + "status": "INITIATED", + "progress": 0, + "error": "string" + }, + "payload": { + "file_id": "string", + "entity_id": "string", + "entity_slug": "string", + "generated_by": "string", + "generated_at": 0, + "suggestions": [ + { + "attribute_name": "string", + "attribute_label": "string", + "attribute_type": "date", + "suggested_value": "string", + "confidence": "high", + "source_page": 0, + "evidence": "string", + "status": "suggested", + "status_updated_by": "string", + "status_updated_at": 0, + "discard_reason": "string", + "is_copied": true, + "copied_by": "string", + "copied_at": 0, + "suggestion_type": "new_value" + } + ] + }, + "createdAt": 0, + "updatedAt": 0 +} +``` + +
+ +--- + +### `getFileAttributeSuggestionJob` + +Get an attribute suggestion job of the file. Poll until `jobStatus.status` is `COMPLETED` or `FAILED`. + +`GET /v1/files/{id}/attribute-suggestion-jobs/{job_id}` + +```ts +const { data } = await client.getFileAttributeSuggestionJob({ + id: '123e4567-e89b-12d3-a456-426614174000', + job_id: 'example', +}) +``` + +
+Response + +```json +{ + "jobId": "string", + "jobStatus": { + "status": "INITIATED", + "progress": 0, + "error": "string" + }, + "payload": { + "file_id": "string", + "entity_id": "string", + "entity_slug": "string", + "generated_by": "string", + "generated_at": 0, + "suggestions": [ + { + "attribute_name": "string", + "attribute_label": "string", + "attribute_type": "date", + "suggested_value": "string", + "confidence": "high", + "source_page": 0, + "evidence": "string", + "status": "suggested", + "status_updated_by": "string", + "status_updated_at": 0, + "discard_reason": "string", + "is_copied": true, + "copied_by": "string", + "copied_at": 0, + "suggestion_type": "new_value" + } + ] + }, + "createdAt": 0, + "updatedAt": 0 +} +``` + +
+ +--- + +### `updateFileAttributeSuggestionStatus` + +Record that suggestions were accepted, discarded or copied. Only the suggestion entries named in the request change; unknown attribute names are ignored. Applying a value to the entity stays with the + +`PATCH /v1/files/{id}/attribute-suggestion-jobs/{job_id}` + +```ts +const { data } = await client.updateFileAttributeSuggestionStatus( + { + id: '123e4567-e89b-12d3-a456-426614174000', + job_id: 'example', + }, + { + suggestionStatusUpdates: [ + {}, + {} + ] + }, +) +``` + +
+Response + +```json +{ + "jobId": "string", + "jobStatus": { + "status": "INITIATED", + "progress": 0, + "error": "string" + }, + "payload": { + "file_id": "string", + "entity_id": "string", + "entity_slug": "string", + "generated_by": "string", + "generated_at": 0, + "suggestions": [ + { + "attribute_name": "string", + "attribute_label": "string", + "attribute_type": "date", + "suggested_value": "string", + "confidence": "high", + "source_page": 0, + "evidence": "string", + "status": "suggested", + "status_updated_by": "string", + "status_updated_at": 0, + "discard_reason": "string", + "is_copied": true, + "copied_by": "string", + "copied_at": 0, + "suggestion_type": "new_value" + } + ] + }, + "createdAt": 0, + "updatedAt": 0 +} +``` + +
+ +--- + +### `getFileText` + +Get the plain-text representation of a file entity. Returns status `not_ready` while text is being prepared and `unsupported` when text is unavailable for the file or organization. + +`GET /v1/files/{id}/text` + +```ts +const { data } = await client.getFileText({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "status": "ready", + "text": "string", + "truncated": true, + "total_chars": 0 +} +``` + +
+ +--- + +### `validateFile` + +Validate an uploaded file against one or more document validation rules +(validation-rules-api rules with `input_type: document`). + +`POST /v1/files/validations` + +```ts +const { data } = await client.validateFile( + null, + { + file: { + entity_id: 'ef7d985c-2385-44f4-9c71-ae06a52264f8' + }, + rule_ids: ['string'] + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "status": "completed", + "file": { + "entity_id": "ef7d985c-2385-44f4-9c71-ae06a52264f8", + "s3ref": {}, + "filename": "string", + "mime_type": "string", + "size_bytes": 0 + }, + "observation": { + "facts": { + "mime_type": "string", + "size_bytes": 0, + "page_count": 0, + "longer_edge_px": 0, + "is_blank": true, + "is_password_protected": true + }, + "judgements": {}, + "document_type": { + "slug": "string", + "confidence": 0 + } + }, + "results": [ + { + "rule_id": "string", + "rule_title": "string", + "level": "basic", + "is_valid": true, + "failed_parts": ["string"], + "warnings": ["string"], + "conditions": [ + { + "id": "string", + "operator": "string", + "outcome": "pass", + "blocking": true, + "message": "string", + "evidence": "string", + "explanation": "string" + } + ] + } + ], + "created_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + ### `previewFile` Generate a thumbnail preview for a file entity. @@ -517,6 +1149,7 @@ const { data } = await client.previewPublicFile({ version: 1, w: 1, h: 1, + keep_original: true, org_id: 'example', }) ``` @@ -572,7 +1205,7 @@ const { data } = await client.generatePublicLink({ ### `listPublicLinksForFile` -**Not yet implemented.** +Fetches all public links previously generated for a file `GET /v1/files/{id}/public/links` @@ -619,7 +1252,7 @@ const { data } = await client.accessPublicLink({ ### `revokePublicLink` -**Not yet implemented.** +Revokes a given public link by ID `DELETE /v1/files/public/links/{id}` @@ -866,9 +1499,16 @@ const { data } = await client.getFilesInCollection({ "mime_type": "application/pdf", "size_bytes": 1234, "readable_size": "1.2 MB", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8", "access_control": "private", "public_url": "https://epilot-prod-user-content.s3.eu-central-1.amazonaws.com/123/4d689aeb-1497-4410-a9fe-b36ca9ac4389/document.pdf", "custom_download_url": "https://some-api-url.com/download?file_id=123", + "custom_download_url_auth": "token", + "preview_summary_de": "string", + "short_summary_de": "string", + "preview_summary_en": "string", + "short_summary_en": "string", + "file_summary_execution_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "source_url": "https://productengineer-content.s3.eu-west-1.amazonaws.com/product-engineer-checklist.pdf", "s3ref": {}, "versions": [ @@ -877,7 +1517,8 @@ const { data } = await client.getFilesInCollection({ "filename": "document.pdf", "size_bytes": 1234, "readable_size": "1.2 MB", - "mime_type": "image/jpeg" + "mime_type": "image/jpeg", + "etag": "9bb58f26192e4ba00f01e2e7b136bbd8" } ], "_updated_at": "1970-01-01T00:00:00.000Z", @@ -980,9 +1621,16 @@ type FileAttributes = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid } ``` @@ -992,6 +1640,437 @@ type FileAttributes = { type FileType = "document" | "document_template" | "text" | "image" | "video" | "audio" | "spreadsheet" | "presentation" | "font" | "archive" | "application" | "unknown" ``` +### `FileSummaryJobStatus` + +Current state of a file summary job. + +```ts +type FileSummaryJobStatus = "queued" | "waiting_for_extraction" | "processing" | "completed" | "failed" | "unsupported" | "stale" +``` + +### `FileSummaryJob` + +```ts +type FileSummaryJob = { + job_id: string // uuid + file_id: string | string // uuid + status: "queued" | "waiting_for_extraction" | "processing" | "completed" | "failed" | "unsupported" | "stale" + error?: string + created_at: string // date-time + updated_at: string // date-time + completed_at?: string // date-time +} +``` + +### `FileSummary` + +```ts +type FileSummary = { + status?: "queued" | "waiting_for_extraction" | "processing" | "completed" | "failed" | "unsupported" | "stale" + job_id?: string // uuid + feedback_available?: boolean + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string +} +``` + +### `FileSummaryFeedback` + +```ts +type FileSummaryFeedback = { + rating: "up" | "down" + comment?: string + user_id: string + submitted_at: string // date-time +} +``` + +### `FileSummaryFeedbackResponse` + +```ts +type FileSummaryFeedbackResponse = { + feedback: { + rating: "up" | "down" + comment?: string + user_id: string + submitted_at: string // date-time + } +} +``` + +### `PutFileSummaryFeedbackRequest` + +```ts +type PutFileSummaryFeedbackRequest = { + rating: "up" | "down" + comment?: string +} +``` + +### `FileAttributeSuggestionJobStatus` + +```ts +type FileAttributeSuggestionJobStatus = { + status: "INITIATED" | "IN_PROGRESS" | "COMPLETED" | "FAILED" + progress: number + error?: string +} +``` + +### `FileAttributeSuggestion` + +```ts +type FileAttributeSuggestion = { + attribute_name?: string + attribute_label?: string + attribute_type?: "date" | "number" | "boolean" | "select" | "string" + suggested_value?: string | number | boolean + confidence?: "high" | "medium" | "low" + source_page?: number + evidence?: string + status?: "suggested" | "accepted" | "discarded" + status_updated_by?: string + status_updated_at?: number + discard_reason?: string + is_copied?: boolean + copied_by?: string + copied_at?: number + suggestion_type?: "new_value" | "update" +} +``` + +### `FileAttributeSuggestionsPayload` + +```ts +type FileAttributeSuggestionsPayload = { + file_id: string + entity_id: string + entity_slug: string + generated_by?: string + generated_at?: number + suggestions: Array<{ + attribute_name?: string + attribute_label?: string + attribute_type?: "date" | "number" | "boolean" | "select" | "string" + suggested_value?: string | number | boolean + confidence?: "high" | "medium" | "low" + source_page?: number + evidence?: string + status?: "suggested" | "accepted" | "discarded" + status_updated_by?: string + status_updated_at?: number + discard_reason?: string + is_copied?: boolean + copied_by?: string + copied_at?: number + suggestion_type?: "new_value" | "update" + }> +} +``` + +### `FileAttributeSuggestionJob` + +```ts +type FileAttributeSuggestionJob = { + jobId: string + jobStatus: { + status: "INITIATED" | "IN_PROGRESS" | "COMPLETED" | "FAILED" + progress: number + error?: string + } + payload: { + file_id: string + entity_id: string + entity_slug: string + generated_by?: string + generated_at?: number + suggestions: Array<{ + attribute_name?: { ... } + attribute_label?: { ... } + attribute_type?: { ... } + suggested_value?: { ... } + confidence?: { ... } + source_page?: { ... } + evidence?: { ... } + status?: { ... } + status_updated_by?: { ... } + status_updated_at?: { ... } + discard_reason?: { ... } + is_copied?: { ... } + copied_by?: { ... } + copied_at?: { ... } + suggestion_type?: { ... } + }> + } + createdAt: number + updatedAt: number +} +``` + +### `CreateFileAttributeSuggestionJobRequest` + +```ts +type CreateFileAttributeSuggestionJobRequest = { + entity_slug: string + entity_id: string // uuid +} +``` + +### `UpdateFileAttributeSuggestionStatusRequest` + +```ts +type UpdateFileAttributeSuggestionStatusRequest = { + suggestionStatusUpdates: unknown | unknown[] +} +``` + +### `FileAttributeSuggestionError` + +```ts +type FileAttributeSuggestionError = { + status?: number + error?: string + error_code?: "entity_or_schema_unavailable" | "file_not_extracted" | "extraction_unsupported" | "extraction_failed" | "extraction_status_unavailable" | "processing_enqueue_failed" | "no_file_attribute_suggestions_job" | "job_not_found" +} +``` + +### `FileTextStatus` + +Availability of the plain-text representation for a file entity. + +```ts +type FileTextStatus = "ready" | "not_ready" | "unsupported" +``` + +### `FileValidationRequest` + +```ts +type FileValidationRequest = { + file: { + entity_id: string | string // uuid + } | { + s3ref: unknown + } + rule_ids: string[] +} +``` + +### `FileValidationFileReference` + +The file to validate - a saved file entity, or an uploaded object not saved as an entity yet. + +```ts +type FileValidationFileReference = { + entity_id: string | string // uuid +} | { + s3ref: unknown +} +``` + +### `FileValidation` + +```ts +type FileValidation = { + id: string + status: "completed" | "pending" | "failed" | "skipped" + file: { + entity_id?: string | string // uuid + s3ref?: unknown + filename?: string + mime_type?: string + size_bytes?: number + } + observation: { + facts: { + mime_type?: { ... } + size_bytes?: { ... } + page_count?: { ... } + longer_edge_px?: { ... } + is_blank?: { ... } + is_password_protected?: { ... } + } + judgements?: Record + document_type?: { + slug?: { ... } + confidence?: { ... } + } + } + results: Array<{ + rule_id: string + rule_title?: string + level: "basic" | "standard" | "advanced" + is_valid: boolean + failed_parts?: string[] + warnings?: string[] + conditions: Array<{ + id: { ... } + operator: { ... } + outcome: { ... } + blocking: { ... } + message: { ... } + evidence?: { ... } + explanation?: { ... } + }> + }> + created_at: string // date-time +} +``` + +### `FileValidationFile` + +The file that was validated, with the identity facts collected from its content. + +```ts +type FileValidationFile = { + entity_id?: string | string // uuid + s3ref?: unknown + filename?: string + mime_type?: string + size_bytes?: number +} +``` + +### `FileValidationObservation` + +Everything observed about the file, as passed to the validation rules engine. + +```ts +type FileValidationObservation = { + facts: { + mime_type?: string + size_bytes?: number + page_count?: number + longer_edge_px?: number + is_blank?: boolean + is_password_protected?: boolean + } + judgements?: Record + document_type?: { + slug?: string + confidence?: number + } +} +``` + +### `FileValidationJudgement` + +```ts +type FileValidationJudgement = { + result: "pass" | "fail" | "uncertain" + confidence?: number + evidence?: string + explanation?: string +} +``` + +### `FileValidationFacts` + +Deterministic properties of the file. A property that is absent could not be determined +(for example the resolution of an image the service cannot decode); conditions that need it +are skipped rather than failed. + + +```ts +type FileValidationFacts = { + mime_type?: string + size_bytes?: number + page_count?: number + longer_edge_px?: number + is_blank?: boolean + is_password_protected?: boolean +} +``` + +### `FileValidationRuleResult` + +```ts +type FileValidationRuleResult = { + rule_id: string + rule_title?: string + level: "basic" | "standard" | "advanced" + is_valid: boolean + failed_parts?: string[] + warnings?: string[] + conditions: Array<{ + id: string + operator: string + outcome: "pass" | "fail" | "uncertain" | "skipped" + blocking: boolean + message: string + evidence?: string + explanation?: string + }> +} +``` + +### `FileValidationConditionResult` + +```ts +type FileValidationConditionResult = { + id: string + operator: string + outcome: "pass" | "fail" | "uncertain" | "skipped" + blocking: boolean + message: string + evidence?: string + explanation?: string +} +``` + +### `FileText` + +```ts +type FileText = { + status: "ready" + text: string + truncated: boolean + total_chars: number +} | { + status: "not_ready" +} | { + status: "unsupported" +} +``` + +### `FileTextReady` + +```ts +type FileTextReady = { + status: "ready" + text: string + truncated: boolean + total_chars: number +} +``` + +### `FileTextNotReady` + +```ts +type FileTextNotReady = { + status: "not_ready" +} +``` + +### `FileTextUnsupported` + +```ts +type FileTextUnsupported = { + status: "unsupported" +} +``` + ### `CustomDownloadUrl` Custom external download url used for the file @@ -1000,6 +2079,14 @@ Custom external download url used for the file type CustomDownloadUrl = string // uri ``` +### `CustomDownloadUrlAuth` + +Authorization mode for the custom_download_url. `presigned` (the default) uses an HMAC-signed URL; `token` authorizes the download via the caller's bearer token, matched against the exact stored custom_download_url. In token mode the File API returns the unsigned custom_download_url (no expires_at/s + +```ts +type CustomDownloadUrlAuth = "presigned" | "token" +``` + ### `FileEntity` ```ts @@ -1016,9 +2103,16 @@ type FileEntity = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid source_url?: string s3ref?: object versions: Array<{ @@ -1027,6 +2121,7 @@ type FileEntity = { size_bytes?: number readable_size?: string mime_type?: string + etag?: string }> _updated_at?: string // date-time _created_at?: string // date-time @@ -1076,9 +2171,16 @@ type SaveS3FilePayload = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid s3ref?: unknown } ``` @@ -1102,9 +2204,16 @@ type SaveFileFromSourceURLPayload = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid source_url?: string // uri } ``` @@ -1128,9 +2237,16 @@ type SaveCustomFilePayload = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid } ``` @@ -1153,9 +2269,16 @@ type SaveFilePayload = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid s3ref?: unknown } | { _id?: object @@ -1173,9 +2296,16 @@ type SaveFilePayload = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid source_url?: string // uri } | { _id?: object @@ -1193,9 +2323,16 @@ type SaveFilePayload = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid } ``` @@ -1218,9 +2355,16 @@ type SaveFilePayloadV2 = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid s3ref?: unknown } | { _id?: object @@ -1238,9 +2382,16 @@ type SaveFilePayloadV2 = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid source_url?: string // uri } | { _id?: object @@ -1258,9 +2409,16 @@ type SaveFilePayloadV2 = { mime_type?: string size_bytes?: number readable_size?: string + etag?: string access_control?: "private" | "public-read" public_url?: string // url custom_download_url?: string // uri + custom_download_url_auth?: "presigned" | "token" + preview_summary_de?: string + short_summary_de?: string + preview_summary_en?: string + short_summary_en?: string + file_summary_execution_id?: string // uuid } ``` @@ -1309,6 +2467,44 @@ type DownloadFilesPayload = Array<{ }> ``` +### `CreateZipJobPayload` + +Request payload to create a ZIP job for bulk file download. +Provide either an explicit list of `file_entity_ids` (up to 1000) or an +`entity_query` that resolves to file entities (up to 10000). + + +```ts +type CreateZipJobPayload = unknown | unknown +``` + +### `ZipJob` + +ZIP job status and result + +```ts +type ZipJob = { + job_id?: string // uuid + status?: "queued" | "downloading" | "zipping" | "uploading" | "sending_notification" | "completed" | "failed" + progress?: { + total_files?: number + downloaded_files?: number + failed_files?: number + } + result?: { + file_entity_id?: string // uuid + download_url?: string // uri + expires_at?: string // date-time + zip_size_bytes?: number + } + error?: string + created_at?: string // date-time + created_by?: string + org_id?: string + updated_at?: string // date-time +} +``` + ### `VerifyCustomDownloadUrlPayload` ```ts @@ -1344,6 +2540,7 @@ type FileItem = { size_bytes?: number readable_size?: string mime_type?: string + etag?: string } ``` diff --git a/docs/sdk/clients/identity.md b/docs/sdk/clients/identity.md new file mode 100644 index 00000000..691e87a3 --- /dev/null +++ b/docs/sdk/clients/identity.md @@ -0,0 +1,1278 @@ +--- +title: "Identity API" +description: "TypeScript SDK client for the epilot Identity API: usage with @epilot/sdk, all operations and schemas." +--- + +# Identity API + +- **Base URL:** `https://id.epilot.cloud` +- **Full API Docs:** [https://docs.epilot.io/api/identity](https://docs.epilot.io/api/identity) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.identity.listClients(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/identity' + +const identityClient = getClient() +authorize(identityClient, () => '') +const { data } = await identityClient.listClients(...) +``` + +## Operations + +**Operator Clients** +- [`listClients`](#listclients) +- [`createOidcClient`](#createoidcclient) +- [`getOidcClient`](#getoidcclient) +- [`updateClient`](#updateclient) +- [`retireClient`](#retireclient) +- [`activateClient`](#activateclient) +- [`suspendClient`](#suspendclient) +- [`rotateClientSecret`](#rotateclientsecret) + +**Operator Organizations** +- [`listClientOrganizations`](#listclientorganizations) +- [`enableClientOrganization`](#enableclientorganization) +- [`getClientOrganization`](#getclientorganization) +- [`updateClientOrganization`](#updateclientorganization) +- [`revokeClientOrganization`](#revokeclientorganization) +- [`suspendClientOrganization`](#suspendclientorganization) +- [`activateClientOrganization`](#activateclientorganization) +- [`getUserSubject`](#getusersubject) + +**Session** +- [`createIdentitySession`](#createidentitysession) +- [`deleteIdentitySession`](#deleteidentitysession) + +**Launch** +- [`launchClient`](#launchclient) + +**Schemas** +- [`Error`](#error) +- [`PartnerClientId`](#partnerclientid) +- [`OrgId`](#orgid) +- [`UserId`](#userid) +- [`Environment`](#environment) +- [`PartnerClientStatus`](#partnerclientstatus) +- [`Scope`](#scope) +- [`HttpsUri`](#httpsuri) +- [`PartnerClientCreate`](#partnerclientcreate) +- [`PartnerClientUpdate`](#partnerclientupdate) +- [`PartnerClient`](#partnerclient) +- [`PartnerClientWithSecret`](#partnerclientwithsecret) +- [`PartnerClientList`](#partnerclientlist) +- [`StatusChangeRequest`](#statuschangerequest) +- [`RotateSecretRequest`](#rotatesecretrequest) +- [`AuthorizationPolicyInput`](#authorizationpolicyinput) +- [`AuthorizationPolicy`](#authorizationpolicy) +- [`OrgEnablementStatus`](#orgenablementstatus) +- [`OrgEnablementCreate`](#orgenablementcreate) +- [`OrgEnablementUpdate`](#orgenablementupdate) +- [`OrgEnablement`](#orgenablement) +- [`OrgEnablementList`](#orgenablementlist) +- [`IdentitySession`](#identitysession) +- [`UserSubject`](#usersubject) + +### `listClients` + +List registered partner clients. The client secret is never returned. + +`GET /v1/identity/operator/clients` + +```ts +const { data } = await client.listClients({ + partner_key: 'example', + status: 'example', + size: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `createOidcClient` + +Create a partner client in `draft` status. The client secret is returned exactly once in this +response and can never be read again; use `rotateClientSecret` to obtain a new one. + +`POST /v1/identity/operator/clients` + +```ts +const { data } = await client.createOidcClient( + null, + { + partner_key: 'babelforce', + display_name: 'Babelforce', + description: 'string', + environment: 'dev', + redirect_uris: ['https://partner.example.com/auth/callback'], + sector_identifier_uri: 'https://partner.example.com/auth/callback', + initiate_login_uri: 'https://partner.example.com/auth/callback', + launch_target_prefixes: ['string'], + scopes_allowed: ['openid'] + }, +) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string", + "client_secret": "string" +} +``` + +
+ +--- + +### `getOidcClient` + +Read a partner client. The client secret is never returned. + +`GET /v1/identity/operator/clients/{client_id}` + +```ts +const { data } = await client.getOidcClient({ + client_id: 'example', +}) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `updateClient` + +Replace the mutable configuration of a client. `config_version` must equal the current +version (compare-and-swap); a mismatch is rejected with `409`. + +`PUT /v1/identity/operator/clients/{client_id}` + +```ts +const { data } = await client.updateClient( + { + client_id: 'example', + }, + { + config_version: 1, + allow_sector_change: false, + display_name: 'string', + description: 'string', + redirect_uris: ['https://partner.example.com/auth/callback'], + sector_identifier_uri: 'https://partner.example.com/auth/callback', + initiate_login_uri: 'https://partner.example.com/auth/callback', + launch_target_prefixes: ['string'], + scopes_allowed: ['openid'] + }, +) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `retireClient` + +Retire a client. The record is kept as a tombstone, the `client_id` is never reused, every +organization enablement is revoked and all provider-side artefacts are revoked. + +`DELETE /v1/identity/operator/clients/{client_id}` + +```ts +const { data } = await client.retireClient({ + client_id: 'example', +}) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `activateClient` + +Activate a `draft` or `suspended` client. Validates that every redirect URI is an absolute +HTTPS URL without fragment, that `scopes_allowed` contains `openid`, and that the +authentication method is `c + +`POST /v1/identity/operator/clients/{client_id}:activate` + +```ts +const { data } = await client.activateClient({ + client_id: 'example', +}) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `suspendClient` + +Immediately block the client for every organization. Provider-side artefacts (codes, tokens, +grants) are revoked; the audit trail is kept. Reversible with `activateClient`. + +`POST /v1/identity/operator/clients/{client_id}:suspend` + +```ts +const { data } = await client.suspendClient( + { + client_id: 'example', + }, + { + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `rotateClientSecret` + +Issue a new client secret. The new secret is returned exactly once. The previous secret +keeps working until `previous_secret_expires_at` unless `compromise_mode` is set, in which +case it stops working + +`POST /v1/identity/operator/clients/{client_id}:rotateSecret` + +```ts +const { data } = await client.rotateClientSecret( + { + client_id: 'example', + }, + { + compromise_mode: false, + migration_window_seconds: 86400 + }, +) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "partner_key": "string", + "display_name": "string", + "description": "string", + "environment": "dev", + "redirect_uris": ["https://partner.example.com/auth/callback"], + "sector_identifier_uri": "https://partner.example.com/auth/callback", + "initiate_login_uri": "https://partner.example.com/auth/callback", + "launch_target_prefixes": ["string"], + "token_endpoint_auth_method": "client_secret_basic", + "grant_types": ["authorization_code"], + "scopes_allowed": ["openid"], + "status": "draft", + "status_reason": "string", + "config_version": 1, + "secret_rotated_at": "1970-01-01T00:00:00.000Z", + "previous_secret_expires_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string", + "client_secret": "string" +} +``` + +
+ +--- + +### `listClientOrganizations` + +List the organizations enabled on a client, including suspended and revoked ones. + +`GET /v1/identity/operator/clients/{client_id}/organizations` + +```ts +const { data } = await client.listClientOrganizations({ + client_id: 'example', + status: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" + } + ] +} +``` + +
+ +--- + +### `enableClientOrganization` + +Enable an epilot organization on a client, recording the customer's authorization policy +(version 1). `allowed_scopes` must contain `openid` and be a subset of the client's +`scopes_allowed`. + +`POST /v1/identity/operator/clients/{client_id}/organizations` + +```ts +const { data } = await client.enableClientOrganization( + { + client_id: 'example', + }, + { + org_id: '739224', + authorization_policy: { + mode: 'preauthorized', + population: 'all_current_org_members', + allowed_scopes: ['openid'], + customer_approval_ref: 'string', + approved_at: '1970-01-01T00:00:00.000Z' + } + }, +) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `getClientOrganization` + +Read one organization enablement. + +`GET /v1/identity/operator/clients/{client_id}/organizations/{org_id}` + +```ts +const { data } = await client.getClientOrganization({ + client_id: 'example', + org_id: 'example', +}) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `updateClientOrganization` + +Record a new version of the customer's authorization policy. `expected_policy_version` must +equal the current version (compare-and-swap); a mismatch is rejected with `409`. + +`PUT /v1/identity/operator/clients/{client_id}/organizations/{org_id}` + +```ts +const { data } = await client.updateClientOrganization( + { + client_id: 'example', + org_id: 'example', + }, + { + expected_policy_version: 1, + authorization_policy: { + mode: 'preauthorized', + population: 'all_current_org_members', + allowed_scopes: ['openid'], + customer_approval_ref: 'string', + approved_at: '1970-01-01T00:00:00.000Z' + } + }, +) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `revokeClientOrganization` + +Revoke an organization's enablement. The record is kept as an audited tombstone; future +authorizations for this organization fail with `access_denied` and provider-side artefacts +bound to it are revok + +`DELETE /v1/identity/operator/clients/{client_id}/organizations/{org_id}` + +```ts +const { data } = await client.revokeClientOrganization( + { + client_id: 'example', + org_id: 'example', + }, + { + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `suspendClientOrganization` + +Temporarily block one organization on this client. Reversible with `activateClientOrganization`. + +`POST /v1/identity/operator/clients/{client_id}/organizations/{org_id}:suspend` + +```ts +const { data } = await client.suspendClientOrganization( + { + client_id: 'example', + org_id: 'example', + }, + { + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `activateClientOrganization` + +Resume a suspended organization on this client. Revoked enablements cannot be re-activated; enabling the organization again (`POST …/organizations`) replaces the revoked entry and continues its policy + +`POST /v1/identity/operator/clients/{client_id}/organizations/{org_id}:activate` + +```ts +const { data } = await client.activateClientOrganization({ + client_id: 'example', + org_id: 'example', +}) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "status": "active", + "status_reason": "string", + "authorization_policy": { + "mode": "preauthorized", + "population": "all_current_org_members", + "allowed_scopes": ["openid"], + "customer_approval_ref": "string", + "approved_at": "1970-01-01T00:00:00.000Z", + "version": 1, + "mandatory_claims": ["org_id"], + "recorded_by": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" + }, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_by": "string" +} +``` + +
+ +--- + +### `getUserSubject` + +The pairwise `sub` this client receives for one epilot user, so the partner can bind the person on its +side **before** the first sign-in (for example a Babelforce agent provisioned through SCIM with +` + +`GET /v1/identity/operator/clients/{client_id}/organizations/{org_id}/users/{user_id}:subject` + +```ts +const { data } = await client.getUserSubject({ + client_id: 'example', + org_id: 'example', + user_id: 'example', +}) +``` + +
+Response + +```json +{ + "client_id": "bf-prod-x7k2", + "org_id": "739224", + "user_id": "100321", + "sub": "v1.dGhpcy1pcy1hLWR1bW15LXN1YmplY3QtdmFsdWUtMDAx", + "key_version": "v1", + "sector": "portal.epilot.cloud" +} +``` + +
+ +--- + +### `createIdentitySession` + +Called by the epilot portal through the portal-host proxy after every persisted 360 session. +Validates the 360 bearer token itself and mirrors it into the `identity_session` cookie +(`HttpOnly; Secure; + +`GET /v1/identity/session` + +```ts +const { data } = await client.createIdentitySession() +``` + +
+Response + +```json +{ + "org_id": "739224", + "user_id": "string", + "expires_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteIdentitySession` + +Clears the `identity_session` cookie. Called by the portal on logout. + +`DELETE /v1/identity/session` + +```ts +const { data } = await client.deleteIdentitySession() +``` + +--- + +### `launchClient` + +One validated place for partner start links (manager UI, hosted apps). Redirects the browser to the +client's registered `initiate_login_uri` with `iss` set to this issuer and, when given, the deep lin + +`GET /v1/identity/launch/{client_id}` + +```ts +const { data } = await client.launchClient({ + client_id: 'example', + target: 'example', + extra: 'example', +}) +``` + +--- + +## Schemas + +### `Error` + +```ts +type Error = { + status: number + error: string + details?: Record[] +} +``` + +### `PartnerClientId` + +Opaque client identifier, unique within the issuer, never reused + +```ts +type PartnerClientId = string +``` + +### `OrgId` + +epilot organization id, an opaque case-sensitive string + +```ts +type OrgId = string +``` + +### `UserId` + +epilot user id (`custom:ivy_user_id` in a 360 token). A user belongs to exactly one organization. + +```ts +type UserId = string +``` + +### `Environment` + +Partner-side environment this client belongs to + +```ts +type Environment = "dev" | "staging" | "production" +``` + +### `PartnerClientStatus` + +```ts +type PartnerClientStatus = "draft" | "active" | "suspended" | "retired" +``` + +### `Scope` + +```ts +type Scope = "openid" | "email" | "profile" +``` + +### `HttpsUri` + +Absolute HTTPS URL without fragment + +```ts +type HttpsUri = string // uri +``` + +### `PartnerClientCreate` + +```ts +type PartnerClientCreate = { + partner_key: string + display_name: string + description?: string + environment: "dev" | "staging" | "production" + redirect_uris: string // uri[] + sector_identifier_uri?: string // uri + initiate_login_uri?: string // uri + launch_target_prefixes?: string[] + scopes_allowed?: "openid" | "email" | "profile"[] +} +``` + +### `PartnerClientUpdate` + +```ts +type PartnerClientUpdate = { + config_version: number + allow_sector_change?: boolean + display_name: string + description?: string + redirect_uris: string // uri[] + sector_identifier_uri?: string // uri + initiate_login_uri?: string // uri + launch_target_prefixes?: string[] + scopes_allowed: "openid" | "email" | "profile"[] +} +``` + +### `PartnerClient` + +```ts +type PartnerClient = { + client_id: string + partner_key: string + display_name: string + description?: string + environment: "dev" | "staging" | "production" + redirect_uris: string // uri[] + sector_identifier_uri?: string // uri + initiate_login_uri?: string // uri + launch_target_prefixes?: string[] + token_endpoint_auth_method: "client_secret_basic" + grant_types: "authorization_code"[] + scopes_allowed: "openid" | "email" | "profile"[] + status: "draft" | "active" | "suspended" | "retired" + status_reason?: string + config_version: number + secret_rotated_at?: string // date-time + previous_secret_expires_at?: string // date-time + created_at: string // date-time + updated_at: string // date-time + created_by?: string + updated_by?: string +} +``` + +### `PartnerClientWithSecret` + +```ts +type PartnerClientWithSecret = { + client_id: string + partner_key: string + display_name: string + description?: string + environment: "dev" | "staging" | "production" + redirect_uris: string // uri[] + sector_identifier_uri?: string // uri + initiate_login_uri?: string // uri + launch_target_prefixes?: string[] + token_endpoint_auth_method: "client_secret_basic" + grant_types: "authorization_code"[] + scopes_allowed: "openid" | "email" | "profile"[] + status: "draft" | "active" | "suspended" | "retired" + status_reason?: string + config_version: number + secret_rotated_at?: string // date-time + previous_secret_expires_at?: string // date-time + created_at: string // date-time + updated_at: string // date-time + created_by?: string + updated_by?: string + client_secret: string +} +``` + +### `PartnerClientList` + +```ts +type PartnerClientList = { + results: Array<{ + client_id: string + partner_key: string + display_name: string + description?: string + environment: "dev" | "staging" | "production" + redirect_uris: string // uri[] + sector_identifier_uri?: string // uri + initiate_login_uri?: string // uri + launch_target_prefixes?: string[] + token_endpoint_auth_method: "client_secret_basic" + grant_types: "authorization_code"[] + scopes_allowed: "openid" | "email" | "profile"[] + status: "draft" | "active" | "suspended" | "retired" + status_reason?: string + config_version: number + secret_rotated_at?: string // date-time + previous_secret_expires_at?: string // date-time + created_at: string // date-time + updated_at: string // date-time + created_by?: string + updated_by?: string + }> + next_cursor?: string +} +``` + +### `StatusChangeRequest` + +```ts +type StatusChangeRequest = { + reason?: string +} +``` + +### `RotateSecretRequest` + +```ts +type RotateSecretRequest = { + compromise_mode?: boolean + migration_window_seconds?: number +} +``` + +### `AuthorizationPolicyInput` + +```ts +type AuthorizationPolicyInput = { + mode?: "preauthorized" + population?: "all_current_org_members" + allowed_scopes: "openid" | "email" | "profile"[] + customer_approval_ref: string + approved_at?: string // date-time +} +``` + +### `AuthorizationPolicy` + +```ts +type AuthorizationPolicy = { + mode?: "preauthorized" + population?: "all_current_org_members" + allowed_scopes: "openid" | "email" | "profile"[] + customer_approval_ref: string + approved_at: string // date-time + version: number + mandatory_claims: "org_id"[] + recorded_by: string + recorded_at: string // date-time +} +``` + +### `OrgEnablementStatus` + +```ts +type OrgEnablementStatus = "active" | "suspended" | "revoked" +``` + +### `OrgEnablementCreate` + +```ts +type OrgEnablementCreate = { + org_id: string + authorization_policy: { + mode?: "preauthorized" + population?: "all_current_org_members" + allowed_scopes: "openid" | "email" | "profile"[] + customer_approval_ref: string + approved_at?: string // date-time + } +} +``` + +### `OrgEnablementUpdate` + +```ts +type OrgEnablementUpdate = { + expected_policy_version: number + authorization_policy: { + mode?: "preauthorized" + population?: "all_current_org_members" + allowed_scopes: "openid" | "email" | "profile"[] + customer_approval_ref: string + approved_at?: string // date-time + } +} +``` + +### `OrgEnablement` + +```ts +type OrgEnablement = { + client_id: string + org_id: string + status: "active" | "suspended" | "revoked" + status_reason?: string + authorization_policy: { + mode?: "preauthorized" + population?: "all_current_org_members" + allowed_scopes: "openid" | "email" | "profile"[] + customer_approval_ref: string + approved_at: string // date-time + version: number + mandatory_claims: "org_id"[] + recorded_by: string + recorded_at: string // date-time + } + created_at: string // date-time + updated_at: string // date-time + created_by?: string + updated_by?: string +} +``` + +### `OrgEnablementList` + +```ts +type OrgEnablementList = { + results: Array<{ + client_id: string + org_id: string + status: "active" | "suspended" | "revoked" + status_reason?: string + authorization_policy: { + mode?: { ... } + population?: { ... } + allowed_scopes: { ... } + customer_approval_ref: { ... } + approved_at: { ... } + version: { ... } + mandatory_claims: { ... } + recorded_by: { ... } + recorded_at: { ... } + } + created_at: string // date-time + updated_at: string // date-time + created_by?: string + updated_by?: string + }> +} +``` + +### `IdentitySession` + +```ts +type IdentitySession = { + org_id: string + user_id: string + expires_at: string // date-time +} +``` + +### `UserSubject` + +```ts +type UserSubject = { + client_id: string + org_id: string + user_id: string + sub: string + key_version: string + sector: string +} +``` diff --git a/docs/sdk/clients/integration-toolkit.md b/docs/sdk/clients/integration-toolkit.md new file mode 100644 index 00000000..4f31ab4e --- /dev/null +++ b/docs/sdk/clients/integration-toolkit.md @@ -0,0 +1,10089 @@ +--- +title: "Integration Toolkit API" +description: "TypeScript SDK client for the epilot Integration Toolkit API: usage with @epilot/sdk, all operations and schemas." +--- + +# Integration Toolkit API + +- **Base URL:** `https://integration-toolkit.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/integration-toolkit](https://docs.epilot.io/api/integration-toolkit) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.integrationToolkit.acknowledgeTracking(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/integration-toolkit' + +const integrationToolkitClient = getClient() +authorize(integrationToolkitClient, () => '') +const { data } = await integrationToolkitClient.acknowledgeTracking(...) +``` + +## Operations + +**erp** +- [`acknowledgeTracking`](#acknowledgetracking) +- [`triggerErp`](#triggererp) +- [`processErpUpdatesEventsV3`](#processerpupdateseventsv3) +- [`queryErpUpdateEvents`](#queryerpupdateevents) +- [`getErpUpdateEvent`](#geterpupdateevent) +- [`listErpUpdateCorrelations`](#listerpupdatecorrelations) +- [`simulateMappingV2`](#simulatemappingv2) +- [`simulateDirect`](#simulatedirect) +- [`simulateMapping`](#simulatemapping) + +**integrations** +- [`listIntegrations`](#listintegrations) +- [`createIntegration`](#createintegration) +- [`getIntegration`](#getintegration) +- [`updateIntegration`](#updateintegration) +- [`deleteIntegration`](#deleteintegration) +- [`queryEvents`](#queryevents) +- [`replayEvents`](#replayevents) +- [`listUseCases`](#listusecases) +- [`createUseCase`](#createusecase) +- [`getUseCase`](#getusecase) +- [`updateUseCase`](#updateusecase) +- [`deleteUseCase`](#deleteusecase) +- [`listUseCaseHistory`](#listusecasehistory) +- [`listDocumentationPages`](#listdocumentationpages) +- [`getDocumentationPage`](#getdocumentationpage) +- [`upsertDocumentationPage`](#upsertdocumentationpage) +- [`deleteDocumentationPage`](#deletedocumentationpage) +- [`listIntegrationsV2`](#listintegrationsv2) +- [`createIntegrationV2`](#createintegrationv2) +- [`getIntegrationV2`](#getintegrationv2) +- [`updateIntegrationV2`](#updateintegrationv2) +- [`deleteIntegrationV2`](#deleteintegrationv2) +- [`listNotificationHistory`](#listnotificationhistory) +- [`testSendNotification`](#testsendnotification) +- [`getNotificationStatus`](#getnotificationstatus) +- [`getSecureProxyWhitelist`](#getsecureproxywhitelist) +- [`updateSecureProxyWhitelist`](#updatesecureproxywhitelist) +- [`listSecureProxyWhitelistHistory`](#listsecureproxywhitelisthistory) +- [`setIntegrationAppMapping`](#setintegrationappmapping) +- [`deleteIntegrationAppMapping`](#deleteintegrationappmapping) +- [`getOutboundStatus`](#getoutboundstatus) +- [`getEntitySyncStatus`](#getentitysyncstatus) +- [`pollOutboundMessages`](#polloutboundmessages) +- [`ackOutboundMessages`](#ackoutboundmessages) +- [`listOutboundDlqMessages`](#listoutbounddlqmessages) +- [`redriveOutboundDlqMessages`](#redriveoutbounddlqmessages) +- [`unblockOutboundStream`](#unblockoutboundstream) +- [`simulateOutboundMapping`](#simulateoutboundmapping) +- [`listSecureProxies`](#listsecureproxies) +- [`generateTypesPreview`](#generatetypespreview) +- [`generateTypes`](#generatetypes) +- [`commitTypes`](#committypes) + +**monitoring** +- [`queryAccessLogs`](#queryaccesslogs) +- [`queryMonitoringEventsV2`](#querymonitoringeventsv2) +- [`getMonitoringStatsV2`](#getmonitoringstatsv2) +- [`getMonitoringTimeSeriesV2`](#getmonitoringtimeseriesv2) +- [`getAssociatedMonitoringEvents`](#getassociatedmonitoringevents) +- [`ingestExternalMonitoringEvents`](#ingestexternalmonitoringevents) +- [`getMonitoringTraceByCorrelation`](#getmonitoringtracebycorrelation) +- [`getMonitoringRunCompletionV2`](#getmonitoringruncompletionv2) + +**proxy** +- [`secureProxy`](#secureproxy) + +**managed-call** +- [`managedCallExecute`](#managedcallexecute) + +**erp-imports** +- [`createErpImport`](#createerpimport) +- [`listErpImports`](#listerpimports) +- [`getErpImport`](#geterpimport) +- [`deleteErpImport`](#deleteerpimport) +- [`getErpImportPreview`](#geterpimportpreview) +- [`downloadErpImportFile`](#downloaderpimportfile) +- [`validateErpImport`](#validateerpimport) +- [`suggestErpImportUseCases`](#suggesterpimportusecases) +- [`executeErpImport`](#executeerpimport) +- [`abortErpImport`](#aborterpimport) + +**Schemas** +- [`S3Reference`](#s3reference) +- [`CreateErpImportRequest`](#createerpimportrequest) +- [`ValidateErpImportRequest`](#validateerpimportrequest) +- [`ErpImportUseCaseSuggestion`](#erpimportusecasesuggestion) +- [`SuggestErpImportUseCasesResponse`](#suggesterpimportusecasesresponse) +- [`ExecuteErpImportRequest`](#executeerpimportrequest) +- [`ErpImportIssue`](#erpimportissue) +- [`ErpImportValidation`](#erpimportvalidation) +- [`ErpImportEntityDetail`](#erpimportentitydetail) +- [`ErpImportProgress`](#erpimportprogress) +- [`ErpImportError`](#erpimporterror) +- [`ErpImportFilePreview`](#erpimportfilepreview) +- [`ErpImportDownload`](#erpimportdownload) +- [`CreateErpImportResponse`](#createerpimportresponse) +- [`ErpImportJob`](#erpimportjob) +- [`ErpImportList`](#erpimportlist) +- [`NotificationHistoryItem`](#notificationhistoryitem) +- [`NotificationHistoryResponse`](#notificationhistoryresponse) +- [`TestNotificationRequest`](#testnotificationrequest) +- [`TestNotificationResponse`](#testnotificationresponse) +- [`NotificationStatusResponse`](#notificationstatusresponse) +- [`NotificationRuleStatus`](#notificationrulestatus) +- [`RuleBaselineStatus`](#rulebaselinestatus) +- [`RuleBaselineBucket`](#rulebaselinebucket) +- [`ErrorResponseBase`](#errorresponsebase) +- [`ErpEvent`](#erpevent) +- [`ErpUpdatesEventsV2Request`](#erpupdateseventsv2request) +- [`ErpEventV3`](#erpeventv3) +- [`ErpUpdatesEventsV3Request`](#erpupdateseventsv3request) +- [`ErpUpdateProcessedEntity`](#erpupdateprocessedentity) +- [`CorrelationCloseResult`](#correlationcloseresult) +- [`ErpUpdateProcessingError`](#erpupdateprocessingerror) +- [`ErpUpdateEventStatus`](#erpupdateeventstatus) +- [`CorrelationUseCaseCounts`](#correlationusecasecounts) +- [`CorrelationStatus`](#correlationstatus) +- [`CorrelationWaitResult`](#correlationwaitresult) +- [`CorrelationWaitBadRequest`](#correlationwaitbadrequest) +- [`CorrelationStatusList`](#correlationstatuslist) +- [`TriggerErpActionRequest`](#triggererpactionrequest) +- [`TriggerWebhookResp`](#triggerwebhookresp) +- [`IntegrationEditableFields`](#integrationeditablefields) +- [`ConnectorConfig`](#connectorconfig) +- [`ManagedCallAuth`](#managedcallauth) +- [`Integration`](#integration) +- [`CreateIntegrationRequest`](#createintegrationrequest) +- [`UpdateIntegrationRequest`](#updateintegrationrequest) +- [`IntegrationMap`](#integrationmap) +- [`EnvironmentFieldConfig`](#environmentfieldconfig) +- [`IntegrationSettings`](#integrationsettings) +- [`AutoRefreshSettings`](#autorefreshsettings) +- [`IntegrationNotificationConfig`](#integrationnotificationconfig) +- [`NotificationRecipient`](#notificationrecipient) +- [`NotificationChannelSet`](#notificationchannelset) +- [`NotificationRule`](#notificationrule) +- [`NotificationDigestConfig`](#notificationdigestconfig) +- [`SetIntegrationAppMappingRequest`](#setintegrationappmappingrequest) +- [`DeleteIntegrationAppMappingRequest`](#deleteintegrationappmappingrequest) +- [`IntegrationAppMapping`](#integrationappmapping) +- [`IntegrationWithUseCases`](#integrationwithusecases) +- [`UpsertIntegrationWithUseCasesRequest`](#upsertintegrationwithusecasesrequest) +- [`InboundIntegrationEventConfiguration`](#inboundintegrationeventconfiguration) +- [`OutboundIntegrationEventConfiguration`](#outboundintegrationeventconfiguration) +- [`IntegrationEntity`](#integrationentity) +- [`IntegrationEntitySharing`](#integrationentitysharing) +- [`IntegrationEntitySharingPartner`](#integrationentitysharingpartner) +- [`IntegrationEntityConditional`](#integrationentityconditional) +- [`IntegrationEntityFromRows`](#integrationentityfromrows) +- [`MappedFieldValue`](#mappedfieldvalue) +- [`IntegrationMeterReading`](#integrationmeterreading) +- [`PruneScopeConfig`](#prunescopeconfig) +- [`MeterReadingPruneScopeConfig`](#meterreadingprunescopeconfig) +- [`MeterUniqueIdsConfig`](#meteruniqueidsconfig) +- [`IntegrationEntityField`](#integrationentityfield) +- [`FileProxyUrlParam`](#fileproxyurlparam) +- [`FileProxyUrlParams`](#fileproxyurlparams) +- [`FileProxyUrlConfig`](#fileproxyurlconfig) +- [`PortalOrigin`](#portalorigin) +- [`PortalRefFilter`](#portalreffilter) +- [`PortalRefConfig`](#portalrefconfig) +- [`EnvVarRefConfig`](#envvarrefconfig) +- [`EmbeddedUseCaseRequest`](#embeddedusecaserequest) +- [`EmbeddedUseCaseRequestBase`](#embeddedusecaserequestbase) +- [`EmbeddedInboundUseCaseRequest`](#embeddedinboundusecaserequest) +- [`EmbeddedOutboundUseCaseRequest`](#embeddedoutboundusecaserequest) +- [`EmbeddedFileProxyUseCaseRequest`](#embeddedfileproxyusecaserequest) +- [`EmbeddedManagedCallUseCaseRequest`](#embeddedmanagedcallusecaserequest) +- [`EmbeddedSecureProxyUseCaseRequest`](#embeddedsecureproxyusecaserequest) +- [`UseCaseBase`](#usecasebase) +- [`InboundUseCase`](#inboundusecase) +- [`OutboundUseCase`](#outboundusecase) +- [`FileProxyUseCase`](#fileproxyusecase) +- [`ManagedCallUseCase`](#managedcallusecase) +- [`SecureProxyUseCase`](#secureproxyusecase) +- [`UseCase`](#usecase) +- [`CreateUseCaseRequest`](#createusecaserequest) +- [`CreateUseCaseRequestBase`](#createusecaserequestbase) +- [`CreateInboundUseCaseRequest`](#createinboundusecaserequest) +- [`CreateOutboundUseCaseRequest`](#createoutboundusecaserequest) +- [`CreateFileProxyUseCaseRequest`](#createfileproxyusecaserequest) +- [`CreateManagedCallUseCaseRequest`](#createmanagedcallusecaserequest) +- [`CreateSecureProxyUseCaseRequest`](#createsecureproxyusecaserequest) +- [`UpdateUseCaseRequest`](#updateusecaserequest) +- [`UpdateUseCaseRequestBase`](#updateusecaserequestbase) +- [`UpdateInboundUseCaseRequest`](#updateinboundusecaserequest) +- [`UpdateOutboundUseCaseRequest`](#updateoutboundusecaserequest) +- [`UpdateFileProxyUseCaseRequest`](#updatefileproxyusecaserequest) +- [`UpdateManagedCallUseCaseRequest`](#updatemanagedcallusecaserequest) +- [`UpdateSecureProxyUseCaseRequest`](#updatesecureproxyusecaserequest) +- [`UseCaseHistoryEntry`](#usecasehistoryentry) +- [`UseCaseHistoryEntryBase`](#usecasehistoryentrybase) +- [`InboundUseCaseHistoryEntry`](#inboundusecasehistoryentry) +- [`OutboundUseCaseHistoryEntry`](#outboundusecasehistoryentry) +- [`FileProxyUseCaseHistoryEntry`](#fileproxyusecasehistoryentry) +- [`ManagedCallUseCaseHistoryEntry`](#managedcallusecasehistoryentry) +- [`SecureProxyUseCaseHistoryEntry`](#secureproxyusecasehistoryentry) +- [`SecureProxyUseCaseConfiguration`](#secureproxyusecaseconfiguration) +- [`SecureProxyWhitelist`](#secureproxywhitelist) +- [`SecureProxyWhitelistUpdate`](#secureproxywhitelistupdate) +- [`SecureProxySummary`](#secureproxysummary) +- [`SecureProxyRequest`](#secureproxyrequest) +- [`SecureProxyResponse`](#secureproxyresponse) +- [`SecureProxyUpstreamError`](#secureproxyupstreamerror) +- [`ManagedCallOperationConfig`](#managedcalloperationconfig) +- [`ManagedCallOperation`](#managedcalloperation) +- [`ManagedCallExecuteRequest`](#managedcallexecuterequest) +- [`ManagedCallExecuteResponse`](#managedcallexecuteresponse) +- [`ManagedCallErrorResponse`](#managedcallerrorresponse) +- [`TypeAnnotations`](#typeannotations) +- [`TypeDescriptor`](#typedescriptor) +- [`UseCaseTypePreview`](#usecasetypepreview) +- [`GenerateTypesPreviewResponse`](#generatetypespreviewresponse) +- [`GenerateTypesRequest`](#generatetypesrequest) +- [`GenerateTypesResponse`](#generatetypesresponse) +- [`CommitTypesRequest`](#committypesrequest) +- [`CommitTypesResponse`](#committypesresponse) +- [`FileProxyUseCaseConfiguration`](#fileproxyusecaseconfiguration) +- [`FileProxySecureProxyAttachment`](#fileproxysecureproxyattachment) +- [`FileProxyAuth`](#fileproxyauth) +- [`FileProxyParam`](#fileproxyparam) +- [`FileProxyStep`](#fileproxystep) +- [`FileProxyFanOutConfig`](#fileproxyfanoutconfig) +- [`FileProxyUploadConfig`](#fileproxyuploadconfig) +- [`FileProxyResponseConfig`](#fileproxyresponseconfig) +- [`MappingSimulationRequest`](#mappingsimulationrequest) +- [`MappingSimulationV2Request`](#mappingsimulationv2request) +- [`MappingSimulationResponse`](#mappingsimulationresponse) +- [`MappingSimulationWarning`](#mappingsimulationwarning) +- [`DirectPayload`](#directpayload) +- [`DirectEntityOperation`](#directentityoperation) +- [`DirectMeterReadingOperation`](#directmeterreadingoperation) +- [`DirectRelationValue`](#directrelationvalue) +- [`DirectRelationItem`](#directrelationitem) +- [`DirectRelationRefValue`](#directrelationrefvalue) +- [`DirectRelationRefItem`](#directrelationrefitem) +- [`DirectSimulationRequest`](#directsimulationrequest) +- [`DirectSimulationResponse`](#directsimulationresponse) +- [`DirectSimulationError`](#directsimulationerror) +- [`EntityUpdate`](#entityupdate) +- [`MeterReadingUpdate`](#meterreadingupdate) +- [`EntityPruneScopeUpdate`](#entityprunescopeupdate) +- [`MeterReadingPruneScopeUpdate`](#meterreadingprunescopeupdate) +- [`IntegrationConfigurationV1`](#integrationconfigurationv1) +- [`IntegrationObjectV1`](#integrationobjectv1) +- [`IntegrationFieldV1`](#integrationfieldv1) +- [`IntegrationConfigurationV2`](#integrationconfigurationv2) +- [`OutboundMapping`](#outboundmapping) +- [`DeliveryConfig`](#deliveryconfig) +- [`WebhookDeliveryConfig`](#webhookdeliveryconfig) +- [`PollDeliveryConfig`](#polldeliveryconfig) +- [`FileProxyDeliveryConfig`](#fileproxydeliveryconfig) +- [`EntitySyncStatusResponse`](#entitysyncstatusresponse) +- [`EntitySyncState`](#entitysyncstate) +- [`OutboundStatusResponse`](#outboundstatusresponse) +- [`OutboundUseCaseStatus`](#outboundusecasestatus) +- [`OutboundFileProxyTargetStatus`](#outboundfileproxytargetstatus) +- [`OutboundPollStatus`](#outboundpollstatus) +- [`WebhookStatus`](#webhookstatus) +- [`OutboundConflict`](#outboundconflict) +- [`PollOutboundMessagesRequest`](#polloutboundmessagesrequest) +- [`OutboundMessage`](#outboundmessage) +- [`PollOutboundMessagesResponse`](#polloutboundmessagesresponse) +- [`AckOutboundMessagesRequest`](#ackoutboundmessagesrequest) +- [`AckResult`](#ackresult) +- [`AckOutboundMessagesResponse`](#ackoutboundmessagesresponse) +- [`OutboundDlqMessage`](#outbounddlqmessage) +- [`OutboundDlqListResponse`](#outbounddlqlistresponse) +- [`RedriveOutboundDlqRequest`](#redriveoutbounddlqrequest) +- [`RedriveOutboundDlqResult`](#redriveoutbounddlqresult) +- [`RedriveOutboundDlqResponse`](#redriveoutbounddlqresponse) +- [`UnblockOutboundStreamRequest`](#unblockoutboundstreamrequest) +- [`UnblockOutboundStreamResponse`](#unblockoutboundstreamresponse) +- [`SimulateOutboundMappingRequest`](#simulateoutboundmappingrequest) +- [`OutboundMappingSimulationError`](#outboundmappingsimulationerror) +- [`SimulateOutboundMappingResponse`](#simulateoutboundmappingresponse) +- [`RelationConfig`](#relationconfig) +- [`RelationItemConfig`](#relationitemconfig) +- [`RelationUniqueIdField`](#relationuniqueidfield) +- [`RelationRefsConfig`](#relationrefsconfig) +- [`RelationRefItemConfig`](#relationrefitemconfig) +- [`RelationRefValueConfig`](#relationrefvalueconfig) +- [`RepeatableFieldType`](#repeatablefieldtype) +- [`ReplayEventsRequest`](#replayeventsrequest) +- [`QueryEventsRequest`](#queryeventsrequest) +- [`QueryInboundMonitoringEventsRequest`](#queryinboundmonitoringeventsrequest) +- [`QueryAccessLogsRequest`](#queryaccesslogsrequest) +- [`AccessLogEntry`](#accesslogentry) +- [`GetMonitoringStatsRequest`](#getmonitoringstatsrequest) +- [`GetMonitoringTimeSeriesRequest`](#getmonitoringtimeseriesrequest) +- [`TimeSeriesBucket`](#timeseriesbucket) +- [`QueryOutboundMonitoringEventsRequest`](#queryoutboundmonitoringeventsrequest) +- [`OutboundMonitoringEvent`](#outboundmonitoringevent) +- [`MonitoringStats`](#monitoringstats) +- [`InboundMonitoringEvent`](#inboundmonitoringevent) +- [`QueryMonitoringEventsV2Request`](#querymonitoringeventsv2request) +- [`ExternalMonitoringSpan`](#externalmonitoringspan) +- [`IngestExternalMonitoringEventsRequest`](#ingestexternalmonitoringeventsrequest) +- [`IngestExternalMonitoringEventsResponse`](#ingestexternalmonitoringeventsresponse) +- [`MonitoringTraceResponse`](#monitoringtraceresponse) +- [`MonitoringCode`](#monitoringcode) +- [`MonitoringEventV2`](#monitoringeventv2) +- [`GetMonitoringStatsV2Request`](#getmonitoringstatsv2request) +- [`GetMonitoringRunCompletionV2Request`](#getmonitoringruncompletionv2request) +- [`MonitoringRunCompletionV2Response`](#monitoringruncompletionv2response) +- [`MonitoringRunCompletionV2`](#monitoringruncompletionv2) +- [`MonitoringRunEntriesV2`](#monitoringrunentriesv2) +- [`MonitoringStatsV2`](#monitoringstatsv2) +- [`GetMonitoringTimeSeriesV2Request`](#getmonitoringtimeseriesv2request) +- [`TimeSeriesBreakdownItemV2`](#timeseriesbreakdownitemv2) +- [`TimeSeriesBucketV2`](#timeseriesbucketv2) +- [`DocumentationPageSummary`](#documentationpagesummary) +- [`DocumentationPage`](#documentationpage) +- [`UpsertDocumentationPageRequest`](#upsertdocumentationpagerequest) + +### `acknowledgeTracking` + +Acknowledges an ERP tracking record by removing it from the tracking table, requires public authentication + +`POST /v1/erp/tracking/acknowledgement` + +```ts +const { data } = await client.acknowledgeTracking( + null, + { + ack_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `triggerErp` + +Triggers the ERP integration process + +`POST /v1/erp/trigger` + +```ts +const { data } = await client.triggerErp( + null, + { + execution_id: 'string', + org_id: 'string', + webhook_id: 'string', + flow_id: 'string', + created_at: '1970-01-01T00:00:00.000Z', + action_id: 'string', + flow_action_id: 'string', + flow_name: 'string', + activity_id: 'string', + entity_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "status_code": "string", + "message": "string", + "body": {}, + "code": "string", + "status": "succeeded", + "start_date": "string", + "end_date": "string", + "event_id": "string" +} +``` + +
+ +--- + +### `processErpUpdatesEventsV3` + +Handles updates from ERP systems using integration_id directly. +This is the v3 version that removes the unused event_type field and renames object_type to event_name +to align with the integration UI n + +`POST /v3/erp/updates/events` + +```ts +const { data } = await client.processErpUpdatesEventsV3( + null, + { + integration_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + correlation_id: 'string', + group_id: 'customer-42', + interactive: true, + correlation_complete: true, + events: [ + {}, + {} + ] + }, +) +``` + +
+Response + +```json +{ + "correlation_id": "string", + "correlation_close": { + "outcome": "applied", + "reasons": ["retry_requested"], + "message": "string" + }, + "results": [ + { + "event_id": "string", + "status": "success", + "interactive": true, + "lane": "interactive", + "message": "string" + } + ] +} +``` + +
+ +--- + +### `queryErpUpdateEvents` + +Waits for the events of one correlation — the long poll behind interactive +registration — and returns the correlation's summary. + +`GET /v3/erp/updates/events` + +```ts +const { data } = await client.queryErpUpdateEvents({ + correlation_id: 'example', + wait: 1, + wait_for_entities: ['...'], + wait_for_use_cases: ['...'], +}) +``` + +
+Response + +```json +{ + "correlation_id": "string", + "integration_id": "string", + "closed": true, + "closed_at": "1970-01-01T00:00:00.000Z", + "complete": true, + "completed_at": "1970-01-01T00:00:00.000Z", + "events_received": 0, + "events_done": 0, + "late_events": 0, + "first_ingested_at": "1970-01-01T00:00:00.000Z", + "last_done_at": "1970-01-01T00:00:00.000Z", + "use_cases": [ + { + "use_case_slug": "string", + "received": 0, + "done": 0, + "error": 0 + } + ], + "entities": [ + { + "slug": "contact", + "_id": "string", + "operation": "created", + "unique_ids": { + "reenumber": "4711" + } + } + ], + "entities_omitted": 0, + "errors": [ + { + "code": "string", + "message": "string", + "event_id": "string", + "occurred_at": "1970-01-01T00:00:00.000Z", + "after_completion": true + } + ], + "errors_total": 0, + "completion": "requirements_met", + "undecided_entity_requirements": ["contract[billing_account_number=4711]"] +} +``` + +
+ +--- + +### `getErpUpdateEvent` + +Returns one interactive event's processing record, without waiting. + +`GET /v3/erp/updates/events/{event_id}` + +```ts +const { data } = await client.getErpUpdateEvent({ + event_id: 'example', +}) +``` + +
+Response + +```json +{ + "event_id": "string", + "correlation_id": "string", + "integration_id": "string", + "status": "accepted", + "lane": "interactive", + "use_case_id": "string", + "use_case_slug": "string", + "event_name": "string", + "ingested_at": "1970-01-01T00:00:00.000Z", + "mapped_at": "1970-01-01T00:00:00.000Z", + "done_at": "1970-01-01T00:00:00.000Z", + "writes_total": 0, + "writes_done": 0, + "entities": [ + { + "slug": "contact", + "_id": "string", + "operation": "created", + "unique_ids": { + "reenumber": "4711" + } + } + ], + "entities_omitted": 0, + "errors": [ + { + "code": "string", + "message": "string", + "event_id": "string", + "occurred_at": "1970-01-01T00:00:00.000Z", + "after_completion": true + } + ], + "errors_total": 0 +} +``` + +
+ +--- + +### `listErpUpdateCorrelations` + +Lists the organization's interactive correlations, newest first by the time +their first event was ingested, with the same summary the correlation wait +returns. + +`GET /v3/erp/updates/correlations` + +```ts +const { data } = await client.listErpUpdateCorrelations({ + integration_id: 'example', + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "correlation_id": "string", + "integration_id": "string", + "closed": true, + "closed_at": "1970-01-01T00:00:00.000Z", + "complete": true, + "completed_at": "1970-01-01T00:00:00.000Z", + "events_received": 0, + "events_done": 0, + "late_events": 0, + "first_ingested_at": "1970-01-01T00:00:00.000Z", + "last_done_at": "1970-01-01T00:00:00.000Z", + "use_cases": [ + { + "use_case_slug": "string", + "received": 0, + "done": 0, + "error": 0 + } + ], + "entities": [ + { + "slug": "contact", + "_id": "string", + "operation": "created", + "unique_ids": { + "reenumber": "4711" + } + } + ], + "entities_omitted": 0, + "errors": [ + { + "code": "string", + "message": "string", + "event_id": "string", + "occurred_at": "1970-01-01T00:00:00.000Z", + "after_completion": true + } + ], + "errors_total": 0 + } + ], + "next_cursor": "string", + "horizon_days": 7 +} +``` + +
+ +--- + +### `simulateMappingV2` + +Test v2.0 mapping configuration by transforming a payload using the provided mapping rules without persisting data. + +`POST /v2/erp/updates/mapping_simulation` + +```ts +const { data } = await client.simulateMappingV2( + null, + { + event_configuration: { + direct: true, + interactive: 'on_request', + entities: [ + { /* ... */ } + ], + meter_readings: [ + { /* ... */ } + ] + }, + format: 'json', + payload: 'string' + }, +) +``` + +
+Response + +```json +{ + "entity_updates": [ + { + "entity_slug": "string", + "unique_identifiers": {}, + "attributes": {}, + "pricing": { + "config": {}, + "data": [ + {} + ] + }, + "sharing": {}, + "mode": "upsert" + } + ], + "meter_readings_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "attributes": {}, + "mode": "upsert" + } + ], + "prune_scope_updates": [ + { + "entity_slug": "string", + "scope": { + "scope_mode": "relations", + "schema": "string", + "unique_ids": {}, + "query": {} + }, + "keep_unique_ids": [ + {} + ], + "deletion_mode": "delete" + } + ], + "meter_readings_prune_scope_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "keep_external_ids": ["string"], + "source": "string" + } + ], + "warnings": [ + { + "entity_schema": "string", + "field": "string", + "message": "string" + } + ] +} +``` + +
+ +--- + +### `simulateDirect` + +Dry run for direct-mode payloads: validates a `DirectPayload` against a `direct: true` +use case configuration and previews the internal entity and meter reading updates the +pipeline would apply — with + +`POST /v1/erp/updates/direct_simulation` + +```ts +const { data } = await client.simulateDirect( + null, + { + event_configuration: { + direct: true, + interactive: 'on_request', + entities: [ + { /* ... */ } + ], + meter_readings: [ + { /* ... */ } + ] + }, + payload: 'string' + }, +) +``` + +
+Response + +```json +{ + "valid": true, + "errors": [ + { + "code": "DIRECT_PAYLOAD_INVALID", + "message": "string", + "operation_index": 0 + } + ], + "warnings": [ + { + "entity_schema": "string", + "field": "string", + "message": "string" + } + ], + "entity_updates": [ + { + "entity_slug": "string", + "unique_identifiers": {}, + "attributes": {}, + "pricing": { + "config": {}, + "data": [ + {} + ] + }, + "sharing": {}, + "mode": "upsert", + "unique_identifiers_metadata": {} + } + ], + "meter_reading_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "attributes": {}, + "mode": "upsert", + "_config": { + "reading_matching": "external_id" + } + } + ] +} +``` + +
+ +--- + +### `simulateMapping` + +Test mapping configuration by transforming a payload using the provided mapping rules without persisting data. + +`POST /v1/erp/updates/mapping_simulation` + +```ts +const { data } = await client.simulateMapping( + null, + { + mapping_configuration: { + version: '1.0', + mapping: { + objects: {} + } + }, + object_type: 'string', + format: 'json', + payload: 'string' + }, +) +``` + +
+Response + +```json +{ + "entity_updates": [ + { + "entity_slug": "string", + "unique_identifiers": {}, + "attributes": {}, + "pricing": { + "config": {}, + "data": [ + {} + ] + }, + "sharing": {}, + "mode": "upsert" + } + ], + "meter_readings_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "attributes": {}, + "mode": "upsert" + } + ], + "prune_scope_updates": [ + { + "entity_slug": "string", + "scope": { + "scope_mode": "relations", + "schema": "string", + "unique_ids": {}, + "query": {} + }, + "keep_unique_ids": [ + {} + ], + "deletion_mode": "delete" + } + ], + "meter_readings_prune_scope_updates": [ + { + "meter": { + "$entity_unique_ids": {} + }, + "meter_counter": { + "$entity_unique_ids": {} + }, + "keep_external_ids": ["string"], + "source": "string" + } + ], + "warnings": [ + { + "entity_schema": "string", + "field": "string", + "message": "string" + } + ] +} +``` + +
+ +--- + +### `listIntegrations` + +Retrieve all integrations for the authenticated organization + +`GET /v1/integrations` + +```ts +const { data } = await client.listIntegrations() +``` + +
+Response + +```json +{ + "integrations": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [], + "maps": [], + "settings": {}, + "integration_type": "erp", + "connector_config": {}, + "protected": true, + "_manifest": ["string"] + } + ] +} +``` + +
+ +--- + +### `createIntegration` + +Create a new integration configuration + +`POST /v1/integrations` + +```ts +const { data } = await client.createIntegration( + null, + { + name: 'string', + description: 'string', + access_token_ids: ['string'], + app_ids: ['string'], + environment_config: [ + { + key: 'string', + label: 'string', + type: 'String', + description: 'string', + required: false, + order: 0 + } + ], + maps: [ + { + key: 'string', + label: 'string', + description: 'string', + value: {} + } + ], + settings: { + autoRefresh: { + enabled: false, + freshnessThresholdMinutes: 1 + }, + notifications: { + enabled: true, + recipients: [ /* ... */ ], + defaultChannels: { /* ... */ }, + monitoredUseCases: ['string'], + monitoredCodes: ['string'], + rules: [ /* ... */ ], + digest: { /* ... */ }, + muteUntil: '1970-01-01T00:00:00.000Z' + } + }, + integration_type: 'erp', + connector_config: { + base_url: 'string', + auth: { + type: 'oauth2_client_credentials', + token_url: 'string', + client_id: 'string', + client_secret: 'string', + scope: 'string', + audience: 'string', + resource: 'string', + body_params: {}, + headers: {}, + query_params: {}, + api_key_header: 'string', + api_key: 'string', + token: 'string' + }, + types_versions: [ + { /* ... */ } + ], + latest_types_version: 'string', + latest_types_package_name: 'string' + }, + protected: true, + _manifest: ['string'] + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"] +} +``` + +
+ +--- + +### `getIntegration` + +Retrieve a specific integration by its ID + +`GET /v1/integrations/{integrationId}` + +```ts +const { data } = await client.getIntegration({ + integrationId: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"] +} +``` + +
+ +--- + +### `updateIntegration` + +Update an existing integration configuration + +`PUT /v1/integrations/{integrationId}` + +```ts +const { data } = await client.updateIntegration( + { + integrationId: 'example', + }, + {}, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"] +} +``` + +
+ +--- + +### `deleteIntegration` + +Delete an integration and all its use cases + +`DELETE /v1/integrations/{integrationId}` + +```ts +const { data } = await client.deleteIntegration({ + integrationId: 'example', +}) +``` + +
+Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `queryEvents` + +Query events for a specific integration + +`POST /v1/integrations/{integrationId}/events` + +```ts +const { data } = await client.queryEvents( + { + integrationId: 'example', + }, + { + event_id: 'string', + event_type: 'CREATE', + correlation_id: 'string', + object_type: 'string', + event_name: 'string', + use_case_id: 'string', + limit: 25, + cursor: { + event_time: '2025-10-31T12:34:56Z', + event_id: 'evt_1234567890abcdef' + } + }, +) +``` + +
+Response + +```json +{ + "data": [ + { + "event_type": "CREATE", + "object_type": "string", + "timestamp": "1970-01-01T00:00:00.000Z", + "format": "json", + "payload": "string", + "deduplication_id": "evt-2025-05-01-12345-create-bp", + "correlation_id": "bp-8f3a2c-7d4e-4b1a-9c2f-1e6d5a4b3c21", + "use_case_id": "string" + } + ], + "next_cursor": { + "event_time": "2025-10-31T12:34:56Z", + "event_id": "evt_1234567890abcdef" + }, + "has_more": true +} +``` + +
+ +--- + +### `replayEvents` + +Replay one or more events for a specific integration. Events will be re-processed with their original payloads but with a new correlation ID for traceability. + +`POST /v1/integrations/{integrationId}/events/replay` + +```ts +const { data } = await client.replayEvents( + { + integrationId: 'example', + }, + { + event_ids: ['string'] + }, +) +``` + +
+Response + +```json +{ + "replayed": 2, + "results": [ + { + "event_id": "string", + "status": "success", + "replay_event_id": "string", + "message": "string" + } + ], + "event_ids": ["string"] +} +``` + +
+ +--- + +### `listUseCases` + +Retrieve all use cases for a specific integration + +`GET /v1/integrations/{integrationId}/use-cases` + +```ts +const { data } = await client.listUseCases({ + integrationId: 'example', +}) +``` + +
+Response + +```json +{ + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": {} + } + ] +} +``` + +
+ +--- + +### `createUseCase` + +Create a new use case for an integration + +`POST /v1/integrations/{integrationId}/use-cases` + +```ts +const { data } = await client.createUseCase( + { + integrationId: 'example', + }, + { + name: 'string', + slug: 'string', + enabled: true, + type: 'inbound', + configuration: { + direct: true, + interactive: 'on_request', + entities: [ + { /* ... */ } + ], + meter_readings: [ + { /* ... */ } + ] + } + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": { + "direct": true, + "interactive": "on_request", + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + } +} +``` + +
+ +--- + +### `getUseCase` + +Retrieve a specific use case by its ID + +`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}` + +```ts +const { data } = await client.getUseCase({ + integrationId: 'example', + useCaseId: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": { + "direct": true, + "interactive": "on_request", + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + } +} +``` + +
+ +--- + +### `updateUseCase` + +Update an existing use case configuration + +`PUT /v1/integrations/{integrationId}/use-cases/{useCaseId}` + +```ts +const { data } = await client.updateUseCase( + { + integrationId: 'example', + useCaseId: 'example', + }, + { + name: 'string', + slug: 'string', + enabled: true, + change_description: 'string', + type: 'inbound', + configuration: { + direct: true, + interactive: 'on_request', + entities: [ + { /* ... */ } + ], + meter_readings: [ + { /* ... */ } + ] + } + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": { + "direct": true, + "interactive": "on_request", + "entities": [ + {} + ], + "meter_readings": [ + {} + ] + } +} +``` + +
+ +--- + +### `deleteUseCase` + +Delete a use case from an integration + +`DELETE /v1/integrations/{integrationId}/use-cases/{useCaseId}` + +```ts +const { data } = await client.deleteUseCase({ + integrationId: 'example', + useCaseId: 'example', +}) +``` + +
+Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `listUseCaseHistory` + +Retrieve historical versions of a use case's configuration. +History entries are returned in reverse chronological order (newest first). +Use the 'cursor' parameter for pagination to fetch additional en + +`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}/history` + +```ts +const { data } = await client.listUseCaseHistory({ + integrationId: 'example', + useCaseId: 'example', + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "history": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "history_created_at": "1970-01-01T00:00:00.000Z", + "type": "inbound", + "configuration": {} + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `listDocumentationPages` + +Retrieve all documentation pages of an integration, without their markdown content. +An integration has at most one general page plus at most one page per use case. +The page id is 'general' for the int + +`GET /v1/integrations/{integrationId}/documentation` + +```ts +const { data } = await client.listDocumentationPages({ + integrationId: 'example', +}) +``` + +
+Response + +```json +{ + "pages": [ + { + "id": "general", + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "scope": "integration", + "use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string" + } + ] +} +``` + +
+ +--- + +### `getDocumentationPage` + +Retrieve a single documentation page including its markdown content + +`GET /v1/integrations/{integrationId}/documentation/{docId}` + +```ts +const { data } = await client.getDocumentationPage({ + integrationId: 'example', + docId: 'example', +}) +``` + +
+Response + +```json +{ + "id": "general", + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "scope": "integration", + "use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "content": "string" +} +``` + +
+ +--- + +### `upsertDocumentationPage` + +Create or update the documentation page identified by docId. +Upsert semantics enforce the invariant of one general page per +integration and one page per use case. For use case pages the +use case must + +`PUT /v1/integrations/{integrationId}/documentation/{docId}` + +```ts +const { data } = await client.upsertDocumentationPage( + { + integrationId: 'example', + docId: 'example', + }, + { + title: 'string', + content: 'string' + }, +) +``` + +
+Response + +```json +{ + "id": "general", + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "scope": "integration", + "use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "title": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "updated_by": "string", + "content": "string" +} +``` + +
+ +--- + +### `deleteDocumentationPage` + +Delete a documentation page + +`DELETE /v1/integrations/{integrationId}/documentation/{docId}` + +```ts +const { data } = await client.deleteDocumentationPage({ + integrationId: 'example', + docId: 'example', +}) +``` + +
+Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `listIntegrationsV2` + +Retrieve all integrations with embedded use cases for the authenticated organization + +`GET /v2/integrations` + +```ts +const { data } = await client.listIntegrationsV2() +``` + +
+Response + +```json +{ + "integrations": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [], + "maps": [], + "settings": {}, + "integration_type": "erp", + "connector_config": {}, + "protected": true, + "_manifest": ["string"], + "use_cases": [] + } + ] +} +``` + +
+ +--- + +### `createIntegrationV2` + +Create a new integration with embedded use cases. + +`POST /v2/integrations` + +```ts +const { data } = await client.createIntegrationV2( + null, + { + name: 'string', + description: 'string', + access_token_ids: ['string'], + app_ids: ['string'], + environment_config: [ + { + key: 'string', + label: 'string', + type: 'String', + description: 'string', + required: false, + order: 0 + } + ], + maps: [ + { + key: 'string', + label: 'string', + description: 'string', + value: {} + } + ], + settings: { + autoRefresh: { + enabled: false, + freshnessThresholdMinutes: 1 + }, + notifications: { + enabled: true, + recipients: [ /* ... */ ], + defaultChannels: { /* ... */ }, + monitoredUseCases: ['string'], + monitoredCodes: ['string'], + rules: [ /* ... */ ], + digest: { /* ... */ }, + muteUntil: '1970-01-01T00:00:00.000Z' + } + }, + integration_type: 'erp', + connector_config: { + base_url: 'string', + auth: { + type: 'oauth2_client_credentials', + token_url: 'string', + client_id: 'string', + client_secret: 'string', + scope: 'string', + audience: 'string', + resource: 'string', + body_params: {}, + headers: {}, + query_params: {}, + api_key_header: 'string', + api_key: 'string', + token: 'string' + }, + types_versions: [ + { /* ... */ } + ], + latest_types_version: 'string', + latest_types_package_name: 'string' + }, + protected: true, + _manifest: ['string'], + use_cases: [ + { + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + slug: 'string', + enabled: true, + change_description: 'string', + type: 'inbound', + configuration: { /* ... */ } + } + ] + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"], + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": {} + } + ] +} +``` + +
+ +--- + +### `getIntegrationV2` + +Retrieve a specific integration with all its embedded use cases + +`GET /v2/integrations/{integrationId}` + +```ts +const { data } = await client.getIntegrationV2({ + integrationId: 'example', +}) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"], + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": {} + } + ] +} +``` + +
+ +--- + +### `updateIntegrationV2` + +Update an existing integration with embedded use cases. +The integration must already exist. +Use cases are updated declaratively: +- Use cases in the request with matching IDs are updated +- Use cases in + +`PUT /v2/integrations/{integrationId}` + +```ts +const { data } = await client.updateIntegrationV2( + { + integrationId: 'example', + }, + { + name: 'string', + description: 'string', + access_token_ids: ['string'], + app_ids: ['string'], + environment_config: [ + { + key: 'string', + label: 'string', + type: 'String', + description: 'string', + required: false, + order: 0 + } + ], + maps: [ + { + key: 'string', + label: 'string', + description: 'string', + value: {} + } + ], + settings: { + autoRefresh: { + enabled: false, + freshnessThresholdMinutes: 1 + }, + notifications: { + enabled: true, + recipients: [ /* ... */ ], + defaultChannels: { /* ... */ }, + monitoredUseCases: ['string'], + monitoredCodes: ['string'], + rules: [ /* ... */ ], + digest: { /* ... */ }, + muteUntil: '1970-01-01T00:00:00.000Z' + } + }, + integration_type: 'erp', + connector_config: { + base_url: 'string', + auth: { + type: 'oauth2_client_credentials', + token_url: 'string', + client_id: 'string', + client_secret: 'string', + scope: 'string', + audience: 'string', + resource: 'string', + body_params: {}, + headers: {}, + query_params: {}, + api_key_header: 'string', + api_key: 'string', + token: 'string' + }, + types_versions: [ + { /* ... */ } + ], + latest_types_version: 'string', + latest_types_package_name: 'string' + }, + protected: true, + _manifest: ['string'], + use_cases: [ + { + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + slug: 'string', + enabled: true, + change_description: 'string', + type: 'inbound', + configuration: { /* ... */ } + } + ] + }, +) +``` + +
+Response + +```json +{ + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "orgId": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "name": "string", + "description": "string", + "access_token_ids": ["string"], + "app_ids": ["string"], + "environment_config": [ + { + "key": "string", + "label": "string", + "type": "String", + "description": "string", + "required": false, + "order": 0 + } + ], + "maps": [ + { + "key": "string", + "label": "string", + "description": "string", + "value": {} + } + ], + "settings": { + "autoRefresh": { + "enabled": false, + "freshnessThresholdMinutes": 1 + }, + "notifications": { + "enabled": true, + "recipients": [], + "defaultChannels": {}, + "monitoredUseCases": ["string"], + "monitoredCodes": ["string"], + "rules": [], + "digest": {}, + "muteUntil": "1970-01-01T00:00:00.000Z" + } + }, + "integration_type": "erp", + "connector_config": { + "base_url": "string", + "auth": { + "type": "oauth2_client_credentials", + "token_url": "string", + "client_id": "string", + "client_secret": "string", + "scope": "string", + "audience": "string", + "resource": "string", + "body_params": {}, + "headers": {}, + "query_params": {}, + "api_key_header": "string", + "api_key": "string", + "token": "string" + }, + "types_versions": [ + {} + ], + "latest_types_version": "string", + "latest_types_package_name": "string" + }, + "protected": true, + "_manifest": ["string"], + "use_cases": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "type": "inbound", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "configuration": {} + } + ] +} +``` + +
+ +--- + +### `deleteIntegrationV2` + +Delete an integration and all its use cases + +`DELETE /v2/integrations/{integrationId}` + +```ts +const { data } = await client.deleteIntegrationV2({ + integrationId: 'example', +}) +``` + +
+Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `listNotificationHistory` + +Returns the cursor-paginated, newest-first notification history for an +integration (every real notification decision — both fired and suppressed). +Requires the `integration:view` permission on the int + +`GET /v2/integrations/{integrationId}/notifications/history` + +```ts +const { data } = await client.listNotificationHistory({ + integrationId: 'example', + cursor: 'example', + limit: 1, + type: 'example', +}) +``` + +
+Response + +```json +{ + "history": [ + { + "id": "string", + "type": "string", + "state_transition": "string", + "severity": "error", + "title": "string", + "occurred_at": "1970-01-01T00:00:00.000Z", + "notified": true, + "suppressed_reason": "muted", + "recipients": ["string"], + "context": {}, + "created_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `testSendNotification` + +Renders and sends ONE representative notification of the requested kind/type to +the CALLING USER ONLY (never any other recipient), so an operator can preview how +a notification looks. A test send does + +`POST /v2/integrations/{integrationId}/notifications/test` + +```ts +const { data } = await client.testSendNotification( + { + integrationId: 'example', + }, + { + kind: 'alert', + type: 'string', + channels: ['email'] + }, +) +``` + +--- + +### `getNotificationStatus` + +Returns the live per-rule alert state and (for 'auto' rules) the current +hour-of-week baseline band for an integration's notification monitoring. +Reflects the latest 5-minute sweep — near-real-time, n + +`GET /v2/integrations/{integrationId}/notifications/status` + +```ts +const { data } = await client.getNotificationStatus({ + integrationId: 'example', + include: 'example', +}) +``` + +
+Response + +```json +{ + "health": "healthy", + "evaluated_at": "1970-01-01T00:00:00.000Z", + "rules": [ + { + "rule_id": "string", + "state": "ok", + "last_fired_at": "1970-01-01T00:00:00.000Z", + "last_cleared_at": "1970-01-01T00:00:00.000Z", + "last_evaluation": { + "evaluated_at": "1970-01-01T00:00:00.000Z", + "observed": 0, + "threshold": 0, + "suppressed_reason": "sample_size" + }, + "baseline": { + "is_mature": true, + "computed_at": "1970-01-01T00:00:00.000Z", + "median": 0, + "mad": 0, + "upper": 0, + "buckets": [ + { + "dow": 1, + "hour": 0, + "median": 0, + "mad": 0 + } + ] + } + } + ] +} +``` + +
+ +--- + +### `getSecureProxyWhitelist` + +Returns the current allowed_domains, allowed_ips, and vpc_mode for a secure_proxy use case. +Staff-only — gated by internal-auth issuer AND admin-portal Cognito user pool membership. +Rejects Login-As t + +`GET /v2/integrations/{integrationId}/use-cases/{useCaseId}/secure-proxy-whitelist` + +```ts +const { data } = await client.getSecureProxyWhitelist({ + integrationId: 'example', + useCaseId: 'example', +}) +``` + +
+Response + +```json +{ + "vpc_mode": "static_ip", + "allowed_domains": ["string"], + "allowed_ips": ["string"] +} +``` + +
+ +--- + +### `updateSecureProxyWhitelist` + +Replaces allowed_domains and/or allowed_ips on a secure_proxy use case. +At least one of the two fields is required. Validation mirrors the CLI's +`validateDomainPatterns` / `validateCidrs`. Writes a US + +`PUT /v2/integrations/{integrationId}/use-cases/{useCaseId}/secure-proxy-whitelist` + +```ts +const { data } = await client.updateSecureProxyWhitelist( + { + integrationId: 'example', + useCaseId: 'example', + }, + { + allowed_domains: ['string'], + allowed_ips: ['string'] + }, +) +``` + +
+Response + +```json +{ + "vpc_mode": "static_ip", + "allowed_domains": ["string"], + "allowed_ips": ["string"] +} +``` + +
+ +--- + +### `listSecureProxyWhitelistHistory` + +Returns the most recent USECASE_HISTORY entries for a secure_proxy use case, +in reverse chronological order (newest first). Each entry includes the +actor email (`changed_by`), the ISO-8601 timestamp ( + +`GET /v2/integrations/{integrationId}/use-cases/{useCaseId}/secure-proxy-whitelist/history` + +```ts +const { data } = await client.listSecureProxyWhitelistHistory({ + integrationId: 'example', + useCaseId: 'example', + limit: 1, +}) +``` + +
+Response + +```json +{ + "history": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integrationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "enabled": true, + "change_description": "string", + "changed_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "history_created_at": "1970-01-01T00:00:00.000Z", + "type": "secure_proxy", + "configuration": { + "vpc_mode": "static_ip", + "allowed_domains": ["string"], + "allowed_ips": ["string"] + } + } + ] +} +``` + +
+ +--- + +### `setIntegrationAppMapping` + +Creates or updates a mapping from an app/component to an integration. +This allows ERP updates sent via app_id and component_id to be associated +with a specific integration configuration. + +`PUT /v1/integrations/{integrationId}/app-mapping` + +```ts +const { data } = await client.setIntegrationAppMapping( + { + integrationId: 'example', + }, + { + app_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + component_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + overwrite: false + }, +) +``` + +
+Response + +```json +{ + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" +} +``` + +
+ +--- + +### `deleteIntegrationAppMapping` + +Removes a mapping from an app/component to an integration. + +`DELETE /v1/integrations/{integrationId}/app-mapping` + +```ts +const { data } = await client.deleteIntegrationAppMapping( + { + integrationId: 'example', + }, + { + app_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + component_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + }, +) +``` + +
+Response + +```json +{ + "message": "string" +} +``` + +
+ +--- + +### `getOutboundStatus` + +Get the status of all outbound use cases for a specific integration. +Returns conflict information when events or webhooks are disabled but the use case is enabled. + +`GET /v1/integrations/{integrationId}/outbound-status` + +```ts +const { data } = await client.getOutboundStatus({ + integrationId: 'example', +}) +``` + +
+Response + +```json +{ + "useCases": [ + { + "useCaseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "useCaseEnabled": true, + "eventCatalogEvent": "contract.created", + "eventEnabled": true, + "webhooks": [ + { + "webhookId": "string", + "webhookName": "string", + "enabled": true + } + ], + "status": "ok", + "conflicts": [ + { + "type": "event_disabled", + "webhookId": "string", + "message": "string" + } + ], + "poll": { + "queue_depth": 0, + "oldest_unconsumed_age_seconds": 0, + "last_poll_at": "1970-01-01T00:00:00.000Z", + "last_ack_at": "1970-01-01T00:00:00.000Z", + "blocked": true, + "dlq_count": 0 + }, + "file_proxy": [ + { + "mapping_id": "string", + "use_case_slug": "string", + "resolved": true, + "target_use_case_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "target_enabled": true, + "target_updated_at": "1970-01-01T00:00:00.000Z", + "unresolved_reason": "not_found" + } + ] + } + ] +} +``` + +
+ +--- + +### `getEntitySyncStatus` + +Get the inbound ERP sync status of an entity: when each integration last +synchronized (checked) the entity against the ERP, and when it last +actually changed it. `last_synced_at` also advances on no-o + +`GET /v1/integrations/entities/{entityId}/sync-status` + +```ts +const { data } = await client.getEntitySyncStatus({ + entityId: 'example', + integration_id: 'example', +}) +``` + +
+Response + +```json +{ + "entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "sync_states": [ + { + "entity_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "entity_slug": "contract", + "use_case_id": "string", + "last_synced_at": "1970-01-01T00:00:00.000Z", + "last_changed_at": "1970-01-01T00:00:00.000Z", + "last_operation": "create", + "last_event_id": "string", + "readings_last_synced_at": "1970-01-01T00:00:00.000Z", + "readings_last_operation": "upsert", + "readings_last_event_id": "string" + } + ] +} +``` + +
+ +--- + +### `pollOutboundMessages` + +Poll outbound messages for an integration's poll-mode use cases. +Takes a lease on the head-of-line batch of the integration's FIFO stream: +the returned messages stay invisible to subsequent polls unti + +`POST /v1/integrations/{integrationId}/outbound/messages/poll` + +```ts +const { data } = await client.pollOutboundMessages( + { + integrationId: 'example', + }, + { + limit: 10 + }, +) +``` + +
+Response + +```json +{ + "messages": [ + { + "id": "string", + "lease_token": "string", + "use_case_id": "string", + "event_name": "string", + "event_id": "string", + "group": "string", + "org_id": "string", + "payload": {}, + "mapping_version": "3f2a9c1b7d4e8f60", + "enqueued_at": "1970-01-01T00:00:00.000Z" + } + ], + "visibility_timeout_seconds": 0, + "has_more": true +} +``` + +
+ +--- + +### `ackOutboundMessages` + +Acknowledge polled outbound messages. Acks are validated against the +active lease and committed as a prefix-contiguous cursor advance: +messages must be acknowledged in stream order. Out-of-order acks + +`POST /v1/integrations/{integrationId}/outbound/messages/ack` + +```ts +const { data } = await client.ackOutboundMessages( + { + integrationId: 'example', + }, + { + acks: [ + { + id: 'string', + lease_token: 'string' + } + ] + }, +) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "string", + "status": "accepted", + "reason": "stale_lease" + } + ] +} +``` + +
+ +--- + +### `listOutboundDlqMessages` + +List an integration's dead-lettered outbound queue messages +(poison_policy enforcement and operator skips move messages here). +Operator endpoint — requires the `integration:manage` grant. Message +payl + +`GET /v1/integrations/{integrationId}/outbound/messages/dlq` + +```ts +const { data } = await client.listOutboundDlqMessages({ + integrationId: 'example', + limit: 1, + next_token: 'example', +}) +``` + +
+Response + +```json +{ + "items": [ + { + "id": "string", + "use_case_id": "string", + "event_name": "string", + "event_id": "string", + "enqueued_at": "1970-01-01T00:00:00.000Z", + "dead_lettered_at": "1970-01-01T00:00:00.000Z", + "delivery_attempts": 0, + "reason": "string", + "mapping_error": "string", + "mapping_version": "string", + "expires_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_token": "string" +} +``` + +
+ +--- + +### `redriveOutboundDlqMessages` + +Redrive selected dead-lettered messages back into the live stream. +Operator endpoint — requires the `integration:manage` grant. +A redriven message is re-enqueued at the tail with a new id and +sequence + +`POST /v1/integrations/{integrationId}/outbound/messages/dlq/redrive` + +```ts +const { data } = await client.redriveOutboundDlqMessages( + { + integrationId: 'example', + }, + { + ids: ['string'], + reapply_mapping: false + }, +) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "string", + "status": "redriven", + "mapping_error": "string" + } + ] +} +``` + +
+ +--- + +### `unblockOutboundStream` + +Unblock an integration's outbound stream halted by the `block` +poison policy: skips (dead-letters) the current blocked head message, +emitting MSG_DEAD_LETTERED and letting the next message become the + + +`POST /v1/integrations/{integrationId}/outbound/messages/unblock` + +```ts +const { data } = await client.unblockOutboundStream( + { + integrationId: 'example', + }, + { + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "unblocked": true, + "dead_lettered_id": "string" +} +``` + +
+ +--- + +### `simulateOutboundMapping` + +Preview a poll delivery's `jsonata_expression` without saving or +enqueueing anything. The expression is checked and evaluated exactly +as at enqueue time: the same length, syntax and binding checks, th + +`POST /v1/integrations/{integrationId}/outbound/mapping-simulation` + +```ts +const { data } = await client.simulateOutboundMapping( + { + integrationId: 'example', + }, + { + jsonata_expression: '{ "contract_number": contract.contract_number, "status": $mapValue($env.erp.statuses, contract.status) }', + payload: {}, + event_id: 'string', + event_catalog_event: 'contract.updated' + }, +) +``` + +
+Response + +```json +{ + "valid": true, + "output": {}, + "error": { + "code": "syntax_error", + "message": "string", + "position": 0 + }, + "mapping_version": "3f2a9c1b7d4e8f60", + "input": {} +} +``` + +
+ +--- + +### `queryAccessLogs` + +Query API access logs for a specific integration's organization. +Returns access token usage analytics filtered by user_id (access token). +Supports infinite scroll pagination with cursor-based navigati + +`POST /v1/integrations/{integrationId}/monitoring/access-logs` + +```ts +const { data } = await client.queryAccessLogs( + { + integrationId: 'example', + }, + { + token_id: 'api_5ZugdRXasLfWBypHi93Fk', + service: 'entity', + method: 'GET', + path: '/v1/entity', + status: 200, + from_date: '2025-01-01T00:00:00Z', + to_date: '2025-01-31T23:59:59Z', + limit: 50, + cursor: { + timestamp: '1970-01-01T00:00:00.000Z', + request_id: 'string' + } + }, +) +``` + +
+Response + +```json +{ + "data": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "environment": "string", + "service": "string", + "request_id": "string", + "method": "string", + "path": "string", + "status": 0, + "response_latency_ms": 0, + "response_length": 0, + "token_id": "string", + "org_id": "string", + "origin": "string", + "source_ip": "string" + } + ], + "next_cursor": { + "timestamp": "1970-01-01T00:00:00.000Z", + "request_id": "string" + }, + "has_more": true +} +``` + +
+ +--- + +### `queryMonitoringEventsV2` + +Query monitoring events from the unified erp_monitoring_v2 table. +Returns all event types (inbound, outbound, file_proxy, etc.) in a single list. +Replaces the separate v1 inbound-events and outbound-e + +`POST /v2/integrations/{integrationId}/monitoring/events` + +```ts +const { data } = await client.queryMonitoringEventsV2( + { + integrationId: 'example', + }, + { + use_case_id: 'string', + use_case_type: 'inbound', + level: 'success', + code: 'string', + event_id: 'string', + correlation_id: 'string', + from_date: '2025-01-01T00:00:00Z', + to_date: '2025-01-31T23:59:59Z', + limit: 50, + cursor: { + created_at: '1970-01-01T00:00:00.000Z', + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6' + } + }, +) +``` + +
+Response + +```json +{ + "data": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "integration_id": "string", + "event_id": "string", + "correlation_id": "string", + "use_case_id": "string", + "use_case_type": "inbound", + "level": "success", + "code": "ACK_CONFIRMED", + "message": "string", + "detail": {}, + "created_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": { + "created_at": "1970-01-01T00:00:00.000Z", + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "has_more": true +} +``` + +
+ +--- + +### `getMonitoringStatsV2` + +Get aggregated statistics from the unified erp_monitoring_v2 table. +Returns combined metrics for all event types with optional breakdowns. + +`POST /v2/integrations/{integrationId}/monitoring/stats` + +```ts +const { data } = await client.getMonitoringStatsV2( + { + integrationId: 'example', + }, + { + from_date: '2025-01-01T00:00:00Z', + to_date: '2025-01-31T23:59:59Z', + correlation_id: 'imp_01M3799K98B6TG7GV7Q2DQT554', + correlation_ids: ['imp_01M3799K98B6TG7GV7Q2DQT554', 'imp_01M374YPQ0E7ZB0VYJZSK72M4E'], + use_case_type: 'inbound', + use_case_types: ['inbound'], + group_by: 'use_case_id', + source: 'monitoring' + }, +) +``` + +
+Response + +```json +{ + "total_events": 0, + "success_count": 0, + "error_count": 0, + "warning_count": 0, + "skipped_count": 0, + "info_count": 0, + "ack_timeout_count": 0, + "success_rate": 0, + "last_error_at": "1970-01-01T00:00:00.000Z", + "last_event_at": "1970-01-01T00:00:00.000Z", + "breakdown": [ + {} + ] +} +``` + +
+ +--- + +### `getMonitoringTimeSeriesV2` + +Get time-series aggregated event counts from the unified erp_monitoring_v2 table. +Returns bucketed counts for chart rendering. + +`POST /v2/integrations/{integrationId}/monitoring/time-series` + +```ts +const { data } = await client.getMonitoringTimeSeriesV2( + { + integrationId: 'example', + }, + { + from_date: '2025-01-01T00:00:00Z', + to_date: '2025-01-31T23:59:59Z', + interval: '5m', + use_case_type: 'inbound', + group_by: 'use_case_type' + }, +) +``` + +
+Response + +```json +{ + "interval": "5m", + "from_date": "1970-01-01T00:00:00.000Z", + "to_date": "1970-01-01T00:00:00.000Z", + "buckets": [ + { + "timestamp": "1970-01-01T00:00:00.000Z", + "success_count": 0, + "error_count": 0, + "warning_count": 0, + "skipped_count": 0, + "info_count": 0, + "total_count": 0, + "breakdown": [ + { + "use_case_type": "inbound", + "use_case_id": "string", + "success_count": 0, + "error_count": 0, + "warning_count": 0, + "skipped_count": 0, + "info_count": 0, + "total_count": 0 + } + ] + } + ] +} +``` + +
+ +--- + +### `getAssociatedMonitoringEvents` + +Returns all monitoring events sharing the same event_id, ordered chronologically. +Also includes the original inbound event payload from erp_incoming_events if available. +Used to display a full event t + +`GET /v2/integrations/{integrationId}/monitoring/events/{eventId}/associated` + +```ts +const { data } = await client.getAssociatedMonitoringEvents({ + integrationId: 'example', + eventId: 'example', +}) +``` + +
+Response + +```json +{ + "monitoring_events": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "integration_id": "string", + "event_id": "string", + "correlation_id": "string", + "use_case_id": "string", + "use_case_type": "inbound", + "level": "success", + "code": "ACK_CONFIRMED", + "message": "string", + "detail": {}, + "created_at": "1970-01-01T00:00:00.000Z" + } + ], + "inbound_event": {} +} +``` + +
+ +--- + +### `ingestExternalMonitoringEvents` + +Ingest monitoring spans produced by an EXTERNAL system (e.g. an integration +middleware), so the Integration Hub is the central monitoring point and the +cross-system event trace spans both the external + +`POST /v2/integrations/{integrationId}/monitoring/external-events` + +```ts +const { data } = await client.ingestExternalMonitoringEvents( + { + integrationId: 'example', + }, + { + events: [ + { + correlation_id: 'string', + level: 'string', + use_case_slug: 'string', + occurred_at: '1970-01-01T00:00:00.000Z', + message: 'string', + detail: {} + } + ] + }, +) +``` + +--- + +### `getMonitoringTraceByCorrelation` + +Returns the cross-system event trace for a `correlation_id`: every monitoring +span sharing it — external spans (middleware) plus epilot's own processing spans +— ordered chronologically, with a rolled- + +`GET /v2/integrations/{integrationId}/monitoring/traces/{correlationId}` + +```ts +const { data } = await client.getMonitoringTraceByCorrelation({ + integrationId: 'example', + correlationId: 'example', +}) +``` + +
+Response + +```json +{ + "correlation_id": "string", + "status": "success", + "started_at": "1970-01-01T00:00:00.000Z", + "ended_at": "1970-01-01T00:00:00.000Z", + "span_count": 0, + "truncated": true, + "spans": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "org_id": "string", + "integration_id": "string", + "event_id": "string", + "correlation_id": "string", + "use_case_id": "string", + "use_case_type": "inbound", + "level": "success", + "code": "ACK_CONFIRMED", + "message": "string", + "detail": {}, + "created_at": "1970-01-01T00:00:00.000Z" + } + ], + "inbound_event": {} +} +``` + +
+ +--- + +### `getMonitoringRunCompletionV2` + +Per-event completion of one or more runs (every monitoring event sharing a +`correlation_id`), each reduced to "how many events have reached a final +outcome, and how many are still going". Unlike `getM + +`POST /v2/integrations/{integrationId}/monitoring/runs/completion` + +```ts +const { data } = await client.getMonitoringRunCompletionV2( + { + integrationId: 'example', + }, + { + correlation_ids: ['string'] + }, +) +``` + +
+Response + +```json +{ + "runs": [ + { + "correlation_id": "string", + "seen": 0, + "in_flight": 0, + "retrying": 0, + "success": 0, + "warning": 0, + "error": 0, + "info": 0, + "entries": { + "total": 0, + "error": 0, + "warning": 0, + "success": 0, + "info": 0, + "retry": 0 + }, + "last_activity_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `listSecureProxies` + +Lists all secure_proxy use cases across all integrations for the authenticated organization. +Returns minimal data suitable for dropdowns and selection UIs. + +`GET /v1/integrations/secure-proxies` + +```ts +const { data } = await client.listSecureProxies() +``` + +
+Response + +```json +{ + "secure_proxies": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "name": "string", + "slug": "string", + "enabled": true, + "vpc_mode": "static_ip", + "allowed_domains": ["string"], + "allowed_ips": ["string"], + "integration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "integration_name": "string" + } + ] +} +``` + +
+ +--- + +### `secureProxy` + +Routes an HTTP request through a VPC with either static IP egress or VPN secure link access. +The VPC mode is determined by the referenced secure_proxy use case configuration. +For secure_link mode, the + +`POST /v1/secure-proxy` + +```ts +const { data } = await client.secureProxy( + null, + { + integration_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + use_case_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + use_case_slug: 'string', + url: 'https://example.com/path', + method: 'GET', + headers: {}, + body: {}, + response_type: 'json' + }, +) +``` + +
+Response + +```json +{ + "status_code": 0, + "headers": {}, + "body": {} +} +``` + +
+ +--- + +### `managedCallExecute` + +Execute a managed call operation synchronously. The slug in the path acts as the RPC method name. +Calls an external partner API with JSONata mapping on both request and response. + +`POST /v1/managed-call/{slug}/execute` + +```ts +const { data } = await client.managedCallExecute( + { + slug: 'example', + }, + { + integration_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + payload: {}, + correlation_id: 'string' + }, +) +``` + +
+Response + +```json +{} +``` + +
+ +--- + +### `generateTypesPreview` + +Analyses the JSONata mappings of all managed-call use cases in the integration and returns scaffolded type descriptors. The frontend uses these to show the type editor modal where developers fill in l + +`POST /v1/integrations/{integrationId}/generate-types-preview` + +```ts +const { data } = await client.generateTypesPreview({ + integrationId: 'example', +}) +``` + +--- + +### `generateTypes` + +Generates a complete TypeScript npm package with typed interfaces for all managed-call use cases. This is a stateless operation that does not persist any changes. Use the commit-types endpoint to lock + +`POST /v1/integrations/{integrationId}/generate-types` + +```ts +const { data } = await client.generateTypes( + { + integrationId: 'example', + }, + { + package_name: '@epilot/hems-cleverpv', + version: '1.0.0', + description: 'string', + domain_package: '@epilot/hems', + domain_map_name: 'HemsUseCaseMap', + annotations: {} + }, +) +``` + +
+Response + +```json +{ + "package_name": "string", + "version": "string", + "files": {}, + "warnings": ["string"] +} +``` + +
+ +--- + +### `commitTypes` + +Commits the generated types by locking use case configurations and updating version tracking. Should be called after the user reviews and downloads the generated package. + +`POST /v1/integrations/{integrationId}/commit-types` + +```ts +const { data } = await client.commitTypes( + { + integrationId: 'example', + }, + { + package_name: '@epilot/hems-cleverpv', + version: '1.0.0', + annotations: {} + }, +) +``` + +
+Response + +```json +{ + "committed": true, + "warnings": ["string"] +} +``` + +
+ +--- + +### `createErpImport` + +Register an already-uploaded file (S3 ref) as a pricing-file import job. Returns the job and a file preview. Nothing runs yet: no use case is chosen and no validation starts here. Optionally rank cand + +`POST /v2/erp/imports` + +```ts +const { data } = await client.createErpImport( + null, + { + s3_reference: { + bucket: 'string', + key: 'string' + }, + include_preview: false, + import_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "job": { + "import_id": "string", + "org_id": "string", + "created_by": "string", + "integration_id": "string", + "use_case_slug": "string", + "format": "csv", + "status": "PENDING", + "s3_input_ref": { + "bucket": "string", + "key": "string" + }, + "size_bytes": 0, + "column_count": 0, + "validation": { + "total_rows": 0, + "blocking": 0, + "warnings": 0, + "entities": {}, + "entity_details": [ + { + "mapping_index": 0, + "entity_schema": "string", + "business_key": {}, + "variants": 0, + "versions": 0, + "condition_attributes": ["grid_area"], + "version_attribute": "valid_from" + } + ], + "issues": [ + { + "code": "UNIQUE_ID_COLUMN_MISSING", + "severity": "warning", + "columns": [ + { + "name": "string", + "entity": "string" + } + ], + "attributes": [ + { + "name": "string", + "entity": "string" + } + ], + "lines": [0], + "subject": "string", + "row": 0, + "expected": "number" + } + ] + }, + "progress": { + "processed_rows": 0, + "total_rows": 0, + "events_published": 0 + }, + "error": { + "code": "VALIDATION_BLOCKED", + "message": "string" + }, + "correlation_id": "string", + "activity_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + }, + "preview": { + "columns": ["string"], + "rows": [ + ["string"] + ] + } +} +``` + +
+ +--- + +### `listErpImports` + +List recent pricing-file import jobs for the org, newest first. + +`GET /v2/erp/imports` + +```ts +const { data } = await client.listErpImports({ + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "import_id": "string", + "org_id": "string", + "created_by": "string", + "integration_id": "string", + "use_case_slug": "string", + "format": "csv", + "status": "PENDING", + "s3_input_ref": { + "bucket": "string", + "key": "string" + }, + "size_bytes": 0, + "column_count": 0, + "validation": { + "total_rows": 0, + "blocking": 0, + "warnings": 0, + "entities": {}, + "entity_details": [ + { + "mapping_index": 0, + "entity_schema": "string", + "business_key": {}, + "variants": 0, + "versions": 0, + "condition_attributes": ["grid_area"], + "version_attribute": "valid_from" + } + ], + "issues": [ + { + "code": "UNIQUE_ID_COLUMN_MISSING", + "severity": "warning", + "columns": [ + { + "name": "string", + "entity": "string" + } + ], + "attributes": [ + { + "name": "string", + "entity": "string" + } + ], + "lines": [0], + "subject": "string", + "row": 0, + "expected": "number" + } + ] + }, + "progress": { + "processed_rows": 0, + "total_rows": 0, + "events_published": 0 + }, + "error": { + "code": "VALIDATION_BLOCKED", + "message": "string" + }, + "correlation_id": "string", + "activity_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `getErpImport` + +Get a pricing-file import job (status, counts, result links). + +`GET /v2/erp/imports/{importId}` + +```ts +const { data } = await client.getErpImport({ + importId: 'example', +}) +``` + +
+Response + +```json +{ + "import_id": "string", + "org_id": "string", + "created_by": "string", + "integration_id": "string", + "use_case_slug": "string", + "format": "csv", + "status": "PENDING", + "s3_input_ref": { + "bucket": "string", + "key": "string" + }, + "size_bytes": 0, + "column_count": 0, + "validation": { + "total_rows": 0, + "blocking": 0, + "warnings": 0, + "entities": {}, + "entity_details": [ + { + "mapping_index": 0, + "entity_schema": "string", + "business_key": {}, + "variants": 0, + "versions": 0, + "condition_attributes": ["grid_area"], + "version_attribute": "valid_from" + } + ], + "issues": [ + { + "code": "UNIQUE_ID_COLUMN_MISSING", + "severity": "warning", + "columns": [ + { + "name": "string", + "entity": "string" + } + ], + "attributes": [ + { + "name": "string", + "entity": "string" + } + ], + "lines": [0], + "subject": "string", + "row": 0, + "expected": "number" + } + ] + }, + "progress": { + "processed_rows": 0, + "total_rows": 0, + "events_published": 0 + }, + "error": { + "code": "VALIDATION_BLOCKED", + "message": "string" + }, + "correlation_id": "string", + "activity_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteErpImport` + +Remove an import and the file it owns. Allowed from any status: an import whose run is still in flight is stopped by the deletion, and rows it already wrote stay written. + +`DELETE /v2/erp/imports/{importId}` + +```ts +const { data } = await client.deleteErpImport({ + importId: 'example', +}) +``` + +--- + +### `getErpImportPreview` + +The file preview of an existing import: its columns and first data rows, the same sample `createErpImport` returns with `include_preview`. Lets a client that opens a job later show its file, and is in + +`GET /v2/erp/imports/{importId}/preview` + +```ts +const { data } = await client.getErpImportPreview({ + importId: 'example', +}) +``` + +
+Response + +```json +{ + "columns": ["string"], + "rows": [ + ["string"] + ] +} +``` + +
+ +--- + +### `downloadErpImportFile` + +A short-lived presigned URL that downloads the file this import was registered with — the import's own copy, so exactly what `:validate` and `:execute` read. The URL serves the file as an attachment u + +`GET /v2/erp/imports/{importId}/download` + +```ts +const { data } = await client.downloadErpImportFile({ + importId: 'example', +}) +``` + +
+Response + +```json +{ + "download_url": "https://example.com/path", + "filename": "string", + "expires_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `validateErpImport` + +Choose the use case to read this file with, and start the validate phase. +Callable from PENDING, READY and FAILED — so a wrong choice is corrected by calling this again with a different use case, rath + +`POST /v2/erp/imports/{importId}:validate` + +```ts +const { data } = await client.validateErpImport( + { + importId: 'example', + }, + { + integration_id: 'string', + use_case_slug: 'string' + }, +) +``` + +--- + +### `suggestErpImportUseCases` + +Rank the org's inbound use cases against this file's columns — the input to the ranked picker ("matches 6 of your 7 columns"). Optional: skip this and call `:validate` directly when the use case is al + +`POST /v2/erp/imports/{importId}:suggest-use-cases` + +```ts +const { data } = await client.suggestErpImportUseCases({ + importId: 'example', +}) +``` + +
+Response + +```json +{ + "file_columns": 0, + "suggestions": [ + { + "integration_id": "string", + "integration_name": "string", + "use_case_slug": "string", + "use_case_name": "string", + "entity_types": 0, + "matched_columns": 0 + } + ] +} +``` + +
+ +--- + +### `executeErpImport` + +Confirm and run the write phase of a validated import. Only a READY job may be executed; any other status returns 409. +The verdict is re-checked against live inputs first: if the mapping or an entity + +`POST /v2/erp/imports/{importId}:execute` + +```ts +const { data } = await client.executeErpImport( + { + importId: 'example', + }, + { + ack_warnings: true + }, +) +``` + +--- + +### `abortErpImport` + +Ask a running import to stop. Valid while the job is VALIDATING or PROCESSING; any other status returns 409. +The stop is cooperative: the job passes through CANCELLING and typically reaches CANCELLED + +`POST /v2/erp/imports/{importId}:abort` + +```ts +const { data } = await client.abortErpImport({ + importId: 'example', +}) +``` + +--- + +## Schemas + +### `S3Reference` + +```ts +type S3Reference = { + bucket: string + key: string +} +``` + +### `CreateErpImportRequest` + +Register an already-uploaded file as an import. The use case is chosen later, via `:validate` — upload and interpretation are separate decisions. + +```ts +type CreateErpImportRequest = { + s3_reference: { + bucket: string + key: string + } + include_preview?: boolean + import_id?: string +} +``` + +### `ValidateErpImportRequest` + +```ts +type ValidateErpImportRequest = { + integration_id: string + use_case_slug: string +} +``` + +### `ErpImportUseCaseSuggestion` + +```ts +type ErpImportUseCaseSuggestion = { + integration_id: string + integration_name: string + use_case_slug: string + use_case_name: string + entity_types: number + matched_columns: number +} +``` + +### `SuggestErpImportUseCasesResponse` + +```ts +type SuggestErpImportUseCasesResponse = { + file_columns: number + suggestions: Array<{ + integration_id: string + integration_name: string + use_case_slug: string + use_case_name: string + entity_types: number + matched_columns: number + }> +} +``` + +### `ExecuteErpImportRequest` + +Confirmation options. Required only when the verdict carries warnings — a clean import needs no body at all. + +```ts +type ExecuteErpImportRequest = { + ack_warnings?: boolean +} +``` + +### `ErpImportIssue` + +A problem found during validation, scoped to the file as a whole rather than to +individual rows. + +`code` is the translation key and the other fields are its parameters — there is +deliberately no message to display. Each code appears at most once (once per +`expected` for `VALUE_FORMAT_INVALID`), with + +```ts +type ErpImportIssue = { + code: "UNIQUE_ID_COLUMN_MISSING" | "MAPPED_COLUMN_MISSING" | "MALFORMED_ROW" | "INVALID_ENCODING" | "EMPTY_FILE" | "TOO_MANY_ROWS" | "BLANK_ROWS_SKIPPED" | "TIER_ROWS_NOT_GROUPED" | "TIER_BANDS_CONFLICT" | "CONDITION_VALUE_MISSING" | "VARIANT_VALUE_CONFLICT" | "ATTRIBUTE_NOT_OVERRIDABLE" | "ATTRIBUTE_NOT_IN_SCHEMA" | "IS_CONDITIONAL_NOT_CONSTANT" | "SCHEMA_NOT_CONDITIONABLE" | "SCHEMA_NOT_FOUND" | "SCHEMA_DECLARES_NO_CONDITIONS" | "GROUPING_KEY_NOT_A_COLUMN" | "GROUPING_KEY_IS_SORT_COLUMN" | "CONDITIONAL_TARGET_MODE_UNSUPPORTED" | "UNIQUE_ID_NOT_IN_SCHEMA" | "VALUE_FORMAT_INVALID" | "MAPPING_EXPRESSION_FAILED" | "FROM_ROWS_EXPRESSION_FAILED" | "VALID_FROM_NOT_MAPPED" + severity: "warning" | "blocking" + columns?: Array<{ + name: string + entity?: string + }> + attributes?: Array<{ + name: string + entity?: string + }> + lines?: number[] + subject?: string + row?: number + expected?: "number" | "text" | "decimal" | "date" +} +``` + +### `ErpImportValidation` + +Validate-phase summary: what the file will create, and whether it may be confirmed. Absent until the validate phase completes. No per-row detail is kept — a rejected file is corrected and imported again. + +```ts +type ErpImportValidation = { + total_rows?: number + blocking: number + warnings: number + entities: Record + entity_details?: Array<{ + mapping_index: number + entity_schema: string + business_key: Record + variants?: number + versions?: number + condition_attributes?: string[] + version_attribute?: string + }> + issues?: Array<{ + code: "UNIQUE_ID_COLUMN_MISSING" | "MAPPED_COLUMN_MISSING" | "MALFORMED_ROW" | "INVALID_ENCODING" | "EMPTY_FILE" | "TOO_MANY_ROWS" | "BLANK_ROWS_SKIPPED" | "TIER_ROWS_NOT_GROUPED" | "TIER_BANDS_CONFLICT" | "CONDITION_VALUE_MISSING" | "VARIANT_VALUE_CONFLICT" | "ATTRIBUTE_NOT_OVERRIDABLE" | "ATTRIBUTE_NOT_IN_SCHEMA" | "IS_CONDITIONAL_NOT_CONSTANT" | "SCHEMA_NOT_CONDITIONABLE" | "SCHEMA_NOT_FOUND" | "SCHEMA_DECLARES_NO_CONDITIONS" | "GROUPING_KEY_NOT_A_COLUMN" | "GROUPING_KEY_IS_SORT_COLUMN" | "CONDITIONAL_TARGET_MODE_UNSUPPORTED" | "UNIQUE_ID_NOT_IN_SCHEMA" | "VALUE_FORMAT_INVALID" | "MAPPING_EXPRESSION_FAILED" | "FROM_ROWS_EXPRESSION_FAILED" | "VALID_FROM_NOT_MAPPED" + severity: "warning" | "blocking" + columns?: Array<{ + name: { ... } + entity?: { ... } + }> + attributes?: Array<{ + name: { ... } + entity?: { ... } + }> + lines?: number[] + subject?: string + row?: number + expected?: "number" | "text" | "decimal" | "date" + }> +} +``` + +### `ErpImportEntityDetail` + +One entity instance the import will write, attributed to the mapping target that produces it. + +```ts +type ErpImportEntityDetail = { + mapping_index: number + entity_schema: string + business_key: Record + variants?: number + versions?: number + condition_attributes?: string[] + version_attribute?: string +} +``` + +### `ErpImportProgress` + +How far the currently running phase has got. Written at every batch boundary, so it advances during long runs rather than only at the end. +`total_rows` is ABSENT during the validate phase until the file has been read to the end — there is deliberately no counting pass, since that would be a second u + +```ts +type ErpImportProgress = { + processed_rows: number + total_rows?: number + events_published?: number +} +``` + +### `ErpImportError` + +Why the import failed — present if and only if status = FAILED. `code` is the translation key; for VALIDATION_BLOCKED the specifics are in `validation`. + +```ts +type ErpImportError = { + code: "VALIDATION_BLOCKED" | "FILE_FORMAT_UNSUPPORTED" | "FILE_UNAVAILABLE" | "VALIDATE_TIMEOUT" | "IMPORT_TIMEOUT" | "USE_CASE_NOT_USABLE" | "IMPORT_NO_PROGRESS" | "TIER_ROWS_NOT_GROUPED" | "CHUNK_TOO_LARGE" | "INTERNAL_ERROR" + message: string +} +``` + +### `ErpImportFilePreview` + +Sample of the file's first rows, using the same parser as `:validate`. Registration refuses a file it cannot read, so a created job always includes this. + +```ts +type ErpImportFilePreview = { + columns: string[] + rows: string[][] +} +``` + +### `ErpImportDownload` + +```ts +type ErpImportDownload = { + download_url: string // uri + filename: string + expires_at: string // date-time +} +``` + +### `CreateErpImportResponse` + +```ts +type CreateErpImportResponse = { + job: { + import_id: string + org_id: string + created_by?: string + integration_id?: string + use_case_slug?: string + format: "csv" | "xlsx" + status: "PENDING" | "VALIDATING" | "READY" | "PROCESSING" | "IMPORTED" | "FAILED" | "CANCELLING" | "CANCELLED" + s3_input_ref: { + bucket: { ... } + key: { ... } + } + size_bytes?: number + column_count?: number + validation?: { + total_rows?: { ... } + blocking: { ... } + warnings: { ... } + entities: { ... } + entity_details?: { ... } + issues?: { ... } + } + progress?: { + processed_rows: { ... } + total_rows?: { ... } + events_published?: { ... } + } + error?: { + code: { ... } + message: { ... } + } + correlation_id?: string + activity_id?: string + created_at: string // date-time + updated_at: string // date-time + } + preview?: { + columns: string[] + rows: string[][] + } +} +``` + +### `ErpImportJob` + +```ts +type ErpImportJob = { + import_id: string + org_id: string + created_by?: string + integration_id?: string + use_case_slug?: string + format: "csv" | "xlsx" + status: "PENDING" | "VALIDATING" | "READY" | "PROCESSING" | "IMPORTED" | "FAILED" | "CANCELLING" | "CANCELLED" + s3_input_ref: { + bucket: string + key: string + } + size_bytes?: number + column_count?: number + validation?: { + total_rows?: number + blocking: number + warnings: number + entities: Record + entity_details?: Array<{ + mapping_index: { ... } + entity_schema: { ... } + business_key: { ... } + variants?: { ... } + versions?: { ... } + condition_attributes?: { ... } + version_attribute?: { ... } + }> + issues?: Array<{ + code: { ... } + severity: { ... } + columns?: { ... } + attributes?: { ... } + lines?: { ... } + subject?: { ... } + row?: { ... } + expected?: { ... } + }> + } + progress?: { + processed_rows: number + total_rows?: number + events_published?: number + } + error?: { + code: "VALIDATION_BLOCKED" | "FILE_FORMAT_UNSUPPORTED" | "FILE_UNAVAILABLE" | "VALIDATE_TIMEOUT" | "IMPORT_TIMEOUT" | "USE_CASE_NOT_USABLE" | "IMPORT_NO_PROGRESS" | "TIER_ROWS_NOT_GROUPED" | "CHUNK_TOO_LARGE" | "INTERNAL_ERROR" + message: string + } + correlation_id?: string + activity_id?: string + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `ErpImportList` + +```ts +type ErpImportList = { + results: Array<{ + import_id: string + org_id: string + created_by?: string + integration_id?: string + use_case_slug?: string + format: "csv" | "xlsx" + status: "PENDING" | "VALIDATING" | "READY" | "PROCESSING" | "IMPORTED" | "FAILED" | "CANCELLING" | "CANCELLED" + s3_input_ref: { + bucket: { ... } + key: { ... } + } + size_bytes?: number + column_count?: number + validation?: { + total_rows?: { ... } + blocking: { ... } + warnings: { ... } + entities: { ... } + entity_details?: { ... } + issues?: { ... } + } + progress?: { + processed_rows: { ... } + total_rows?: { ... } + events_published?: { ... } + } + error?: { + code: { ... } + message: { ... } + } + correlation_id?: string + activity_id?: string + created_at: string // date-time + updated_at: string // date-time + }> + next_cursor?: string +} +``` + +### `NotificationHistoryItem` + +A single notification-history row (one real notification decision). + +```ts +type NotificationHistoryItem = { + id: string + type: string + state_transition?: string + severity: "error" | "warning" | "info" + title: string + occurred_at: string // date-time + notified: boolean + suppressed_reason?: "muted" | "debounced" | "recipient_opt_out" + recipients: string[] + context: Record + created_at: string // date-time +} +``` + +### `NotificationHistoryResponse` + +```ts +type NotificationHistoryResponse = { + history: Array<{ + id: string + type: string + state_transition?: string + severity: "error" | "warning" | "info" + title: string + occurred_at: string // date-time + notified: boolean + suppressed_reason?: "muted" | "debounced" | "recipient_opt_out" + recipients: string[] + context: Record + created_at: string // date-time + }> + next_cursor?: string +} +``` + +### `TestNotificationRequest` + +```ts +type TestNotificationRequest = { + kind: "alert" | "digest" + type?: string + channels?: "email" | "in_app"[] +} +``` + +### `TestNotificationResponse` + +```ts +type TestNotificationResponse = { + sent: boolean + recipient: string + channels: string[] + notification_id?: string +} +``` + +### `NotificationStatusResponse` + +```ts +type NotificationStatusResponse = { + health: "healthy" | "alerting" | "muted" + evaluated_at?: string // date-time + rules: Array<{ + rule_id: string + state: "ok" | "alerting" | "recovered" + last_fired_at?: string // date-time + last_cleared_at?: string // date-time + last_evaluation?: { + evaluated_at: { ... } + observed: { ... } + threshold?: { ... } + suppressed_reason?: { ... } + } + baseline?: { + is_mature: { ... } + computed_at?: { ... } + median?: { ... } + mad?: { ... } + upper?: { ... } + buckets?: { ... } + } + }> +} +``` + +### `NotificationRuleStatus` + +```ts +type NotificationRuleStatus = { + rule_id: string + state: "ok" | "alerting" | "recovered" + last_fired_at?: string // date-time + last_cleared_at?: string // date-time + last_evaluation?: { + evaluated_at: string // date-time + observed: number + threshold?: number + suppressed_reason?: "sample_size" + } + baseline?: { + is_mature: boolean + computed_at?: string // date-time + median?: number + mad?: number + upper?: number + buckets?: Array<{ + dow: { ... } + hour: { ... } + median: { ... } + mad: { ... } + }> + } +} +``` + +### `RuleBaselineStatus` + +```ts +type RuleBaselineStatus = { + is_mature: boolean + computed_at?: string // date-time + median?: number + mad?: number + upper?: number + buckets?: Array<{ + dow: number + hour: number + median: number + mad: number + }> +} +``` + +### `RuleBaselineBucket` + +```ts +type RuleBaselineBucket = { + dow: number + hour: number + median: number + mad: number +} +``` + +### `ErrorResponseBase` + +```ts +type ErrorResponseBase = { + code?: string + message?: string +} +``` + +### `ErpEvent` + +```ts +type ErpEvent = { + event_type: "CREATE" | "UPDATE" | "DELETE" + object_type: string + timestamp: string // date-time + format: "json" | "xml" + payload: string | Record + deduplication_id?: string + correlation_id?: string + use_case_id?: string +} +``` + +### `ErpUpdatesEventsV2Request` + +```ts +type ErpUpdatesEventsV2Request = { + integration_id: string // uuid + correlation_id?: string + events: Array<{ + event_type: "CREATE" | "UPDATE" | "DELETE" + object_type: string + timestamp: string // date-time + format: "json" | "xml" + payload: string | Record + deduplication_id?: string + correlation_id?: string + use_case_id?: string + }> +} +``` + +### `ErpEventV3` + +```ts +type ErpEventV3 = unknown | unknown +``` + +### `ErpUpdatesEventsV3Request` + +```ts +type ErpUpdatesEventsV3Request = { + integration_id: string // uuid + correlation_id?: string + group_id?: string + interactive?: boolean + correlation_complete?: boolean + events: unknown | unknown[] +} +``` + +### `ErpUpdateProcessedEntity` + +An entity an interactive event wrote. + +```ts +type ErpUpdateProcessedEntity = { + slug: string + _id: string + operation: "created" | "updated" | "deleted" | "unchanged" + unique_ids: Record +} +``` + +### `CorrelationCloseResult` + +What became of the request's `correlation_complete`. Present exactly when the +request carried `correlation_complete: true`; absent otherwise. + + +```ts +type CorrelationCloseResult = { + outcome: "applied" | "rate_limited" | "ignored" + reasons?: "retry_requested" | "queue_refused" | "events_under_own_correlation_ids" | "events_duplicate" | "events_not_configured" | "events_not_interactive" | "events_unrecorded" | "rate_limited" | "rate_limit_unavailable" | "other_integration" | "close_failed" | "interactive_unavailable"[] + message?: string +} +``` + +### `ErpUpdateProcessingError` + +A failure nothing will retry. + +```ts +type ErpUpdateProcessingError = { + code: string + message: string + event_id?: string + occurred_at: string // date-time + after_completion?: boolean +} +``` + +### `ErpUpdateEventStatus` + +One interactive event's processing record. + +```ts +type ErpUpdateEventStatus = { + event_id: string + correlation_id?: string + integration_id?: string + status: "accepted" | "processing" | "done" | "partial" | "error" + lane: "interactive" | "priority" | "default" | "deferred" + use_case_id?: string + use_case_slug?: string + event_name?: string + ingested_at: string // date-time + mapped_at?: string // date-time + done_at?: string // date-time + writes_total: number + writes_done: number + entities: Array<{ + slug: string + _id: string + operation: "created" | "updated" | "deleted" | "unchanged" + unique_ids: Record + }> + entities_omitted?: number + errors: Array<{ + code: string + message: string + event_id?: string + occurred_at: string // date-time + after_completion?: boolean + }> + errors_total: number +} +``` + +### `CorrelationUseCaseCounts` + +How many of a correlation's events belong to one use case, and how they ended. + +```ts +type CorrelationUseCaseCounts = { + use_case_slug: string + received: number + done: number + error: number +} +``` + +### `CorrelationStatus` + +One correlation's summary. + +```ts +type CorrelationStatus = { + correlation_id: string + integration_id?: string + closed: boolean + closed_at?: string // date-time + complete: boolean + completed_at?: string // date-time + events_received: number + events_done: number + late_events: number + first_ingested_at?: string // date-time + last_done_at?: string // date-time + use_cases: Array<{ + use_case_slug: string + received: number + done: number + error: number + }> + entities: Array<{ + slug: string + _id: string + operation: "created" | "updated" | "deleted" | "unchanged" + unique_ids: Record + }> + entities_omitted?: number + errors: Array<{ + code: string + message: string + event_id?: string + occurred_at: string // date-time + after_completion?: boolean + }> + errors_total: number +} +``` + +### `CorrelationWaitResult` + +```ts +type CorrelationWaitResult = { + correlation_id: string + integration_id?: string + closed: boolean + closed_at?: string // date-time + complete: boolean + completed_at?: string // date-time + events_received: number + events_done: number + late_events: number + first_ingested_at?: string // date-time + last_done_at?: string // date-time + use_cases: Array<{ + use_case_slug: string + received: number + done: number + error: number + }> + entities: Array<{ + slug: string + _id: string + operation: "created" | "updated" | "deleted" | "unchanged" + unique_ids: Record + }> + entities_omitted?: number + errors: Array<{ + code: string + message: string + event_id?: string + occurred_at: string // date-time + after_completion?: boolean + }> + errors_total: number + completion: "requirements_met" | "complete" | "timeout" | "error" + undecided_entity_requirements?: string[] +} +``` + +### `CorrelationWaitBadRequest` + +```ts +type CorrelationWaitBadRequest = { + message: string + slug?: string + rejected_key?: string + use_case_slug?: string + allowed_keys?: string[] +} +``` + +### `CorrelationStatusList` + +```ts +type CorrelationStatusList = { + results: Array<{ + correlation_id: string + integration_id?: string + closed: boolean + closed_at?: string // date-time + complete: boolean + completed_at?: string // date-time + events_received: number + events_done: number + late_events: number + first_ingested_at?: string // date-time + last_done_at?: string // date-time + use_cases: Array<{ + use_case_slug: { ... } + received: { ... } + done: { ... } + error: { ... } + }> + entities: Array<{ + slug: { ... } + _id: { ... } + operation: { ... } + unique_ids: { ... } + }> + entities_omitted?: number + errors: Array<{ + code: { ... } + message: { ... } + event_id?: { ... } + occurred_at: { ... } + after_completion?: { ... } + }> + errors_total: number + }> + next_cursor: string + horizon_days: number +} +``` + +### `TriggerErpActionRequest` + +```ts +type TriggerErpActionRequest = { + execution_id: string + org_id: string + webhook_id: string + flow_id: string + created_at: string // date-time + action_id: string + flow_action_id: string + flow_name: string + activity_id: string + entity_id: string +} +``` + +### `TriggerWebhookResp` + +```ts +type TriggerWebhookResp = { + status_code?: string + message?: string + body?: object + code?: string + status?: "succeeded" | "failed" + start_date?: string + end_date?: string + event_id?: string +} +``` + +### `IntegrationEditableFields` + +```ts +type IntegrationEditableFields = { + name?: string + description?: string + access_token_ids?: string[] + app_ids?: string[] + environment_config?: Array<{ + key: string + label: string + type: "String" | "SecretString" + description?: string + required?: boolean + order?: number + }> + maps?: Array<{ + key: string + label: string + description?: string + value: Record + }> + settings?: { + autoRefresh?: { + enabled?: { ... } + freshnessThresholdMinutes?: { ... } + } + notifications?: { + enabled: { ... } + recipients: { ... } + defaultChannels: { ... } + monitoredUseCases?: { ... } + monitoredCodes?: { ... } + rules: { ... } + digest: { ... } + muteUntil?: { ... } + } + } + integration_type?: "erp" | "connector" + connector_config?: { + base_url?: string + auth?: { + type?: { ... } + token_url?: { ... } + client_id?: { ... } + client_secret?: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + api_key_header?: { ... } + api_key?: { ... } + token?: { ... } + } + types_versions?: Array<{ + version: { ... } + package_name: { ... } + generated_at: { ... } + generated_by: { ... } + status: { ... } + }> + latest_types_version?: string + latest_types_package_name?: string + } + protected?: boolean + _manifest?: string[] +} +``` + +### `ConnectorConfig` + +Shared configuration for connector-type integrations + +```ts +type ConnectorConfig = { + base_url?: string + auth?: { + type?: "oauth2_client_credentials" | "api_key" | "bearer" + token_url?: string + client_id?: string + client_secret?: string + scope?: string + audience?: string + resource?: string + body_params?: Record + headers?: Record + query_params?: Record + api_key_header?: string + api_key?: string + token?: string + } + types_versions?: Array<{ + version: string + package_name: string + generated_at: string // date-time + generated_by: string + status: "active" | "deprecated" + }> + latest_types_version?: string + latest_types_package_name?: string +} +``` + +### `ManagedCallAuth` + +Authentication configuration for managed call requests + +```ts +type ManagedCallAuth = { + type?: "oauth2_client_credentials" | "api_key" | "bearer" + token_url?: string + client_id?: string + client_secret?: string + scope?: string + audience?: string + resource?: string + body_params?: Record + headers?: Record + query_params?: Record + api_key_header?: string + api_key?: string + token?: string +} +``` + +### `Integration` + +```ts +type Integration = { + id: string // uuid + orgId: string + created_at: string // date-time + updated_at: string // date-time + name: string + description?: string + access_token_ids?: string[] + app_ids?: string[] + environment_config?: Array<{ + key: string + label: string + type: "String" | "SecretString" + description?: string + required?: boolean + order?: number + }> + maps?: Array<{ + key: string + label: string + description?: string + value: Record + }> + settings?: { + autoRefresh?: { + enabled?: { ... } + freshnessThresholdMinutes?: { ... } + } + notifications?: { + enabled: { ... } + recipients: { ... } + defaultChannels: { ... } + monitoredUseCases?: { ... } + monitoredCodes?: { ... } + rules: { ... } + digest: { ... } + muteUntil?: { ... } + } + } + integration_type?: "erp" | "connector" + connector_config?: { + base_url?: string + auth?: { + type?: { ... } + token_url?: { ... } + client_id?: { ... } + client_secret?: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + api_key_header?: { ... } + api_key?: { ... } + token?: { ... } + } + types_versions?: Array<{ + version: { ... } + package_name: { ... } + generated_at: { ... } + generated_by: { ... } + status: { ... } + }> + latest_types_version?: string + latest_types_package_name?: string + } + protected?: boolean + _manifest?: string[] +} +``` + +### `CreateIntegrationRequest` + +```ts +type CreateIntegrationRequest = { + name: string + description?: string + access_token_ids?: string[] + app_ids?: string[] + environment_config?: Array<{ + key: string + label: string + type: "String" | "SecretString" + description?: string + required?: boolean + order?: number + }> + maps?: Array<{ + key: string + label: string + description?: string + value: Record + }> + settings?: { + autoRefresh?: { + enabled?: { ... } + freshnessThresholdMinutes?: { ... } + } + notifications?: { + enabled: { ... } + recipients: { ... } + defaultChannels: { ... } + monitoredUseCases?: { ... } + monitoredCodes?: { ... } + rules: { ... } + digest: { ... } + muteUntil?: { ... } + } + } + integration_type?: "erp" | "connector" + connector_config?: { + base_url?: string + auth?: { + type?: { ... } + token_url?: { ... } + client_id?: { ... } + client_secret?: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + api_key_header?: { ... } + api_key?: { ... } + token?: { ... } + } + types_versions?: Array<{ + version: { ... } + package_name: { ... } + generated_at: { ... } + generated_by: { ... } + status: { ... } + }> + latest_types_version?: string + latest_types_package_name?: string + } + protected?: boolean + _manifest?: string[] +} +``` + +### `UpdateIntegrationRequest` + +```ts +type UpdateIntegrationRequest = { + name?: string + description?: string + access_token_ids?: string[] + app_ids?: string[] + environment_config?: Array<{ + key: string + label: string + type: "String" | "SecretString" + description?: string + required?: boolean + order?: number + }> + maps?: Array<{ + key: string + label: string + description?: string + value: Record + }> + settings?: { + autoRefresh?: { + enabled?: { ... } + freshnessThresholdMinutes?: { ... } + } + notifications?: { + enabled: { ... } + recipients: { ... } + defaultChannels: { ... } + monitoredUseCases?: { ... } + monitoredCodes?: { ... } + rules: { ... } + digest: { ... } + muteUntil?: { ... } + } + } + integration_type?: "erp" | "connector" + connector_config?: { + base_url?: string + auth?: { + type?: { ... } + token_url?: { ... } + client_id?: { ... } + client_secret?: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + api_key_header?: { ... } + api_key?: { ... } + token?: { ... } + } + types_versions?: Array<{ + version: { ... } + package_name: { ... } + generated_at: { ... } + generated_by: { ... } + status: { ... } + }> + latest_types_version?: string + latest_types_package_name?: string + } + protected?: boolean + _manifest?: string[] +} +``` + +### `IntegrationMap` + +A flat key/value map stored as an Environments API variable of type `JSON`. Values must be strings, numbers, booleans or null; the serialised map must not exceed 32 KB. + + +```ts +type IntegrationMap = { + key: string + label: string + description?: string + value: Record +} +``` + +### `EnvironmentFieldConfig` + +```ts +type EnvironmentFieldConfig = { + key: string + label: string + type: "String" | "SecretString" + description?: string + required?: boolean + order?: number +} +``` + +### `IntegrationSettings` + +Settings for the integration + +```ts +type IntegrationSettings = { + autoRefresh?: { + enabled?: boolean + freshnessThresholdMinutes?: number + } + notifications?: { + enabled: boolean + recipients: Array<{ + user_id: { ... } + }> + defaultChannels: { + email: { ... } + in_app: { ... } + } + monitoredUseCases?: string[] + monitoredCodes?: string[] + rules: Array<{ + id?: { ... } + name?: { ... } + type: { ... } + enabled: { ... } + channels?: { ... } + codes?: { ... } + threshold?: { ... } + sensitivity?: { ... } + fallbackThreshold?: { ... } + window?: { ... } + minSampleSize?: { ... } + quietPeriod?: { ... } + }> + digest: { + enabled: { ... } + frequency: { ... } + dayOfWeek?: { ... } + timeOfDay: { ... } + timezone: { ... } + channels: { ... } + includeHealthy: { ... } + skipIfEmpty: { ... } + } + muteUntil?: string // date-time + } +} +``` + +### `AutoRefreshSettings` + +Auto-refresh settings for keeping integration data fresh + +```ts +type AutoRefreshSettings = { + enabled?: boolean + freshnessThresholdMinutes?: number +} +``` + +### `IntegrationNotificationConfig` + +Integration monitoring notification configuration. Rides Integration.settings.notifications (camelCase) and surfaces on both v1 and v2 GET/PUT. Unknown keys are stripped server-side to stay forward-compatible with deferred (V2) rule types. + +```ts +type IntegrationNotificationConfig = { + enabled: boolean + recipients: Array<{ + user_id: string + }> + defaultChannels: { + email: boolean + in_app: boolean + } + monitoredUseCases?: string[] + monitoredCodes?: string[] + rules: Array<{ + id?: string + name?: string + type: "critical_error" | "error_threshold" | "warning_threshold" | "success_rate_drop" | "recovery" | "silence" + enabled: boolean + channels?: { + email: { ... } + in_app: { ... } + } + codes?: string[] + threshold?: number | "auto" + sensitivity?: "low" | "medium" | "high" + fallbackThreshold?: number + window?: string + minSampleSize?: number + quietPeriod?: string + }> + digest: { + enabled: boolean + frequency: "daily" | "weekly" + dayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6 + timeOfDay: string + timezone: string + channels: { + email: { ... } + in_app: { ... } + } + includeHealthy: boolean + skipIfEmpty: boolean + } + muteUntil?: string // date-time +} +``` + +### `NotificationRecipient` + +A configured recipient. Only the epilot user_id is stored. + +```ts +type NotificationRecipient = { + user_id: string +} +``` + +### `NotificationChannelSet` + +Delivery channel toggles. New channels added in svc-notification-api inherit here. + +```ts +type NotificationChannelSet = { + email: boolean + in_app: boolean +} +``` + +### `NotificationRule` + +A single notification rule. Only the params relevant to a given type are set. The id is optional on write: the server mints a ULID when omitted and preserves a supplied id verbatim (a stable id keeps a rule's AlertState across config saves). + +```ts +type NotificationRule = { + id?: string + name?: string + type: "critical_error" | "error_threshold" | "warning_threshold" | "success_rate_drop" | "recovery" | "silence" + enabled: boolean + channels?: { + email: boolean + in_app: boolean + } + codes?: string[] + threshold?: number | "auto" + sensitivity?: "low" | "medium" | "high" + fallbackThreshold?: number + window?: string + minSampleSize?: number + quietPeriod?: string +} +``` + +### `NotificationDigestConfig` + +Digest schedule and content configuration. + +```ts +type NotificationDigestConfig = { + enabled: boolean + frequency: "daily" | "weekly" + dayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6 + timeOfDay: string + timezone: string + channels: { + email: boolean + in_app: boolean + } + includeHealthy: boolean + skipIfEmpty: boolean +} +``` + +### `SetIntegrationAppMappingRequest` + +```ts +type SetIntegrationAppMappingRequest = { + app_id: string // uuid + component_id: string // uuid + overwrite?: boolean +} +``` + +### `DeleteIntegrationAppMappingRequest` + +```ts +type DeleteIntegrationAppMappingRequest = { + app_id: string // uuid + component_id: string // uuid +} +``` + +### `IntegrationAppMapping` + +```ts +type IntegrationAppMapping = { + integration_id: string // uuid +} +``` + +### `IntegrationWithUseCases` + +```ts +type IntegrationWithUseCases = { + use_cases: Array<{ + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "inbound" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + direct?: { ... } + interactive?: { ... } + entities?: { ... } + meter_readings?: { ... } + } + } | { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "outbound" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + event_catalog_event: { ... } + event_filter?: { ... } + mappings: { ... } + ack_tracking?: { ... } + } + } | { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "file_proxy" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + direction?: { ... } + upload?: { ... } + fan_out?: { ... } + secure_proxy?: { ... } + auth?: { ... } + params?: { ... } + allowed_origins?: { ... } + steps: { ... } + response?: { ... } + prevent_indirect_serving?: { ... } + } + } | { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "managed_call" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + operation: { ... } + request_mapping?: { ... } + response_mapping?: { ... } + inbound_use_case_slug?: { ... } + } + type_annotations?: { + request?: { ... } + response?: { ... } + } + types_locked?: boolean + } | { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "secure_proxy" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + vpc_mode: { ... } + allowed_domains?: { ... } + allowed_ips?: { ... } + } + }> +} +``` + +### `UpsertIntegrationWithUseCasesRequest` + +```ts +type UpsertIntegrationWithUseCasesRequest = { + name: string + description?: string + access_token_ids?: string[] + app_ids?: string[] + environment_config?: Array<{ + key: string + label: string + type: "String" | "SecretString" + description?: string + required?: boolean + order?: number + }> + maps?: Array<{ + key: string + label: string + description?: string + value: Record + }> + settings?: { + autoRefresh?: { + enabled?: { ... } + freshnessThresholdMinutes?: { ... } + } + notifications?: { + enabled: { ... } + recipients: { ... } + defaultChannels: { ... } + monitoredUseCases?: { ... } + monitoredCodes?: { ... } + rules: { ... } + digest: { ... } + muteUntil?: { ... } + } + } + integration_type?: "erp" | "connector" + connector_config?: { + base_url?: string + auth?: { + type?: { ... } + token_url?: { ... } + client_id?: { ... } + client_secret?: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + api_key_header?: { ... } + api_key?: { ... } + token?: { ... } + } + types_versions?: Array<{ + version: { ... } + package_name: { ... } + generated_at: { ... } + generated_by: { ... } + status: { ... } + }> + latest_types_version?: string + latest_types_package_name?: string + } + protected?: boolean + _manifest?: string[] + use_cases?: Array<{ + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "inbound" + configuration?: { + direct?: { ... } + interactive?: { ... } + entities?: { ... } + meter_readings?: { ... } + } + } | { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "outbound" + configuration?: { + event_catalog_event: { ... } + event_filter?: { ... } + mappings: { ... } + ack_tracking?: { ... } + } + } | { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "file_proxy" + configuration?: { + direction?: { ... } + // ... +} +``` + +### `InboundIntegrationEventConfiguration` + +Configuration for inbound use cases (ERP to epilot) + +```ts +type InboundIntegrationEventConfiguration = { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: string + unique_ids: string[] + jsonataExpression?: string + enabled?: boolean | string + mode?: "upsert" | "delete" | "purge" | "upsert-prune-scope-purge" | "upsert-prune-scope-delete" + scope?: { + scope_mode: { ... } + schema?: { ... } + unique_ids?: { ... } + query?: { ... } + } + fields?: Array<{ + attribute: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + _type?: { ... } + enabled?: { ... } + relations?: { ... } + relation_refs?: { ... } + file_proxy_url?: { ... } + portal_ref?: { ... } + env_var_ref?: { ... } + }> + conditional?: { + from_rows: { ... } + } + sharing?: { + partners: { ... } + } + }> + meter_readings?: Array<{ + jsonataExpression?: string + reading_matching?: "external_id" | "strict-date" + mode?: "upsert" | "delete" | "upsert-prune-scope" + scope?: { + source?: { ... } + } + meter: { + unique_ids: { ... } + } + meter_counter?: { + unique_ids: { ... } + } + fields: Array<{ + attribute: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + _type?: { ... } + enabled?: { ... } + relations?: { ... } + relation_refs?: { ... } + file_proxy_url?: { ... } + portal_ref?: { ... } + env_var_ref?: { ... } + }> + }> +} +``` + +### `OutboundIntegrationEventConfiguration` + +Configuration for outbound use cases. Defines the event that triggers the flow and the webhook mappings. + +```ts +type OutboundIntegrationEventConfiguration = { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: string // uuid + name: string + jsonata_expression?: string + enabled: boolean + delivery: { + type: { ... } + webhook_id: { ... } + webhook_name?: { ... } + webhook_url?: { ... } + } | { + type: { ... } + retention_days?: { ... } + poison_policy?: { ... } + max_delivery_attempts?: { ... } + } | { + type: { ... } + use_case_slug: { ... } + } + created_at?: string // date-time + updated_at?: string // date-time + }> + ack_tracking?: "on" | "off" +} +``` + +### `IntegrationEntity` + +```ts +type IntegrationEntity = { + entity_schema: string + unique_ids: string[] + jsonataExpression?: string + enabled?: boolean | string + mode?: "upsert" | "delete" | "purge" | "upsert-prune-scope-purge" | "upsert-prune-scope-delete" + scope?: { + scope_mode: "relations" | "query" + schema?: string + unique_ids?: Array<{ + attribute: { ... } + _type?: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + }> + query?: Array<{ + attribute: { ... } + _type?: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + }> + } + fields?: Array<{ + attribute: string + field?: string + jsonataExpression?: string + constant?: unknown + _type?: "email" | "phone" + enabled?: boolean | string + relations?: { + operation: { ... } + items?: { ... } + jsonataExpression?: { ... } + } + relation_refs?: { + operation: { ... } + items?: { ... } + jsonataExpression?: { ... } + } + file_proxy_url?: { + use_case_slug: { ... } + params?: { ... } + } | { + use_case_id: { ... } + params?: { ... } + } + portal_ref?: { + filter?: { ... } + select?: { ... } + return?: { ... } + } | { + filter?: { ... } + select?: { ... } + return: { ... } + jsonataExpression: { ... } + } + env_var_ref?: { + key: { ... } + default?: { ... } + return?: { ... } + } | { + key: { ... } + default?: { ... } + return: { ... } + jsonataExpression: { ... } + } + }> + conditional?: { + from_rows: Array<{ + attribute: { ... } + sort_by: { ... } + item: { ... } + }> + } + sharing?: { + partners: Array<{ + partner_org_id: { ... } + enabled?: { ... } + }> + } +} +``` + +### `IntegrationEntitySharing` + +Keeps the mapped entity's sharing with partner organizations in sync. After the entity is written, it is shared with every listed partner whose `enabled` is true and unshared from every listed partner whose `enabled` is false. Changes are computed against the entity's current `_acl`, so a repeated e + +```ts +type IntegrationEntitySharing = { + partners: Array<{ + partner_org_id: string + enabled?: boolean | string + }> +} +``` + +### `IntegrationEntitySharingPartner` + +```ts +type IntegrationEntitySharingPartner = { + partner_org_id: string + enabled?: boolean | string +} +``` + +### `IntegrationEntityConditional` + +Conditional Pricing extras for this target, used when it writes a conditional entity (a Product, Price or Coupon carrying context-dependent variants). The conditions themselves are declared on the entity schema, not here. + +```ts +type IntegrationEntityConditional = { + from_rows: Array<{ + attribute: string + sort_by: { + field: { ... } + } | { + constant: { ... } + } | { + jsonataExpression: { ... } + } + item: Record + }> +} +``` + +### `IntegrationEntityFromRows` + +Build one array attribute from the rows of one variant-version, ordered by a column. A commodity file carries one row per consumption band, while a variant-version holds exactly one `tiers` array. + +```ts +type IntegrationEntityFromRows = { + attribute: string + sort_by: { + field: string + } | { + constant: unknown + } | { + jsonataExpression: string + } + item: Record +} +``` + +### `MappedFieldValue` + +One mapped value. Exactly one of field, constant or jsonataExpression must be set — the same three forms `IntegrationEntityField` accepts. + +```ts +type MappedFieldValue = { + field: string +} | { + constant: unknown +} | { + jsonataExpression: string +} +``` + +### `IntegrationMeterReading` + +```ts +type IntegrationMeterReading = { + jsonataExpression?: string + reading_matching?: "external_id" | "strict-date" + mode?: "upsert" | "delete" | "upsert-prune-scope" + scope?: { + source?: string + } + meter: { + unique_ids: Array<{ + attribute: { ... } + _type?: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + }> + } + meter_counter?: { + unique_ids: Array<{ + attribute: { ... } + _type?: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + }> + } + fields: Array<{ + attribute: string + field?: string + jsonataExpression?: string + constant?: unknown + _type?: "email" | "phone" + enabled?: boolean | string + relations?: { + operation: { ... } + items?: { ... } + jsonataExpression?: { ... } + } + relation_refs?: { + operation: { ... } + items?: { ... } + jsonataExpression?: { ... } + } + file_proxy_url?: { + use_case_slug: { ... } + params?: { ... } + } | { + use_case_id: { ... } + params?: { ... } + } + portal_ref?: { + filter?: { ... } + select?: { ... } + return?: { ... } + } | { + filter?: { ... } + select?: { ... } + return: { ... } + jsonataExpression: { ... } + } + env_var_ref?: { + key: { ... } + default?: { ... } + return?: { ... } + } | { + key: { ... } + default?: { ... } + return: { ... } + jsonataExpression: { ... } + } + }> +} +``` + +### `PruneScopeConfig` + +Scope configuration for upsert-prune-scope modes. +Defines how to find entities that should be pruned if not in the upsert payload. +The scope is resolved against the original event payload (not individual array items). + + +```ts +type PruneScopeConfig = { + scope_mode: "relations" | "query" + schema?: string + unique_ids?: Array<{ + attribute: string + _type?: "email" | "phone" + field?: string + jsonataExpression?: string + constant?: unknown + }> + query?: Array<{ + attribute: string + _type?: "email" | "phone" + field?: string + jsonataExpression?: string + constant?: unknown + }> +} +``` + +### `MeterReadingPruneScopeConfig` + +Scope configuration for meter reading upsert-prune-scope mode. +The scope is all readings for the same meter + counter. + + +```ts +type MeterReadingPruneScopeConfig = { + source?: string +} +``` + +### `MeterUniqueIdsConfig` + +```ts +type MeterUniqueIdsConfig = { + unique_ids: Array<{ + attribute: string + _type?: "email" | "phone" + field?: string + jsonataExpression?: string + constant?: unknown + }> +} +``` + +### `IntegrationEntityField` + +```ts +type IntegrationEntityField = { + attribute: string + field?: string + jsonataExpression?: string + constant?: unknown + _type?: "email" | "phone" + enabled?: boolean | string + relations?: { + operation: "_set" | "_append" | "_append_all" + items?: Array<{ + entity_schema: { ... } + _tags?: { ... } + unique_ids: { ... } + required?: { ... } + }> + jsonataExpression?: string + } + relation_refs?: { + operation: "_set" | "_append" | "_append_all" + items?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + path: { ... } + value: { ... } + }> + jsonataExpression?: string + } + file_proxy_url?: { + use_case_slug: string + params?: Record + } | { + use_case_id: string + params?: Record + } + portal_ref?: { + filter?: { + origin?: { ... } + enabled?: { ... } + is_dummy?: { ... } + is_epilot_domain?: { ... } + name?: { ... } + domain?: { ... } + } + select?: "single" | "all" + return?: "portal_id" | "origin" | "domain" | "name" + } | { + filter?: { + origin?: { ... } + enabled?: { ... } + is_dummy?: { ... } + is_epilot_domain?: { ... } + name?: { ... } + domain?: { ... } + } + select?: "single" | "all" + return: "jsonata" + jsonataExpression: string + } + env_var_ref?: { + key: string + default?: string + return?: "value" + } | { + key: string + default?: string + return: "jsonata" + jsonataExpression: string + } +} +``` + +### `FileProxyUrlParam` + +Parameter for file proxy URL. Exactly one of field, constant, or jsonataExpression must be set. + +```ts +type FileProxyUrlParam = { + field: string +} | { + constant: unknown +} | { + jsonataExpression: string +} +``` + +### `FileProxyUrlParams` + +Custom query parameters. Keys become URL param names, values resolved from payload. + +```ts +type FileProxyUrlParams = Record +``` + +### `FileProxyUrlConfig` + +Auto-constructs a file proxy download URL. orgId and integrationId are injected from context. Exactly one of use_case_id or use_case_slug must be provided. Using use_case_slug is recommended as it is portable across environments. + + +```ts +type FileProxyUrlConfig = { + use_case_slug: string + params?: Record +} | { + use_case_id: string + params?: Record +} +``` + +### `PortalOrigin` + +Origin/type of an epilot portal configuration. + +```ts +type PortalOrigin = "END_CUSTOMER_PORTAL" | "INSTALLER_PORTAL" | "B2B_PORTAL" | "ADDITIONAL_PORTAL" +``` + +### `PortalRefFilter` + +Filter applied to the org's portal configurations before selection. All filters default to "match any" except `enabled` (default `true`) and `is_dummy` (default `false`). Set `enabled` or `is_dummy` to `null` to opt out of the default. + + +```ts +type PortalRefFilter = { + origin?: "END_CUSTOMER_PORTAL" | "INSTALLER_PORTAL" | "B2B_PORTAL" | "ADDITIONAL_PORTAL" | "END_CUSTOMER_PORTAL" | "INSTALLER_PORTAL" | "B2B_PORTAL" | "ADDITIONAL_PORTAL"[] + enabled?: boolean + is_dummy?: boolean + is_epilot_domain?: boolean + name?: string + domain?: string +} +``` + +### `PortalRefConfig` + +Resolves to a property of one of the calling organization's epilot portal configurations at runtime, replacing hard-coded environment-specific portal UUIDs in inbound mappings. Matched portals are sorted ascending by `(_created_at, portal_id)`; portals without `_created_at` sort first (treated as ol + +```ts +type PortalRefConfig = { + filter?: { + origin?: "END_CUSTOMER_PORTAL" | "INSTALLER_PORTAL" | "B2B_PORTAL" | "ADDITIONAL_PORTAL" | "END_CUSTOMER_PORTAL" | "INSTALLER_PORTAL" | "B2B_PORTAL" | "ADDITIONAL_PORTAL"[] + enabled?: boolean + is_dummy?: boolean + is_epilot_domain?: boolean + name?: string + domain?: string + } + select?: "single" | "all" + return?: "portal_id" | "origin" | "domain" | "name" +} | { + filter?: { + origin?: "END_CUSTOMER_PORTAL" | "INSTALLER_PORTAL" | "B2B_PORTAL" | "ADDITIONAL_PORTAL" | "END_CUSTOMER_PORTAL" | "INSTALLER_PORTAL" | "B2B_PORTAL" | "ADDITIONAL_PORTAL"[] + enabled?: boolean + is_dummy?: boolean + is_epilot_domain?: boolean + name?: string + domain?: string + } + select?: "single" | "all" + return: "jsonata" + jsonataExpression: string +} +``` + +### `EnvVarRefConfig` + +Resolves to an org-scoped environment variable from the epilot environments-api service at runtime, replacing hard-coded environment-specific values (URLs, prefixes, identifiers) in inbound mappings. Secrets (`SecretString` values) are never exposed; the runtime treats both "missing key" and "secret + +```ts +type EnvVarRefConfig = { + key: string + default?: string + return?: "value" +} | { + key: string + default?: string + return: "jsonata" + jsonataExpression: string +} +``` + +### `EmbeddedUseCaseRequest` + +```ts +type EmbeddedUseCaseRequest = { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "inbound" + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} | { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "outbound" + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} | { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "file_proxy" + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + required: { ... } + description?: { ... } + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: { ... } + method: { ... } + headers?: { ... } + body_jsonata?: { ... } + enabled?: { ... } + body?: { ... } + response_type: { ... } + // ... +} +``` + +### `EmbeddedUseCaseRequestBase` + +```ts +type EmbeddedUseCaseRequestBase = { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string +} +``` + +### `EmbeddedInboundUseCaseRequest` + +```ts +type EmbeddedInboundUseCaseRequest = { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "inbound" + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} +``` + +### `EmbeddedOutboundUseCaseRequest` + +```ts +type EmbeddedOutboundUseCaseRequest = { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "outbound" + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} +``` + +### `EmbeddedFileProxyUseCaseRequest` + +```ts +type EmbeddedFileProxyUseCaseRequest = { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "file_proxy" + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + required: { ... } + description?: { ... } + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: { ... } + method: { ... } + headers?: { ... } + body_jsonata?: { ... } + enabled?: { ... } + body?: { ... } + response_type: { ... } + }> + response?: { + body: { ... } + encoding: { ... } + filename?: { ... } + content_type?: { ... } + } + prevent_indirect_serving?: boolean + } +} +``` + +### `EmbeddedManagedCallUseCaseRequest` + +```ts +type EmbeddedManagedCallUseCaseRequest = { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "managed_call" + configuration?: { + operation: { + method: { ... } + path: { ... } + headers?: { ... } + query_params?: { ... } + } + request_mapping?: string + response_mapping?: string + inbound_use_case_slug?: string + } +} +``` + +### `EmbeddedSecureProxyUseCaseRequest` + +```ts +type EmbeddedSecureProxyUseCaseRequest = { + id?: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + type: "secure_proxy" + configuration?: { + vpc_mode: "static_ip" | "secure_link" + allowed_domains?: string[] + allowed_ips?: string[] + } +} +``` + +### `UseCaseBase` + +```ts +type UseCaseBase = { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `InboundUseCase` + +```ts +type InboundUseCase = { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "inbound" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} +``` + +### `OutboundUseCase` + +```ts +type OutboundUseCase = { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "outbound" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} +``` + +### `FileProxyUseCase` + +```ts +type FileProxyUseCase = { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "file_proxy" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + required: { ... } + description?: { ... } + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: { ... } + method: { ... } + headers?: { ... } + body_jsonata?: { ... } + enabled?: { ... } + body?: { ... } + response_type: { ... } + }> + response?: { + body: { ... } + encoding: { ... } + filename?: { ... } + content_type?: { ... } + } + prevent_indirect_serving?: boolean + } +} +``` + +### `ManagedCallUseCase` + +```ts +type ManagedCallUseCase = { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "managed_call" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + operation: { + method: { ... } + path: { ... } + headers?: { ... } + query_params?: { ... } + } + request_mapping?: string + response_mapping?: string + inbound_use_case_slug?: string + } + type_annotations?: { + request?: Record + response?: Record + } + types_locked?: boolean +} +``` + +### `SecureProxyUseCase` + +```ts +type SecureProxyUseCase = { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "secure_proxy" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + vpc_mode: "static_ip" | "secure_link" + allowed_domains?: string[] + allowed_ips?: string[] + } +} +``` + +### `UseCase` + +```ts +type UseCase = { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "inbound" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} | { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "outbound" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} | { + id: string // uuid + integrationId: string // uuid + name: string + slug?: string + type: "file_proxy" + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + // ... +} +``` + +### `CreateUseCaseRequest` + +```ts +type CreateUseCaseRequest = { + name: string + slug: string + enabled: boolean + type: "inbound" + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} | { + name: string + slug: string + enabled: boolean + type: "outbound" + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} | { + name: string + slug: string + enabled: boolean + type: "file_proxy" + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + required: { ... } + description?: { ... } + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: { ... } + method: { ... } + headers?: { ... } + body_jsonata?: { ... } + enabled?: { ... } + body?: { ... } + response_type: { ... } + }> + response?: { + body: { ... } + encoding: { ... } + filename?: { ... } + content_type?: { ... } + // ... +} +``` + +### `CreateUseCaseRequestBase` + +```ts +type CreateUseCaseRequestBase = { + name: string + slug: string + enabled: boolean +} +``` + +### `CreateInboundUseCaseRequest` + +```ts +type CreateInboundUseCaseRequest = { + name: string + slug: string + enabled: boolean + type: "inbound" + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} +``` + +### `CreateOutboundUseCaseRequest` + +```ts +type CreateOutboundUseCaseRequest = { + name: string + slug: string + enabled: boolean + type: "outbound" + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} +``` + +### `CreateFileProxyUseCaseRequest` + +```ts +type CreateFileProxyUseCaseRequest = { + name: string + slug: string + enabled: boolean + type: "file_proxy" + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + required: { ... } + description?: { ... } + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: { ... } + method: { ... } + headers?: { ... } + body_jsonata?: { ... } + enabled?: { ... } + body?: { ... } + response_type: { ... } + }> + response?: { + body: { ... } + encoding: { ... } + filename?: { ... } + content_type?: { ... } + } + prevent_indirect_serving?: boolean + } +} +``` + +### `CreateManagedCallUseCaseRequest` + +```ts +type CreateManagedCallUseCaseRequest = { + name: string + slug: string + enabled: boolean + type: "managed_call" + configuration?: { + operation: { + method: { ... } + path: { ... } + headers?: { ... } + query_params?: { ... } + } + request_mapping?: string + response_mapping?: string + inbound_use_case_slug?: string + } +} +``` + +### `CreateSecureProxyUseCaseRequest` + +```ts +type CreateSecureProxyUseCaseRequest = { + name: string + slug: string + enabled: boolean + type: "secure_proxy" + configuration?: { + vpc_mode: "static_ip" | "secure_link" + allowed_domains?: string[] + allowed_ips?: string[] + } +} +``` + +### `UpdateUseCaseRequest` + +```ts +type UpdateUseCaseRequest = { + name?: string + slug?: string + enabled?: boolean + change_description?: string + type?: "inbound" + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} | { + name?: string + slug?: string + enabled?: boolean + change_description?: string + type?: "outbound" + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} | { + name?: string + slug?: string + enabled?: boolean + change_description?: string + type?: "file_proxy" + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + required: { ... } + description?: { ... } + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: { ... } + method: { ... } + headers?: { ... } + body_jsonata?: { ... } + enabled?: { ... } + body?: { ... } + response_type: { ... } + }> + response?: { + body: { ... } + // ... +} +``` + +### `UpdateUseCaseRequestBase` + +```ts +type UpdateUseCaseRequestBase = { + name?: string + slug?: string + enabled?: boolean + change_description?: string +} +``` + +### `UpdateInboundUseCaseRequest` + +```ts +type UpdateInboundUseCaseRequest = { + name?: string + slug?: string + enabled?: boolean + change_description?: string + type?: "inbound" + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} +``` + +### `UpdateOutboundUseCaseRequest` + +```ts +type UpdateOutboundUseCaseRequest = { + name?: string + slug?: string + enabled?: boolean + change_description?: string + type?: "outbound" + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} +``` + +### `UpdateFileProxyUseCaseRequest` + +```ts +type UpdateFileProxyUseCaseRequest = { + name?: string + slug?: string + enabled?: boolean + change_description?: string + type?: "file_proxy" + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + required: { ... } + description?: { ... } + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: { ... } + method: { ... } + headers?: { ... } + body_jsonata?: { ... } + enabled?: { ... } + body?: { ... } + response_type: { ... } + }> + response?: { + body: { ... } + encoding: { ... } + filename?: { ... } + content_type?: { ... } + } + prevent_indirect_serving?: boolean + } +} +``` + +### `UpdateManagedCallUseCaseRequest` + +```ts +type UpdateManagedCallUseCaseRequest = { + name?: string + slug?: string + enabled?: boolean + change_description?: string + type?: "managed_call" + configuration?: { + operation: { + method: { ... } + path: { ... } + headers?: { ... } + query_params?: { ... } + } + request_mapping?: string + response_mapping?: string + inbound_use_case_slug?: string + } + type_annotations?: { + request?: Record + response?: Record + } +} +``` + +### `UpdateSecureProxyUseCaseRequest` + +```ts +type UpdateSecureProxyUseCaseRequest = { + name?: string + slug?: string + enabled?: boolean + change_description?: string + type?: "secure_proxy" + configuration?: { + vpc_mode: "static_ip" | "secure_link" + allowed_domains?: string[] + allowed_ips?: string[] + } +} +``` + +### `UseCaseHistoryEntry` + +```ts +type UseCaseHistoryEntry = { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time + type: "inbound" + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} | { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time + type: "outbound" + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} | { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time + type: "file_proxy" + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + // ... +} +``` + +### `UseCaseHistoryEntryBase` + +```ts +type UseCaseHistoryEntryBase = { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time +} +``` + +### `InboundUseCaseHistoryEntry` + +```ts +type InboundUseCaseHistoryEntry = { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time + type: "inbound" + configuration?: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } +} +``` + +### `OutboundUseCaseHistoryEntry` + +```ts +type OutboundUseCaseHistoryEntry = { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time + type: "outbound" + configuration?: { + event_catalog_event: string + event_filter?: string + mappings: Array<{ + id?: { ... } + name: { ... } + jsonata_expression?: { ... } + enabled: { ... } + delivery: { ... } + created_at?: { ... } + updated_at?: { ... } + }> + ack_tracking?: "on" | "off" + } +} +``` + +### `FileProxyUseCaseHistoryEntry` + +```ts +type FileProxyUseCaseHistoryEntry = { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time + type: "file_proxy" + configuration?: { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: { ... } + max_file_bytes?: { ... } + max_delivery_attempts?: { ... } + } + fan_out?: { + enabled: { ... } + } + secure_proxy?: { + use_case_slug: { ... } + } + auth?: { + type: { ... } + token_url: { ... } + client_id: { ... } + client_secret: { ... } + scope?: { ... } + audience?: { ... } + resource?: { ... } + username?: { ... } + password?: { ... } + body_params?: { ... } + headers?: { ... } + query_params?: { ... } + } + params?: Array<{ + name: { ... } + required: { ... } + description?: { ... } + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: { ... } + method: { ... } + headers?: { ... } + body_jsonata?: { ... } + enabled?: { ... } + body?: { ... } + response_type: { ... } + }> + response?: { + body: { ... } + encoding: { ... } + filename?: { ... } + content_type?: { ... } + } + prevent_indirect_serving?: boolean + } +} +``` + +### `ManagedCallUseCaseHistoryEntry` + +```ts +type ManagedCallUseCaseHistoryEntry = { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time + type: "managed_call" + configuration?: { + operation: { + method: { ... } + path: { ... } + headers?: { ... } + query_params?: { ... } + } + request_mapping?: string + response_mapping?: string + inbound_use_case_slug?: string + } + type_annotations?: { + request?: Record + response?: Record + } + types_locked?: boolean +} +``` + +### `SecureProxyUseCaseHistoryEntry` + +```ts +type SecureProxyUseCaseHistoryEntry = { + id: string // uuid + useCaseId: string // uuid + integrationId: string // uuid + name: string + slug?: string + enabled: boolean + change_description?: string + changed_by?: string + created_at: string // date-time + updated_at: string // date-time + history_created_at: string // date-time + type: "secure_proxy" + configuration?: { + vpc_mode: "static_ip" | "secure_link" + allowed_domains?: string[] + allowed_ips?: string[] + } +} +``` + +### `SecureProxyUseCaseConfiguration` + +Configuration for secure_proxy use cases. Defines how to route requests through a secure VPC. + + +```ts +type SecureProxyUseCaseConfiguration = { + vpc_mode: "static_ip" | "secure_link" + allowed_domains?: string[] + allowed_ips?: string[] +} +``` + +### `SecureProxyWhitelist` + +Current whitelist state for a secure_proxy use case. vpc_mode is read-only +context so the UI can show the user what mode the pool is in. + + +```ts +type SecureProxyWhitelist = { + vpc_mode: "static_ip" | "secure_link" + allowed_domains: string[] + allowed_ips: string[] +} +``` + +### `SecureProxyWhitelistUpdate` + +Partial update for a secure_proxy whitelist. At least one of +`allowed_domains` or `allowed_ips` must be provided. + +Per-field semantics: + - **omitted** — the field is not modified; the stored value is preserved. + - **non-empty array** — the stored value is replaced with the supplied list. + - **emp + +```ts +type SecureProxyWhitelistUpdate = { + allowed_domains?: string[] + allowed_ips?: string[] +} +``` + +### `SecureProxySummary` + +```ts +type SecureProxySummary = { + id: string // uuid + name: string + slug?: string + enabled: boolean + vpc_mode: "static_ip" | "secure_link" + allowed_domains?: string[] + allowed_ips?: string[] + integration_id: string // uuid + integration_name: string +} +``` + +### `SecureProxyRequest` + +```ts +type SecureProxyRequest = { + integration_id: string // uuid + use_case_id?: string // uuid + use_case_slug?: string + url: string // uri + method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" + headers?: Record + body?: unknown + response_type?: "json" | "binary" +} +``` + +### `SecureProxyResponse` + +```ts +type SecureProxyResponse = { + status_code?: number + headers?: Record + body?: unknown +} +``` + +### `SecureProxyUpstreamError` + +Error payload returned when epilot could not obtain an HTTP response from the proxied target. The failure is epilot-generated (HTTP 502) but the cause is usually remote-side; `code`/`reason` make that attributable. + +```ts +type SecureProxyUpstreamError = { + message: "Upstream network error" | "Upstream error" + code?: string + reason?: string +} +``` + +### `ManagedCallOperationConfig` + +Configuration for managed_call use cases. Defines a single API operation with JSONata mapping. + +```ts +type ManagedCallOperationConfig = { + operation: { + method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" + path: string + headers?: Record + query_params?: Record + } + request_mapping?: string + response_mapping?: string + inbound_use_case_slug?: string +} +``` + +### `ManagedCallOperation` + +HTTP operation configuration for managed calls + +```ts +type ManagedCallOperation = { + method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" + path: string + headers?: Record + query_params?: Record +} +``` + +### `ManagedCallExecuteRequest` + +```ts +type ManagedCallExecuteRequest = { + integration_id: string // uuid + payload?: Record + correlation_id?: string +} +``` + +### `ManagedCallExecuteResponse` + +The response from a managed call execution. +On success, returns the JSONata-mapped response data directly (no wrapper). +The shape is entirely defined by your response_mapping JSONata expression. +If no response_mapping is configured, returns the raw external API response. +Check the X-Inbound-Event-Id + +```ts +type ManagedCallExecuteResponse = unknown +``` + +### `ManagedCallErrorResponse` + +```ts +type ManagedCallErrorResponse = { + error: { + code: string + message: string + details?: Record + } +} +``` + +### `TypeAnnotations` + +Developer-provided type annotations for a use case's request and response fields + +```ts +type TypeAnnotations = { + request?: Record + response?: Record +} +``` + +### `TypeDescriptor` + +Describes the inferred type shape of a JSONata expression + +```ts +type TypeDescriptor = { + kind: "object" | "array" | "string" | "number" | "boolean" | "null" | "unknown" | "union" + properties?: Record + items?: { ... } + source?: string + variants?: { ... }[] +} +``` + +### `UseCaseTypePreview` + +Scaffolded type descriptors for a single use case + +```ts +type UseCaseTypePreview = { + slug: string + name?: string + request_shape: { + kind: "object" | "array" | "string" | "number" | "boolean" | "null" | "unknown" | "union" + properties?: Record + items?: { ... } + source?: string + variants?: { ... }[] + } + response_shape: { + kind: "object" | "array" | "string" | "number" | "boolean" | "null" | "unknown" | "union" + properties?: Record + items?: { ... } + source?: string + variants?: { ... }[] + } + existing_annotations?: { + request?: Record + response?: Record + } +} +``` + +### `GenerateTypesPreviewResponse` + +```ts +type GenerateTypesPreviewResponse = { + integration_name?: string + use_cases: Array<{ + slug: string + name?: string + request_shape: { + kind: { ... } + properties?: { ... } + items?: { ... } + source?: { ... } + variants?: { ... } + } + response_shape: { + kind: { ... } + properties?: { ... } + items?: { ... } + source?: { ... } + variants?: { ... } + } + existing_annotations?: { + request?: { ... } + response?: { ... } + } + }> + previous_version?: string + suggested_version?: string + suggested_bump?: "major" | "minor" + detected_changes?: Array<{ + slug: string + field: string + type: "breaking" | "non-breaking" + description: string + }> +} +``` + +### `GenerateTypesRequest` + +```ts +type GenerateTypesRequest = { + package_name: string + version: string + description?: string + domain_package?: string + domain_map_name?: string + annotations?: Record + response?: Record + }> +} +``` + +### `GenerateTypesResponse` + +```ts +type GenerateTypesResponse = { + package_name: string + version: string + files: Record + warnings?: string[] +} +``` + +### `CommitTypesRequest` + +```ts +type CommitTypesRequest = { + package_name: string + version: string + annotations?: Record + response?: Record + }> +} +``` + +### `CommitTypesResponse` + +```ts +type CommitTypesResponse = { + committed: boolean + warnings?: string[] +} +``` + +### `FileProxyUseCaseConfiguration` + +Configuration for file_proxy use cases. Defines how to authenticate and move files +between epilot and an external document system, in either direction (see `direction`). + +**Download** (`direction: download`, the default) fetches a file from the external system +and serves it to a browser. The downloa + +```ts +type FileProxyUseCaseConfiguration = { + direction?: "download" | "upload" + upload?: { + max_total_bytes?: number + max_file_bytes?: number + max_delivery_attempts?: number + } + fan_out?: { + enabled: boolean + } + secure_proxy?: { + use_case_slug: string + } + auth?: { + type: "oauth2_client_credentials" | "oauth2_password" + token_url: string + client_id: string + client_secret: string + scope?: string + audience?: string + resource?: string + username?: string + password?: string + body_params?: Record + headers?: Record + query_params?: Record + } + params?: Array<{ + name: string + required: boolean + description?: string + }> + allowed_origins?: string // uri[] + steps: Array<{ + url: string + method: "GET" | "POST" | "PUT" | "PATCH" + headers?: Record + body_jsonata?: string + enabled?: string + body?: string + response_type: "json" | "binary" + }> + response?: { + body: string + encoding: "base64" | "binary" + filename?: string + content_type?: string + } + prevent_indirect_serving?: boolean +} +``` + +### `FileProxySecureProxyAttachment` + +```ts +type FileProxySecureProxyAttachment = { + use_case_slug: string +} +``` + +### `FileProxyAuth` + +```ts +type FileProxyAuth = { + type: "oauth2_client_credentials" | "oauth2_password" + token_url: string + client_id: string + client_secret: string + scope?: string + audience?: string + resource?: string + username?: string + password?: string + body_params?: Record + headers?: Record + query_params?: Record +} +``` + +### `FileProxyParam` + +```ts +type FileProxyParam = { + name: string + required: boolean + description?: string +} +``` + +### `FileProxyStep` + +```ts +type FileProxyStep = { + url: string + method: "GET" | "POST" | "PUT" | "PATCH" + headers?: Record + body_jsonata?: string + enabled?: string + body?: string + response_type: "json" | "binary" +} +``` + +### `FileProxyFanOutConfig` + +Whether one event produces one delivery per file, or a single delivery carrying all of +them. The split is always over the event's `event_attachments` — there is no expression +to write, because an upload only ever runs on events that declare that field. + +Each resulting delivery is fully independent: + +```ts +type FileProxyFanOutConfig = { + enabled: boolean +} +``` + +### `FileProxyUploadConfig` + +Upload-side settings for a file_proxy use case with `direction: upload`. +The surrounding file_proxy configuration owns WHAT and HOW to send: `fan_out`, +auth, and the steps with their `body_jsonata`. This nested object governs +upload-specific limits and how the final external response is judged. The + + +```ts +type FileProxyUploadConfig = { + max_total_bytes?: number + max_file_bytes?: number + max_delivery_attempts?: number +} +``` + +### `FileProxyResponseConfig` + +How to extract the file from the step results. REQUIRED when `direction` is `download`; +rejected when `direction` is `upload` (an upload has no file to extract). + + +```ts +type FileProxyResponseConfig = { + body: string + encoding: "base64" | "binary" + filename?: string + content_type?: string +} +``` + +### `MappingSimulationRequest` + +```ts +type MappingSimulationRequest = { + mapping_configuration: { + version?: "1.0" + mapping: { + objects: { ... } + } + } | { + version: "2.0" + mapping: { + events: { ... } + } + } + object_type: string + format: "json" | "xml" + payload: string | Record +} +``` + +### `MappingSimulationV2Request` + +Request for v2 mapping simulation. Uses the same configuration format stored in integration use case resources, +making it easier to test configurations before saving them. + + +```ts +type MappingSimulationV2Request = { + event_configuration: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } + format: "json" | "xml" + payload: string | Record +} +``` + +### `MappingSimulationResponse` + +```ts +type MappingSimulationResponse = { + entity_updates: Array<{ + entity_slug: string + unique_identifiers: Record + attributes: Record + pricing?: { + config: { ... } + data: { ... } + } + sharing?: Record + mode: "upsert" | "delete" | "purge" + }> + meter_readings_updates?: Array<{ + meter: { + $entity_unique_ids: { ... } + } + meter_counter?: { + $entity_unique_ids?: { ... } + } + attributes: Record + mode: "upsert" | "delete" + }> + prune_scope_updates?: Array<{ + entity_slug: string + scope: { + scope_mode: { ... } + schema?: { ... } + unique_ids?: { ... } + query?: { ... } + } + keep_unique_ids: Record[] + deletion_mode: "delete" | "purge" + }> + meter_readings_prune_scope_updates?: Array<{ + meter: { + $entity_unique_ids: { ... } + } + meter_counter?: { + $entity_unique_ids?: { ... } + } + keep_external_ids: string[] + source?: string + }> + warnings?: Array<{ + entity_schema: string + field: string + message: string + }> +} +``` + +### `MappingSimulationWarning` + +```ts +type MappingSimulationWarning = { + entity_schema: string + field: string + message: string +} +``` + +### `DirectPayload` + +The payload of an ERP event routed to a `direct: true` use case: a versioned envelope of +pre-mapped operations that skip the mapping engine. Sent as the `payload` of an +`ErpEventV3` - either as a JSON object or as a JSON string (`format` must be `json`; +XML is rejected for direct use cases). + +The sc + +```ts +type DirectPayload = { + version: string + operations: Array<{ + type?: "entity" + entity_slug: string + unique_ids: Record + unique_id_types?: Record + mode?: "upsert" | "delete" | "purge" + attributes?: Record + } | { + type: "meter_reading" + meter: { + unique_ids: { ... } + } + counter?: { + unique_ids: { ... } + } + mode?: "upsert" | "delete" + reading_matching?: "external_id" | "strict-date" + attributes: { + external_id: { ... } + timestamp: { ... } + source: { ... } + value: { ... } + } + }> +} +``` + +### `DirectEntityOperation` + +A single pre-mapped entity operation: upserts, soft-deletes, or purges one entity, +identified by its unique ids. Produces the same internal update as a mapped-mode entity +configuration, so create-vs-update resolution, relation resolution, ordering, and +monitoring behave identically. + + +```ts +type DirectEntityOperation = { + type?: "entity" + entity_slug: string + unique_ids: Record + unique_id_types?: Record + mode?: "upsert" | "delete" | "purge" + attributes?: Record | { + _set?: { ... } + _append?: { ... } + _append_all?: { ... } + } + } | { + $relation_ref: Array<{ + schema: { ... } + unique_ids: { ... } + unique_id_types?: { ... } + path: { ... } + value: { ... } + }> | { + _set?: { ... } + _append?: { ... } + _append_all?: { ... } + } + } | unknown> +} +``` + +### `DirectMeterReadingOperation` + +A single pre-mapped meter reading operation: upserts or deletes one reading on a meter +(and optionally a specific counter), identified by their unique ids. Produces the same +internal update as a mapped-mode meter reading configuration. + + +```ts +type DirectMeterReadingOperation = { + type: "meter_reading" + meter: { + unique_ids: Record + } + counter?: { + unique_ids: Record + } + mode?: "upsert" | "delete" + reading_matching?: "external_id" | "strict-date" + attributes: { + external_id: string | number + timestamp: string + source: "ECP" | "ERP" | "360" | "journey-submission" + value: number | string + } +} +``` + +### `DirectRelationValue` + +An entity attribute value that establishes relations to other entities. Written on any +attribute inside a direct entity operation's `attributes`. + +Two forms are accepted: a bare array of items (shorthand for `_set`, i.e. replace), or +an object with EXACTLY ONE of the operations `_set` (replace), `_a + +```ts +type DirectRelationValue = { + $relation: Array<{ + entity_id?: string + schema?: string + unique_ids?: Record + unique_id_types?: Record + tags?: string[] + }> | { + _set?: Array<{ + entity_id?: { ... } + schema?: { ... } + unique_ids?: { ... } + unique_id_types?: { ... } + tags?: { ... } + }> + _append?: Array<{ + entity_id?: { ... } + schema?: { ... } + unique_ids?: { ... } + unique_id_types?: { ... } + tags?: { ... } + }> + _append_all?: Array<{ + entity_id?: { ... } + schema?: { ... } + unique_ids?: { ... } + unique_id_types?: { ... } + tags?: { ... } + }> + } +} +``` + +### `DirectRelationItem` + +One relation target: either an already-resolved reference (`entity_id`), or a lookup by +unique ids (`schema` + `unique_ids`, resolved by the pipeline like any other unique-id +lookup, including stub creation and retry when the target does not exist yet). The two +forms are mutually exclusive. Use `_id + +```ts +type DirectRelationItem = { + entity_id?: string + schema?: string + unique_ids?: Record + unique_id_types?: Record + tags?: string[] +} +``` + +### `DirectRelationRefValue` + +An entity attribute value that references an ITEM INSIDE a repeatable attribute of +another entity - for example one address out of a contact's `address` list. The target +entity is looked up by unique ids, then the item at `path` matching `value` is +referenced (creating it when missing). + +The same op + +```ts +type DirectRelationRefValue = { + $relation_ref: Array<{ + schema: string + unique_ids: Record + unique_id_types?: Record + path: string + value: unknown + }> | { + _set?: Array<{ + schema: { ... } + unique_ids: { ... } + unique_id_types?: { ... } + path: { ... } + value: { ... } + }> + _append?: Array<{ + schema: { ... } + unique_ids: { ... } + unique_id_types?: { ... } + path: { ... } + value: { ... } + }> + _append_all?: Array<{ + schema: { ... } + unique_ids: { ... } + unique_id_types?: { ... } + path: { ... } + value: { ... } + }> + } +} +``` + +### `DirectRelationRefItem` + +One relation-ref target - the entity to look up, and the repeatable item to reference on it. + +```ts +type DirectRelationRefItem = { + schema: string + unique_ids: Record + unique_id_types?: Record + path: string + value: unknown +} +``` + +### `DirectSimulationRequest` + +Request for a direct-mode dry run: the `direct: true` use case configuration to test +against, and the payload to validate and translate. + + +```ts +type DirectSimulationRequest = { + event_configuration: { + direct?: boolean + interactive?: "disabled" | "on_request" | "always" + entities?: Array<{ + entity_schema: { ... } + unique_ids: { ... } + jsonataExpression?: { ... } + enabled?: { ... } + mode?: { ... } + scope?: { ... } + fields?: { ... } + conditional?: { ... } + sharing?: { ... } + }> + meter_readings?: Array<{ + jsonataExpression?: { ... } + reading_matching?: { ... } + mode?: { ... } + scope?: { ... } + meter: { ... } + meter_counter?: { ... } + fields: { ... } + }> + } + payload: string | { + version: string + operations: Array<{ + type?: { ... } + entity_slug: { ... } + unique_ids: { ... } + unique_id_types?: { ... } + mode?: { ... } + attributes?: { ... } + } | { + type: { ... } + meter: { ... } + counter?: { ... } + mode?: { ... } + reading_matching?: { ... } + attributes: { ... } + }> + } +} +``` + +### `DirectSimulationResponse` + +Result of a direct-mode dry run. `valid: false` responses list EVERY violation found +across all operations in `errors`. `valid: true` responses preview the internal updates +the pipeline would apply, plus non-blocking `warnings`. + + +```ts +type DirectSimulationResponse = { + valid: boolean + errors: Array<{ + code: "DIRECT_PAYLOAD_INVALID" | "DIRECT_VERSION_UNSUPPORTED" | "DIRECT_ENTITY_NOT_ALLOWED" + message: string + operation_index?: number + }> + warnings?: Array<{ + entity_schema: string + field: string + message: string + }> + entity_updates?: Array<{ + entity_slug: string + unique_identifiers: Record + attributes: Record + pricing?: { + config: { ... } + data: { ... } + } + sharing?: Record + mode: "upsert" | "delete" | "purge" + unique_identifiers_metadata?: Record + }> + meter_reading_updates?: Array<{ + meter: { + $entity_unique_ids: { ... } + } + meter_counter?: { + $entity_unique_ids?: { ... } + } + attributes: Record + mode: "upsert" | "delete" + _config?: { + reading_matching?: { ... } + } + }> +} +``` + +### `DirectSimulationError` + +One validation error found during a direct-mode dry run. + +```ts +type DirectSimulationError = { + code: "DIRECT_PAYLOAD_INVALID" | "DIRECT_VERSION_UNSUPPORTED" | "DIRECT_ENTITY_NOT_ALLOWED" + message: string + operation_index?: number +} +``` + +### `EntityUpdate` + +```ts +type EntityUpdate = { + entity_slug: string + unique_identifiers: Record + attributes: Record + pricing?: { + config: Record + data: Record[] + } + sharing?: Record + mode: "upsert" | "delete" | "purge" +} +``` + +### `MeterReadingUpdate` + +```ts +type MeterReadingUpdate = { + meter: { + $entity_unique_ids: Record + } + meter_counter?: { + $entity_unique_ids?: Record + } + attributes: Record + mode: "upsert" | "delete" +} +``` + +### `EntityPruneScopeUpdate` + +A resolved entity prune scope. At runtime, entities of `entity_slug` found within `scope` whose unique identifiers are not listed in `keep_unique_ids` are removed using `deletion_mode`. + +```ts +type EntityPruneScopeUpdate = { + entity_slug: string + scope: { + scope_mode: "relations" | "query" + schema?: string + unique_ids?: Record + query?: Record + } + keep_unique_ids: Record[] + deletion_mode: "delete" | "purge" +} +``` + +### `MeterReadingPruneScopeUpdate` + +A resolved meter reading prune scope. At runtime, readings of the given meter (+ counter) whose external ids are not listed in `keep_external_ids` are deleted. + +```ts +type MeterReadingPruneScopeUpdate = { + meter: { + $entity_unique_ids: Record + } + meter_counter?: { + $entity_unique_ids?: Record + } + keep_external_ids: string[] + source?: string +} +``` + +### `IntegrationConfigurationV1` + +```ts +type IntegrationConfigurationV1 = { + version?: "1.0" + mapping: { + objects: Record + } +} +``` + +### `IntegrationObjectV1` + +```ts +type IntegrationObjectV1 = { + unique_ids: Record> + fields: Array<{ + entity: string + attribute: string + field?: string + jsonataExpression?: string + }> +} +``` + +### `IntegrationFieldV1` + +```ts +type IntegrationFieldV1 = { + entity: string + attribute: string + field?: string + jsonataExpression?: string +} +``` + +### `IntegrationConfigurationV2` + +```ts +type IntegrationConfigurationV2 = { + version: "2.0" + mapping: { + events: Record + } +} +``` + +### `OutboundMapping` + +A mapping that delivers an event to an external system by one of three mechanisms — pushed to a webhook (with a JSONata payload transformation), made available on the pull-based poll queue (the raw event payload, or its JSONata transformation when the mapping carries one), or handed to a file_proxy + +```ts +type OutboundMapping = { + id?: string // uuid + name: string + jsonata_expression?: string + enabled: boolean + delivery: { + type: "webhook" + webhook_id: string + webhook_name?: string + webhook_url?: string + } | { + type: "poll" + retention_days?: number + poison_policy?: "dead_letter" | "block" + max_delivery_attempts?: number + } | { + type: "file_proxy" + use_case_slug: string + } + created_at?: string // date-time + updated_at?: string // date-time +} +``` + +### `DeliveryConfig` + +Configuration for how the event should be delivered. webhook = push delivery via svc-webhooks (JSONata-transformed payload); poll = pull-based queue delivery where the consumer fetches items via the poll API (raw event payload, or its JSONata transformation when the mapping carries a jsonata_express + +```ts +type DeliveryConfig = { + type: "webhook" + webhook_id: string + webhook_name?: string + webhook_url?: string +} | { + type: "poll" + retention_days?: number + poison_policy?: "dead_letter" | "block" + max_delivery_attempts?: number +} | { + type: "file_proxy" + use_case_slug: string +} +``` + +### `WebhookDeliveryConfig` + +Push delivery of the transformed event to a webhook via svc-webhooks + +```ts +type WebhookDeliveryConfig = { + type: "webhook" + webhook_id: string + webhook_name?: string + webhook_url?: string +} +``` + +### `PollDeliveryConfig` + +Pull-based queue delivery. Consumers fetch and acknowledge items via the poll API. When the mapping carries a `jsonata_expression`, it is evaluated once at enqueue time against the standardized event-catalog event (with `$env`/`$mapValue`/`$mapKey` bindings) and its output — a JSON object — is the d + +```ts +type PollDeliveryConfig = { + type: "poll" + retention_days?: number + poison_policy?: "dead_letter" | "block" + max_delivery_attempts?: number +} +``` + +### `FileProxyDeliveryConfig` + +Push delivery to an external document system through a `file_proxy` use case. + +A pure pointer, deliberately. The outbound use case decides WHEN to deliver — its event +name plus `event_filter` — and the referenced `file_proxy` use case decides WHAT and HOW: +which items to fan out over (`fan_out`), wh + +```ts +type FileProxyDeliveryConfig = { + type: "file_proxy" + use_case_slug: string +} +``` + +### `EntitySyncStatusResponse` + +```ts +type EntitySyncStatusResponse = { + entity_id: string // uuid + sync_states: Array<{ + entity_id: string // uuid + integration_id: string // uuid + entity_slug: string + use_case_id?: string + last_synced_at?: string // date-time + last_changed_at?: string // date-time + last_operation?: "create" | "patch" | "delete" | "no-op" + last_event_id?: string + readings_last_synced_at?: string // date-time + readings_last_operation?: "upsert" | "delete" + readings_last_event_id?: string + }> +} +``` + +### `EntitySyncState` + +Inbound sync state of one entity for one integration. Carries two +independent groups: the entity-level fields (`last_synced_at`, …) and, +on meter/meter_counter entities, the readings-level fields +(`readings_last_synced_at`, …). Either group can be present alone — a +meter whose readings sync via the + +```ts +type EntitySyncState = { + entity_id: string // uuid + integration_id: string // uuid + entity_slug: string + use_case_id?: string + last_synced_at?: string // date-time + last_changed_at?: string // date-time + last_operation?: "create" | "patch" | "delete" | "no-op" + last_event_id?: string + readings_last_synced_at?: string // date-time + readings_last_operation?: "upsert" | "delete" + readings_last_event_id?: string +} +``` + +### `OutboundStatusResponse` + +```ts +type OutboundStatusResponse = { + useCases: Array<{ + useCaseId: string // uuid + name: string + useCaseEnabled: boolean + eventCatalogEvent?: string + eventEnabled?: boolean + webhooks?: Array<{ + webhookId: { ... } + webhookName?: { ... } + enabled?: { ... } + }> + status: "ok" | "conflict" | "disabled" + conflicts?: Array<{ + type: { ... } + webhookId?: { ... } + message: { ... } + }> + poll?: { + queue_depth: { ... } + oldest_unconsumed_age_seconds: { ... } + last_poll_at: { ... } + last_ack_at: { ... } + blocked: { ... } + dlq_count: { ... } + } + file_proxy?: Array<{ + mapping_id: { ... } + use_case_slug: { ... } + resolved: { ... } + target_use_case_id?: { ... } + target_enabled?: { ... } + target_updated_at?: { ... } + unresolved_reason?: { ... } + }> + }> +} +``` + +### `OutboundUseCaseStatus` + +```ts +type OutboundUseCaseStatus = { + useCaseId: string // uuid + name: string + useCaseEnabled: boolean + eventCatalogEvent?: string + eventEnabled?: boolean + webhooks?: Array<{ + webhookId: string + webhookName?: string + enabled?: boolean + }> + status: "ok" | "conflict" | "disabled" + conflicts?: Array<{ + type: "event_disabled" | "all_webhooks_disabled" | "event_enabled_while_disabled" | "webhook_enabled_while_disabled" | "stream_blocked" | "dlq_items_present" + webhookId?: string + message: string + }> + poll?: { + queue_depth: number + oldest_unconsumed_age_seconds: number + last_poll_at: string // date-time + last_ack_at: string // date-time + blocked: boolean + dlq_count: number + } + file_proxy?: Array<{ + mapping_id: string + use_case_slug: string + resolved: boolean + target_use_case_id?: string // uuid + target_enabled?: boolean + target_updated_at?: string // date-time + unresolved_reason?: "not_found" | "wrong_type" | "wrong_direction" | "disabled" + }> +} +``` + +### `OutboundFileProxyTargetStatus` + +Resolution state of one file_proxy mapping's referenced upload use case. + +Because the transport lives on a separate use case, edits to the endpoint or credentials +do not appear in THIS use case's history. `target_updated_at` is the hook that lets an +operator notice a target changed underneath a deli + +```ts +type OutboundFileProxyTargetStatus = { + mapping_id: string + use_case_slug: string + resolved: boolean + target_use_case_id?: string // uuid + target_enabled?: boolean + target_updated_at?: string // date-time + unresolved_reason?: "not_found" | "wrong_type" | "wrong_direction" | "disabled" +} +``` + +### `OutboundPollStatus` + +Queue/consumer health for a poll-mode use case. Present only on use +cases with a poll delivery mapping — webhook-only use cases are +unaffected. Depth/age/DLQ numbers are first-page approximations. + + +```ts +type OutboundPollStatus = { + queue_depth: number + oldest_unconsumed_age_seconds: number + last_poll_at: string // date-time + last_ack_at: string // date-time + blocked: boolean + dlq_count: number +} +``` + +### `WebhookStatus` + +```ts +type WebhookStatus = { + webhookId: string + webhookName?: string + enabled?: boolean +} +``` + +### `OutboundConflict` + +```ts +type OutboundConflict = { + type: "event_disabled" | "all_webhooks_disabled" | "event_enabled_while_disabled" | "webhook_enabled_while_disabled" | "stream_blocked" | "dlq_items_present" + webhookId?: string + message: string +} +``` + +### `PollOutboundMessagesRequest` + +```ts +type PollOutboundMessagesRequest = { + limit?: number +} +``` + +### `OutboundMessage` + +```ts +type OutboundMessage = { + id: string + lease_token: string + use_case_id: string + event_name: string + event_id: string + group: string + org_id?: string + payload: Record + mapping_version?: string + enqueued_at: string // date-time +} +``` + +### `PollOutboundMessagesResponse` + +```ts +type PollOutboundMessagesResponse = { + messages: Array<{ + id: string + lease_token: string + use_case_id: string + event_name: string + event_id: string + group: string + org_id?: string + payload: Record + mapping_version?: string + enqueued_at: string // date-time + }> + visibility_timeout_seconds: number + has_more: boolean +} +``` + +### `AckOutboundMessagesRequest` + +```ts +type AckOutboundMessagesRequest = { + acks: Array<{ + id: string + lease_token: string + }> +} +``` + +### `AckResult` + +```ts +type AckResult = { + id: string + status: "accepted" | "rejected" + reason?: "stale_lease" | "out_of_order" | "not_found" +} +``` + +### `AckOutboundMessagesResponse` + +```ts +type AckOutboundMessagesResponse = { + results: Array<{ + id: string + status: "accepted" | "rejected" + reason?: "stale_lease" | "out_of_order" | "not_found" + }> +} +``` + +### `OutboundDlqMessage` + +```ts +type OutboundDlqMessage = { + id: string + use_case_id: string + event_name: string + event_id: string + enqueued_at?: string // date-time + dead_lettered_at: string // date-time + delivery_attempts: number + reason?: string + mapping_error?: string + mapping_version?: string + expires_at?: string // date-time +} +``` + +### `OutboundDlqListResponse` + +```ts +type OutboundDlqListResponse = { + items: Array<{ + id: string + use_case_id: string + event_name: string + event_id: string + enqueued_at?: string // date-time + dead_lettered_at: string // date-time + delivery_attempts: number + reason?: string + mapping_error?: string + mapping_version?: string + expires_at?: string // date-time + }> + next_token?: string +} +``` + +### `RedriveOutboundDlqRequest` + +```ts +type RedriveOutboundDlqRequest = { + ids: string[] + reapply_mapping?: boolean +} +``` + +### `RedriveOutboundDlqResult` + +```ts +type RedriveOutboundDlqResult = { + id: string + status: "redriven" | "not_found" | "mapping_failed" + mapping_error?: string +} +``` + +### `RedriveOutboundDlqResponse` + +```ts +type RedriveOutboundDlqResponse = { + results: Array<{ + id: string + status: "redriven" | "not_found" | "mapping_failed" + mapping_error?: string + }> +} +``` + +### `UnblockOutboundStreamRequest` + +```ts +type UnblockOutboundStreamRequest = { + reason?: string +} +``` + +### `UnblockOutboundStreamResponse` + +```ts +type UnblockOutboundStreamResponse = { + unblocked: boolean + dead_lettered_id?: string +} +``` + +### `SimulateOutboundMappingRequest` + +Exactly one of `payload` or `event_id` is required. `event_id` needs +`event_catalog_event` to name the event it belongs to. + + +```ts +type SimulateOutboundMappingRequest = { + jsonata_expression: string + payload?: Record + event_id?: string + event_catalog_event?: string +} +``` + +### `OutboundMappingSimulationError` + +```ts +type OutboundMappingSimulationError = { + code: "syntax_error" | "unknown_binding" | "evaluation_error" | "timeout" | "invalid_output" | "expression_too_long" + message: string + position?: number +} +``` + +### `SimulateOutboundMappingResponse` + +```ts +type SimulateOutboundMappingResponse = { + valid: boolean + output?: Record + error?: { + code: "syntax_error" | "unknown_binding" | "evaluation_error" | "timeout" | "invalid_output" | "expression_too_long" + message: string + position?: number + } + mapping_version: string + input?: Record +} +``` + +### `RelationConfig` + +```ts +type RelationConfig = { + operation: "_set" | "_append" | "_append_all" + items?: Array<{ + entity_schema: string + _tags?: string[] + unique_ids: Array<{ + attribute: { ... } + _type?: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + }> + required?: boolean + }> + jsonataExpression?: string +} +``` + +### `RelationItemConfig` + +```ts +type RelationItemConfig = { + entity_schema: string + _tags?: string[] + unique_ids: Array<{ + attribute: string + _type?: "email" | "phone" + field?: string + jsonataExpression?: string + constant?: unknown + }> + required?: boolean +} +``` + +### `RelationUniqueIdField` + +```ts +type RelationUniqueIdField = { + attribute: string + _type?: "email" | "phone" + field?: string + jsonataExpression?: string + constant?: unknown +} +``` + +### `RelationRefsConfig` + +Configuration for relation references ($relation_ref). +Relation references link to a specific item within a repeatable attribute on a related entity. +Common use case: referencing a specific address within a contact's address list. + + +```ts +type RelationRefsConfig = { + operation: "_set" | "_append" | "_append_all" + items?: Array<{ + entity_schema: string + unique_ids: Array<{ + attribute: { ... } + _type?: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + }> + path: string + value: { + attribute: { ... } + operation?: { ... } + field?: { ... } + jsonataExpression?: { ... } + constant?: { ... } + } + }> + jsonataExpression?: string +} +``` + +### `RelationRefItemConfig` + +Configuration for a single relation reference item + +```ts +type RelationRefItemConfig = { + entity_schema: string + unique_ids: Array<{ + attribute: string + _type?: "email" | "phone" + field?: string + jsonataExpression?: string + constant?: unknown + }> + path: string + value: { + attribute: string + operation?: "_set" | "_append" | "_append_all" + field?: string + jsonataExpression?: string + constant?: unknown + } +} +``` + +### `RelationRefValueConfig` + +Configuration for the value to set on the related entity's attribute + +```ts +type RelationRefValueConfig = { + attribute: string + operation?: "_set" | "_append" | "_append_all" + field?: string + jsonataExpression?: string + constant?: unknown +} +``` + +### `RepeatableFieldType` + +Type hint for repeatable fields that require special search handling. +These fields are stored as arrays of objects (e.g., email: [{ email: "value" }]). + + +```ts +type RepeatableFieldType = "email" | "phone" +``` + +### `ReplayEventsRequest` + +```ts +type ReplayEventsRequest = { + event_ids: string[] +} +``` + +### `QueryEventsRequest` + +```ts +type QueryEventsRequest = { + event_id?: string + event_type?: "CREATE" | "UPDATE" | "DELETE" + correlation_id?: string + object_type?: string + event_name?: string + use_case_id?: string + limit?: number + cursor?: { + event_time?: string // date-time + event_id?: string + } +} +``` + +### `QueryInboundMonitoringEventsRequest` + +```ts +type QueryInboundMonitoringEventsRequest = { + use_case_id?: string // uuid + event_type?: "CREATE" | "UPDATE" | "DELETE" | "TRIGGER" + sync_type?: "entity" | "meter_reading" | "webhook" | "api_deprecation" + status?: "success" | "error" | "skipped" | "warning" + error_category?: "validation" | "configuration" | "downstream_api" | "timeout" | "system" + correlation_id?: string + object_type?: string + event_name?: string + event_id?: string + from_date?: string // date-time + to_date?: string // date-time + limit?: number + cursor?: { + completed_at?: string // date-time + event_id?: string + } +} +``` + +### `QueryAccessLogsRequest` + +```ts +type QueryAccessLogsRequest = { + token_id?: string + service?: string + method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD" + path?: string + status?: number + from_date?: string // date-time + to_date?: string // date-time + limit?: number + cursor?: { + timestamp?: string // date-time + request_id?: string + } +} +``` + +### `AccessLogEntry` + +```ts +type AccessLogEntry = { + timestamp?: string // date-time + environment?: string + service?: string + request_id?: string + method?: string + path?: string + status?: number + response_latency_ms?: number + response_length?: number + token_id?: string + org_id?: string + origin?: string + source_ip?: string +} +``` + +### `GetMonitoringStatsRequest` + +```ts +type GetMonitoringStatsRequest = { + from_date?: string // date-time + to_date?: string // date-time + inbound_group_by?: "use_case_id" | "sync_type" | "status" | "error_category" | "object_type" | "event_name" | "date"[] + outbound_group_by?: "event_name" | "status" | "webhook_config_id" | "date"[] +} +``` + +### `GetMonitoringTimeSeriesRequest` + +```ts +type GetMonitoringTimeSeriesRequest = { + from_date: string // date-time + to_date?: string // date-time + interval: "5m" | "10m" | "30m" | "1h" | "3h" | "1d" + direction?: "inbound" | "outbound" | "both" +} +``` + +### `TimeSeriesBucket` + +```ts +type TimeSeriesBucket = { + timestamp: string // date-time + inbound?: { + success_count?: number + error_count?: number + warning_count?: number + skipped_count?: number + total_count?: number + } + outbound?: { + success_count?: number + error_count?: number + pending_count?: number + total_count?: number + } +} +``` + +### `QueryOutboundMonitoringEventsRequest` + +```ts +type QueryOutboundMonitoringEventsRequest = { + event_name?: string + status?: "succeeded" | "failed" | "pending" + webhook_config_id?: string + from_date?: string // date-time + to_date?: string // date-time + limit?: number + cursor?: { + created_at?: string // date-time + event_id?: string + } +} +``` + +### `OutboundMonitoringEvent` + +```ts +type OutboundMonitoringEvent = { + org_id: string + event_id: string + event_name: string + status: "succeeded" | "failed" | "pending" + url?: string + http_method?: string + http_response?: Record + webhook_config_id?: string + metadata?: Record + execution_context?: Record + payload?: Record + created_at: string // date-time + updated_at?: string // date-time +} +``` + +### `MonitoringStats` + +```ts +type MonitoringStats = { + inbound: { + total_events: number + total_correlations?: number + success_count: number + error_count: number + skipped_count: number + warning_count?: number + success_rate?: number + last_error_at?: string // date-time + breakdown?: Record[] + } + outbound: { + total_events: number + success_count: number + error_count: number + pending_count?: number + success_rate?: number + last_error_at?: string // date-time + breakdown?: Record[] + } +} +``` + +### `InboundMonitoringEvent` + +```ts +type InboundMonitoringEvent = { + org_id: string + event_id: string + correlation_id?: string + integration_id?: string + use_case_id?: string + event_type?: "CREATE" | "UPDATE" | "DELETE" | "TRIGGER" + object_type: string + sync_type: "entity" | "meter_reading" | "webhook" | "api_deprecation" + status: "success" | "error" | "skipped" | "warning" + error_code?: string + error_message?: string + error_category?: "validation" | "configuration" | "downstream_api" | "timeout" | "system" + processing_duration_ms?: number + received_at: string // date-time + completed_at: string // date-time +} +``` + +### `QueryMonitoringEventsV2Request` + +```ts +type QueryMonitoringEventsV2Request = { + use_case_id?: string + use_case_type?: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy" + level?: "success" | "error" | "info" | "warning" | "skipped" + code?: string + event_id?: string + correlation_id?: string + from_date?: string // date-time + to_date?: string // date-time + limit?: number + cursor?: { + created_at?: string // date-time + id?: string // uuid + } +} +``` + +### `ExternalMonitoringSpan` + +A single monitoring span produced by an external system. `correlation_id`, `level`, `use_case_slug`, `occurred_at` and `message` are all required and `level` must be one of success|error|warning|info — but these are validated PER SPAN at ingest and reported in the per-item `results[]`, so one malfor + +```ts +type ExternalMonitoringSpan = { + correlation_id?: string + level?: string + use_case_slug?: string + occurred_at?: string // date-time + message?: string + detail?: Record +} +``` + +### `IngestExternalMonitoringEventsRequest` + +```ts +type IngestExternalMonitoringEventsRequest = { + events: Array<{ + correlation_id?: string + level?: string + use_case_slug?: string + occurred_at?: string // date-time + message?: string + detail?: Record + }> +} +``` + +### `IngestExternalMonitoringEventsResponse` + +```ts +type IngestExternalMonitoringEventsResponse = { + accepted: number + rejected: number + results?: Array<{ + index: number + status: "accepted" | "rejected" + reason?: string + }> +} +``` + +### `MonitoringTraceResponse` + +```ts +type MonitoringTraceResponse = { + correlation_id: string + status: "success" | "error" | "warning" | "info" + started_at?: string // date-time + ended_at?: string // date-time + span_count: number + truncated: boolean + spans: Array<{ + id: string // uuid + org_id: string + integration_id: string + event_id: string + correlation_id?: string + use_case_id?: string + use_case_type: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy" | "" + level: "success" | "error" | "info" | "warning" + code?: "ACK_CONFIRMED" | "ACK_PENDING" | "ACK_TIMEOUT" | "ATTACHMENT_NOT_FOUND" | "ATTRIBUTE_TYPE_MISMATCH" | "CONDITIONAL_VARIANTS_WRITTEN" | "CONDITIONAL_VARIANT_WRITE_FAILED" | "CONDITIONAL_VARIANT_WRITE_WARNING" | "CORRELATION_CLOSED_EMPTY" | "CORRELATION_CLOSED_INCOMPLETE" | "CORRELATION_CLOSE_IGNORED" | "CORRELATION_COMPLETED" | "CORRELATION_EVENT_LIMIT_EXCEEDED" | "CORRELATION_ID_MISSING" | "CORRELATION_LATE_EVENT" | "CORRELATION_REQUIREMENT_FAILED" | "CORRELATION_WAIT_REJECTED" | "CORRELATION_WAIT_TIMEOUT" | "DEPRECATED_ENDPOINT" | "DIRECT_ENTITY_NOT_ALLOWED" | "DIRECT_PAYLOAD_INVALID" | "DIRECT_VERSION_UNSUPPORTED" | "DUPLICATE_EVENT" | "ENTITY_CREATED" | "ENTITY_DELETED" | "ENTITY_NO_OP" | "ENTITY_REFERENCE_NOT_FOUND" | "ENTITY_UPDATED" | "ENV_VAR_REF_JSONATA_FAILED" | "ENV_VAR_REF_LOOKUP_FAILED" | "ENV_VAR_REF_NOT_FOUND" | "EVENT_NOT_CONFIGURED" | "EXTERNAL_API_ERROR" | "EXTERNAL_ERROR" | "EXTERNAL_INFO" | "EXTERNAL_SUCCESS" | "EXTERNAL_WARNING" | "FAN_OUT_EMPTY" | "FAN_OUT_INVALID_RESULT" | "FILE_EXTRACTION_FAILED" | "FILE_FETCH_FAILED" | "FILE_PROXY_OK" | "FILE_PROXY_UPLOADED" | "FILE_PROXY_UPLOAD_ENQUEUED" | "FILE_PROXY_UPLOAD_FAILED" | "FILE_PROXY_UPLOAD_RETRYING" | "FILE_TOO_LARGE" | "INTEGRATION_NOT_FOUND" | "INTERACTIVE_CROSS_LANE_WRITE" | "INTERACTIVE_NOT_ALLOWED" | "INTERACTIVE_RATE_LIMITED" | "INVALID_METER_READING_ATTRIBUTES" | "LOOKUP_UNMAPPED" | "MALFORMED_PAYLOAD" | "MAPPING_EXPRESSION_FAILED" | "METERING_API_ERROR" | "METER_READING_DELETED" | "METER_READING_GROUP_FAILED" | "METER_READING_GROUP_RETRYING" | "METER_READING_UPSERTED" | "MISSING_METER_COUNTER_UNIQUE_IDS" | "MISSING_METER_UNIQUE_IDS" | "MISSING_REQUIRED_PARAM" | "MISSING_UNIQUE_IDENTIFIERS" | "MSG_ACKED" | "MSG_DEAD_LETTERED" | "MSG_ENQUEUED" | "MSG_EXPIRED_UNPOLLED" | "MSG_HEAD_BLOCKED" | "MSG_LATE_ARRIVAL" | "OAUTH2_TOKEN_FAILURE" | "ORG_DROPPED" | "PAYLOAD_TOO_LARGE" | "PORTAL_REF_AMBIGUOUS" | "PORTAL_REF_JSONATA_FAILED" | "PORTAL_REF_LOOKUP_FAILED" | "PORTAL_REF_NO_MATCH" | "PROCESSING_STATE_LIMIT" | "PRUNE_SCOPE_COMPLETED" | "PRUNE_SCOPE_PARTIAL_FAILURE" | "RECURSION_DEPTH_EXCEEDED" | "RELATION_MISSING_UNIQUE_IDS" | "RELATION_REF_ITEM_NOT_FOUND" | "RELATION_REF_VALUE_UNDEFINED" | "REQUIRED_PARAM_MISSING" | "SECURE_PROXY_DISABLED" | "SECURE_PROXY_DOMAIN_BLOCKED" | "SECURE_PROXY_DOMAIN_NOT_ALLOWED" | "SECURE_PROXY_ERROR" | "SECURE_PROXY_INVALID_CONFIG" | "SECURE_PROXY_INVALID_TYPE" | "SECURE_PROXY_INVALID_URL" | "SECURE_PROXY_IP_BLOCKED" | "SECURE_PROXY_IP_NOT_ALLOWED" | "SECURE_PROXY_NOT_FOUND" | "SECURE_PROXY_OK" | "SECURE_PROXY_UNAVAILABLE" | "SHARING_FAILED" | "SHARING_PARTNER_NOT_CONNECTED" | "SHARING_REJECTED" | "SIGNATURE_VERIFICATION_FAILED" | "SIGNATURE_VERIFICATION_UNAVAILABLE" | "SOFT_DELETED_ENTITY_MATCHED" | "STEP_DISABLED" | "TIMEOUT" | "UNIQUE_ID_LOOKUP_UNRESOLVABLE" | "UNIQUE_ID_MULTIPLE_MATCHES" | "UNIQUE_ID_NOT_IN_SCHEMA" | "UNIQUE_ID_TYPE_DERIVATION_FAILED" | "UNKNOWN_ERROR" | "USE_CASE_DISABLED" | "USE_CASE_INVALID_TYPE" | "USE_CASE_MISSING_CONFIG" | "USE_CASE_NOT_FOUND" | "WEBHOOK_DELIVERED" | "WEBHOOK_DELIVERY_FAILED" | "WEBHOOK_SKIPPED" | string + message?: string + detail?: Record + created_at: string // date-time + }> + inbound_event?: Record +} +``` + +### `MonitoringCode` + +The monitoring code taxonomy — every code the Integration Toolkit itself emits, +with a fixed level (see the published code reference at +https://docs.epilot.io/docs/integrations/integration-toolkit/monitoring/codes). + +This schema exists so consumers can import the union as a type. It never +constrains + +```ts +type MonitoringCode = "ACK_CONFIRMED" | "ACK_PENDING" | "ACK_TIMEOUT" | "ATTACHMENT_NOT_FOUND" | "ATTRIBUTE_TYPE_MISMATCH" | "CONDITIONAL_VARIANTS_WRITTEN" | "CONDITIONAL_VARIANT_WRITE_FAILED" | "CONDITIONAL_VARIANT_WRITE_WARNING" | "CORRELATION_CLOSED_EMPTY" | "CORRELATION_CLOSED_INCOMPLETE" | "CORRELATION_CLOSE_IGNORED" | "CORRELATION_COMPLETED" | "CORRELATION_EVENT_LIMIT_EXCEEDED" | "CORRELATION_ID_MISSING" | "CORRELATION_LATE_EVENT" | "CORRELATION_REQUIREMENT_FAILED" | "CORRELATION_WAIT_REJECTED" | "CORRELATION_WAIT_TIMEOUT" | "DEPRECATED_ENDPOINT" | "DIRECT_ENTITY_NOT_ALLOWED" | "DIRECT_PAYLOAD_INVALID" | "DIRECT_VERSION_UNSUPPORTED" | "DUPLICATE_EVENT" | "ENTITY_CREATED" | "ENTITY_DELETED" | "ENTITY_NO_OP" | "ENTITY_REFERENCE_NOT_FOUND" | "ENTITY_UPDATED" | "ENV_VAR_REF_JSONATA_FAILED" | "ENV_VAR_REF_LOOKUP_FAILED" | "ENV_VAR_REF_NOT_FOUND" | "EVENT_NOT_CONFIGURED" | "EXTERNAL_API_ERROR" | "EXTERNAL_ERROR" | "EXTERNAL_INFO" | "EXTERNAL_SUCCESS" | "EXTERNAL_WARNING" | "FAN_OUT_EMPTY" | "FAN_OUT_INVALID_RESULT" | "FILE_EXTRACTION_FAILED" | "FILE_FETCH_FAILED" | "FILE_PROXY_OK" | "FILE_PROXY_UPLOADED" | "FILE_PROXY_UPLOAD_ENQUEUED" | "FILE_PROXY_UPLOAD_FAILED" | "FILE_PROXY_UPLOAD_RETRYING" | "FILE_TOO_LARGE" | "INTEGRATION_NOT_FOUND" | "INTERACTIVE_CROSS_LANE_WRITE" | "INTERACTIVE_NOT_ALLOWED" | "INTERACTIVE_RATE_LIMITED" | "INVALID_METER_READING_ATTRIBUTES" | "LOOKUP_UNMAPPED" | "MALFORMED_PAYLOAD" | "MAPPING_EXPRESSION_FAILED" | "METERING_API_ERROR" | "METER_READING_DELETED" | "METER_READING_GROUP_FAILED" | "METER_READING_GROUP_RETRYING" | "METER_READING_UPSERTED" | "MISSING_METER_COUNTER_UNIQUE_IDS" | "MISSING_METER_UNIQUE_IDS" | "MISSING_REQUIRED_PARAM" | "MISSING_UNIQUE_IDENTIFIERS" | "MSG_ACKED" | "MSG_DEAD_LETTERED" | "MSG_ENQUEUED" | "MSG_EXPIRED_UNPOLLED" | "MSG_HEAD_BLOCKED" | "MSG_LATE_ARRIVAL" | "OAUTH2_TOKEN_FAILURE" | "ORG_DROPPED" | "PAYLOAD_TOO_LARGE" | "PORTAL_REF_AMBIGUOUS" | "PORTAL_REF_JSONATA_FAILED" | "PORTAL_REF_LOOKUP_FAILED" | "PORTAL_REF_NO_MATCH" | "PROCESSING_STATE_LIMIT" | "PRUNE_SCOPE_COMPLETED" | "PRUNE_SCOPE_PARTIAL_FAILURE" | "RECURSION_DEPTH_EXCEEDED" | "RELATION_MISSING_UNIQUE_IDS" | "RELATION_REF_ITEM_NOT_FOUND" | "RELATION_REF_VALUE_UNDEFINED" | "REQUIRED_PARAM_MISSING" | "SECURE_PROXY_DISABLED" | "SECURE_PROXY_DOMAIN_BLOCKED" | "SECURE_PROXY_DOMAIN_NOT_ALLOWED" | "SECURE_PROXY_ERROR" | "SECURE_PROXY_INVALID_CONFIG" | "SECURE_PROXY_INVALID_TYPE" | "SECURE_PROXY_INVALID_URL" | "SECURE_PROXY_IP_BLOCKED" | "SECURE_PROXY_IP_NOT_ALLOWED" | "SECURE_PROXY_NOT_FOUND" | "SECURE_PROXY_OK" | "SECURE_PROXY_UNAVAILABLE" | "SHARING_FAILED" | "SHARING_PARTNER_NOT_CONNECTED" | "SHARING_REJECTED" | "SIGNATURE_VERIFICATION_FAILED" | "SIGNATURE_VERIFICATION_UNAVAILABLE" | "SOFT_DELETED_ENTITY_MATCHED" | "STEP_DISABLED" | "TIMEOUT" | "UNIQUE_ID_LOOKUP_UNRESOLVABLE" | "UNIQUE_ID_MULTIPLE_MATCHES" | "UNIQUE_ID_NOT_IN_SCHEMA" | "UNIQUE_ID_TYPE_DERIVATION_FAILED" | "UNKNOWN_ERROR" | "USE_CASE_DISABLED" | "USE_CASE_INVALID_TYPE" | "USE_CASE_MISSING_CONFIG" | "USE_CASE_NOT_FOUND" | "WEBHOOK_DELIVERED" | "WEBHOOK_DELIVERY_FAILED" | "WEBHOOK_SKIPPED" +``` + +### `MonitoringEventV2` + +```ts +type MonitoringEventV2 = { + id: string // uuid + org_id: string + integration_id: string + event_id: string + correlation_id?: string + use_case_id?: string + use_case_type: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy" | "" + level: "success" | "error" | "info" | "warning" + code?: "ACK_CONFIRMED" | "ACK_PENDING" | "ACK_TIMEOUT" | "ATTACHMENT_NOT_FOUND" | "ATTRIBUTE_TYPE_MISMATCH" | "CONDITIONAL_VARIANTS_WRITTEN" | "CONDITIONAL_VARIANT_WRITE_FAILED" | "CONDITIONAL_VARIANT_WRITE_WARNING" | "CORRELATION_CLOSED_EMPTY" | "CORRELATION_CLOSED_INCOMPLETE" | "CORRELATION_CLOSE_IGNORED" | "CORRELATION_COMPLETED" | "CORRELATION_EVENT_LIMIT_EXCEEDED" | "CORRELATION_ID_MISSING" | "CORRELATION_LATE_EVENT" | "CORRELATION_REQUIREMENT_FAILED" | "CORRELATION_WAIT_REJECTED" | "CORRELATION_WAIT_TIMEOUT" | "DEPRECATED_ENDPOINT" | "DIRECT_ENTITY_NOT_ALLOWED" | "DIRECT_PAYLOAD_INVALID" | "DIRECT_VERSION_UNSUPPORTED" | "DUPLICATE_EVENT" | "ENTITY_CREATED" | "ENTITY_DELETED" | "ENTITY_NO_OP" | "ENTITY_REFERENCE_NOT_FOUND" | "ENTITY_UPDATED" | "ENV_VAR_REF_JSONATA_FAILED" | "ENV_VAR_REF_LOOKUP_FAILED" | "ENV_VAR_REF_NOT_FOUND" | "EVENT_NOT_CONFIGURED" | "EXTERNAL_API_ERROR" | "EXTERNAL_ERROR" | "EXTERNAL_INFO" | "EXTERNAL_SUCCESS" | "EXTERNAL_WARNING" | "FAN_OUT_EMPTY" | "FAN_OUT_INVALID_RESULT" | "FILE_EXTRACTION_FAILED" | "FILE_FETCH_FAILED" | "FILE_PROXY_OK" | "FILE_PROXY_UPLOADED" | "FILE_PROXY_UPLOAD_ENQUEUED" | "FILE_PROXY_UPLOAD_FAILED" | "FILE_PROXY_UPLOAD_RETRYING" | "FILE_TOO_LARGE" | "INTEGRATION_NOT_FOUND" | "INTERACTIVE_CROSS_LANE_WRITE" | "INTERACTIVE_NOT_ALLOWED" | "INTERACTIVE_RATE_LIMITED" | "INVALID_METER_READING_ATTRIBUTES" | "LOOKUP_UNMAPPED" | "MALFORMED_PAYLOAD" | "MAPPING_EXPRESSION_FAILED" | "METERING_API_ERROR" | "METER_READING_DELETED" | "METER_READING_GROUP_FAILED" | "METER_READING_GROUP_RETRYING" | "METER_READING_UPSERTED" | "MISSING_METER_COUNTER_UNIQUE_IDS" | "MISSING_METER_UNIQUE_IDS" | "MISSING_REQUIRED_PARAM" | "MISSING_UNIQUE_IDENTIFIERS" | "MSG_ACKED" | "MSG_DEAD_LETTERED" | "MSG_ENQUEUED" | "MSG_EXPIRED_UNPOLLED" | "MSG_HEAD_BLOCKED" | "MSG_LATE_ARRIVAL" | "OAUTH2_TOKEN_FAILURE" | "ORG_DROPPED" | "PAYLOAD_TOO_LARGE" | "PORTAL_REF_AMBIGUOUS" | "PORTAL_REF_JSONATA_FAILED" | "PORTAL_REF_LOOKUP_FAILED" | "PORTAL_REF_NO_MATCH" | "PROCESSING_STATE_LIMIT" | "PRUNE_SCOPE_COMPLETED" | "PRUNE_SCOPE_PARTIAL_FAILURE" | "RECURSION_DEPTH_EXCEEDED" | "RELATION_MISSING_UNIQUE_IDS" | "RELATION_REF_ITEM_NOT_FOUND" | "RELATION_REF_VALUE_UNDEFINED" | "REQUIRED_PARAM_MISSING" | "SECURE_PROXY_DISABLED" | "SECURE_PROXY_DOMAIN_BLOCKED" | "SECURE_PROXY_DOMAIN_NOT_ALLOWED" | "SECURE_PROXY_ERROR" | "SECURE_PROXY_INVALID_CONFIG" | "SECURE_PROXY_INVALID_TYPE" | "SECURE_PROXY_INVALID_URL" | "SECURE_PROXY_IP_BLOCKED" | "SECURE_PROXY_IP_NOT_ALLOWED" | "SECURE_PROXY_NOT_FOUND" | "SECURE_PROXY_OK" | "SECURE_PROXY_UNAVAILABLE" | "SHARING_FAILED" | "SHARING_PARTNER_NOT_CONNECTED" | "SHARING_REJECTED" | "SIGNATURE_VERIFICATION_FAILED" | "SIGNATURE_VERIFICATION_UNAVAILABLE" | "SOFT_DELETED_ENTITY_MATCHED" | "STEP_DISABLED" | "TIMEOUT" | "UNIQUE_ID_LOOKUP_UNRESOLVABLE" | "UNIQUE_ID_MULTIPLE_MATCHES" | "UNIQUE_ID_NOT_IN_SCHEMA" | "UNIQUE_ID_TYPE_DERIVATION_FAILED" | "UNKNOWN_ERROR" | "USE_CASE_DISABLED" | "USE_CASE_INVALID_TYPE" | "USE_CASE_MISSING_CONFIG" | "USE_CASE_NOT_FOUND" | "WEBHOOK_DELIVERED" | "WEBHOOK_DELIVERY_FAILED" | "WEBHOOK_SKIPPED" | string + message?: string + detail?: Record + created_at: string // date-time +} +``` + +### `GetMonitoringStatsV2Request` + +```ts +type GetMonitoringStatsV2Request = { + from_date?: string // date-time + to_date?: string // date-time + correlation_id?: string + correlation_ids?: string[] + use_case_type?: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy" + use_case_types?: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy"[] + group_by?: "use_case_id" | "use_case_type" | "level" | "code" | "correlation_id" | "date" + source?: "monitoring" | "incoming" +} +``` + +### `GetMonitoringRunCompletionV2Request` + +```ts +type GetMonitoringRunCompletionV2Request = { + correlation_ids: string[] +} +``` + +### `MonitoringRunCompletionV2Response` + +```ts +type MonitoringRunCompletionV2Response = { + runs: Array<{ + correlation_id: string + seen: number + in_flight: number + retrying: number + success: number + warning: number + error: number + info: number + entries: { + total: { ... } + error: { ... } + warning: { ... } + success: { ... } + info: { ... } + retry: { ... } + } + last_activity_at: string // date-time + }> +} +``` + +### `MonitoringRunCompletionV2` + +Per-event completion of one run. Every count is in EVENTS (distinct `event_id`), never rows: `seen = in_flight + success + warning + error + info`. + +```ts +type MonitoringRunCompletionV2 = { + correlation_id: string + seen: number + in_flight: number + retrying: number + success: number + warning: number + error: number + info: number + entries: { + total: number + error: number + warning: number + success: number + info: number + retry: number + } + last_activity_at: string // date-time +} +``` + +### `MonitoringRunEntriesV2` + +The run's monitoring rows counted by level — the rows its trace lists, correlation-level rows (wait outcomes, closes) included. Unlike the event counts above, one event can contribute many rows (one per entity written, plus every caveat and retry). Retry markers count under `retry` only, so a failed + +```ts +type MonitoringRunEntriesV2 = { + total: number + error: number + warning: number + success: number + info: number + retry: number +} +``` + +### `MonitoringStatsV2` + +```ts +type MonitoringStatsV2 = { + total_events: number + success_count: number + error_count: number + warning_count: number + skipped_count: number + info_count: number + ack_timeout_count?: number + success_rate?: number + last_error_at?: string // date-time + last_event_at?: string // date-time + breakdown?: Record[] +} +``` + +### `GetMonitoringTimeSeriesV2Request` + +```ts +type GetMonitoringTimeSeriesV2Request = { + from_date: string // date-time + to_date?: string // date-time + interval: "5m" | "10m" | "30m" | "1h" | "3h" | "1d" + use_case_type?: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy" + group_by?: "use_case_type" | "use_case" +} +``` + +### `TimeSeriesBreakdownItemV2` + +```ts +type TimeSeriesBreakdownItemV2 = { + use_case_type?: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy" + use_case_id?: string + success_count: number + error_count: number + warning_count: number + skipped_count: number + info_count: number + total_count: number +} +``` + +### `TimeSeriesBucketV2` + +```ts +type TimeSeriesBucketV2 = { + timestamp: string // date-time + success_count?: number + error_count?: number + warning_count?: number + skipped_count?: number + info_count?: number + total_count: number + breakdown?: Array<{ + use_case_type?: "inbound" | "outbound" | "file_proxy" | "managed_call" | "secure_proxy" + use_case_id?: string + success_count: number + error_count: number + warning_count: number + skipped_count: number + info_count: number + total_count: number + }> +} +``` + +### `DocumentationPageSummary` + +Documentation page metadata without the markdown content + +```ts +type DocumentationPageSummary = { + id: string + integration_id: string // uuid + scope: "integration" | "use_case" + use_case_id?: string // uuid + title: string + created_at: string // date-time + created_by?: string + updated_at: string // date-time + updated_by?: string +} +``` + +### `DocumentationPage` + +A markdown documentation page of an integration + +```ts +type DocumentationPage = { + id: string + integration_id: string // uuid + scope: "integration" | "use_case" + use_case_id?: string // uuid + title: string + created_at: string // date-time + created_by?: string + updated_at: string // date-time + updated_by?: string + content: string +} +``` + +### `UpsertDocumentationPageRequest` + +```ts +type UpsertDocumentationPageRequest = { + title: string + content: string +} +``` diff --git a/docs/sdk/clients/journey.md b/docs/sdk/clients/journey.md index 64023d85..98f7e7cb 100644 --- a/docs/sdk/clients/journey.md +++ b/docs/sdk/clients/journey.md @@ -33,6 +33,16 @@ const { data } = await journeyClient.getJourneysByOrgId(...) - [`getJourneysByOrgId`](#getjourneysbyorgid) - [`getJourney`](#getjourney) - [`removeJourney`](#removejourney) +- [`createJourneyRevision`](#createjourneyrevision) +- [`listJourneyRevisions`](#listjourneyrevisions) +- [`getJourneyRevision`](#getjourneyrevision) +- [`updateJourneyRevisionMetadata`](#updatejourneyrevisionmetadata) +- [`publishJourneyRevision`](#publishjourneyrevision) +- [`getJourneyPublishState`](#getjourneypublishstate) +- [`getJourneyEnvironment`](#getjourneyenvironment) +- [`resolveJourneyExternalValues`](#resolvejourneyexternalvalues) +- [`getJourneyEnvironmentVariables`](#getjourneyenvironmentvariables) +- [`getJourneyTemplateVariables`](#getjourneytemplatevariables) - [`getJourneyProducts`](#getjourneyproducts) - [`createJourney`](#createjourney) - [`updateJourney`](#updatejourney) @@ -50,6 +60,21 @@ const { data } = await journeyClient.getJourneysByOrgId(...) - [`removeJourneyV2`](#removejourneyv2) **Schemas** +- [`EnvironmentMapEntry`](#environmentmapentry) +- [`EnvironmentMap`](#environmentmap) +- [`EnvironmentLink`](#environmentlink) +- [`EnvironmentLinkList`](#environmentlinklist) +- [`EnvironmentScalarList`](#environmentscalarlist) +- [`JourneyEnvironmentResponse`](#journeyenvironmentresponse) +- [`JourneyExternalValuesRequest`](#journeyexternalvaluesrequest) +- [`JourneyExternalValuesResponse`](#journeyexternalvaluesresponse) +- [`ExternalValueError`](#externalvalueerror) +- [`JourneyTemplatingContext`](#journeytemplatingcontext) +- [`JourneyTemplateVariablesResponse`](#journeytemplatevariablesresponse) +- [`JourneyTemplating`](#journeytemplating) +- [`JourneyTemplatingLink`](#journeytemplatinglink) +- [`JourneyTemplatingTranslatable`](#journeytemplatingtranslatable) +- [`JourneyEnvironmentVariablesResponse`](#journeyenvironmentvariablesresponse) - [`GetJourneysResponse`](#getjourneysresponse) - [`JourneyResponse`](#journeyresponse) - [`JourneyProductsResponse`](#journeyproductsresponse) @@ -59,8 +84,21 @@ const { data } = await journeyClient.getJourneysByOrgId(...) - [`SearchJourneysQueryRequest`](#searchjourneysqueryrequest) - [`SearchJourneysResponse`](#searchjourneysresponse) - [`Journey`](#journey) +- [`JourneyServedRevision`](#journeyservedrevision) +- [`JourneyActivationGuarantee`](#journeyactivationguarantee) - [`JourneyFeatureFlags`](#journeyfeatureflags) - [`JourneyAuditInfo`](#journeyauditinfo) +- [`JourneyRevisionRequest`](#journeyrevisionrequest) +- [`PublishRevisionRequest`](#publishrevisionrequest) +- [`RevisionMetadataUpdate`](#revisionmetadataupdate) +- [`JourneyRevisionSummary`](#journeyrevisionsummary) +- [`JourneyRevisionList`](#journeyrevisionlist) +- [`JourneyRevision`](#journeyrevision) +- [`JourneyRevisionConflict`](#journeyrevisionconflict) +- [`JourneyPublishState`](#journeypublishstate) +- [`PublishResult`](#publishresult) +- [`JourneyValidationResponse`](#journeyvalidationresponse) +- [`JourneyValidationError`](#journeyvalidationerror) - [`S3Reference`](#s3reference) - [`TemplateSettings`](#templatesettings) - [`GenerateDocumentResponse`](#generatedocumentresponse) @@ -103,6 +141,8 @@ Get journey by id. Private journeys requires valid private token to be passed ```ts const { data } = await client.getJourney({ id: '123e4567-e89b-12d3-a456-426614174000', + version: 1, + revision_id: 'example', source: 'example', orgId: 'example', }) @@ -125,7 +165,9 @@ const { data } = await client.getJourney({ "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, + "guestVisible": true, "name": "string", "stepId": "string", "schema": {}, @@ -160,10 +202,13 @@ const { data } = await client.getJourney({ "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -179,6 +224,7 @@ const { data } = await client.getJourney({ "templateId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "targetedCustomer": "string", "description": "string", "organizationSettings": {}, @@ -188,26 +234,43 @@ const { data } = await client.getJourney({ "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "useAustrianLabels": true, "enableDarkMode": true, "accessMode": "PUBLIC", + "authGate": { + "stepId": "string" + }, "isPublished": true, "status": "string", "isActive": true, "savingProgress": { - "savingMode": "auto", - "supportedVersion": 0 + "mode": "auto", + "supportedRevision": 0 + }, + "thirdPartyCookies": true, + "betaFeatures": { + "modernProducts": true, + "modernLauncher": true }, - "thirdPartyCookies": true + "offline": { + "enabled": true, + "packTtlHours": 24 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "createdBy": "string", "updatedBy": "string", "__lastModifiedAt": "string", @@ -216,7 +279,14 @@ const { data } = await client.getJourney({ "deletedAt": "string", "version": 0, "revisions": 0, - "featureFlags": {} + "featureFlags": {}, + "templating": { + "customVariables": [ + {} + ], + "env": {} + }, + "revision_id": "42" } ``` @@ -238,6 +308,603 @@ const { data } = await client.removeJourney({ --- +### `createJourneyRevision` + +Creates a revision: an immutable copy of the complete journey configuration, identified by `revision_id`. Nothing customers receive changes; the revision only becomes the published version when it is + +`POST /v1/journey/configuration/{id}/revisions` + +```ts +const { data } = await client.createJourneyRevision( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + journeyId: 'string', + organizationId: 'string', + brandId: 'string', + name: 'string', + steps: [ + { + showStepName: true, + title: 'string', + subTitle: 'string', + showStepSubtitle: true, + showStepper: true, + showStepperLabels: true, + stepperType: 'numbers', + hideNextButton: true, + guestVisible: true, + name: 'string', + stepId: 'string', + schema: {}, + uischema: {}, + maxWidth: 'small' + } + ], + design: { + logoUrl: 'string', + theme: {}, + designTokens: {} + }, + rules: [ + { + type: 'inject', + sourceType: 'journey', + source: 'string', + target: 'string' + } + ], + logics: [ + { + autoGeneratedId: 'string', + conditions: ['string'], + actions: ['string'] + } + ], + logicsV4: {}, + contextSchema: [ + { + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + type: 'string', + paramKey: 'string', + isRequired: true, + shouldLoadEntity: true, + description: 'string' + } + ], + journey_type: 'Sales template (Premium)', + protected: true, + protectedEditable: ['string'], + settings: { + embedOptions: { + mode: 'full-screen', + lang: 'de', + width: 'string', + topBar: true, + scrollToTop: true, + button: { /* ... */ } + }, + safeModeAutomation: true, + canary: true, + designId: 'string', + templateId: 'string', + entityId: 'string', + mappingsAutomationId: 'string', + newMappings: true, + targetedCustomer: 'string', + description: 'string', + organizationSettings: {}, + publicToken: 'string', + runtimeEntities: ['ORDER'], + filePurposes: ['string'], + entityTags: ['string'], + addressSuggestionsFileUrl: 'string', + addressSuggestionsFileId: 'string', + addressSuggestionsCountryCode: 'string', + addressSuggestionsEnableAutoComplete: true, + addressSuggestionsSource: ['string'], + addressSuggestionsEnableFreeText: true, + useNewDesign: true, + useAustrianLabels: true, + enableDarkMode: true, + accessMode: 'PUBLIC', + authGate: { + stepId: 'string' + }, + isPublished: true, + status: 'string', + isActive: true, + savingProgress: { + mode: 'auto', + supportedRevision: 0 + }, + thirdPartyCookies: true, + betaFeatures: { + modernProducts: true, + modernLauncher: true + }, + offline: { + enabled: true, + packTtlHours: 24 + } + }, + validationRules: { + block1: 'rule123', + block2: ['rule456', 'rule789'], + block3: { + field1: 'rule101', + field2: ['rule102', 'rule103'] + } + }, + _manifest: ['123e4567-e89b-12d3-a456-426614174000'], + createdBy: 'string', + updatedBy: 'string', + __lastModifiedAt: 'string', + parent_revision_id: '41', + based_on_revision_id: '37', + mapping_config_version: 12, + revision_name: 'Changes to Steps and Logic' + }, +) +``` + +
+Response + +```json +{ + "revision_id": "42", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "Summer campaign", + "description": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "is_published": true, + "metadata_updated_at": "1970-01-01T00:00:00.000Z", + "metadata_updated_by": "string", + "mapping_config_version": 12 +} +``` + +
+ +--- + +### `listJourneyRevisions` + +Lists the journey's revision history, newest first. Metadata only, no configuration payload. `is_published` says whether a revision is the published version right now, which is a different question fr + +`GET /v1/journey/configuration/{id}/revisions` + +```ts +const { data } = await client.listJourneyRevisions({ + id: '123e4567-e89b-12d3-a456-426614174000', + limit: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "revision_id": "42", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "Summer campaign", + "description": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "is_published": true, + "metadata_updated_at": "1970-01-01T00:00:00.000Z", + "metadata_updated_by": "string", + "mapping_config_version": 12 + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `getJourneyRevision` + +Returns one revision with its full configuration, in the shape the builder holds a journey in, so it can be loaded straight into the editor as unsaved changes. Reading a revision changes nothing; a cl + +`GET /v1/journey/configuration/{id}/revisions/{revision_id}` + +```ts +const { data } = await client.getJourneyRevision({ + id: '123e4567-e89b-12d3-a456-426614174000', + revision_id: 'example', +}) +``` + +
+Response + +```json +{ + "revision_id": "42", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "Summer campaign", + "description": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "is_published": true, + "metadata_updated_at": "1970-01-01T00:00:00.000Z", + "metadata_updated_by": "string", + "mapping_config_version": 12, + "configuration": { + "journeyId": "string", + "organizationId": "string", + "brandId": "string", + "name": "string", + "steps": [ + {} + ], + "design": { + "logoUrl": "string", + "theme": {}, + "designTokens": {} + }, + "rules": [ + {} + ], + "logics": [ + {} + ], + "logicsV4": {}, + "contextSchema": [ + {} + ], + "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], + "settings": { + "embedOptions": {}, + "safeModeAutomation": true, + "canary": true, + "designId": "string", + "templateId": "string", + "entityId": "string", + "mappingsAutomationId": "string", + "newMappings": true, + "targetedCustomer": "string", + "description": "string", + "organizationSettings": {}, + "publicToken": "string", + "runtimeEntities": ["ORDER"], + "filePurposes": ["string"], + "entityTags": ["string"], + "addressSuggestionsFileUrl": "string", + "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, + "useNewDesign": true, + "useAustrianLabels": true, + "enableDarkMode": true, + "accessMode": "PUBLIC", + "authGate": {}, + "isPublished": true, + "status": "string", + "isActive": true, + "savingProgress": {}, + "thirdPartyCookies": true, + "betaFeatures": {}, + "offline": {} + }, + "validationRules": { + "block1": "rule123", + "block2": ["rule456", "rule789"], + "block3": {} + }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "createdBy": "string", + "updatedBy": "string", + "__lastModifiedAt": "string", + "createdAt": "string", + "lastModifiedAt": "string", + "deletedAt": "string", + "version": 0, + "revisions": 0, + "featureFlags": {}, + "templating": { + "customVariables": [], + "env": {} + } + } +} +``` + +
+ +--- + +### `updateJourneyRevisionMetadata` + +Corrects the name and description of a revision that has been published, e.g. to fix a typo or add context after the fact. Metadata only: the revision's configuration, the journey record customers rec + +`PATCH /v1/journey/configuration/{id}/revisions/{revision_id}` + +```ts +const { data } = await client.updateJourneyRevisionMetadata( + { + id: '123e4567-e89b-12d3-a456-426614174000', + revision_id: 'example', + }, + { + name: 'Summer campaign', + description: 'string' + }, +) +``` + +
+Response + +```json +{ + "revision_id": "42", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "name": "Summer campaign", + "description": "string", + "published_at": "1970-01-01T00:00:00.000Z", + "is_published": true, + "metadata_updated_at": "1970-01-01T00:00:00.000Z", + "metadata_updated_by": "string", + "mapping_config_version": 12 +} +``` + +
+ +--- + +### `publishJourneyRevision` + +Makes one revision the published version, the one customers receive, in a single transaction: the revision's configuration is copied onto the journey record, its datasource set onto the published data + +`POST /v1/journey/configuration/{id}/publish` + +```ts +const { data } = await client.publishJourneyRevision( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + revision_id: '42', + name: 'Summer campaign', + description: 'string' + }, +) +``` + +
+Response + +```json +{ + "revision_id": "42", + "name": "Summer campaign", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "post_publish_warnings": ["string"] +} +``` + +
+ +--- + +### `getJourneyPublishState` + +Answers which revision is the published version without paging through the history. A journey that has not adopted versioning yet returns `200` with `published_revision_id: null`, not `404`. + +`GET /v1/journey/configuration/{id}/publish-state` + +```ts +const { data } = await client.getJourneyPublishState({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "journey_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "published_revision_id": "42", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string" +} +``` + +
+ +--- + +### `getJourneyEnvironment` + +Resolve the environment variables referenced by this journey: the environment-backed datasources declared in its steps, whether they source a block's options or supply the value an attached validation + +`GET /v1/journey/configuration/{id}/environment` + +```ts +const { data } = await client.getJourneyEnvironment({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "items": [ + { + "datasourceId": "string", + "type": "Text", + "value": "string" + } + ], + "errors": [ + { + "datasourceId": "string", + "code": "not_found" + } + ], + "variables": [ + { + "key": "string", + "type": "Text", + "value": "string" + } + ], + "variableErrors": [ + { + "key": "string", + "code": "not_found" + } + ] +} +``` + +
+ +--- + +### `resolveJourneyExternalValues` + +Resolve the External Values hooks this journey's validation rules compare against. + +`POST /v1/journey/configuration/{id}/external-values` + +```ts +const { data } = await client.resolveJourneyExternalValues( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + items: [ + { + datasourceId: 'string', + context: {} + } + ] + }, +) +``` + +
+Response + +```json +{ + "items": [ + { + "datasourceId": "string", + "values": {}, + "errors": [ + { + "result_id": "string", + "code": "string", + "message": "string" + } + ], + "policy": { + "on_unavailable": "skip" + } + } + ], + "errors": [ + { + "datasourceId": "string", + "code": "unknown_datasource" + } + ] +} +``` + +
+ +--- + +### `getJourneyEnvironmentVariables` + +List the organization's client-safe environment variables a journey may use: Map and List```` as an options source; Text, Number, Boolean and lists of them in logic conditions. Only variables that c + +`GET /v1/journey/environment-variables` + +```ts +const { data } = await client.getJourneyEnvironmentVariables() +``` + +
+Response + +```json +{ + "items": [ + { + "key": "string", + "type": "Text", + "value": "string", + "description": "string" + } + ] +} +``` + +
+ +--- + +### `getJourneyTemplateVariables` + +List what a journey template can reference beyond the entity's own attributes: the organization's Custom Variables and its scalar environment variables (`String`, `Text`, `Number`, `Boolean`). Names o + +`GET /v1/journey/template-variables` + +```ts +const { data } = await client.getJourneyTemplateVariables() +``` + +
+Response + +```json +{ + "customVariables": [ + { + "key": "string", + "name": "string" + } + ], + "environment": [ + { + "key": "string", + "type": "String", + "description": "string", + "group": "string" + } + ] +} +``` + +
+ +--- + ### `getJourneyProducts` Get products available in the journey by id. requires public journey token to be passed. @@ -269,10 +936,16 @@ const { data } = await client.getJourneyProducts({ "_org": "string", "code": "string", "description": "string", - "feature": [], - "product_images": [], + "feature": [ + {} + ], + "product_images": [ + {} + ], "legal_footnote": "string", - "product_downloads": [], + "product_downloads": [ + {} + ], "price": {} } ] @@ -306,7 +979,9 @@ const { data } = await client.createJourney( showStepSubtitle: true, showStepper: true, showStepperLabels: true, + stepperType: 'numbers', hideNextButton: true, + guestVisible: true, name: 'string', stepId: 'string', schema: {}, @@ -341,10 +1016,13 @@ const { data } = await client.createJourney( type: 'string', paramKey: 'string', isRequired: true, - shouldLoadEntity: true + shouldLoadEntity: true, + description: 'string' } ], journey_type: 'Sales template (Premium)', + protected: true, + protectedEditable: ['string'], settings: { embedOptions: { mode: 'full-screen', @@ -360,6 +1038,7 @@ const { data } = await client.createJourney( templateId: 'string', entityId: 'string', mappingsAutomationId: 'string', + newMappings: true, targetedCustomer: 'string', description: 'string', organizationSettings: {}, @@ -369,26 +1048,43 @@ const { data } = await client.createJourney( entityTags: ['string'], addressSuggestionsFileUrl: 'string', addressSuggestionsFileId: 'string', + addressSuggestionsCountryCode: 'string', + addressSuggestionsEnableAutoComplete: true, + addressSuggestionsSource: ['string'], + addressSuggestionsEnableFreeText: true, useNewDesign: true, useAustrianLabels: true, enableDarkMode: true, accessMode: 'PUBLIC', + authGate: { + stepId: 'string' + }, isPublished: true, status: 'string', isActive: true, savingProgress: { - savingMode: 'auto', - supportedVersion: 0 + mode: 'auto', + supportedRevision: 0 + }, + thirdPartyCookies: true, + betaFeatures: { + modernProducts: true, + modernLauncher: true }, - thirdPartyCookies: true + offline: { + enabled: true, + packTtlHours: 24 + } }, validationRules: { block1: 'rule123', - block2: { - field1: 'rule456', - field2: 'rule789' + block2: ['rule456', 'rule789'], + block3: { + field1: 'rule101', + field2: ['rule102', 'rule103'] } }, + _manifest: ['123e4567-e89b-12d3-a456-426614174000'], createdBy: 'string', updatedBy: 'string', __lastModifiedAt: 'string' @@ -413,7 +1109,9 @@ const { data } = await client.createJourney( "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, + "guestVisible": true, "name": "string", "stepId": "string", "schema": {}, @@ -448,10 +1146,13 @@ const { data } = await client.createJourney( "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -467,6 +1168,7 @@ const { data } = await client.createJourney( "templateId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "targetedCustomer": "string", "description": "string", "organizationSettings": {}, @@ -476,26 +1178,43 @@ const { data } = await client.createJourney( "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "useAustrianLabels": true, "enableDarkMode": true, "accessMode": "PUBLIC", + "authGate": { + "stepId": "string" + }, "isPublished": true, "status": "string", "isActive": true, "savingProgress": { - "savingMode": "auto", - "supportedVersion": 0 + "mode": "auto", + "supportedRevision": 0 + }, + "thirdPartyCookies": true, + "betaFeatures": { + "modernProducts": true, + "modernLauncher": true }, - "thirdPartyCookies": true + "offline": { + "enabled": true, + "packTtlHours": 24 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "createdBy": "string", "updatedBy": "string", "__lastModifiedAt": "string", @@ -504,7 +1223,13 @@ const { data } = await client.createJourney( "deletedAt": "string", "version": 0, "revisions": 0, - "featureFlags": {} + "featureFlags": {}, + "templating": { + "customVariables": [ + {} + ], + "env": {} + } } ``` @@ -534,7 +1259,9 @@ const { data } = await client.updateJourney( showStepSubtitle: true, showStepper: true, showStepperLabels: true, + stepperType: 'numbers', hideNextButton: true, + guestVisible: true, name: 'string', stepId: 'string', schema: {}, @@ -569,10 +1296,13 @@ const { data } = await client.updateJourney( type: 'string', paramKey: 'string', isRequired: true, - shouldLoadEntity: true + shouldLoadEntity: true, + description: 'string' } ], journey_type: 'Sales template (Premium)', + protected: true, + protectedEditable: ['string'], settings: { embedOptions: { mode: 'full-screen', @@ -588,6 +1318,7 @@ const { data } = await client.updateJourney( templateId: 'string', entityId: 'string', mappingsAutomationId: 'string', + newMappings: true, targetedCustomer: 'string', description: 'string', organizationSettings: {}, @@ -597,26 +1328,43 @@ const { data } = await client.updateJourney( entityTags: ['string'], addressSuggestionsFileUrl: 'string', addressSuggestionsFileId: 'string', + addressSuggestionsCountryCode: 'string', + addressSuggestionsEnableAutoComplete: true, + addressSuggestionsSource: ['string'], + addressSuggestionsEnableFreeText: true, useNewDesign: true, useAustrianLabels: true, enableDarkMode: true, accessMode: 'PUBLIC', + authGate: { + stepId: 'string' + }, isPublished: true, status: 'string', isActive: true, savingProgress: { - savingMode: 'auto', - supportedVersion: 0 + mode: 'auto', + supportedRevision: 0 + }, + thirdPartyCookies: true, + betaFeatures: { + modernProducts: true, + modernLauncher: true }, - thirdPartyCookies: true + offline: { + enabled: true, + packTtlHours: 24 + } }, validationRules: { block1: 'rule123', - block2: { - field1: 'rule456', - field2: 'rule789' + block2: ['rule456', 'rule789'], + block3: { + field1: 'rule101', + field2: ['rule102', 'rule103'] } }, + _manifest: ['123e4567-e89b-12d3-a456-426614174000'], createdBy: 'string', updatedBy: 'string', __lastModifiedAt: 'string' @@ -671,6 +1419,8 @@ const { data } = await client.patchUpdateJourney( {} ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": {}, "safeModeAutomation": true, @@ -679,6 +1429,7 @@ const { data } = await client.patchUpdateJourney( "templateId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "targetedCustomer": "string", "description": "string", "organizationSettings": {}, @@ -688,20 +1439,29 @@ const { data } = await client.patchUpdateJourney( "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "useAustrianLabels": true, "enableDarkMode": true, "accessMode": "PUBLIC", + "authGate": {}, "isPublished": true, "status": "string", "isActive": true, "savingProgress": {}, - "thirdPartyCookies": true + "thirdPartyCookies": true, + "betaFeatures": {}, + "offline": {} }, "validationRules": { "block1": "rule123", - "block2": {} + "block2": ["rule456", "rule789"], + "block3": {} }, + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], "createdBy": "string", "updatedBy": "string", "__lastModifiedAt": "string", @@ -710,7 +1470,11 @@ const { data } = await client.patchUpdateJourney( "deletedAt": "string", "version": 0, "revisions": 0, - "featureFlags": {} + "featureFlags": {}, + "templating": { + "customVariables": [], + "env": {} + } } } ``` @@ -786,6 +1550,7 @@ const { data } = await client.generateDocument( context_data: { additionalProperties: 'string' }, + context_entity_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', language: 'de' }, ) @@ -834,7 +1599,7 @@ const { data } = await client.generateDocument( "template_with_datatable": false, "enabled_template_settings_persistence": false, "misconfigured_margins": false, - "file_entity_id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p" + "file_entity_id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d" } } ``` @@ -866,7 +1631,9 @@ const { data } = await client.createJourneyV2( showStepSubtitle: true, showStepper: true, showStepperLabels: true, + stepperType: 'numbers', hideNextButton: true, + guestVisible: true, name: 'string', stepId: 'string', schema: {}, @@ -901,10 +1668,13 @@ const { data } = await client.createJourneyV2( type: 'string', paramKey: 'string', isRequired: true, - shouldLoadEntity: true + shouldLoadEntity: true, + description: 'string' } ], journey_type: 'Sales template (Premium)', + protected: true, + protectedEditable: ['string'], settings: { embedOptions: { mode: 'full-screen', @@ -912,15 +1682,13 @@ const { data } = await client.createJourneyV2( width: 'string', topBar: true, scrollToTop: true, - button: { - text: 'string', - align: 'left' - } + button: { /* ... */ } }, safeModeAutomation: true, designId: 'string', entityId: 'string', mappingsAutomationId: 'string', + newMappings: true, templateId: 'string', targetedCustomer: 'string', description: 'string', @@ -930,16 +1698,38 @@ const { data } = await client.createJourneyV2( entityTags: ['string'], addressSuggestionsFileUrl: 'string', addressSuggestionsFileId: 'string', + addressSuggestionsCountryCode: 'string', + addressSuggestionsEnableAutoComplete: true, + addressSuggestionsSource: ['string'], + addressSuggestionsEnableFreeText: true, useNewDesign: true, thirdPartyCookies: true, accessMode: 'PUBLIC', - enableDarkMode: true + authGate: { + stepId: 'string' + }, + enableDarkMode: true, + useAustrianLabels: true, + isActive: true, + savingProgress: { + mode: 'auto', + supportedRevision: 0 + }, + betaFeatures: { + modernProducts: true, + modernLauncher: true + }, + offline: { + enabled: true, + packTtlHours: 24 + } }, validationRules: { block1: 'rule123', - block2: { - field1: 'rule456', - field2: 'rule789' + block2: ['rule456', 'rule789'], + block3: { + field1: 'rule101', + field2: ['rule102', 'rule103'] } }, _manifest: ['123e4567-e89b-12d3-a456-426614174000'] @@ -963,7 +1753,9 @@ const { data } = await client.createJourneyV2( "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, + "guestVisible": true, "name": "string", "stepId": "string", "schema": {}, @@ -998,10 +1790,13 @@ const { data } = await client.createJourneyV2( "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1009,15 +1804,13 @@ const { data } = await client.createJourneyV2( "width": "string", "topBar": true, "scrollToTop": true, - "button": { - "text": "string", - "align": "left" - } + "button": {} }, "safeModeAutomation": true, "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1027,16 +1820,38 @@ const { data } = await client.createJourneyV2( "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + }, + "betaFeatures": { + "modernProducts": true, + "modernLauncher": true + }, + "offline": { + "enabled": true, + "packTtlHours": 24 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1068,7 +1883,9 @@ const { data } = await client.updateJourneyV2( showStepSubtitle: true, showStepper: true, showStepperLabels: true, + stepperType: 'numbers', hideNextButton: true, + guestVisible: true, name: 'string', stepId: 'string', schema: {}, @@ -1103,10 +1920,13 @@ const { data } = await client.updateJourneyV2( type: 'string', paramKey: 'string', isRequired: true, - shouldLoadEntity: true + shouldLoadEntity: true, + description: 'string' } ], journey_type: 'Sales template (Premium)', + protected: true, + protectedEditable: ['string'], settings: { embedOptions: { mode: 'full-screen', @@ -1114,15 +1934,13 @@ const { data } = await client.updateJourneyV2( width: 'string', topBar: true, scrollToTop: true, - button: { - text: 'string', - align: 'left' - } + button: { /* ... */ } }, safeModeAutomation: true, designId: 'string', entityId: 'string', mappingsAutomationId: 'string', + newMappings: true, templateId: 'string', targetedCustomer: 'string', description: 'string', @@ -1132,16 +1950,38 @@ const { data } = await client.updateJourneyV2( entityTags: ['string'], addressSuggestionsFileUrl: 'string', addressSuggestionsFileId: 'string', + addressSuggestionsCountryCode: 'string', + addressSuggestionsEnableAutoComplete: true, + addressSuggestionsSource: ['string'], + addressSuggestionsEnableFreeText: true, useNewDesign: true, thirdPartyCookies: true, accessMode: 'PUBLIC', - enableDarkMode: true + authGate: { + stepId: 'string' + }, + enableDarkMode: true, + useAustrianLabels: true, + isActive: true, + savingProgress: { + mode: 'auto', + supportedRevision: 0 + }, + betaFeatures: { + modernProducts: true, + modernLauncher: true + }, + offline: { + enabled: true, + packTtlHours: 24 + } }, validationRules: { block1: 'rule123', - block2: { - field1: 'rule456', - field2: 'rule789' + block2: ['rule456', 'rule789'], + block3: { + field1: 'rule101', + field2: ['rule102', 'rule103'] } }, _manifest: ['123e4567-e89b-12d3-a456-426614174000'] @@ -1165,7 +2005,9 @@ const { data } = await client.updateJourneyV2( "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, + "guestVisible": true, "name": "string", "stepId": "string", "schema": {}, @@ -1200,10 +2042,13 @@ const { data } = await client.updateJourneyV2( "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1211,15 +2056,13 @@ const { data } = await client.updateJourneyV2( "width": "string", "topBar": true, "scrollToTop": true, - "button": { - "text": "string", - "align": "left" - } + "button": {} }, "safeModeAutomation": true, "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1229,16 +2072,38 @@ const { data } = await client.updateJourneyV2( "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + }, + "betaFeatures": { + "modernProducts": true, + "modernLauncher": true + }, + "offline": { + "enabled": true, + "packTtlHours": 24 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1281,7 +2146,9 @@ const { data } = await client.patchUpdateJourneyV2( "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, + "guestVisible": true, "name": "string", "stepId": "string", "schema": {}, @@ -1316,10 +2183,13 @@ const { data } = await client.patchUpdateJourneyV2( "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1327,15 +2197,13 @@ const { data } = await client.patchUpdateJourneyV2( "width": "string", "topBar": true, "scrollToTop": true, - "button": { - "text": "string", - "align": "left" - } + "button": {} }, "safeModeAutomation": true, "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1345,16 +2213,38 @@ const { data } = await client.patchUpdateJourneyV2( "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + }, + "betaFeatures": { + "modernProducts": true, + "modernLauncher": true + }, + "offline": { + "enabled": true, + "packTtlHours": 24 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1374,6 +2264,7 @@ Get journey by id ```ts const { data } = await client.getJourneyV2({ id: '123e4567-e89b-12d3-a456-426614174000', + version: 1, }) ``` @@ -1393,7 +2284,9 @@ const { data } = await client.getJourneyV2({ "showStepSubtitle": true, "showStepper": true, "showStepperLabels": true, + "stepperType": "numbers", "hideNextButton": true, + "guestVisible": true, "name": "string", "stepId": "string", "schema": {}, @@ -1428,10 +2321,13 @@ const { data } = await client.getJourneyV2({ "type": "string", "paramKey": "string", "isRequired": true, - "shouldLoadEntity": true + "shouldLoadEntity": true, + "description": "string" } ], "journey_type": "Sales template (Premium)", + "protected": true, + "protectedEditable": ["string"], "settings": { "embedOptions": { "mode": "full-screen", @@ -1439,15 +2335,13 @@ const { data } = await client.getJourneyV2({ "width": "string", "topBar": true, "scrollToTop": true, - "button": { - "text": "string", - "align": "left" - } + "button": {} }, "safeModeAutomation": true, "designId": "string", "entityId": "string", "mappingsAutomationId": "string", + "newMappings": true, "templateId": "string", "targetedCustomer": "string", "description": "string", @@ -1457,16 +2351,38 @@ const { data } = await client.getJourneyV2({ "entityTags": ["string"], "addressSuggestionsFileUrl": "string", "addressSuggestionsFileId": "string", + "addressSuggestionsCountryCode": "string", + "addressSuggestionsEnableAutoComplete": true, + "addressSuggestionsSource": ["string"], + "addressSuggestionsEnableFreeText": true, "useNewDesign": true, "thirdPartyCookies": true, "accessMode": "PUBLIC", - "enableDarkMode": true + "authGate": { + "stepId": "string" + }, + "enableDarkMode": true, + "useAustrianLabels": true, + "isActive": true, + "savingProgress": { + "mode": "auto", + "supportedRevision": 0 + }, + "betaFeatures": { + "modernProducts": true, + "modernLauncher": true + }, + "offline": { + "enabled": true, + "packTtlHours": 24 + } }, "validationRules": { "block1": "rule123", - "block2": { - "field1": "rule456", - "field2": "rule789" + "block2": ["rule456", "rule789"], + "block3": { + "field1": "rule101", + "field2": ["rule102", "rule103"] } }, "_manifest": ["123e4567-e89b-12d3-a456-426614174000"] @@ -1510,7 +2426,8 @@ const { data } = await client.getSettingsForJourney({ { "organizationId": "739224", "canary": true, - "thirdPartyCookies": true + "thirdPartyCookies": true, + "offline": true } ``` @@ -1548,6 +2465,249 @@ const { data } = await client.getButtonOptions({ ## Schemas +### `EnvironmentMapEntry` + +```ts +type EnvironmentMapEntry = { + key: string + value: string | Record +} +``` + +### `EnvironmentMap` + +```ts +type EnvironmentMap = { + fallbackLanguage?: string + options: Array<{ + key: string + value: string | Record + }> +} +``` + +### `EnvironmentLink` + +One link a customer clicks. `label` and `description` are each either a +plain string or one string per language, deciding that independently. +Mirrors environments-api's `LinkFields`. + + +```ts +type EnvironmentLink = { + url: string + label: string | Record + description?: string | Record +} +``` + +### `EnvironmentLinkList` + +A list of links, served under this service's own `List``` type +token. environments-api types the variable `List` and declares the +element type inside the value; journey-api composes the two so a +consumer needs only one discriminant. + + +```ts +type EnvironmentLinkList = { + itemType: "Link" + fallbackLanguage?: string + items: Array<{ + url: string + label: string | Record + description?: string | Record + }> +} +``` + +### `EnvironmentScalarList` + +A list of scalars, served under this service's own `List```, +`List``` or `List``` token (ER-5455). Read by logic +conditions; flattened to `items` by the journey runtime. + + +```ts +type EnvironmentScalarList = { + itemType: "Text" | "Number" | "Boolean" + items: string | number | boolean[] +} +``` + +### `JourneyEnvironmentResponse` + +```ts +type JourneyEnvironmentResponse = { + items: Array<{ + datasourceId: string + type: "Text" | "Number" | "Boolean" | "Map" | "List" + value: string | number | boolean | { + fallbackLanguage?: { ... } + options: { ... } + } | { + itemType: { ... } + fallbackLanguage?: { ... } + items: { ... } + } + }> + errors: Array<{ + datasourceId: string + code: "not_found" | "unsupported_type" | "not_set" | "invalid_value" | "incompatible_consumer" + }> + variables?: Array<{ + key: string + type: "Text" | "Number" | "Boolean" | "List" | "List" | "List" + value: string | number | boolean | { + itemType: { ... } + items: { ... } + } + }> + variableErrors?: Array<{ + key: string + code: "not_found" | "unsupported_type" | "not_set" | "invalid_value" + }> +} +``` + +### `JourneyExternalValuesRequest` + +```ts +type JourneyExternalValuesRequest = { + items: Array<{ + datasourceId: string + context: Record + }> +} +``` + +### `JourneyExternalValuesResponse` + +```ts +type JourneyExternalValuesResponse = { + items: Array<{ + datasourceId: string + values: Record + errors?: Array<{ + result_id?: { ... } + code: { ... } + message?: { ... } + }> + policy?: { + on_unavailable?: { ... } + } + }> + errors: Array<{ + datasourceId: string + code: "unknown_datasource" | "resolver_unavailable" + }> +} +``` + +### `ExternalValueError` + +```ts +type ExternalValueError = { + result_id?: string + code: string + message?: string +} +``` + +### `JourneyTemplatingContext` + +What the journey's Handlebars templates need from the organization, derived from the served configuration only. Present when the journey contains templates and templating is enabled for the organization. Read-only: like `featureFlags`, it is dropped from any write, so a client that sends the configu + +```ts +type JourneyTemplatingContext = { + templating?: { + customVariables: Array<{ + key: { ... } + template: { ... } + }> + env: Record + } +} +``` + +### `JourneyTemplateVariablesResponse` + +```ts +type JourneyTemplateVariablesResponse = { + customVariables: Array<{ + key: string + name: string + }> + environment: Array<{ + key: string + type: "String" | "Text" | "Number" | "Boolean" | "Link" + description?: string + group?: string + }> +} +``` + +### `JourneyTemplating` + +```ts +type JourneyTemplating = { + customVariables: Array<{ + key: string + template: string + }> + env: Record + description?: string | Record + }> +} +``` + +### `JourneyTemplatingLink` + +A Link variable; label and description are a string or per-language strings, resolved by the runtime + +```ts +type JourneyTemplatingLink = { + url: string + label: string | Record + description?: string | Record +} +``` + +### `JourneyTemplatingTranslatable` + +```ts +type JourneyTemplatingTranslatable = string | Record +``` + +### `JourneyEnvironmentVariablesResponse` + +```ts +type JourneyEnvironmentVariablesResponse = { + items: Array<{ + key: string + type: "Text" | "Number" | "Boolean" | "Map" | "List" | "List" | "List" | "List" + value: string | number | boolean | { + fallbackLanguage?: { ... } + options: { ... } + } | { + itemType: { ... } + fallbackLanguage?: { ... } + items: { ... } + } | { + itemType: { ... } + items: { ... } + } + description?: string + }> +} +``` + ### `GetJourneysResponse` ```ts @@ -1570,7 +2730,9 @@ type JourneyResponse = { showStepSubtitle?: { ... } showStepper?: { ... } showStepperLabels?: { ... } + stepperType?: { ... } hideNextButton?: { ... } + guestVisible?: { ... } name: { ... } stepId?: { ... } schema: { ... } @@ -1607,8 +2769,11 @@ type JourneyResponse = { paramKey: { ... } isRequired?: { ... } shouldLoadEntity?: { ... } + description?: { ... } }> journey_type?: string + protected?: boolean + protectedEditable?: string[] settings?: { embedOptions?: { ... } safeModeAutomation?: { ... } @@ -1617,6 +2782,7 @@ type JourneyResponse = { templateId?: { ... } entityId?: { ... } mappingsAutomationId?: { ... } + newMappings?: { ... } targetedCustomer?: { ... } description?: { ... } organizationSettings?: { ... } @@ -1626,27 +2792,32 @@ type JourneyResponse = { entityTags?: { ... } addressSuggestionsFileUrl?: { ... } addressSuggestionsFileId?: { ... } + addressSuggestionsCountryCode?: { ... } + addressSuggestionsEnableAutoComplete?: { ... } + addressSuggestionsSource?: { ... } + addressSuggestionsEnableFreeText?: { ... } useNewDesign?: { ... } useAustrianLabels?: { ... } enableDarkMode?: { ... } accessMode?: { ... } + authGate?: { ... } isPublished?: { ... } status?: { ... } isActive?: { ... } savingProgress?: { ... } thirdPartyCookies?: { ... } + betaFeatures?: { ... } + offline?: { ... } } - validationRules?: Record> + validationRules?: Record> + _manifest?: string // uuid[] createdBy?: string updatedBy?: string __lastModifiedAt?: string createdAt: string lastModifiedAt: string deletedAt?: string - version: number - revisions: number - featureFlags?: Record - } + // ... } ``` @@ -1697,7 +2868,9 @@ type JourneyCreationRequest = { showStepSubtitle?: boolean showStepper?: boolean showStepperLabels?: boolean + stepperType?: "numbers" | "progress bar" hideNextButton?: boolean + guestVisible?: boolean name: string stepId?: string schema: unknown @@ -1740,8 +2913,11 @@ type JourneyCreationRequest = { paramKey: string isRequired?: boolean shouldLoadEntity?: boolean + description?: string }> journey_type?: string + protected?: boolean + protectedEditable?: string[] settings?: { embedOptions?: { mode?: { ... } @@ -1757,6 +2933,7 @@ type JourneyCreationRequest = { templateId?: string entityId?: string mappingsAutomationId?: string + newMappings?: boolean targetedCustomer?: string description?: string organizationSettings?: Record @@ -1766,31 +2943,173 @@ type JourneyCreationRequest = { entityTags?: string[] addressSuggestionsFileUrl?: string addressSuggestionsFileId?: string + addressSuggestionsCountryCode?: string + addressSuggestionsEnableAutoComplete?: boolean + addressSuggestionsSource?: string[] + addressSuggestionsEnableFreeText?: boolean useNewDesign?: boolean useAustrianLabels?: boolean enableDarkMode?: boolean accessMode?: "PUBLIC" | "PRIVATE" + authGate?: { + stepId: { ... } + } isPublished?: boolean status?: string - isActive?: boolean - savingProgress?: { - savingMode?: { ... } - supportedVersion?: { ... } + // ... +} +``` + +### `JourneyCreationRequestV2` + +```ts +type JourneyCreationRequestV2 = { + journeyId?: string + brandId?: string + name: string + steps: Array<{ + showStepName?: boolean + title?: string + subTitle?: string + showStepSubtitle?: boolean + showStepper?: boolean + showStepperLabels?: boolean + stepperType?: "numbers" | "progress bar" + hideNextButton?: boolean + guestVisible?: boolean + name: string + stepId?: string + schema: unknown + uischema: unknown + maxWidth?: "small" | "medium" | "large" | "extra large" + }> + design?: { + logoUrl?: string + theme?: Record + designTokens?: object + } + rules?: Array<{ + type: "inject" | "injectWithKey" + sourceType: "journey" | "step" | "block" + source: string + target: string + }> + logics?: Array<{ + autoGeneratedId?: string + conditions: string[] + actions: string[] + }> + logicsV4?: Record> + settings?: object + }> + contextSchema?: Array<{ + id?: string // uuid + type: string + paramKey: string + isRequired?: boolean + shouldLoadEntity?: boolean + description?: string + }> + journey_type?: string + protected?: boolean + protectedEditable?: string[] + settings?: { + embedOptions?: { + mode?: { ... } + lang?: { ... } + width?: { ... } + topBar?: { ... } + scrollToTop?: { ... } + button?: { ... } } + safeModeAutomation?: boolean + designId?: string + entityId?: string + mappingsAutomationId?: string + newMappings?: boolean + templateId?: string + targetedCustomer?: string + description?: string + publicToken?: string + runtimeEntities?: "ORDER" | "OPPORTUNITY"[] + filePurposes?: string[] + entityTags?: string[] + addressSuggestionsFileUrl?: string + addressSuggestionsFileId?: string + addressSuggestionsCountryCode?: string + addressSuggestionsEnableAutoComplete?: boolean + addressSuggestionsSource?: string[] + addressSuggestionsEnableFreeText?: boolean + useNewDesign?: boolean thirdPartyCookies?: boolean - } - validationRules?: Record> - createdBy?: string - updatedBy?: string - __lastModifiedAt?: string + accessMode?: "PUBLIC" | "PRIVATE" + authGate?: { + stepId: { ... } + } + enableDarkMode?: boolean + useAustrianLabels?: boolean + isActive?: boolean + savingProgress?: { + mode?: { ... } + supportedRevision?: { ... } + // ... +} +``` + +### `SearchJourneysQueryRequest` + +```ts +type SearchJourneysQueryRequest = { + q?: string + from?: number + size?: number + sort?: string } ``` -### `JourneyCreationRequestV2` +### `SearchJourneysResponse` ```ts -type JourneyCreationRequestV2 = { +type SearchJourneysResponse = { + hits?: number + results?: Array<{ + _id?: string // uuid + _schema?: string + _title?: string + _org?: string + _created_at?: string // date-time + _updated_at?: string // date-time + _tags?: string[] + _manifest?: string // uuid[] + journey_name?: string + journey_id?: string // uuid + journey_type?: string + design?: string + created_by?: Array<{ + id?: { ... } + }> + journey_version?: "Flex" + }> +} +``` + +### `Journey` + +```ts +type Journey = { journeyId?: string + organizationId: string brandId?: string name: string steps: Array<{ @@ -1800,7 +3119,9 @@ type JourneyCreationRequestV2 = { showStepSubtitle?: boolean showStepper?: boolean showStepperLabels?: boolean + stepperType?: "numbers" | "progress bar" hideNextButton?: boolean + guestVisible?: boolean name: string stepId?: string schema: unknown @@ -1843,8 +3164,11 @@ type JourneyCreationRequestV2 = { paramKey: string isRequired?: boolean shouldLoadEntity?: boolean + description?: string }> journey_type?: string + protected?: boolean + protectedEditable?: string[] settings?: { embedOptions?: { mode?: { ... } @@ -1855,69 +3179,89 @@ type JourneyCreationRequestV2 = { button?: { ... } } safeModeAutomation?: boolean - designId?: string + canary?: boolean + designId: string + templateId?: string entityId?: string mappingsAutomationId?: string - templateId?: string + newMappings?: boolean targetedCustomer?: string description?: string + organizationSettings?: Record publicToken?: string runtimeEntities?: "ORDER" | "OPPORTUNITY"[] filePurposes?: string[] entityTags?: string[] addressSuggestionsFileUrl?: string addressSuggestionsFileId?: string + addressSuggestionsCountryCode?: string + addressSuggestionsEnableAutoComplete?: boolean + addressSuggestionsSource?: string[] + addressSuggestionsEnableFreeText?: boolean useNewDesign?: boolean - thirdPartyCookies?: boolean - accessMode?: "PUBLIC" | "PRIVATE" + useAustrianLabels?: boolean enableDarkMode?: boolean + accessMode?: "PUBLIC" | "PRIVATE" + authGate?: { + stepId: { ... } + } + isPublished?: boolean + status?: string + // ... +} +``` + +### `JourneyServedRevision` + +Which revision the runtime read served: the requested one, or the published version when no revision was requested. Absent while the journey has not adopted versioning and on legacy `version` reads. + + +```ts +type JourneyServedRevision = { + revision_id?: string +} +``` + +### `JourneyActivationGuarantee` + +Journeys read from the API always carry an explicit `settings.isActive`. The flag remains optional in request bodies. + + +```ts +type JourneyActivationGuarantee = { + settings: { + isActive: boolean } - validationRules?: Record> - _manifest?: string // uuid[] } ``` -### `SearchJourneysQueryRequest` +### `JourneyFeatureFlags` ```ts -type SearchJourneysQueryRequest = { - q?: string - from?: number - size?: number - sort?: string +type JourneyFeatureFlags = { + featureFlags?: Record } ``` -### `SearchJourneysResponse` +### `JourneyAuditInfo` ```ts -type SearchJourneysResponse = { - hits?: number - results?: Array<{ - _id?: string // uuid - _schema?: string - _title?: string - _org?: string - _created_at?: string // date-time - _updated_at?: string // date-time - _tags?: string[] - _manifest?: string // uuid[] - journey_name?: string - journey_id?: string // uuid - journey_type?: string - design?: string - created_by?: Array<{ - id?: { ... } - }> - journey_version?: "Flex" - }> +type JourneyAuditInfo = { + createdAt: string + lastModifiedAt: string + deletedAt?: string + version: number + revisions: number } ``` -### `Journey` +### `JourneyRevisionRequest` + +The complete journey configuration a revision is created from, same shape as the `PUT` body. Server-managed attributes of the journey record (`revisions`, `version`, publish metadata) are ignored. + ```ts -type Journey = { +type JourneyRevisionRequest = { journeyId?: string organizationId: string brandId?: string @@ -1929,7 +3273,9 @@ type Journey = { showStepSubtitle?: boolean showStepper?: boolean showStepperLabels?: boolean + stepperType?: "numbers" | "progress bar" hideNextButton?: boolean + guestVisible?: boolean name: string stepId?: string schema: unknown @@ -1972,8 +3318,11 @@ type Journey = { paramKey: string isRequired?: boolean shouldLoadEntity?: boolean + description?: string }> journey_type?: string + protected?: boolean + protectedEditable?: string[] settings?: { embedOptions?: { mode?: { ... } @@ -1989,6 +3338,7 @@ type Journey = { templateId?: string entityId?: string mappingsAutomationId?: string + newMappings?: boolean targetedCustomer?: string description?: string organizationSettings?: Record @@ -1998,46 +3348,266 @@ type Journey = { entityTags?: string[] addressSuggestionsFileUrl?: string addressSuggestionsFileId?: string + addressSuggestionsCountryCode?: string + addressSuggestionsEnableAutoComplete?: boolean + addressSuggestionsSource?: string[] + addressSuggestionsEnableFreeText?: boolean useNewDesign?: boolean useAustrianLabels?: boolean enableDarkMode?: boolean accessMode?: "PUBLIC" | "PRIVATE" + authGate?: { + stepId: { ... } + } isPublished?: boolean status?: string - isActive?: boolean - savingProgress?: { - savingMode?: { ... } - supportedVersion?: { ... } + // ... +} +``` + +### `PublishRevisionRequest` + +```ts +type PublishRevisionRequest = { + revision_id: string + name?: string + description?: string +} +``` + +### `RevisionMetadataUpdate` + +```ts +type RevisionMetadataUpdate = { + name?: string + description?: string +} +``` + +### `JourneyRevisionSummary` + +```ts +type JourneyRevisionSummary = { + revision_id: string + created_at: string // date-time + created_by?: string + name?: string + description?: string + published_at?: string // date-time + is_published: boolean + metadata_updated_at?: string // date-time + metadata_updated_by?: string + mapping_config_version?: number +} +``` + +### `JourneyRevisionList` + +```ts +type JourneyRevisionList = { + results: Array<{ + revision_id: string + created_at: string // date-time + created_by?: string + name?: string + description?: string + published_at?: string // date-time + is_published: boolean + metadata_updated_at?: string // date-time + metadata_updated_by?: string + mapping_config_version?: number + }> + next_cursor?: string +} +``` + +### `JourneyRevision` + +```ts +type JourneyRevision = { + revision_id: string + created_at: string // date-time + created_by?: string + name?: string + description?: string + published_at?: string // date-time + is_published: boolean + metadata_updated_at?: string // date-time + metadata_updated_by?: string + mapping_config_version?: number + configuration: { + journeyId?: string + organizationId: string + brandId?: string + name: string + steps: Array<{ + showStepName?: { ... } + title?: { ... } + subTitle?: { ... } + showStepSubtitle?: { ... } + showStepper?: { ... } + showStepperLabels?: { ... } + stepperType?: { ... } + hideNextButton?: { ... } + guestVisible?: { ... } + name: { ... } + stepId?: { ... } + schema: { ... } + uischema: { ... } + maxWidth?: { ... } + }> + design?: { + logoUrl?: { ... } + theme?: { ... } + designTokens?: { ... } } - thirdPartyCookies?: boolean - } - validationRules?: Record> - createdBy?: string - updatedBy?: string - __lastModifiedAt?: string - createdAt: string - lastModifiedAt: string + rules?: Array<{ + type: { ... } + sourceType: { ... } + source: { ... } + target: { ... } + }> + logics?: Array<{ + autoGeneratedId?: { ... } + conditions: { ... } + actions: { ... } + }> + logicsV4?: Record + contextSchema?: Array<{ + id?: { ... } + type: { ... } + paramKey: { ... } + isRequired?: { ... } + shouldLoadEntity?: { ... } + description?: { ... } + }> + journey_type?: string + protected?: boolean + protectedEditable?: string[] + settings?: { + embedOptions?: { ... } + safeModeAutomation?: { ... } + canary?: { ... } + designId: { ... } + templateId?: { ... } + entityId?: { ... } + mappingsAutomationId?: { ... } + newMappings?: { ... } + targetedCustomer?: { ... } + description?: { ... } + organizationSettings?: { ... } + publicToken?: { ... } + runtimeEntities?: { ... } + filePurposes?: { ... } + entityTags?: { ... } + addressSuggestionsFileUrl?: { ... } + addressSuggestionsFileId?: { ... } + addressSuggestionsCountryCode?: { ... } + addressSuggestionsEnableAutoComplete?: { ... } + addressSuggestionsSource?: { ... } + addressSuggestionsEnableFreeText?: { ... } + useNewDesign?: { ... } + useAustrianLabels?: { ... } + enableDarkMode?: { ... } + accessMode?: { ... } + authGate?: { ... } + isPublished?: { ... } + status?: { ... } + isActive?: { ... } + savingProgress?: { ... } + thirdPartyCookies?: { ... } + betaFeatures?: { ... } // ... } ``` -### `JourneyFeatureFlags` +### `JourneyRevisionConflict` ```ts -type JourneyFeatureFlags = { - featureFlags?: Record +type JourneyRevisionConflict = { + message: string + latest_revision: { + revision_id: string + created_at: string // date-time + created_by?: string + name?: string + description?: string + published_at?: string // date-time + is_published: boolean + metadata_updated_at?: string // date-time + metadata_updated_by?: string + mapping_config_version?: number + } } ``` -### `JourneyAuditInfo` +### `JourneyPublishState` ```ts -type JourneyAuditInfo = { - createdAt: string - lastModifiedAt: string - deletedAt?: string - version: number - revisions: number +type JourneyPublishState = { + journey_id: string // uuid + published_revision_id: string + published_at?: string // date-time + published_by?: string +} +``` + +### `PublishResult` + +```ts +type PublishResult = { + revision_id: string + name: string + published_at: string // date-time + published_by?: string + post_publish_warnings: string[] +} +``` + +### `JourneyValidationResponse` + +```ts +type JourneyValidationResponse = { + valid: boolean + errors: Array<{ + type?: string + severity?: "critical" | "high" | "medium" | "low" + message?: string + affectedStepIds?: string[] + count?: number + autoFix?: { + feasible?: { ... } + confidence?: { ... } + reason?: { ... } + details?: { ... } + } + }> + warnings?: Array<{ + type?: string + message?: string + }> +} +``` + +### `JourneyValidationError` + +```ts +type JourneyValidationError = { + error: string + message: string + details: Array<{ + pattern?: string + severity?: "critical" | "high" | "medium" | "low" + message?: string + count?: number + }> } ``` @@ -2124,6 +3694,7 @@ type GenerateDocumentRequest = { context_data: { additionalProperties?: string } + context_entity_id?: string // uuid language?: string } ``` @@ -2135,6 +3706,7 @@ type GetSettingsForJourney = { organizationId?: string canary?: boolean thirdPartyCookies?: boolean + offline?: boolean } ``` @@ -2152,19 +3724,20 @@ type ButtonOption = { ### `ValidationRuleRef` References to validation rules organized by blocks and fields. -Maps block IDs to either rule IDs (for block-level rules) or rule references (for field-level rules). +Maps block IDs to either one or more ordered rule IDs (for block-level rules) +or rule references (for field-level rules). ```ts -type ValidationRuleRef = Record> +type ValidationRuleRef = Record> ``` ### `RuleRef` Field-level rule references within a block. -Maps field names to rule IDs. +Maps field names to one or more ordered rule IDs. ```ts -type RuleRef = Record +type RuleRef = Record ``` diff --git a/docs/sdk/clients/kanban.md b/docs/sdk/clients/kanban.md index 76e82271..8caaacfd 100644 --- a/docs/sdk/clients/kanban.md +++ b/docs/sdk/clients/kanban.md @@ -44,10 +44,12 @@ const { data } = await kanbanClient.createKanbanBoard(...) - [`executeFlowsQuery`](#executeflowsquery) **Schemas** +- [`Error`](#error) - [`BoardSummary`](#boardsummary) - [`Board`](#board) - [`Swimlane`](#swimlane) - [`Sorting`](#sorting) +- [`GroupBy`](#groupby) - [`BoardFilter`](#boardfilter) - [`FilterGroup`](#filtergroup) - [`FilterOperator`](#filteroperator) @@ -59,7 +61,7 @@ const { data } = await kanbanClient.createKanbanBoard(...) ### `createKanbanBoard` -Create a Kanban board +Creates a new Kanban board with the provided configuration. `POST /v1/kanban/board` @@ -117,6 +119,9 @@ const { data } = await client.createKanbanBoard( field: 'created_at', direction: 'asc' }, + group_by: { + field: 'context_entity' + }, search_query: 'task 1' } }, @@ -178,6 +183,9 @@ const { data } = await client.createKanbanBoard( "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } } @@ -189,7 +197,7 @@ const { data } = await client.createKanbanBoard( ### `getKanbanBoards` -Get all Kanban boards +Returns a list of all Kanban boards accessible to the authenticated user. `GET /v1/kanban/boards` @@ -226,7 +234,7 @@ const { data } = await client.getKanbanBoards({ ### `getKanbanBoard` -Get a Kanban board +Retrieves a Kanban board by ID, including its full configuration (swimlanes, filters, sorting, card fields). `GET /v1/kanban/board/{boardId}` @@ -291,6 +299,9 @@ const { data } = await client.getKanbanBoard({ "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } } @@ -302,7 +313,7 @@ const { data } = await client.getKanbanBoard({ ### `updateKanbanBoard` -Update a Kanban board +Fully replaces the configuration of an existing Kanban board by ID. `PUT /v1/kanban/board/{boardId}` @@ -362,6 +373,9 @@ const { data } = await client.updateKanbanBoard( field: 'created_at', direction: 'asc' }, + group_by: { + field: 'context_entity' + }, search_query: 'task 1' } }, @@ -423,6 +437,9 @@ const { data } = await client.updateKanbanBoard( "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } } @@ -434,7 +451,7 @@ const { data } = await client.updateKanbanBoard( ### `patchKanbanBoard` -Patch a Kanban board +Partially updates fields of an existing Kanban board by ID. `PATCH /v1/kanban/board/{boardId}` @@ -508,6 +525,9 @@ const { data } = await client.patchKanbanBoard( "field": "created_at", "direction": "asc" }, + "group_by": { + "field": "context_entity" + }, "search_query": "task 1" } } @@ -519,7 +539,7 @@ const { data } = await client.patchKanbanBoard( ### `deleteKanbanBoard` -Delete a Kanban board +Permanently deletes a Kanban board by ID. This action is irreversible. `DELETE /v1/kanban/board/{boardId}` @@ -533,7 +553,7 @@ const { data } = await client.deleteKanbanBoard({ ### `setDefaultKanbanBoard` -Set default board for organization +Sets a Kanban board as the default board for the organization. `PUT /v1/kanban/org/default-board` @@ -559,7 +579,7 @@ const { data } = await client.setDefaultKanbanBoard({ ### `clearDefaultKanbanBoard` -Clear default board for organization +Removes the default board configuration for the organization. `DELETE /v1/kanban/org/default-board` @@ -583,7 +603,7 @@ const { data } = await client.clearDefaultKanbanBoard() ### `flowsAutocomplete` -Autocomplete flows data +Returns autocomplete suggestions for a given attribute in the Flows dataset. `GET /v1/kanban/query/flows:autocomplete` @@ -612,7 +632,7 @@ const { data } = await client.flowsAutocomplete({ ### `executeFlowsQuery` -Query Flows Data for Kanban View. +Executes a query against the Flows dataset and returns paginated results for use in Kanban card rendering. `POST /v1/kanban/query/flows:execute` @@ -635,6 +655,9 @@ const { data } = await client.executeFlowsQuery( field: 'created_at', direction: 'asc' }, + group_by: { + field: 'context_entity' + }, from: 0, size: 10 }, @@ -649,10 +672,10 @@ const { data } = await client.executeFlowsQuery( "results": [ {} ], - "hits": 0, - "page_number": 0, - "page_size": 0, - "total_pages": 0 + "hits": 42, + "page_number": 1, + "page_size": 10, + "total_pages": 5 } ``` @@ -662,8 +685,21 @@ const { data } = await client.executeFlowsQuery( ## Schemas +### `Error` + +Standard error response + +```ts +type Error = { + message?: string + status?: number +} +``` + ### `BoardSummary` +Summary representation of a Kanban board, returned in list responses. Does not include swimlane and filter configuration details. + ```ts type BoardSummary = { id?: string @@ -682,6 +718,8 @@ type BoardSummary = { ### `Board` +Full representation of a Kanban board, including swimlane layout, filter configuration, card display fields, and sorting options. + ```ts type Board = { id?: string @@ -715,6 +753,9 @@ type Board = { field: { ... } direction?: { ... } } + group_by?: { + field: { ... } + } search_query?: string } } @@ -722,6 +763,8 @@ type Board = { ### `Swimlane` +A vertical column in a Kanban board that groups workflow tasks or entities matching its filter criteria. Each swimlane has an independent filter and a display position. + ```ts type Swimlane = { id?: string @@ -745,6 +788,8 @@ type Swimlane = { ### `Sorting` +Defines how query results should be sorted. Specify a field name and sort direction. + ```ts type Sorting = { field: string @@ -752,14 +797,26 @@ type Sorting = { } ``` +### `GroupBy` + +Defines how tasks should be grouped within each swimlane. Tasks with the same group value are returned adjacently in the result set. + +```ts +type GroupBy = { + field: "context_entity" | "phase" | "task" +} +``` + ### `BoardFilter` +A filter group containing one or more filter items or nested filter groups. Items are combined using the specified logical operator (AND/OR). + ```ts type BoardFilter = { items: Array<{ key: string operator: "EQUALS" | "NOT_EQUALS" | "EMPTY" | "NOT_EMPTY" | "CONTAINS" | "NOT_CONTAINS" | "IS_ONE_OF" | "IS_NONE_OF" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" - value?: string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | number | boolean | string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | number | boolean[] + value?: string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" | number | boolean | string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" | number | boolean[] data_type?: "string" | "number" | "boolean" | "date" } | { items: Array<{ @@ -781,7 +838,7 @@ type FilterGroup = { items: Array<{ key: string operator: "EQUALS" | "NOT_EQUALS" | "EMPTY" | "NOT_EMPTY" | "CONTAINS" | "NOT_CONTAINS" | "IS_ONE_OF" | "IS_NONE_OF" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" - value?: string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | number | boolean | string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | number | boolean[] + value?: string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" | number | boolean | string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" | number | boolean[] data_type?: "string" | "number" | "boolean" | "date" }> combination: "AND" | "OR" @@ -801,7 +858,7 @@ type FilterOperator = "EQUALS" | "NOT_EQUALS" | "EMPTY" | "NOT_EMPTY" | "CONTAIN Dynamic date keywords that resolve to actual dates at runtime ```ts -type DynamicDateValue = "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" +type DynamicDateValue = "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" ``` ### `ValueType` @@ -809,11 +866,13 @@ type DynamicDateValue = "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | " The value to compare against - can be a single value (string, number, boolean, or dynamic date) or an array of values ```ts -type ValueType = string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | number | boolean | string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | number | boolean[] +type ValueType = string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" | number | boolean | string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" | number | boolean[] ``` ### `FlowsQueryRequest` +Request payload for executing a query against the Flows dataset. Supports filter conditions, sorting, grouping, and offset-based pagination. + ```ts type FlowsQueryRequest = { filters?: { @@ -832,6 +891,9 @@ type FlowsQueryRequest = { field: string direction?: "asc" | "desc" } + group_by?: { + field: "context_entity" | "phase" | "task" + } from?: number size?: number } @@ -839,6 +901,8 @@ type FlowsQueryRequest = { ### `FlowsQueryResult` +Paginated result set returned from a Flows query. Each item in `results` is a workflow task record with dynamic fields depending on the dataset configuration. + ```ts type FlowsQueryResult = { results?: Record[] @@ -855,7 +919,7 @@ type FlowsQueryResult = { type FilterItem = { key: string operator: "EQUALS" | "NOT_EQUALS" | "EMPTY" | "NOT_EMPTY" | "CONTAINS" | "NOT_CONTAINS" | "IS_ONE_OF" | "IS_NONE_OF" | "GREATER_THAN" | "LESS_THAN" | "GREATER_THAN_OR_EQUAL" | "LESS_THAN_OR_EQUAL" - value?: string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | number | boolean | string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | number | boolean[] + value?: string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" | number | boolean | string | "TODAY" | "TOMORROW" | "YESTERDAY" | "IN_THE_FUTURE" | "IN_THE_PAST" | "THIS_WEEK" | "NEXT_WEEK" | "LAST_WEEK" | "THIS_MONTH" | "NEXT_MONTH" | "LAST_MONTH" | "TODAY_OR_EARLIER" | number | boolean[] data_type?: "string" | "number" | "boolean" | "date" } ``` diff --git a/docs/sdk/clients/message.md b/docs/sdk/clients/message.md index 6bee3450..426d1033 100644 --- a/docs/sdk/clients/message.md +++ b/docs/sdk/clients/message.md @@ -42,21 +42,30 @@ const { data } = await messageClient.sendMessage(...) - [`markReadMessageV2`](#markreadmessagev2) - [`markUnreadMessage`](#markunreadmessage) - [`getUnread`](#getunread) +- [`getUnreadCounts`](#getunreadcounts) - [`markUnreadMessageV2`](#markunreadmessagev2) +- [`spamMessage`](#spammessage) +- [`unspamMessage`](#unspammessage) - [`getMessageV2`](#getmessagev2) **Threads** - [`searchThreads`](#searchthreads) - [`searchThreadsV2`](#searchthreadsv2) - [`searchIds`](#searchids) +- [`getAssigneeWorkload`](#getassigneeworkload) - [`updateThread`](#updatethread) - [`deleteThread`](#deletethread) - [`moveThread`](#movethread) - [`markThreadAsDone`](#markthreadasdone) - [`markThreadAsOpen`](#markthreadasopen) - [`getThreadTimeline`](#getthreadtimeline) +- [`getThreadSummary`](#getthreadsummary) - [`trashThread`](#trashthread) - [`untrashThread`](#untrashthread) +- [`spamThread`](#spamthread) +- [`unspamThread`](#unspamthread) +- [`bulkMoveThreads`](#bulkmovethreads) +- [`bulkAssignThreads`](#bulkassignthreads) - [`threadBulkActionsRead`](#threadbulkactionsread) - [`threadBulkActionsUnread`](#threadbulkactionsunread) - [`threadBulkActionsFavorite`](#threadbulkactionsfavorite) @@ -71,6 +80,7 @@ const { data } = await messageClient.sendMessage(...) - [`markUnreadThread`](#markunreadthread) - [`markUnreadThreadV2`](#markunreadthreadv2) - [`assignThread`](#assignthread) +- [`dismissThreadLinkSuggestions`](#dismissthreadlinksuggestions) - [`unassignThread`](#unassignthread) - [`assignUsers`](#assignusers) - [`assignUsersV2`](#assignusersv2) @@ -92,14 +102,49 @@ const { data } = await messageClient.sendMessage(...) - [`AttachmentsRelation`](#attachmentsrelation) - [`File`](#file) - [`MessageRequestParams`](#messagerequestparams) +- [`ThreadView`](#threadview) +- [`UnreadCountScope`](#unreadcountscope) +- [`UnreadCountsPayload`](#unreadcountspayload) +- [`UnreadCountsResult`](#unreadcountsresult) +- [`UnreadCountBuckets`](#unreadcountbuckets) - [`SearchParamsV2`](#searchparamsv2) - [`SearchParams`](#searchparams) - [`SearchIDParams`](#searchidparams) +- [`AssigneeWorkloadParams`](#assigneeworkloadparams) +- [`AssigneeWorkload`](#assigneeworkload) +- [`AssigneeWorkloadResults`](#assigneeworkloadresults) - [`ReadMessagePayload`](#readmessagepayload) - [`ReadingScope`](#readingscope) +- [`ThreadReplyContext`](#threadreplycontext) +- [`ReplyContextMessage`](#replycontextmessage) +- [`ReplyContextEntityRef`](#replycontextentityref) +- [`ThreadSummary`](#threadsummary) +- [`ThreadSummaryPayload`](#threadsummarypayload) +- [`ThreadSummaryEntityRef`](#threadsummaryentityref) +- [`ThreadSummaryContext`](#threadsummarycontext) +- [`SimilarSentMessagesRequest`](#similarsentmessagesrequest) +- [`SimilarSentMessagesResponse`](#similarsentmessagesresponse) +- [`SimilarSentMessage`](#similarsentmessage) - [`ThreadTimeline`](#threadtimeline) - [`ThreadDoneEvent`](#threaddoneevent) - [`ThreadOpenEvent`](#threadopenevent) +- [`WorkflowStartedEvent`](#workflowstartedevent) +- [`ThreadUserAssignedEvent`](#threaduserassignedevent) +- [`MessageLabelAddedEvent`](#messagelabeladdedevent) +- [`MessageLabelRemovedEvent`](#messagelabelremovedevent) +- [`MessageEntityLinkedEvent`](#messageentitylinkedevent) +- [`MessageEntityUnlinkedEvent`](#messageentityunlinkedevent) +- [`MessageAutoReplySentEvent`](#messageautoreplysentevent) +- [`ThreadMovedToInboxEvent`](#threadmovedtoinboxevent) +- [`ThreadTrashedEvent`](#threadtrashedevent) +- [`ThreadRestoredEvent`](#threadrestoredevent) +- [`LinkSuggestionCandidate`](#linksuggestioncandidate) +- [`LinkSuggestion`](#linksuggestion) +- [`TimelineLinkSuggestion`](#timelinelinksuggestion) +- [`MessageEntityLinkSuggestedEvent`](#messageentitylinksuggestedevent) +- [`MessageEntityLinkSuggestionDismissedEvent`](#messageentitylinksuggestiondismissedevent) +- [`TimelineLinkedEntity`](#timelinelinkedentity) +- [`TimelineActor`](#timelineactor) - [`TimelineEventData`](#timelineeventdata) - [`TimelineEvent`](#timelineevent) - [`BulkActionsPayloadWithScopes`](#bulkactionspayloadwithscopes) @@ -156,6 +201,7 @@ const { data } = await client.updateMessage() "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -209,7 +255,8 @@ const { data } = await client.updateMessage() "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -253,6 +300,7 @@ const { data } = await client.getMessage({ "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -306,7 +354,8 @@ const { data } = await client.getMessage({ "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -365,6 +414,24 @@ const { data } = await client.searchMessages( { inbox_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3', q: 'subject:"Request for solar panel price" AND _tags:INBOX', + view: { + folder: 'inbox', + mailbox: 'organization', + labels: ['string'], + purposes: ['string'], + filters: ['unread'], + from: ['string'], + to: ['string'], + assigned_to: ['string'], + include_unassigned: true, + date_from_days_ago: 0, + date_to_days_ago: 0, + email_filter: ['string'], + text: 'string', + thread_ids: ['string'], + pinned_by: 'string' + }, + user_groups: ['string'], fields: ['_id', '_title', 'first_name', 'account', '!account.*._files', '**._product'], from: 0, size: 10, @@ -393,6 +460,7 @@ const { data } = await client.searchMessages( "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -446,7 +514,8 @@ const { data } = await client.searchMessages( "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -562,7 +631,49 @@ const { data } = await client.getUnread({ "count": 14, "unread": 0, "drafts": 12, - "unassigned": 1 + "unassigned": 1, + "spam": 3 +} +``` + +
+ +--- + +### `getUnreadCounts` + +Unread counts for several named scopes in one request. + +`POST /v1/message/unread:counts` + +```ts +const { data } = await client.getUnreadCounts( + null, + { + actor: 'organization', + email_filter: ['string'], + user_groups: ['string'], + scopes: [ + { + name: 'inbox-support', + type: 'organization', + q: '_tags.keyword:inbox AND !_tags.keyword:trash', + view_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3', + inbox_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3' + } + ] + }, +) +``` + +
+Response + +```json +{ + "enabled": true, + "counts": {}, + "omitted": ["string"] } ``` @@ -650,6 +761,24 @@ const { data } = await client.searchThreadsV2( { inbox_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3', q: 'subject:"Request for solar panel price" AND _tags:INBOX', + view: { + folder: 'inbox', + mailbox: 'organization', + labels: ['string'], + purposes: ['string'], + filters: ['unread'], + from: ['string'], + to: ['string'], + assigned_to: ['string'], + include_unassigned: true, + date_from_days_ago: 0, + date_to_days_ago: 0, + email_filter: ['string'], + text: 'string', + thread_ids: ['string'], + pinned_by: 'string' + }, + user_groups: ['string'], fields: ['_id', '_title', 'first_name', 'account', '!account.*._files', '**._product'], from: 0, size: 10, @@ -702,6 +831,25 @@ Search threads and return all id's const { data } = await client.searchIds( null, { + view: { + folder: 'inbox', + mailbox: 'organization', + labels: ['string'], + purposes: ['string'], + filters: ['unread'], + from: ['string'], + to: ['string'], + assigned_to: ['string'], + include_unassigned: true, + date_from_days_ago: 0, + date_to_days_ago: 0, + email_filter: ['string'], + text: 'string', + thread_ids: ['string'], + pinned_by: 'string' + }, + user_groups: ['string'], + inbox_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3', q: 'subject:"Request for solar panel price" AND _tags:INBOX' }, ) @@ -721,6 +869,39 @@ const { data } = await client.searchIds( --- +### `getAssigneeWorkload` + +Return the open-thread workload for a set of user ids. + +`POST /v2/message/threads:workload` + +```ts +const { data } = await client.getAssigneeWorkload( + null, + { + user_ids: ['11000902', '11001053'] + }, +) +``` + +
+Response + +```json +{ + "workloads": [ + { + "user_id": "11000902", + "open_threads": 2 + } + ] +} +``` + +
+ +--- + ### `updateThread` Modify thread metadata @@ -750,6 +931,7 @@ const { data } = await client.updateThread() "latest_message": { "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -790,6 +972,7 @@ const { data } = await client.updateThread() "latest_trash_message": { "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -915,12 +1098,24 @@ const { data } = await client.getThreadTimeline({ { "events": [ { + "id": "string", "data": { "type": "THREAD_DONE", "user_id": "123", "organization_id": "456" }, - "timestamp": "2024-01-01T00:00:00.000Z" + "timestamp": "2024-01-01T00:00:00Z", + "message_id": "string", + "source": "user", + "automated": true, + "actor": { + "user_id": "string", + "email": "string" + }, + "automation": { + "id": "string", + "name": "string" + } } ] } @@ -930,6 +1125,52 @@ const { data } = await client.getThreadTimeline({ --- +### `getThreadSummary` + +AI summary of a thread. Returns `202` while it is generated; poll until `jobStatus.status` is `COMPLETED` or `FAILED`. + +`GET /v1/message/threads/{id}/summary` + +```ts +const { data } = await client.getThreadSummary({ + id: '123e4567-e89b-12d3-a456-426614174000', + message_id: 'example', +}) +``` + +
+Response + +```json +{ + "orgId": "string", + "jobId": "string", + "executionId": "string", + "jobStatus": { + "status": "INITIATED", + "error": "string" + }, + "payload": { + "summary": ["string"], + "topics": ["string"], + "next_steps": ["string"], + "refs": [ + { + "id": "string", + "displayText": "Raven GmbH", + "schema": "contact" + } + ] + }, + "createdAt": "1970-01-01T00:00:00.000Z", + "updatedAt": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + ### `trashThread` Move a thread to trash @@ -958,6 +1199,102 @@ const { data } = await client.untrashThread({ --- +### `spamThread` + +Mark a thread as spam + +`POST /v1/message/threads/{id}/spam` + +```ts +const { data } = await client.spamThread({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `unspamThread` + +Remove spam marking from a thread + +`POST /v1/message/threads/{id}/unspam` + +```ts +const { data } = await client.unspamThread({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `spamMessage` + +Mark a single message as spam. Also marks the parent thread as spam if all messages in the thread are spam. + +`POST /v1/message/messages/{id}/spam` + +```ts +const { data } = await client.spamMessage({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `unspamMessage` + +Remove spam marking from a single message. Also removes spam from the parent thread if no other messages are spam. + +`POST /v1/message/messages/{id}/unspam` + +```ts +const { data } = await client.unspamMessage({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `bulkMoveThreads` + +Move many threads to a different inbox + +`POST /v1/message/threads/bulk:move` + +```ts +const { data } = await client.bulkMoveThreads( + null, + { + ids: ['6b299eda-4018-4554-8965-c4b5598e6531'], + assign_to: ['206801'], + inbox_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3', + scopes: ['organization', 'user'] + }, +) +``` + +--- + +### `bulkAssignThreads` + +Assign many threads + +`POST /v1/message/threads/bulk:assign` + +```ts +const { data } = await client.bulkAssignThreads( + null, + { + ids: ['6b299eda-4018-4554-8965-c4b5598e6531'], + assign_to: ['206801'], + inbox_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3', + scopes: ['organization', 'user'] + }, +) +``` + +--- + ### `threadBulkActionsRead` Perform a bulk action of marking an array of thread ids as read @@ -969,6 +1306,8 @@ const { data } = await client.threadBulkActionsRead( null, { ids: ['6b299eda-4018-4554-8965-c4b5598e6531'], + assign_to: ['206801'], + inbox_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3', scopes: ['organization', 'user'] }, ) @@ -987,6 +1326,8 @@ const { data } = await client.threadBulkActionsUnread( null, { ids: ['6b299eda-4018-4554-8965-c4b5598e6531'], + assign_to: ['206801'], + inbox_id: '3f34ce73-089c-4d45-a5ee-c161234e41c3', scopes: ['organization', 'user'] }, ) @@ -1203,6 +1544,37 @@ const { data } = await client.assignThread( --- +### `dismissThreadLinkSuggestions` + +Dismiss pending candidates of entity-link suggestions on a thread. A suggestion is recorded on a message when an identifier in it matched entities of different customers, so nothing was linked automat + +`POST /v1/message/threads/{id}/link-suggestions/dismiss` + +```ts +const { data } = await client.dismissThreadLinkSuggestions( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + suggestion_ids: ['string'], + entity_ids: ['string'] + }, +) +``` + +
+Response + +```json +{ + "dismissed": ["string"] +} +``` + +
+ +--- + ### `unassignThread` Unassign thread from entities @@ -1213,6 +1585,7 @@ Unassign thread from entities const { data } = await client.unassignThread( { id: '123e4567-e89b-12d3-a456-426614174000', + unlink_mapped_entities: true, }, [ { @@ -1320,6 +1693,7 @@ const { data } = await client.createDraft( "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -1373,7 +1747,8 @@ const { data } = await client.createDraft( "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -1393,7 +1768,7 @@ const { data } = await client.createDraft( ### `sendDraft` -Send the existing draft to the recipients +Send the existing draft to the recipients. `POST /v1/message/drafts:send` @@ -1415,6 +1790,7 @@ const { data } = await client.sendDraft() "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -1468,7 +1844,8 @@ const { data } = await client.sendDraft() "may_be_signature_attachment": true, "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", "inline": false, - "send_as_link": false + "send_as_link": false, + "save_to_entity": true } ] }, @@ -1508,6 +1885,19 @@ const { data } = await client.getMessageV2({ ```json { + "link_suggestions": [ + { + "id": "string", + "identifier": "string", + "found_in": "string", + "status": "pending", + "candidates": [], + "accepted_entity_ids": ["string"], + "resolved_by": {}, + "resolved_at": "1970-01-01T00:00:00.000Z", + "created_at": "1970-01-01T00:00:00.000Z" + } + ], "html_omitted": false, "html_download_url": "https://s3.eu-central-1.amazonaws.com/epilot-attachments/3f34ce73-089c-4d45-a5ee-c161234e41c3/3f34ce73-089c-4d45-a5ee-c161234e41c3.html", "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", @@ -1519,6 +1909,7 @@ const { data } = await client.getMessageV2({ "_updated_at": "2021-02-10T09:14:31.990Z", "message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>", "sender": "206801", + "updated_by": "206801", "subject": "Request for solar panel price", "html": "
We at ABC GmbH would like to request a price quote for the solar panel.
", "text": "We at ABC GmbH would like to request a price quote for the solar panel.", @@ -1565,15 +1956,7 @@ const { data } = await client.getMessageV2({ ], "file": { "$relation": [ - { - "entity_id": "f820ce3b-07b0-45ae-bcc6-babb2f53f79f", - "filename": "Produktinformationen_epilot360_Double_Opt_in.pdf", - "is_message_attachment": true, - "may_be_signature_attachment": true, - "cid": "fb222496-a1a5-4639-94f2-07b5e35e4068", - "inline": false, - "send_as_link": false - } + {} ] }, "references": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com> ", @@ -1635,6 +2018,7 @@ type Thread = { latest_message?: { message_id?: string sender?: string + updated_by?: string subject: string html?: string text?: string @@ -1687,6 +2071,7 @@ type Thread = { latest_trash_message?: { message_id?: string sender?: string + updated_by?: string subject: string html?: string text?: string @@ -1725,8 +2110,6 @@ type Thread = { send_status?: { ... } send_error?: { ... } }> - file?: { - $relation?: { ... } // ... } ``` @@ -1737,6 +2120,7 @@ type Thread = { type Message = { message_id?: string sender?: string + updated_by?: string subject: string html?: string text?: string @@ -1784,6 +2168,7 @@ type Message = { cid?: { ... } inline?: { ... } send_as_link?: { ... } + save_to_entity?: { ... } }> } references?: string @@ -1809,6 +2194,7 @@ type MessageV2 = { _updated_at: string // date-time message_id?: string sender?: string + updated_by?: string subject: string html?: string text?: string @@ -1856,6 +2242,7 @@ type MessageV2 = { cid?: { ... } inline?: { ... } send_as_link?: { ... } + save_to_entity?: { ... } }> } references?: string @@ -1894,6 +2281,7 @@ type AttachmentsRelation = { cid?: string inline?: boolean send_as_link?: boolean + save_to_entity?: boolean }> } ``` @@ -1909,6 +2297,7 @@ type File = { cid?: string inline?: boolean send_as_link?: boolean + save_to_entity?: boolean } ``` @@ -1917,6 +2306,7 @@ type File = { ```ts type MessageRequestParams = { complete_thread?: boolean + mark_thread_as_read?: boolean thread?: { topic: string assigned_to?: string[] @@ -1969,9 +2359,94 @@ type MessageRequestParams = { cid?: { ... } inline?: { ... } send_as_link?: { ... } + save_to_entity?: { ... } }> } template_id?: string + source?: "manual" | "automation" | "workflow" | "partner" | "bulk" | "system" +} +``` + +### `ThreadView` + +A central-inbox view, described structurally so the server compiles the query for it. Both the +thread list and the unread count for a view are compiled from the same description, so the two +cannot disagree about what the view means. + +Every field is optional and an omitted field adds no condition, so + +```ts +type ThreadView = { + folder?: "inbox" | "favorite" | "sent" | "trash" | "spam" | "unassignable" | "draft" + mailbox?: "organization" | "agent" + labels?: string[] + purposes?: string[] + filters?: "unread" | "resolved" | "trash"[] + from?: string[] + to?: string[] + assigned_to?: string[] + include_unassigned?: boolean + date_from_days_ago?: number + date_to_days_ago?: number + email_filter?: string[] + text?: string + thread_ids?: string[] + pinned_by?: string +} +``` + +### `UnreadCountScope` + +```ts +type UnreadCountScope = { + name: string + type: "organization" | "shared_inbox" | "saved_view" + q?: string + view_id?: string + inbox_id?: string | string[] +} +``` + +### `UnreadCountsPayload` + +```ts +type UnreadCountsPayload = { + actor: "organization" | "user" + email_filter?: string[] + user_groups?: string[] + scopes: Array<{ + name: string + type: "organization" | "shared_inbox" | "saved_view" + q?: string + view_id?: string + inbox_id?: string | string[] + }> +} +``` + +### `UnreadCountsResult` + +```ts +type UnreadCountsResult = { + enabled: boolean + counts: Record + omitted?: string[] +} +``` + +### `UnreadCountBuckets` + +```ts +type UnreadCountBuckets = { + unread: number + drafts?: number + unassigned?: number + spam?: number } ``` @@ -1980,7 +2455,25 @@ type MessageRequestParams = { ```ts type SearchParamsV2 = { inbox_id?: string | string[] - q: string + q?: string + view?: { + folder?: "inbox" | "favorite" | "sent" | "trash" | "spam" | "unassignable" | "draft" + mailbox?: "organization" | "agent" + labels?: string[] + purposes?: string[] + filters?: "unread" | "resolved" | "trash"[] + from?: string[] + to?: string[] + assigned_to?: string[] + include_unassigned?: boolean + date_from_days_ago?: number + date_to_days_ago?: number + email_filter?: string[] + text?: string + thread_ids?: string[] + pinned_by?: string + } + user_groups?: string[] fields?: string[] from?: number size?: number @@ -2006,10 +2499,57 @@ type SearchParams = { ```ts type SearchIDParams = { + view?: { + folder?: "inbox" | "favorite" | "sent" | "trash" | "spam" | "unassignable" | "draft" + mailbox?: "organization" | "agent" + labels?: string[] + purposes?: string[] + filters?: "unread" | "resolved" | "trash"[] + from?: string[] + to?: string[] + assigned_to?: string[] + include_unassigned?: boolean + date_from_days_ago?: number + date_to_days_ago?: number + email_filter?: string[] + text?: string + thread_ids?: string[] + pinned_by?: string + } + user_groups?: string[] + inbox_id?: string | string[] q?: string } ``` +### `AssigneeWorkloadParams` + +```ts +type AssigneeWorkloadParams = { + user_ids: string[] +} +``` + +### `AssigneeWorkload` + +```ts +type AssigneeWorkload = { + user_id: string + open_threads: number +} +``` + +### `AssigneeWorkloadResults` + +```ts +type AssigneeWorkloadResults = { + workloads: Array<{ + user_id: string + open_threads: number + }> +} +``` + ### `ReadMessagePayload` ```ts @@ -2026,11 +2566,167 @@ Who is marking an item as read or unread. type ReadingScope = "organization" | "user" ``` +### `ThreadReplyContext` + +```ts +type ThreadReplyContext = { + thread_id: string + topic?: string + reply_to_message_id?: string + messages: Array<{ + id: string + created_at?: string // date-time + type: "RECEIVED" | "SENT" + role: "customer" | "agent" | "partner" + subject?: string + from?: { + address?: { ... } + name?: { ... } + } + text: string + }> + related_entities: Array<{ + _id: string + _schema: string + }> +} +``` + +### `ReplyContextMessage` + +```ts +type ReplyContextMessage = { + id: string + created_at?: string // date-time + type: "RECEIVED" | "SENT" + role: "customer" | "agent" | "partner" + subject?: string + from?: { + address?: string + name?: string + } + text: string +} +``` + +### `ReplyContextEntityRef` + +```ts +type ReplyContextEntityRef = { + _id: string + _schema: string +} +``` + +### `ThreadSummary` + +```ts +type ThreadSummary = { + orgId: string + jobId: string + executionId?: string + jobStatus: { + status: "INITIATED" | "IN_PROGRESS" | "COMPLETED" | "FAILED" + error?: string + } + payload?: { + summary?: string[] + topics?: string[] + next_steps?: string[] + refs?: Array<{ + id: { ... } + displayText: { ... } + schema: { ... } + }> + } + createdAt: string // date-time + updatedAt: string // date-time +} +``` + +### `ThreadSummaryPayload` + +Present once the summary is generated + +```ts +type ThreadSummaryPayload = { + summary?: string[] + topics?: string[] + next_steps?: string[] + refs?: Array<{ + id: string + displayText: string + schema: string + }> +} +``` + +### `ThreadSummaryEntityRef` + +```ts +type ThreadSummaryEntityRef = { + id: string + displayText: string + schema: string +} +``` + +### `ThreadSummaryContext` + +```ts +type ThreadSummaryContext = { + thread_id: string + message_id: string + subject: string + conversation: string + entity_context: string +} +``` + +### `SimilarSentMessagesRequest` + +```ts +type SimilarSentMessagesRequest = { + queries: string[] + limit?: number + min_score?: number +} +``` + +### `SimilarSentMessagesResponse` + +```ts +type SimilarSentMessagesResponse = { + results: Array<{ + message_id: string + thread_id?: string + subject?: string + text: string + created_at?: string + score: number + }> +} +``` + +### `SimilarSentMessage` + +```ts +type SimilarSentMessage = { + message_id: string + thread_id?: string + subject?: string + text: string + created_at?: string + score: number +} +``` + ### `ThreadTimeline` ```ts type ThreadTimeline = { events: Array<{ + id?: string data: { type: { ... } user_id: { ... } @@ -2039,8 +2735,62 @@ type ThreadTimeline = { type: { ... } user_id: { ... } organization_id: { ... } + } | { + type: { ... } + workflow_id?: { ... } + workflow_name?: { ... } + } | { + type: { ... } + added?: { ... } + removed?: { ... } + } | { + type: { ... } + label: { ... } + label_name?: { ... } + } | { + type: { ... } + label: { ... } + label_name?: { ... } + } | { + type: { ... } + entities?: { ... } + link_kind?: { ... } + from_suggestion?: { ... } + } | { + type: { ... } + entities?: { ... } + link_kind?: { ... } + } | { + type: { ... } + suggestions?: { ... } + } | { + type: { ... } + suggestions?: { ... } + } | { + type: { ... } + reply_message_id?: { ... } + parent_message_id?: { ... } + } | { + type: { ... } + target_inbox_id?: { ... } + target_inbox_name?: { ... } + } | { + type: { ... } + } | { + type: { ... } } timestamp: string + message_id?: string + source?: "user" | "automation" | "system" + automated?: boolean + actor?: { + user_id?: { ... } + email?: { ... } + } + automation?: { + id?: { ... } + name?: { ... } + } }> } ``` @@ -2065,6 +2815,221 @@ type ThreadOpenEvent = { } ``` +### `WorkflowStartedEvent` + +```ts +type WorkflowStartedEvent = { + type: "WORKFLOW_STARTED" + workflow_id?: string + workflow_name?: string +} +``` + +### `ThreadUserAssignedEvent` + +```ts +type ThreadUserAssignedEvent = { + type: "THREAD_USER_ASSIGNED" + added?: string[] + removed?: string[] +} +``` + +### `MessageLabelAddedEvent` + +```ts +type MessageLabelAddedEvent = { + type: "MESSAGE_LABEL_ADDED" + label: string + label_name?: string +} +``` + +### `MessageLabelRemovedEvent` + +```ts +type MessageLabelRemovedEvent = { + type: "MESSAGE_LABEL_REMOVED" + label: string + label_name?: string +} +``` + +### `MessageEntityLinkedEvent` + +```ts +type MessageEntityLinkedEvent = { + type: "MESSAGE_ENTITY_LINKED" + entities?: Array<{ + entity_id: string + schema?: string + }> + link_kind?: "manual" | "auto" + from_suggestion?: boolean +} +``` + +### `MessageEntityUnlinkedEvent` + +```ts +type MessageEntityUnlinkedEvent = { + type: "MESSAGE_ENTITY_UNLINKED" + entities?: Array<{ + entity_id: string + schema?: string + }> + link_kind?: "manual" | "auto" +} +``` + +### `MessageAutoReplySentEvent` + +```ts +type MessageAutoReplySentEvent = { + type: "MESSAGE_AUTO_REPLY_SENT" + reply_message_id?: string + parent_message_id?: string +} +``` + +### `ThreadMovedToInboxEvent` + +```ts +type ThreadMovedToInboxEvent = { + type: "THREAD_MOVED_TO_INBOX" + target_inbox_id?: string + target_inbox_name?: string +} +``` + +### `ThreadTrashedEvent` + +```ts +type ThreadTrashedEvent = { + type: "THREAD_TRASHED" +} +``` + +### `ThreadRestoredEvent` + +```ts +type ThreadRestoredEvent = { + type: "THREAD_RESTORED" +} +``` + +### `LinkSuggestionCandidate` + +```ts +type LinkSuggestionCandidate = { + entity_id: string + schema: string + attribute?: string + attribute_value?: string + title?: string + status?: "pending" | "linked" | "dismissed" + resolved_by?: { + user_id?: string + email?: string + } + resolved_at?: string // date-time +} +``` + +### `LinkSuggestion` + +```ts +type LinkSuggestion = { + id: string + identifier: string + found_in?: string + status: "pending" | "accepted" | "dismissed" + candidates: Array<{ + entity_id: string + schema: string + attribute?: string + attribute_value?: string + title?: string + status?: "pending" | "linked" | "dismissed" + resolved_by?: { + user_id?: { ... } + email?: { ... } + } + resolved_at?: string // date-time + }> + accepted_entity_ids?: string[] + resolved_by?: { + user_id?: string + email?: string + } + resolved_at?: string // date-time + created_at?: string // date-time +} +``` + +### `TimelineLinkSuggestion` + +```ts +type TimelineLinkSuggestion = { + id?: string + identifier: string + candidates?: Array<{ + entity_id: string + schema?: string + }> +} +``` + +### `MessageEntityLinkSuggestedEvent` + +```ts +type MessageEntityLinkSuggestedEvent = { + type: "MESSAGE_ENTITY_LINK_SUGGESTED" + suggestions?: Array<{ + id?: string + identifier: string + candidates?: Array<{ + entity_id: { ... } + schema?: { ... } + }> + }> +} +``` + +### `MessageEntityLinkSuggestionDismissedEvent` + +```ts +type MessageEntityLinkSuggestionDismissedEvent = { + type: "MESSAGE_ENTITY_LINK_SUGGESTION_DISMISSED" + suggestions?: Array<{ + id?: string + identifier: string + candidates?: Array<{ + entity_id: { ... } + schema?: { ... } + }> + }> +} +``` + +### `TimelineLinkedEntity` + +```ts +type TimelineLinkedEntity = { + entity_id: string + schema?: string +} +``` + +### `TimelineActor` + +```ts +type TimelineActor = { + user_id?: string + email?: string +} +``` + ### `TimelineEventData` ```ts @@ -2076,6 +3041,69 @@ type TimelineEventData = { type: "THREAD_OPEN" user_id: string organization_id: string +} | { + type: "WORKFLOW_STARTED" + workflow_id?: string + workflow_name?: string +} | { + type: "THREAD_USER_ASSIGNED" + added?: string[] + removed?: string[] +} | { + type: "MESSAGE_LABEL_ADDED" + label: string + label_name?: string +} | { + type: "MESSAGE_LABEL_REMOVED" + label: string + label_name?: string +} | { + type: "MESSAGE_ENTITY_LINKED" + entities?: Array<{ + entity_id: string + schema?: string + }> + link_kind?: "manual" | "auto" + from_suggestion?: boolean +} | { + type: "MESSAGE_ENTITY_UNLINKED" + entities?: Array<{ + entity_id: string + schema?: string + }> + link_kind?: "manual" | "auto" +} | { + type: "MESSAGE_ENTITY_LINK_SUGGESTED" + suggestions?: Array<{ + id?: string + identifier: string + candidates?: Array<{ + entity_id: { ... } + schema?: { ... } + }> + }> +} | { + type: "MESSAGE_ENTITY_LINK_SUGGESTION_DISMISSED" + suggestions?: Array<{ + id?: string + identifier: string + candidates?: Array<{ + entity_id: { ... } + schema?: { ... } + }> + }> +} | { + type: "MESSAGE_AUTO_REPLY_SENT" + reply_message_id?: string + parent_message_id?: string +} | { + type: "THREAD_MOVED_TO_INBOX" + target_inbox_id?: string + target_inbox_name?: string +} | { + type: "THREAD_TRASHED" +} | { + type: "THREAD_RESTORED" } ``` @@ -2083,6 +3111,7 @@ type TimelineEventData = { ```ts type TimelineEvent = { + id?: string data: { type: "THREAD_DONE" user_id: string @@ -2091,8 +3120,76 @@ type TimelineEvent = { type: "THREAD_OPEN" user_id: string organization_id: string + } | { + type: "WORKFLOW_STARTED" + workflow_id?: string + workflow_name?: string + } | { + type: "THREAD_USER_ASSIGNED" + added?: string[] + removed?: string[] + } | { + type: "MESSAGE_LABEL_ADDED" + label: string + label_name?: string + } | { + type: "MESSAGE_LABEL_REMOVED" + label: string + label_name?: string + } | { + type: "MESSAGE_ENTITY_LINKED" + entities?: Array<{ + entity_id: { ... } + schema?: { ... } + }> + link_kind?: "manual" | "auto" + from_suggestion?: boolean + } | { + type: "MESSAGE_ENTITY_UNLINKED" + entities?: Array<{ + entity_id: { ... } + schema?: { ... } + }> + link_kind?: "manual" | "auto" + } | { + type: "MESSAGE_ENTITY_LINK_SUGGESTED" + suggestions?: Array<{ + id?: { ... } + identifier: { ... } + candidates?: { ... } + }> + } | { + type: "MESSAGE_ENTITY_LINK_SUGGESTION_DISMISSED" + suggestions?: Array<{ + id?: { ... } + identifier: { ... } + candidates?: { ... } + }> + } | { + type: "MESSAGE_AUTO_REPLY_SENT" + reply_message_id?: string + parent_message_id?: string + } | { + type: "THREAD_MOVED_TO_INBOX" + target_inbox_id?: string + target_inbox_name?: string + } | { + type: "THREAD_TRASHED" + } | { + type: "THREAD_RESTORED" } timestamp: string + message_id?: string + source?: "user" | "automation" | "system" + automated?: boolean + actor?: { + user_id?: string + email?: string + } + automation?: { + id?: string + name?: string + } } ``` @@ -2101,6 +3198,8 @@ type TimelineEvent = { ```ts type BulkActionsPayloadWithScopes = { ids: string[] + assign_to?: string[] + inbox_id?: string scopes?: "organization" | "user"[] } ``` diff --git a/docs/sdk/clients/metering.md b/docs/sdk/clients/metering.md index a01d6bdb..44fccac0 100644 --- a/docs/sdk/clients/metering.md +++ b/docs/sdk/clients/metering.md @@ -42,6 +42,7 @@ const { data } = await meteringClient.getCustomerMeters(...) - [`createMeterReading`](#createmeterreading) - [`createMeterReadings`](#createmeterreadings) - [`batchWriteMeterReadings`](#batchwritemeterreadings) +- [`pruneMeterReadings`](#prunemeterreadings) - [`createMeterReadingFromSubmission`](#createmeterreadingfromsubmission) - [`getAllowedReadingForMeter`](#getallowedreadingformeter) - [`createReadingWithMeter`](#createreadingwithmeter) @@ -49,6 +50,12 @@ const { data } = await meteringClient.getCustomerMeters(...) - [`updateMeterReading`](#updatemeterreading) - [`deleteMeterReading`](#deletemeterreading) +**Metering** +- [`getReadingChangesets`](#getreadingchangesets) +- [`applyReadingChangeset`](#applyreadingchangeset) +- [`dismissReadingChangeset`](#dismissreadingchangeset) +- [`updateReadingChangeset`](#updatereadingchangeset) + **Schemas** - [`ErrorResp`](#errorresp) - [`EntityId`](#entityid) @@ -68,6 +75,11 @@ const { data } = await meteringClient.getCustomerMeters(...) - [`Reading`](#reading) - [`MeterReading`](#meterreading) - [`PortalMeterReading`](#portalmeterreading) +- [`BatchReadingBase`](#batchreadingbase) +- [`CreateOrUpdateBatchReading`](#createorupdatebatchreading) +- [`DeleteBatchReading`](#deletebatchreading) +- [`BatchReading`](#batchreading) +- [`PruneMeterReadingsPayload`](#prunemeterreadingspayload) - [`UpdateMeterReading`](#updatemeterreading) - [`MeterCounter`](#metercounter) - [`CounterReadingOnSubmission`](#counterreadingonsubmission) @@ -78,16 +90,23 @@ const { data } = await meteringClient.getCustomerMeters(...) - [`Rule`](#rule) - [`JourneyActions`](#journeyactions) - [`ReadingWithMeter`](#readingwithmeter) +- [`MeterReadingChangeset`](#meterreadingchangeset) +- [`FuzzyConfig`](#fuzzyconfig) +- [`ProposedReading`](#proposedreading) +- [`ChangesetCreator`](#changesetcreator) +- [`TimestampTolerance`](#timestamptolerance) - [`ActivityId`](#activityid) ### `getCustomerMeters` -Get Customer Meters +Retrieves all meters associated with the authenticated portal customer. `GET /v1/metering/meter` ```ts -const { data } = await client.getCustomerMeters() +const { data } = await client.getCustomerMeters({ + include_pending_changesets: true, +}) ```
@@ -123,7 +142,7 @@ const { data } = await client.getCustomerMeters() ], "used_for": "Domestic Usage", "manufacturer": "Energy One", - "calibration_date": "2022-10-10T00:00:00.000Z", + "calibration_date": "2022-10-10", "contract": { "$relation": [ { @@ -155,7 +174,7 @@ const { data } = await client.getCustomerMeters() } ] }, - "last_reading": "2022-10-10T00:00:00.000Z", + "last_reading": "2022-10-10", "current_consumption": 100.5 } ] @@ -168,7 +187,7 @@ const { data } = await client.getCustomerMeters() ### `getMetersByContractId` -Retrieves all meters related to a contract. +Retrieves all meters associated with a given contract entity. `GET /v1/metering/contract/meters/{contract_id}` @@ -211,7 +230,7 @@ const { data } = await client.getMetersByContractId({ ], "used_for": "Domestic Usage", "manufacturer": "Energy One", - "calibration_date": "2022-10-10T00:00:00.000Z", + "calibration_date": "2022-10-10", "contract": { "$relation": [ { @@ -239,7 +258,7 @@ const { data } = await client.getMetersByContractId({ ### `updateMeter` -Update Meter +Partially updates the details of a meter entity by ID. `PATCH /v1/metering/meter/{id}` @@ -284,7 +303,7 @@ const { data } = await client.updateMeter( ], "used_for": "Domestic Usage", "manufacturer": "Energy One", - "calibration_date": "2022-10-10T00:00:00.000Z", + "calibration_date": "2022-10-10", "contract": { "$relation": [ { @@ -311,7 +330,7 @@ const { data } = await client.updateMeter( ### `getMeter` -Get Meter +Retrieves the full details of a specific meter by ID, including related entities and available journey actions. `GET /v1/metering/meter/{id}` @@ -354,7 +373,7 @@ const { data } = await client.getMeter({ ], "used_for": "Domestic Usage", "manufacturer": "Energy One", - "calibration_date": "2022-10-10T00:00:00.000Z", + "calibration_date": "2022-10-10", "contract": { "$relation": [ { @@ -407,7 +426,7 @@ const { data } = await client.getMeter({ ### `getMeterCounters` -Get Meter Counters +Retrieves all meter counters associated with a given meter. `GET /v1/metering/counter` @@ -436,9 +455,9 @@ const { data } = await client.getMeterCounters({ "transformer_ratio": 70, "unit": "string", "forecast_reading_value": 270, - "forecast_as_of": "2022-12-10T00:00:00.000Z", + "forecast_as_of": "2022-12-10", "current_consumption": 240, - "last_reading": "2022-10-10T00:00:00.000Z", + "last_reading": "2022-10-10", "conversion_factor": 3, "tariff_type": "ht" } @@ -452,7 +471,7 @@ const { data } = await client.getMeterCounters({ ### `getCounterDetails` -Get Counter Details +Retrieves the full details of a single meter counter by its ID. `GET /v1/metering/counter/{counter_id}` @@ -480,9 +499,9 @@ const { data } = await client.getCounterDetails({ "transformer_ratio": 70, "unit": "string", "forecast_reading_value": 270, - "forecast_as_of": "2022-12-10T00:00:00.000Z", + "forecast_as_of": "2022-12-10", "current_consumption": 240, - "last_reading": "2022-10-10T00:00:00.000Z", + "last_reading": "2022-10-10", "conversion_factor": 3, "tariff_type": "ht" } @@ -495,13 +514,15 @@ const { data } = await client.getCounterDetails({ ### `createMeterReading` -Create Meter Reading +Inserts a new meter reading. `POST /v1/metering/reading` ```ts const { data } = await client.createMeterReading( - null, + { + direct: true, + }, { value: 240, read_by: 'John Doe', @@ -509,7 +530,7 @@ const { data } = await client.createMeterReading( meter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', counter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', direction: 'feed-in', - timestamp: '2022-10-10T00:00:00.000Z', + timestamp: '2022-10-10', source: 'ECP', status: 'valid', external_id: 'string', @@ -536,7 +557,7 @@ const { data } = await client.createMeterReading( "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -557,7 +578,7 @@ const { data } = await client.createMeterReading( ### `createMeterReadings` -Create Meter Readings +Inserts multiple meter readings at once. Limited to 100 readings per request. `POST /v1/metering/readings` @@ -567,6 +588,8 @@ const { data } = await client.createMeterReadings( async: true, activity_id: 'example', skip_validation: true, + direct: true, + create_ticket: true, }, { readings: [ @@ -577,7 +600,7 @@ const { data } = await client.createMeterReadings( meter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', counter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', direction: 'feed-in', - timestamp: '2022-10-10T00:00:00.000Z', + timestamp: '2022-10-10', source: 'ECP', status: 'valid', external_id: 'string', @@ -607,7 +630,7 @@ const { data } = await client.createMeterReadings( "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -629,7 +652,8 @@ const { data } = await client.createMeterReadings( ### `createPortalMeterReadings` -Inserts multiple meter readings at once for a given meter. Limited to 2 readings per request. +Inserts multiple meter readings at once for a given meter via the end customer portal. +Limited to 100 readings per request. `POST /v1/metering/readings/{meter_id}` @@ -637,6 +661,7 @@ Inserts multiple meter readings at once for a given meter. Limited to 2 readings const { data } = await client.createPortalMeterReadings( { meter_id: 'example', + direct: true, }, { readings: [ @@ -647,7 +672,7 @@ const { data } = await client.createPortalMeterReadings( meter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', counter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', direction: 'feed-in', - timestamp: '2022-10-10T00:00:00.000Z', + timestamp: '2022-10-10', source: 'ECP', status: 'valid', external_id: 'string', @@ -677,7 +702,7 @@ const { data } = await client.createPortalMeterReadings( "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -699,7 +724,7 @@ const { data } = await client.createPortalMeterReadings( ### `batchWriteMeterReadings` -Batch Write Readings +Upserts or deletes multiple meter readings at once. Limited to 100 readings per request. `POST /v2/metering/readings` @@ -709,29 +734,31 @@ const { data } = await client.batchWriteMeterReadings( async: true, skip_validation: true, activity_id: 'example', + direct: true, + create_ticket: true, }, { identifiers: ['string'], readings: [ { - value: 240, - read_by: 'John Doe', - reason: '', meter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', counter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', direction: 'feed-in', - timestamp: '2022-10-10T00:00:00.000Z', - source: 'ECP', - status: 'valid', + timestamp: '2022-10-10T10:00:00Z', external_id: 'string', - remark: 'Customer reported unusual consumption', metadata: { registration_id: '1234567890', business_unit: 'ABC' }, + operation: 'create', + value: 240, + source: 'ECP', + read_by: 'John Doe', + reason: '', + status: 'valid', + remark: 'Customer reported unusual consumption', note: 'string', - unit: 'string', - operation: 'create' + unit: 'string' } ] }, @@ -751,7 +778,7 @@ const { data } = await client.batchWriteMeterReadings( "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -771,9 +798,48 @@ const { data } = await client.batchWriteMeterReadings( --- +### `pruneMeterReadings` + +Deletes every reading of a meter whose `external_id` is NOT in the provided keep list — in a single request. + +`POST /v2/metering/readings/prune` + +```ts +const { data } = await client.pruneMeterReadings( + { + async: true, + activity_id: 'example', + create_ticket: true, + dry_run: true, + }, + { + meter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + counter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + source: 'ECP', + keep_external_ids: ['erp-reading-1', 'erp-reading-2'] + }, +) +``` + +
+Response + +```json +{ + "data": { + "deleted_count": 42, + "kept_count": 12 + } +} +``` + +
+ +--- + ### `createMeterReadingFromSubmission` -Create Meter Reading from Submission +Creates meter readings from a journey submission payload. `POST /v1/metering/reading/submission` @@ -829,7 +895,7 @@ const { data } = await client.createMeterReadingFromSubmission( ### `getAllowedReadingForMeter` -Get allowed reading for the given meter +Returns the allowed min/max reading range for each counter of the given meter. `GET /v1/metering/allowed/reading/{meter_id}` @@ -861,7 +927,7 @@ const { data } = await client.getAllowedReadingForMeter({ ### `createReadingWithMeter` -Create Reading with Meter +Creates a meter reading along with meter lookup or creation by MA-LO ID and OBIS number. `POST /v1/metering/reading/with-meter` @@ -896,7 +962,7 @@ const { data } = await client.createReadingWithMeter( "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -917,7 +983,9 @@ const { data } = await client.createReadingWithMeter( ### `getReadingsByInterval` -Get Readings by Interval +Retrieves all readings specified in an interval. +If the start_date and end_date are equal, then it returns the readings of the specified date. +The start_date should be less than or equal to the end_da `GET /v1/metering/reading/{meter_id}/{counter_id}` @@ -932,6 +1000,7 @@ const { data } = await client.getReadingsByInterval({ from: 1, type: 'example', sort: 'example', + include_pending_changesets: true, }) ``` @@ -948,7 +1017,7 @@ const { data } = await client.getReadingsByInterval({ "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -972,7 +1041,7 @@ const { data } = await client.getReadingsByInterval({ ### `updateMeterReading` -Update Meter Reading +Updates an existing meter reading identified by meter ID, counter ID, and timestamp. `PUT /v1/metering/reading/{meter_id}/{counter_id}` @@ -990,7 +1059,7 @@ const { data } = await client.updateMeterReading( meter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', counter_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', direction: 'feed-in', - timestamp: '2022-10-10T00:00:00.000Z', + timestamp: '2022-10-10', source: 'ECP', status: 'valid', external_id: 'string', @@ -1015,7 +1084,7 @@ const { data } = await client.updateMeterReading( "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "direction": "feed-in", - "timestamp": "2022-10-10T00:00:00.000Z", + "timestamp": "2022-10-10", "source": "ECP", "status": "valid", "external_id": "string", @@ -1036,7 +1105,7 @@ const { data } = await client.updateMeterReading( ### `deleteMeterReading` -Delete Meter Reading +Permanently deletes a meter reading identified by meter ID, counter ID, and timestamp. `DELETE /v1/metering/reading/{meter_id}/{counter_id}` @@ -1065,6 +1134,305 @@ const { data } = await client.deleteMeterReading({ --- +### `getReadingChangesets` + +Lists the pending reading changesets for a counter. + +`GET /v1/metering/reading/{meter_id}/{counter_id}/changesets` + +```ts +const { data } = await client.getReadingChangesets({ + meter_id: 'example', + counter_id: 'example', +}) +``` + +
+Response + +```json +{ + "changesets": [ + { + "changeset_id": "string", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "previous": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "edit_mode": "external", + "match_strategy": "exact", + "timestamp_tolerance": "exact", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "type": "user", + "id": "string" + }, + "source": "360", + "fuzzy_config": { + "percentage_threshold": 0.01, + "absolute_threshold": 0 + }, + "dismissed_reason": "string", + "dismissed_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `applyReadingChangeset` + +Applies (approves) a pending reading changeset: the proposed reading value is written to ClickHouse and the pending changeset is removed. + +`POST /v1/metering/reading/{meter_id}/{counter_id}/changesets/{changeset_id}:apply` + +```ts +const { data } = await client.applyReadingChangeset({ + meter_id: 'example', + counter_id: 'example', + changeset_id: 'example', +}) +``` + +
+Response + +```json +{ + "reading": { + "value": 240, + "read_by": "John Doe", + "reason": "", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "direction": "feed-in", + "timestamp": "2022-10-10", + "source": "ECP", + "status": "valid", + "external_id": "string", + "remark": "Customer reported unusual consumption", + "metadata": { + "registration_id": "1234567890", + "business_unit": "ABC" + }, + "note": "string", + "unit": "string" + }, + "changeset": { + "changeset_id": "string", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "previous": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "edit_mode": "external", + "match_strategy": "exact", + "timestamp_tolerance": "exact", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "type": "user", + "id": "string" + }, + "source": "360", + "fuzzy_config": { + "percentage_threshold": 0.01, + "absolute_threshold": 0 + }, + "dismissed_reason": "string", + "dismissed_at": "1970-01-01T00:00:00.000Z" + } +} +``` + +
+ +--- + +### `dismissReadingChangeset` + +Dismisses (rejects) a pending reading changeset: the changeset is removed without being applied. The reading value remains unchanged. + +`POST /v1/metering/reading/{meter_id}/{counter_id}/changesets/{changeset_id}:dismiss` + +```ts +const { data } = await client.dismissReadingChangeset( + { + meter_id: 'example', + counter_id: 'example', + changeset_id: 'example', + }, + { + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "changeset_id": "string", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "previous": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "edit_mode": "external", + "match_strategy": "exact", + "timestamp_tolerance": "exact", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "type": "user", + "id": "string" + }, + "source": "360", + "fuzzy_config": { + "percentage_threshold": 0.01, + "absolute_threshold": 0 + }, + "dismissed_reason": "string", + "dismissed_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateReadingChangeset` + +Edits a pending reading changeset by updating its proposed value, without going through the normal write path. + +`PATCH /v1/metering/reading/{meter_id}/{counter_id}/changesets/{changeset_id}` + +```ts +const { data } = await client.updateReadingChangeset( + { + meter_id: 'example', + counter_id: 'example', + changeset_id: 'example', + }, + { + proposed: { + value: 0, + direction: 'feed-in', + timestamp: '1970-01-01T00:00:00.000Z', + reason: 'string', + remark: 'string', + read_by: 'string', + status: 'valid', + external_id: 'string' + } + }, +) +``` + +
+Response + +```json +{ + "changeset_id": "string", + "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "proposed": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "previous": { + "value": 0, + "direction": "feed-in", + "timestamp": "1970-01-01T00:00:00.000Z", + "reason": "string", + "remark": "string", + "read_by": "string", + "status": "valid", + "external_id": "string" + }, + "edit_mode": "external", + "match_strategy": "exact", + "timestamp_tolerance": "exact", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": { + "type": "user", + "id": "string" + }, + "source": "360", + "fuzzy_config": { + "percentage_threshold": 0.01, + "absolute_threshold": 0 + }, + "dismissed_reason": "string", + "dismissed_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + ## Schemas ### `ErrorResp` @@ -1280,6 +1648,107 @@ type PortalMeterReading = { } ``` +### `BatchReadingBase` + +Base properties shared by all batch reading operations + +```ts +type BatchReadingBase = { + meter_id?: string // uuid + counter_id?: string // uuid + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + external_id?: string + metadata?: Record +} +``` + +### `CreateOrUpdateBatchReading` + +Schema for create or update operations - requires value, source, and meter_id + +```ts +type CreateOrUpdateBatchReading = { + meter_id: string // uuid + counter_id?: string // uuid + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + external_id?: string + metadata?: Record + operation?: "create" | "update" + value: number + source: "ECP" | "ERP" | "360" | "journey-submission" + read_by?: string + reason?: "" | "regular" | "irregular" | "last" | "first" | "meter_change" | "contract_change" | "meter_adjustment" + status?: "valid" | "in-validation" | "implausible" | null | "" + remark?: string + note?: string + unit?: string +} +``` + +### `DeleteBatchReading` + +Schema for delete operations - only requires identifier fields specified in the identifiers parameter + +```ts +type DeleteBatchReading = { + meter_id?: string // uuid + counter_id?: string // uuid + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + external_id?: string + metadata?: Record + operation: "delete" +} +``` + +### `BatchReading` + +A meter reading for batch operations. The required fields depend on the operation: +- create/update: requires value, source, and meter_id +- delete: only requires the fields specified in the identifiers parameter + + +```ts +type BatchReading = { + meter_id: string // uuid + counter_id?: string // uuid + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + external_id?: string + metadata?: Record + operation?: "create" | "update" + value: number + source: "ECP" | "ERP" | "360" | "journey-submission" + read_by?: string + reason?: "" | "regular" | "irregular" | "last" | "first" | "meter_change" | "contract_change" | "meter_adjustment" + status?: "valid" | "in-validation" | "implausible" | null | "" + remark?: string + note?: string + unit?: string +} | { + meter_id?: string // uuid + counter_id?: string // uuid + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + external_id?: string + metadata?: Record + operation: "delete" +} +``` + +### `PruneMeterReadingsPayload` + +```ts +type PruneMeterReadingsPayload = { + meter_id: string // uuid + counter_id?: string // uuid + source?: "ECP" | "ERP" | "360" | "journey-submission" + keep_external_ids: string[] +} +``` + ### `UpdateMeterReading` ```ts @@ -1427,6 +1896,114 @@ type ReadingWithMeter = { } ``` +### `MeterReadingChangeset` + +```ts +type MeterReadingChangeset = { + changeset_id: string + meter_id?: string // uuid + counter_id?: string // uuid + proposed: { + value: number + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + reason?: string + remark?: string + read_by?: string + status?: "valid" | "in-validation" | "implausible" + external_id?: string + } + previous?: { + value: number + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + reason?: string + remark?: string + read_by?: string + status?: "valid" | "in-validation" | "implausible" + external_id?: string + } + edit_mode: "external" | "approval" + match_strategy?: "exact" | "fuzzy" + timestamp_tolerance?: "exact" | { + type: "same-day" + timezone?: string + } | { + type: "within-seconds" + seconds: number + } + created_at: string // date-time + created_by?: { + type?: "user" | "portal_user" | "api_client" | "automation" + id?: string + } + source?: "360" | "ECP" | "ERP" | "journey-submission" + fuzzy_config?: { + percentage_threshold?: number + absolute_threshold?: number + } + dismissed_reason?: string + dismissed_at?: string // date-time +} +``` + +### `FuzzyConfig` + +Numeric-threshold fuzzy matching for meter reading auto-clear. + +NOTE: This is intentionally different from entity-api's FuzzyConfig. Entity-api's +fuzzy strategies (suffix, digits_only, normalize_phone, ignore_fields, +contains_entry, regex) are designed for strings and structured objects (IBAN, phone + +```ts +type FuzzyConfig = { + percentage_threshold?: number + absolute_threshold?: number +} +``` + +### `ProposedReading` + +```ts +type ProposedReading = { + value: number + direction?: "feed-in" | "feed-out" + timestamp?: string // date-time + reason?: string + remark?: string + read_by?: string + status?: "valid" | "in-validation" | "implausible" + external_id?: string +} +``` + +### `ChangesetCreator` + +```ts +type ChangesetCreator = { + type?: "user" | "portal_user" | "api_client" | "automation" + id?: string +} +``` + +### `TimestampTolerance` + +Slack on `reading.timestamp` when auto-clear matches an incoming reading +against a pending changeset. Both sides reference the SAME physical +meter-read event — one as stored when the user submitted, the other as +echoed back by the ERP. The tolerance accommodates round-trip format +drift between the t + +```ts +type TimestampTolerance = "exact" | { + type: "same-day" + timezone?: string +} | { + type: "within-seconds" + seconds: number +} +``` + ### `ActivityId` See https://github.com/ulid/spec diff --git a/docs/sdk/clients/notes.md b/docs/sdk/clients/notes.md index 340a6a4d..892e57b6 100644 --- a/docs/sdk/clients/notes.md +++ b/docs/sdk/clients/notes.md @@ -41,6 +41,10 @@ const { data } = await notesClient.createNote(...) **Pinning** - [`pinNote`](#pinnote) +**Archive** +- [`archiveNote`](#archivenote) +- [`unarchiveNote`](#unarchivenote) + **Reactions** - [`addNoteReaction`](#addnotereaction) - [`removeNoteReaction`](#removenotereaction) @@ -58,6 +62,7 @@ const { data } = await notesClient.createNote(...) - [`NoteEntityParent`](#noteentityparent) - [`NotePutRequestBody`](#noteputrequestbody) - [`NoteSearchByContextRequestBody`](#notesearchbycontextrequestbody) +- [`NotesListFilter`](#noteslistfilter) - [`NotesSearchRequestResponse`](#notessearchrequestresponse) - [`NoteContexts`](#notecontexts) - [`WorkflowExecution`](#workflowexecution) @@ -184,16 +189,20 @@ const { data } = await client.updateNote( } ], pinned_at: '1970-01-01T00:00:00.000Z', - created_by: { - type: 'user', - user_id: 'string', - display_name: 'string', - org_id: 'string', - email: 'string', - phone: 'string' - }, + edited_at: '1970-01-01T00:00:00.000Z', + created_by: [ + { + type: 'user', + user_id: 'string', + display_name: 'string', + org_id: 'string', + email: 'string', + phone: 'string' + } + ], read_by: ['string'], - reactions: {} + reactions: {}, + _archived_at: '1970-01-01T00:00:00.000Z' }, ) ``` @@ -230,6 +239,8 @@ const { data } = await client.searchNotesByContext( id: 'string' } ], + include_related_schemas: ['string'], + filter: 'active', from: 0, size: 10 }, @@ -252,6 +263,34 @@ const { data } = await client.pinNote({ --- +### `archiveNote` + +Archives a root Note entry by setting its `_archived_at` timestamp to the current server time. The same timestamp is cascaded to every comment under the note so the entire thread is hidden from defaul + +`POST /v1/note/{id}/archive` + +```ts +const { data } = await client.archiveNote({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `unarchiveNote` + +Unarchives a root Note entry by clearing its `_archived_at` value. The clear cascades to every comment under the note so the entire thread returns to the active view. Returns 400 if the supplied id is + +`POST /v1/note/{id}/unarchive` + +```ts +const { data } = await client.unarchiveNote({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + ### `getNoteContexts` Gets all the Entity and non-Entity records the Note is contextually attached to @@ -481,16 +520,18 @@ type NotePatchRequestBody = { id: string }> pinned_at?: string // date-time - created_by?: { + edited_at?: string // date-time + created_by?: Array<{ type: "user" | "group" user_id?: string display_name?: string org_id?: string email?: string phone?: string - } + }> read_by?: string[] reactions?: Record + _archived_at?: string // date-time } ``` @@ -566,16 +607,18 @@ type NotePutRequestBody = { id: string }> pinned_at?: string // date-time - created_by?: { + edited_at?: string // date-time + created_by?: Array<{ type: "user" | "group" user_id?: string display_name?: string org_id?: string email?: string phone?: string - } + }> read_by?: string[] reactions?: Record + _archived_at?: string // date-time } ``` @@ -587,11 +630,21 @@ type NoteSearchByContextRequestBody = { type: "workflow_execution" | "workflow_task" | "workflow_configuration" | "journey_configuration" | "entity" id: string }> + include_related_schemas?: string[] + filter?: "all" | "active" | "archived" from?: number size?: number } ``` +### `NotesListFilter` + +Archive-state filter. 'active' (default) returns non-archived notes only, 'archived' returns only archived notes, 'all' returns both. + +```ts +type NotesListFilter = "all" | "active" | "archived" +``` + ### `NotesSearchRequestResponse` ```ts diff --git a/docs/sdk/clients/notification.md b/docs/sdk/clients/notification.md index ac9e84d6..02609879 100644 --- a/docs/sdk/clients/notification.md +++ b/docs/sdk/clients/notification.md @@ -154,7 +154,8 @@ const { data } = await client.getNotificationsV2({ "email": false, "in_app": false } - } + }, + "allowed_channels": ["in_app"] } ] } @@ -235,6 +236,7 @@ const { data } = await client.createNotification( in_app: false } }, + allowed_channels: ['in_app'], read_state: false, visibility_user_ids: ['1', '2', '3', '4', '5'] }, @@ -328,7 +330,8 @@ const { data } = await client.getNotifications({ "email": false, "in_app": false } - } + }, + "allowed_channels": ["in_app"] } ] } @@ -417,7 +420,8 @@ const { data } = await client.getNotification({ "email": false, "in_app": false } - } + }, + "allowed_channels": ["in_app"] } ``` @@ -932,6 +936,7 @@ type NotificationItem = { payload?: object }> force_notify_users?: Record + allowed_channels?: "email" | "in_app"[] } ``` @@ -968,6 +973,7 @@ type Notification = { payload?: object }> force_notify_users?: Record + allowed_channels?: "email" | "in_app"[] read_state?: boolean visibility_user_ids?: string[] } @@ -1006,6 +1012,7 @@ type NotificationBase = { payload?: object }> force_notify_users?: Record + allowed_channels?: "email" | "in_app"[] } ``` diff --git a/docs/sdk/clients/organization.md b/docs/sdk/clients/organization.md index 42109829..d7e50bc0 100644 --- a/docs/sdk/clients/organization.md +++ b/docs/sdk/clients/organization.md @@ -38,23 +38,34 @@ const { data } = await organizationClient.getCurrentOrganization(...) - [`getSettings`](#getsettings) - [`putSettingsValue`](#putsettingsvalue) - [`deleteSettingsValue`](#deletesettingsvalue) +- [`notifySettingsValueUpdated`](#notifysettingsvalueupdated) + +**Feature Settings** +- [`getOrganizationFeatureSettings`](#getorganizationfeaturesettings) + +**Announcements** +- [`getActiveAnnouncement`](#getactiveannouncement) +- [`acknowledgeAnnouncement`](#acknowledgeannouncement) **Schemas** - [`OrganizationId`](#organizationid) - [`Organization`](#organization) -- [`InternalOrganization`](#internalorganization) -- [`SettingKey`](#settingkey) - [`Settings`](#settings) - [`SettingsValue`](#settingsvalue) -- [`CreateOrganizationRequest`](#createorganizationrequest) -- [`DataPointsResponse`](#datapointsresponse) -- [`DataPoint`](#datapoint) -- [`OrganizationToCleanup`](#organizationtocleanup) -- [`OrganizationCleanupStatus`](#organizationcleanupstatus) +- [`FeatureSettings`](#featuresettings) +- [`FeatureFlagMetadata`](#featureflagmetadata) +- [`I18nString`](#i18nstring) +- [`VisibilityRule`](#visibilityrule) +- [`AnnouncementType`](#announcementtype) +- [`AnnouncementMessage`](#announcementmessage) +- [`Announcement`](#announcement) +- [`AnnouncementOrganizationStatusValue`](#announcementorganizationstatusvalue) +- [`AnnouncementOrganizationStatus`](#announcementorganizationstatus) +- [`ActiveAnnouncementResponse`](#activeannouncementresponse) ### `getCurrentOrganization` -Get caller's current organization +Retrieves the organization associated with the authenticated user's current session. `GET /v2/organization/current` @@ -90,7 +101,8 @@ const { data } = await client.getCurrentOrganization() "type": "Vendor", "symbol": "EPI", "pricing_tier": "professional", - "free_user_limit": 50 + "free_user_limit": 50, + "tags": ["test org"] } ``` @@ -100,7 +112,7 @@ const { data } = await client.getCurrentOrganization() ### `getOrganization` -Get an organization +Retrieves detailed information about a specific organization by its unique identifier. `GET /v2/organization/{org_id}` @@ -138,7 +150,8 @@ const { data } = await client.getOrganization({ "type": "Vendor", "symbol": "EPI", "pricing_tier": "professional", - "free_user_limit": 50 + "free_user_limit": 50, + "tags": ["test org"] } ``` @@ -148,7 +161,7 @@ const { data } = await client.getOrganization({ ### `updateOrganization` -Updates an organization +Updates an organization's profile information. `PATCH /v2/organization/{org_id}` @@ -181,7 +194,8 @@ const { data } = await client.updateOrganization( type: 'Vendor', symbol: 'EPI', pricing_tier: 'professional', - free_user_limit: 50 + free_user_limit: 50, + tags: ['test org'] }, ) ``` @@ -214,7 +228,8 @@ const { data } = await client.updateOrganization( "type": "Vendor", "symbol": "EPI", "pricing_tier": "professional", - "free_user_limit": 50 + "free_user_limit": 50, + "tags": ["test org"] } ``` @@ -224,7 +239,7 @@ const { data } = await client.updateOrganization( ### `getSettings` -Get full organization settings object +Retrieves all configuration settings for an organization. `GET /v2/organization/{org_id}/settings` @@ -241,7 +256,12 @@ const { data } = await client.getSettings({ { "double_opt_in": { "enabled": true - } + }, + "email_tracking": { + "enabled": true, + "track_opens": true + }, + "default_language": "de" } ``` @@ -251,7 +271,7 @@ const { data } = await client.getSettings({ ### `putSettingsValue` -Updates an organization setting +Creates or updates a specific organization setting identified by its key. `PUT /v2/organization/{org_id}/settings/{key}` @@ -282,7 +302,7 @@ const { data } = await client.putSettingsValue( ### `deleteSettingsValue` -Updates an organization nsetting +Removes a specific organization setting identified by its key. `DELETE /v2/organization/{org_id}/settings/{key}` @@ -295,16 +315,160 @@ const { data } = await client.deleteSettingsValue({ --- +### `notifySettingsValueUpdated` + +Sends an internal notification that an organization setting was updated. + +`POST /v2/organization/{org_id}/settings/{key}/notifications` + +```ts +const { data } = await client.notifySettingsValueUpdated( + { + org_id: 'example', + key: 'example', + }, + { + user_email: 'string', + org_name: 'string', + value: { + enabled: true + } + }, +) +``` + +
+Response + +```json +{ + "delivered": true +} +``` + +
+ +--- + +### `getOrganizationFeatureSettings` + +Get organization feature settings. + +`GET /v2/organization/feature-settings` + +```ts +const { data } = await client.getOrganizationFeatureSettings() +``` + +--- + +### `getActiveAnnouncement` + +Returns the announcement (e.g. a subprocessor change notice) to show as a portal banner for the +caller's organization. + +`GET /v2/organization/announcements/active` + +```ts +const { data } = await client.getActiveAnnouncement() +``` + +
+Response + +```json +{ + "announcement": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "subprocessor_change", + "message": { + "de": "Wir haben unsere Liste der Subdienstleister aktualisiert (gültig ab 01.11.2026). Bitte prüfe die Änderungen.", + "en": "We have updated our list of subprocessors (effective 01.11.2026). Please review the changes." + }, + "link_url": "string", + "list_version": "string", + "effective_date": "1970-01-01", + "window_days": 0, + "status": "draft", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z", + "published_at": "1970-01-01T00:00:00.000Z", + "published_by": "string", + "expires_at": "1970-01-01T00:00:00.000Z", + "archived_at": "1970-01-01T00:00:00.000Z", + "archived_by": "string", + "materialized_at": "1970-01-01T00:00:00.000Z" + }, + "can_acknowledge": true +} +``` + +
+ +--- + +### `acknowledgeAnnouncement` + +Acknowledges an announcement on behalf of the caller's organization. Only org admins +(`organization:edit`) may acknowledge. + +`POST /v2/organization/announcements/{announcement_id}/acknowledge` + +```ts +const { data } = await client.acknowledgeAnnouncement( + { + announcement_id: 'example', + }, + { + portal: '360' + }, +) +``` + +
+Response + +```json +{ + "announcement_id": "string", + "org_id": "string", + "org_name": "string", + "status": "acknowledged", + "acknowledged_by": { + "user_id": "string", + "name": "string", + "email": "string" + }, + "acknowledged_at": "1970-01-01T00:00:00.000Z", + "portal": "360", + "list_version": "string", + "recorded_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + ## Schemas ### `OrganizationId` +Unique identifier for an organization (tenant) in the epilot platform + ```ts type OrganizationId = string ``` ### `Organization` +Represents an epilot organization (tenant). + +An organization contains all the configuration, branding, and contact information +for a tenant account on the epilot platform. + + ```ts type Organization = { id?: string @@ -319,7 +483,7 @@ type Organization = { street?: string street_number?: string } - organization_use?: "Production" | "Sandbox" + organization_use?: "Production" | "Sandbox" | "Preview" parent_production_org_id?: string created_date?: string // date-time logo_url?: string @@ -331,116 +495,223 @@ type Organization = { symbol?: string pricing_tier?: string free_user_limit?: number + tags?: string[] } ``` -### `InternalOrganization` +### `Settings` + +A key-value map of all organization settings. +Keys are setting identifiers and values can be any valid JSON type. + ```ts -type InternalOrganization = { - id?: string - name?: string - email?: string - phone?: string - website?: string - address?: { - country?: string - city?: string - postal_code?: string - street?: string - street_number?: string +type Settings = Record +``` + +### `SettingsValue` + +The value of an organization setting. +Can be any valid JSON type: string, number, boolean, array, or object. + + +```ts +type SettingsValue = string | number | boolean | Record[] | Record +``` + +### `FeatureSettings` + +Feature settings metadata served to frontend applications. + +```ts +type FeatureSettings = { + version: string + feature_flags: Array<{ + feature_name: string + title?: { + key: { ... } + default_value?: { ... } + } + description?: { + key: { ... } + default_value?: { ... } + } + badge?: "alpha" | "beta" | "new" | "advanced" | "experiment" | "deprecated" + confetti?: boolean + one_way?: boolean + reverse_checked?: boolean + is_visible_for_partner?: boolean + visibility_rules: Array<{ + type: { ... } + setting_key?: { ... } + flag_name?: { ... } + pricing_tier_classes?: { ... } + action?: { ... } + resource?: { ... } + rule?: { ... } + rules?: { ... } + }> + }> +} +``` + +### `FeatureFlagMetadata` + +Metadata for a single feature flag toggle + +```ts +type FeatureFlagMetadata = { + feature_name: string + title?: { + key: string + default_value?: string } - organization_use?: "Production" | "Sandbox" - parent_production_org_id?: string - created_date?: string // date-time - logo_url?: string - logo_thumbnail_url?: string - signature?: string - is_unlicensed_org?: boolean - style?: Record - type?: "Vendor" | "Partner" - symbol?: string - pricing_tier?: string - free_user_limit?: number + description?: { + key: string + default_value?: string + } + badge?: "alpha" | "beta" | "new" | "advanced" | "experiment" | "deprecated" + confetti?: boolean + one_way?: boolean + reverse_checked?: boolean + is_visible_for_partner?: boolean + visibility_rules: Array<{ + type: "always" | "never" | "advanced_mode" | "pricing_tier" | "pricing_tier_class" | "production_org" | "feature_flag" | "permission" | "setting_enabled" | "flag_enabled" | "not" | "and" | "or" + setting_key?: string + flag_name?: string + pricing_tier_classes?: string[] + action?: string + resource?: string + rule?: { ... } + rules?: { ... }[] + }> } ``` -### `SettingKey` +### `I18nString` + +Internationalized string with a translation key and optional default value ```ts -type SettingKey = string +type I18nString = { + key: string + default_value?: string +} ``` -### `Settings` +### `VisibilityRule` + +A rule that determines feature visibility. Rules are combined with AND logic +at the top level. Supports boolean combinators (and, or, not) for complex logic. + ```ts -type Settings = Record +type VisibilityRule = { + type: "always" | "never" | "advanced_mode" | "pricing_tier" | "pricing_tier_class" | "production_org" | "feature_flag" | "permission" | "setting_enabled" | "flag_enabled" | "not" | "and" | "or" + setting_key?: string + flag_name?: string + pricing_tier_classes?: string[] + action?: string + resource?: string + rule?: { ... } + rules?: { ... }[] +} ``` -### `SettingsValue` +### `AnnouncementType` ```ts -type SettingsValue = string | number | boolean | Record[] | Record +type AnnouncementType = "subprocessor_change" ``` -### `CreateOrganizationRequest` +### `AnnouncementMessage` ```ts -type CreateOrganizationRequest = { - organization_detail?: { - name: string - email_address?: string - type: string - organization_use?: "Production" | "Sandbox" - pricing_tier_id: string - } - owner_user?: { - full_name?: string - email_address: string - } +type AnnouncementMessage = { + de: string + en?: string } ``` -### `DataPointsResponse` +### `Announcement` ```ts -type DataPointsResponse = Array<{ - id?: number - max_customer?: number - actual_customer?: number -}> +type Announcement = { + id: string // uuid + type: "subprocessor_change" + message: { + de: string + en?: string + } + link_url: string + list_version: string + effective_date: string // date + window_days: number + status: "draft" | "published" | "archived" + created_at: string // date-time + created_by?: string + updated_at: string // date-time + published_at?: string // date-time + published_by?: string + expires_at?: string // date-time + archived_at?: string // date-time + archived_by?: string + materialized_at?: string // date-time +} ``` -### `DataPoint` +### `AnnouncementOrganizationStatusValue` ```ts -type DataPoint = { - id?: number - max_customer?: number - actual_customer?: number -} +type AnnouncementOrganizationStatusValue = "acknowledged" | "pending" | "expired" | "superseded" ``` -### `OrganizationToCleanup` +### `AnnouncementOrganizationStatus` ```ts -type OrganizationToCleanup = { +type AnnouncementOrganizationStatus = { + announcement_id: string org_id: string - deleted_at: string // date-time - deleted_by: string + org_name?: string + status: "acknowledged" | "pending" | "expired" | "superseded" + acknowledged_by?: { + user_id: string + name?: string + email?: string + } + acknowledged_at?: string // date-time + portal?: string + list_version: string + recorded_at?: string // date-time } ``` -### `OrganizationCleanupStatus` +### `ActiveAnnouncementResponse` ```ts -type OrganizationCleanupStatus = { - org_id: string - service_name: string - operations?: Array<{ - action?: string - resource?: string - extra_info?: string | number | boolean | Record[] | Record - }> +type ActiveAnnouncementResponse = { + announcement: { + id: string // uuid + type: "subprocessor_change" + message: { + de: { ... } + en?: { ... } + } + link_url: string + list_version: string + effective_date: string // date + window_days: number + status: "draft" | "published" | "archived" + created_at: string // date-time + created_by?: string + updated_at: string // date-time + published_at?: string // date-time + published_by?: string + expires_at?: string // date-time + archived_at?: string // date-time + archived_by?: string + materialized_at?: string // date-time + } + can_acknowledge: boolean } ``` diff --git a/docs/sdk/clients/permissions.md b/docs/sdk/clients/permissions.md index a0f68348..a793be3b 100644 --- a/docs/sdk/clients/permissions.md +++ b/docs/sdk/clients/permissions.md @@ -50,7 +50,10 @@ const { data } = await permissionsClient.listCurrentRoles(...) - [`Grant`](#grant) - [`GrantWithDependencies`](#grantwithdependencies) - [`GrantCondition`](#grantcondition) +- [`EqualsCurrentUserCondition`](#equalscurrentusercondition) +- [`NotEqualsCurrentUserCondition`](#notequalscurrentusercondition) - [`EqualsCondition`](#equalscondition) +- [`NotEqualsCondition`](#notequalscondition) - [`RoleId`](#roleid) - [`BaseRole`](#baserole) - [`BaseRoleForCreate`](#baseroleforcreate) @@ -110,7 +113,8 @@ const { data } = await client.listCurrentRoles() ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ] } @@ -157,7 +161,8 @@ const { data } = await client.listAllRoles() ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ] } @@ -205,7 +210,8 @@ const { data } = await client.createRole( ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ``` @@ -261,7 +267,8 @@ const { data } = await client.searchRoles( ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ] } @@ -308,7 +315,8 @@ const { data } = await client.getRole({ ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ``` @@ -348,7 +356,8 @@ const { data } = await client.putRole( ] } ], - parent_role: '123:owner' + parent_role: '123:owner', + vendor_created: true }, ) ``` @@ -378,7 +387,8 @@ const { data } = await client.putRole( ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ``` @@ -423,7 +433,8 @@ const { data } = await client.deleteRole({ ] } ], - "parent_role": "123:owner" + "parent_role": "123:owner", + "vendor_created": true } ``` @@ -610,6 +621,30 @@ type GrantWithDependencies = { type GrantCondition = object ``` +### `EqualsCurrentUserCondition` + +Check if any relation_user attribute on the entity contains the current user. When attribute is provided, only that specific attribute path is checked. When attributes is provided, it takes precedence over attribute and the condition passes when the current user appears in ANY of the listed attribut + +```ts +type EqualsCurrentUserCondition = { + attribute?: string + attributes?: string[] + operation: "equals_current_user" +} +``` + +### `NotEqualsCurrentUserCondition` + +Check if the current user is absent from the relation_user attributes on the entity. When attribute is provided, only that specific attribute path is checked. When attributes is provided, it takes precedence over attribute and the condition passes only when the current user appears in NONE of the li + +```ts +type NotEqualsCurrentUserCondition = { + attribute?: string + attributes?: string[] + operation: "not_equals_current_user" +} +``` + ### `EqualsCondition` Check if attribute equals to any of the values @@ -622,6 +657,18 @@ type EqualsCondition = { } ``` +### `NotEqualsCondition` + +Passes when the attribute does not equal any of the values. Records where the attribute is missing or empty pass the condition. + +```ts +type NotEqualsCondition = { + attribute: string + operation: "not_equals" + values: unknown[] +} +``` + ### `RoleId` Format: ``:`` @@ -685,6 +732,7 @@ type UserRole = { conditions?: object[] }> parent_role?: object + vendor_created?: boolean } ``` @@ -745,6 +793,7 @@ type PartnerRole = { }> partner_org_id?: object vendor_enforced_user_limit?: number + vendor_created?: boolean } ``` @@ -784,6 +833,7 @@ type Role = { conditions?: object[] }> parent_role?: object + vendor_created?: boolean } | { id: string name: string @@ -826,6 +876,7 @@ type Role = { }> partner_org_id?: object vendor_enforced_user_limit?: number + vendor_created?: boolean } | { id: string name: string @@ -918,6 +969,7 @@ type OrgRoles = { conditions?: { ... } }> parent_role?: object + vendor_created?: boolean } | { id: string name: string @@ -960,6 +1012,7 @@ type OrgRoles = { }> partner_org_id?: object vendor_enforced_user_limit?: number + vendor_created?: boolean } | { id: string name: string diff --git a/docs/sdk/clients/phone-integration.md b/docs/sdk/clients/phone-integration.md new file mode 100644 index 00000000..20c4259d --- /dev/null +++ b/docs/sdk/clients/phone-integration.md @@ -0,0 +1,2585 @@ +--- +title: "Phone Integration API" +description: "TypeScript SDK client for the epilot Phone Integration API: usage with @epilot/sdk, all operations and schemas." +--- + +# Phone Integration API + +- **Base URL:** `https://phone-integration-api.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/phone-integration](https://docs.epilot.io/api/phone-integration) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.phoneIntegration.batchSearchCustomers(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/phone-integration' + +const phoneIntegrationClient = getClient() +authorize(phoneIntegrationClient, () => '') +const { data } = await phoneIntegrationClient.batchSearchCustomers(...) +``` + +## Operations + +**phone-integration** +- [`batchSearchCustomers`](#batchsearchcustomers) +- [`getActiveCall`](#getactivecall) +- [`reportActiveCall`](#reportactivecall) +- [`clearActiveCall`](#clearactivecall) + +**manager** +- [`getManagerStatus`](#getmanagerstatus) +- [`listPhoneAgents`](#listphoneagents) +- [`assignPhoneAgent`](#assignphoneagent) +- [`removePhoneAgent`](#removephoneagent) +- [`getLiveSnapshot`](#getlivesnapshot) +- [`listLiveAgents`](#listliveagents) +- [`setAgentRouting`](#setagentrouting) +- [`previewAgentRouting`](#previewagentrouting) +- [`setAgentPresence`](#setagentpresence) +- [`listAgentPresences`](#listagentpresences) +- [`listQueues`](#listqueues) +- [`getQueue`](#getqueue) +- [`getCallReport`](#getcallreport) +- [`getLiveKpis`](#getlivekpis) +- [`getAgentPerformance`](#getagentperformance) +- [`listMissedCalls`](#listmissedcalls) +- [`requestMissedCallCallback`](#requestmissedcallcallback) +- [`getAgentActivity`](#getagentactivity) +- [`getQueueSettings`](#getqueuesettings) +- [`setQueueSettings`](#setqueuesettings) +- [`getCallHandlingSettings`](#getcallhandlingsettings) +- [`setCallHandlingSettings`](#setcallhandlingsettings) +- [`getQueuePerformance`](#getqueueperformance) +- [`listSkills`](#listskills) +- [`createSkill`](#createskill) +- [`deleteSkill`](#deleteskill) +- [`setQueueSkill`](#setqueueskill) +- [`removeQueueSkill`](#removequeueskill) + +**operator** +- [`listProviderSetups`](#listprovidersetups) +- [`getProviderSetup`](#getprovidersetup) +- [`setupProvider`](#setupprovider) + +**Schemas** +- [`ManagerStatus`](#managerstatus) +- [`PhoneAgent`](#phoneagent) +- [`AssignPhoneAgentRequest`](#assignphoneagentrequest) +- [`ProviderSetup`](#providersetup) +- [`ProviderSetupSummary`](#providersetupsummary) +- [`ProviderSetupRequest`](#providersetuprequest) +- [`CustomerBatchSearchResult`](#customerbatchsearchresult) +- [`CustomerSearchResult`](#customersearchresult) +- [`CustomerIdentifier`](#customeridentifier) +- [`CustomerSummary`](#customersummary) +- [`ActiveCall`](#activecall) +- [`ActiveCallReport`](#activecallreport) +- [`AgentState`](#agentstate) +- [`AgentPresence`](#agentpresence) +- [`AgentPresenceRequest`](#agentpresencerequest) +- [`AgentPresenceChange`](#agentpresencechange) +- [`Skill`](#skill) +- [`QueueRef`](#queueref) +- [`PersonRef`](#personref) +- [`EligibilityPath`](#eligibilitypath) +- [`AgentQueueEligibility`](#agentqueueeligibility) +- [`LiveAgent`](#liveagent) +- [`LiveAgentCounters`](#liveagentcounters) +- [`QueueHealth`](#queuehealth) +- [`QueueLive`](#queuelive) +- [`LiveSnapshot`](#livesnapshot) +- [`QueueRoutingStep`](#queueroutingstep) +- [`QueueOverview`](#queueoverview) +- [`EligibleAgent`](#eligibleagent) +- [`WaitingCall`](#waitingcall) +- [`QueueDetail`](#queuedetail) +- [`AgentRoutingRequest`](#agentroutingrequest) +- [`AgentRouting`](#agentrouting) +- [`AgentRoutingPreview`](#agentroutingpreview) +- [`CallReport`](#callreport) +- [`QueuePerformance`](#queueperformance) +- [`QueuePerformanceReport`](#queueperformancereport) +- [`SkillCatalogueEntry`](#skillcatalogueentry) +- [`SkillCatalogue`](#skillcatalogue) +- [`CreateSkillRequest`](#createskillrequest) +- [`SkillDeletion`](#skilldeletion) +- [`QueueSkillChange`](#queueskillchange) +- [`ErrorResponse`](#errorresponse) +- [`KpiPeriod`](#kpiperiod) +- [`LiveKpis`](#livekpis) +- [`AgentPerformance`](#agentperformance) +- [`AgentPerformanceReport`](#agentperformancereport) +- [`MissedCallCaller`](#missedcallcaller) +- [`MissedCallCallback`](#missedcallcallback) +- [`MissedCallCallbackRequest`](#missedcallcallbackrequest) +- [`MissedCall`](#missedcall) +- [`MissedCallList`](#missedcalllist) +- [`AgentActivityEvent`](#agentactivityevent) +- [`AgentPresenceTotal`](#agentpresencetotal) +- [`AgentActivity`](#agentactivity) +- [`QueueSettingsUpdate`](#queuesettingsupdate) +- [`QueueSettings`](#queuesettings) +- [`WrapUpTimes`](#wrapuptimes) +- [`CallHandlingSettings`](#callhandlingsettings) + +### `batchSearchCustomers` + +Resolves up to 50 identifiers to epilot customers (Contacts) in one +request — for example every number in an agent's call history. + +`GET /v1/customer:batchSearch` + +```ts +const { data } = await client.batchSearchCustomers({ + id: ['...'], + customer_number: ['...'], + external_id: ['...'], + phone_number: ['...'], + email: ['...'], + x-trace-id: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "identifier": { + "type": "id", + "value": "+4917012345678" + }, + "status": "found", + "customer": { + "id": "dba8e5f9-8b3f-4608-b887-cd0798fce624", + "name": "Max Mustermann", + "customer_number": "4711" + } + } + ] +} +``` + +
+ +--- + +### `getActiveCall` + +Whether the signed-in user is on a phone call right now, and which conversation it is. The +answer is about the caller only (the user of the bearer token). + +`GET /v1/calls/active` + +```ts +const { data } = await client.getActiveCall() +``` + +
+Response + +```json +{ + "on_call": true, + "conversation_id": "01KW704DAM1PM5SDGKFDY9BNK0", + "started_at": "1970-01-01T00:00:00.000Z", + "source": "softphone", + "expires_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `reportActiveCall` + +Reports the call the signed-in user is on. Sent by the epilot 360 phone when a call is +answered and again every 30 seconds while it lasts: a report is valid for 2 minutes +(`expires_at`), so a phone th + +`PUT /v1/calls/active` + +```ts +const { data } = await client.reportActiveCall( + null, + { + conversation_id: '01KW704DAM1PM5SDGKFDY9BNK0', + started_at: '2026-11-10T10:00:00.000Z' + }, +) +``` + +
+Response + +```json +{ + "on_call": true, + "conversation_id": "01KW704DAM1PM5SDGKFDY9BNK0", + "started_at": "1970-01-01T00:00:00.000Z", + "source": "softphone", + "expires_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `clearActiveCall` + +Clears the signed-in user's reported call, when their part of it ended (hung up, or handed +over to another agent). With `conversation_id`, only a report of that conversation is +cleared, so a late "cal + +`DELETE /v1/calls/active` + +```ts +const { data } = await client.clearActiveCall({ + conversation_id: 'example', +}) +``` + +--- + +### `getManagerStatus` + +Whether the caller's organization is ready for phone agents: the telephony provider tenant +exists and is configured. The control center shows a "not set up" state when `ready` is false. +Requires `phon + +`GET /v1/manager/status` + +```ts +const { data } = await client.getManagerStatus() +``` + +
+Response + +```json +{ + "provider": "babelforce", + "ready": true, + "reasons": ["provider_tenant_missing"] +} +``` + +
+ +--- + +### `listPhoneAgents` + +Organization members who hold the phone (`phone:use`), each joined with the provider user behind +them. Requires `phone:manage`. + +`GET /v1/manager/agents` + +```ts +const { data } = await client.listPhoneAgents() +``` + +
+Response + +```json +{ + "results": [ + { + "user_id": "string", + "email": "string", + "display_name": "string", + "status": "active", + "provider_user_id": "string", + "provider_roles": ["string"], + "assigned_at": "1970-01-01T00:00:00.000Z", + "assigned_by": "string" + } + ] +} +``` + +
+ +--- + +### `assignPhoneAgent` + +Gives an organization member the phone. In order: the member is verified with user-api, their +pairwise subject for the provider is read from identity-api, the provider user is created (or +found) bound + +`POST /v1/manager/agents` + +```ts +const { data } = await client.assignPhoneAgent( + null, + { + user_id: 'string' + }, +) +``` + +
+Response + +```json +{ + "user_id": "string", + "email": "string", + "display_name": "string", + "status": "active", + "provider_user_id": "string", + "provider_roles": ["string"], + "assigned_at": "1970-01-01T00:00:00.000Z", + "assigned_by": "string" +} +``` + +
+ +--- + +### `removePhoneAgent` + +Takes the phone away from a member: the `phone_agent` role is removed first, then the provider +user is deactivated (never deleted: call history keeps referring to it). Requires `phone:manage`. + +`DELETE /v1/manager/agents/{user_id}` + +```ts +const { data } = await client.removePhoneAgent({ + user_id: 'example', +}) +``` + +--- + +### `getLiveSnapshot` + +One snapshot of the organization's live phone state for the control center's Overview: agent +presence counters and per-queue health (waiting calls, longest wait, eligible vs available +agents). The pro + +`GET /v1/manager/live` + +```ts +const { data } = await client.getLiveSnapshot() +``` + +
+Response + +```json +{ + "captured_at": "1970-01-01T00:00:00.000Z", + "agents": { + "total": 0, + "online": 0, + "available": 0, + "on_call": 0, + "wrap_up": 0, + "offline": 0 + }, + "queues": [ + { + "id": "string", + "name": "string", + "waiting": 0, + "longest_wait_seconds": 0, + "expected_wait_seconds": 0, + "eligible": 0, + "available": 0, + "health": "healthy" + } + ], + "calls_waiting": 0, + "longest_wait_seconds": 0, + "expected_wait_seconds": 0 +} +``` + +
+ +--- + +### `listLiveAgents` + +The organization's phone agents with their live phone status, their skills (as the phone system +holds them) and the queues they can take calls from. Agents that are epilot phone agents carry +the epilo + +`GET /v1/manager/agents/live` + +```ts +const { data } = await client.listLiveAgents() +``` + +
+Response + +```json +{ + "captured_at": "1970-01-01T00:00:00.000Z", + "results": [ + { + "provider_agent_id": "string", + "user_id": "string", + "name": "string", + "email": "string", + "enabled": true, + "state": "available", + "presence": { + "name": "string", + "label": "string", + "available": true + }, + "display_status": "string", + "skills": ["string"], + "queues": [ + { + "id": "string", + "name": "string", + "via": ["skill"], + "skills": ["string"], + "locked": true + } + ], + "current_call": { + "started_at": "1970-01-01T00:00:00.000Z", + "queue_name": "string" + } + } + ] +} +``` + +
+ +--- + +### `setAgentRouting` + +Sets an agent's skills and direct queue membership (full sets, not deltas), in this order: +1. Skills: the agent's skills in the phone system are replaced by `skills` (lowercased, see + `Skill`), so t + +`PUT /v1/manager/agents/{provider_agent_id}/routing` + +```ts +const { data } = await client.setAgentRouting( + { + provider_agent_id: 'example', + }, + { + skills: ['string'], + queue_ids: ['string'], + include_own_steps: false + }, +) +``` + +
+Response + +```json +{ + "provider_agent_id": "string", + "skills": ["string"], + "queues": [ + { + "id": "string", + "name": "string", + "via": ["skill"], + "skills": ["string"], + "locked": true + } + ] +} +``` + +
+ +--- + +### `previewAgentRouting` + +The routing impact of `setAgentRouting` with the same body, without changing anything: the +queues the agent can take calls from now (as the phone system routes today) and after the +change, what is add + +`POST /v1/manager/agents/{provider_agent_id}/routing:preview` + +```ts +const { data } = await client.previewAgentRouting( + { + provider_agent_id: 'example', + }, + { + skills: ['string'], + queue_ids: ['string'], + include_own_steps: false + }, +) +``` + +
+Response + +```json +{ + "provider_agent_id": "string", + "before": [ + { + "id": "string", + "name": "string" + } + ], + "after": [ + { + "id": "string", + "name": "string" + } + ], + "added": [ + { + "id": "string", + "name": "string" + } + ], + "removed": [ + { + "id": "string", + "name": "string" + } + ], + "coverage_lost": [ + { + "id": "string", + "name": "string" + } + ], + "locked": [ + { + "id": "string", + "name": "string" + } + ] +} +``` + +
+ +--- + +### `setAgentPresence` + +Puts the agent on one of the phone system's presences (`listAgentPresences`), as the agent could +in the phone app. A presence that is not `available` stops queue calls to the agent until it +changes ag + +`PUT /v1/manager/agents/{provider_agent_id}/presence` + +```ts +const { data } = await client.setAgentPresence( + { + provider_agent_id: 'example', + }, + { + presence: 'string' + }, +) +``` + +
+Response + +```json +{ + "provider_agent_id": "string", + "presence": { + "name": "string", + "label": "string", + "available": true + } +} +``` + +
+ +--- + +### `listAgentPresences` + +The presences the organization's agents can be on (e.g. Available, Break, Meeting), as the phone +system defines them. `available` presences let agents take queue calls. Requires `phone:manage`. + +`GET /v1/manager/presences` + +```ts +const { data } = await client.listAgentPresences() +``` + +
+Response + +```json +{ + "results": [ + { + "name": "string", + "label": "string", + "available": true + } + ] +} +``` + +
+ +--- + +### `listQueues` + +The organization's queues with live demand (waiting calls, longest wait), staffing (eligible +vs available agents), derived health and who can take their calls: the routing steps in the +order the phone + +`GET /v1/manager/queues` + +```ts +const { data } = await client.listQueues() +``` + +
+Response + +```json +{ + "captured_at": "1970-01-01T00:00:00.000Z", + "results": [ + { + "id": "string", + "name": "string", + "waiting": 0, + "longest_wait_seconds": 0, + "expected_wait_seconds": 0, + "eligible": 0, + "available": 0, + "health": "healthy", + "numbers": ["string"], + "routing": [ + { + "id": "string", + "order": 0, + "label": "string", + "enabled": true, + "skills": ["string"], + "people": [ + { + "provider_agent_id": "string", + "user_id": "string", + "name": "string" + } + ], + "team_members": ["string"], + "managed_by_epilot": true + } + ] + } + ] +} +``` + +
+ +--- + +### `getQueue` + +One queue for the control center's queue drawer: the overview fields plus the agents currently +eligible for it (with live status and how they are eligible) and the calls waiting in it. +Requires `phone + +`GET /v1/manager/queues/{queue_id}` + +```ts +const { data } = await client.getQueue({ + queue_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "string", + "name": "string", + "waiting": 0, + "longest_wait_seconds": 0, + "expected_wait_seconds": 0, + "eligible": 0, + "available": 0, + "health": "healthy", + "numbers": ["string"], + "routing": [ + { + "id": "string", + "order": 0, + "label": "string", + "enabled": true, + "skills": ["string"], + "people": [ + { + "provider_agent_id": "string", + "user_id": "string", + "name": "string" + } + ], + "team_members": ["string"], + "managed_by_epilot": true + } + ], + "captured_at": "1970-01-01T00:00:00.000Z", + "eligible_agents": [ + { + "provider_agent_id": "string", + "user_id": "string", + "name": "string", + "email": "string", + "state": "available", + "presence": { + "name": "string", + "label": "string", + "available": true + }, + "via": ["skill"], + "skills": ["string"] + } + ], + "waiting_calls": [ + { + "id": "string", + "from_masked": "string", + "contact": { + "id": "string", + "name": "string" + }, + "waited_seconds": 0, + "state": "string" + } + ] +} +``` + +
+ +--- + +### `getCallReport` + +Inbound call outcomes for a period, from the provider's call reporting: how many inbound calls +there were, how many an agent handled (bridged) and how many ended without an agent (abandoned +or failed) + +`GET /v1/manager/reporting/calls` + +```ts +const { data } = await client.getCallReport({ + from: 'example', + to: 'example', +}) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "inbound_total": 0, + "handled_by_agent": 0, + "abandoned_or_failed": 0, + "previous_period": { + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "inbound_total": 0 + } +} +``` + +
+ +--- + +### `getLiveKpis` + +Service KPIs of the organization's phone team for a period: call counts, abandon rate, waits +and handling times, from the provider's metrics or, where it has none, its call reporting. A KPI +the provid + +`GET /v1/manager/live/kpis` + +```ts +const { data } = await client.getLiveKpis({ + period: 'example', + from: 'example', + to: 'example', +}) +``` + +
+Response + +```json +{ + "captured_at": "1970-01-01T00:00:00.000Z", + "period": "today", + "calls_total": 0, + "answered_total": 0, + "abandoned_total": 0, + "abandon_rate_percent": 0, + "average_wait_seconds": 0, + "longest_wait_seconds": 0, + "average_talk_seconds": 0, + "average_handle_seconds": 0, + "average_hold_seconds": 0 +} +``` + +
+ +--- + +### `getAgentPerformance` + +Per-agent performance for a period from the provider's call reporting: calls handled and talk, +hold, wrap-up and handle times, one row per agent who handled at least one call. Agents that are +epilot p + +`GET /v1/manager/reporting/agents` + +```ts +const { data } = await client.getAgentPerformance({ + from: 'example', + to: 'example', +}) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "results": [ + { + "provider_agent_id": "string", + "user_id": "string", + "name": "string", + "calls_handled": 0, + "outbound_calls": 0, + "talk_seconds_total": 0, + "talk_seconds_average": 0, + "hold_seconds_total": 0, + "wrap_up_seconds_average": 0, + "handle_seconds_average": 0 + } + ] +} +``` + +
+ +--- + +### `listMissedCalls` + +Callers who did not reach an agent in a period, newest first, one row per caller: an inbound +call (grouped by the provider's session, so transfer legs count once) that ended without being +bridged to a + +`GET /v1/manager/missed-calls` + +```ts +const { data } = await client.listMissedCalls({ + from: 'example', + to: 'example', +}) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "results": [ + { + "call_id": "string", + "last_missed_at": "1970-01-01T00:00:00.000Z", + "first_missed_at": "1970-01-01T00:00:00.000Z", + "attempts": 1, + "queue": { + "id": "string", + "name": "string" + }, + "longest_wait_seconds": 0, + "caller": { + "anonymous": true, + "number_masked": "string", + "contact": { + "id": "string", + "name": "string" + } + }, + "resolved": true, + "can_call_back": true, + "callback": { + "state": "queued", + "requested_at": "1970-01-01T00:00:00.000Z", + "requested_by": "string", + "queue": { + "id": "string", + "name": "string" + }, + "callback_call_id": "string" + } + } + ] +} +``` + +
+ +--- + +### `requestMissedCallCallback` + +Asks the phone system to call the caller of a missed call back: the provider queues an outbound +callback on a queue (the missed call's queue unless `queue_id` names another), so the next +eligible agen + +`POST /v1/manager/missed-calls/{call_id}/callback` + +```ts +const { data } = await client.requestMissedCallCallback( + { + call_id: 'example', + }, + { + queue_id: 'string' + }, +) +``` + +--- + +### `getAgentActivity` + +An agent's activity in a period from the provider's agent logs: presence changes and calls in +time order, the time spent on each presence and the number of calls handled. The window is at +most 31 days + +`GET /v1/manager/agents/{provider_agent_id}/activity` + +```ts +const { data } = await client.getAgentActivity({ + provider_agent_id: 'example', + from: 'example', + to: 'example', +}) +``` + +
+Response + +```json +{ + "provider_agent_id": "string", + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "events": [ + { + "at": "1970-01-01T00:00:00.000Z", + "kind": "presence", + "presence": { + "name": "string", + "label": "string", + "available": true + }, + "call": { + "call_id": "string", + "direction": "inbound", + "queue_name": "string", + "duration_seconds": 0 + }, + "description": "string" + } + ], + "presence_totals": [ + { + "presence": { + "name": "string", + "label": "string", + "available": true + }, + "seconds": 0 + } + ], + "calls_handled": 0 +} +``` + +
+ +--- + +### `getQueueSettings` + +A queue's call handling settings as the phone system holds them: how many callers may wait, +how long an agent's phone rings, the wrap-up time after a call and how many agents are tried +per call. +Requi + +`GET /v1/manager/queues/{queue_id}/settings` + +```ts +const { data } = await client.getQueueSettings({ + queue_id: 'example', +}) +``` + +
+Response + +```json +{ + "queue_id": "string", + "name": "string", + "max_size": 0, + "ring_timeout_seconds": 5, + "wrap_up_seconds": 0, + "max_dial_count": 1 +} +``` + +
+ +--- + +### `setQueueSettings` + +Replaces a queue's call handling settings (all fields, not a delta); the phone system applies +them to the next call. The queue's name and routing are not changed. +Requires `phone:manage`. + +`PUT /v1/manager/queues/{queue_id}/settings` + +```ts +const { data } = await client.setQueueSettings( + { + queue_id: 'example', + }, + { + max_size: 0, + ring_timeout_seconds: 5, + wrap_up_seconds: 0, + max_dial_count: 1 + }, +) +``` + +
+Response + +```json +{ + "queue_id": "string", + "name": "string", + "max_size": 0, + "ring_timeout_seconds": 5, + "wrap_up_seconds": 0, + "max_dial_count": 1 +} +``` + +
+ +--- + +### `getCallHandlingSettings` + +The organization's call handling settings for all agents: wrap-up rules (including whether +agents may call out during wrap-up), wrap-up times after unsuccessful calls, and recording +defaults. +Requires + +`GET /v1/manager/settings/call-handling` + +```ts +const { data } = await client.getCallHandlingSettings() +``` + +
+Response + +```json +{ + "wrap_up": { + "inbound_cancel_allowed": true, + "inbound_extend_allowed": true, + "inbound_max_extension_seconds": 0, + "outbound_enabled": true, + "outbound_cancel_allowed": true, + "outbound_extend_allowed": true, + "outbound_max_extension_seconds": 0, + "outbound_calls_allowed": true + }, + "after_unsuccessful_inbound": { + "busy_seconds": 0, + "unreachable_seconds": 0, + "declined_seconds": 0 + }, + "after_unsuccessful_outbound": { + "busy_seconds": 0, + "unreachable_seconds": 0, + "declined_seconds": 0 + }, + "recording": { + "always_record_outbound": true, + "agents_may_delete": true, + "hide_recording_controls": true + } +} +``` + +
+ +--- + +### `setCallHandlingSettings` + +Replaces the organization's call handling settings (the full object, not a delta). +Requires `phone:manage`. + +`PUT /v1/manager/settings/call-handling` + +```ts +const { data } = await client.setCallHandlingSettings( + null, + { + wrap_up: { + inbound_cancel_allowed: true, + inbound_extend_allowed: true, + inbound_max_extension_seconds: 0, + outbound_enabled: true, + outbound_cancel_allowed: true, + outbound_extend_allowed: true, + outbound_max_extension_seconds: 0, + outbound_calls_allowed: true + }, + after_unsuccessful_inbound: { + busy_seconds: 0, + unreachable_seconds: 0, + declined_seconds: 0 + }, + after_unsuccessful_outbound: { + busy_seconds: 0, + unreachable_seconds: 0, + declined_seconds: 0 + }, + recording: { + always_record_outbound: true, + agents_may_delete: true, + hide_recording_controls: true + } + }, +) +``` + +
+Response + +```json +{ + "wrap_up": { + "inbound_cancel_allowed": true, + "inbound_extend_allowed": true, + "inbound_max_extension_seconds": 0, + "outbound_enabled": true, + "outbound_cancel_allowed": true, + "outbound_extend_allowed": true, + "outbound_max_extension_seconds": 0, + "outbound_calls_allowed": true + }, + "after_unsuccessful_inbound": { + "busy_seconds": 0, + "unreachable_seconds": 0, + "declined_seconds": 0 + }, + "after_unsuccessful_outbound": { + "busy_seconds": 0, + "unreachable_seconds": 0, + "declined_seconds": 0 + }, + "recording": { + "always_record_outbound": true, + "agents_may_delete": true, + "hide_recording_controls": true + } +} +``` + +
+ +--- + +### `getQueuePerformance` + +Inbound call outcomes per queue for a period, derived from the provider's call reporting (the +phone system has no per-queue report): every inbound call that started in [from, to) is counted +for the qu + +`GET /v1/manager/reporting/queues` + +```ts +const { data } = await client.getQueuePerformance({ + from: 'example', + to: 'example', +}) +``` + +
+Response + +```json +{ + "from": "1970-01-01T00:00:00.000Z", + "to": "1970-01-01T00:00:00.000Z", + "results": [ + { + "queue": { + "id": "string", + "name": "string" + }, + "inbound_total": 0, + "handled_by_agent": 0, + "abandoned_or_failed": 0, + "abandon_rate_percent": 0, + "average_wait_seconds": 0 + } + ] +} +``` + +
+ +--- + +### `listSkills` + +The organization's skill catalogue: the skills epilot keeps for it (created in the control +center, `source: epilot`) together with every skill the phone system already uses on an agent or +in a queue's + +`GET /v1/manager/skills` + +```ts +const { data } = await client.listSkills() +``` + +
+Response + +```json +{ + "results": [ + { + "tag": "string", + "source": "epilot", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string" + } + ] +} +``` + +
+ +--- + +### `createSkill` + +Adds a skill to the organization's catalogue (epilot only: nothing is written to the phone +system until an agent gets the skill or a queue accepts it). The skill is trimmed, must then be +1 to 100 char + +`POST /v1/manager/skills` + +```ts +const { data } = await client.createSkill( + null, + { + tag: 'string' + }, +) +``` + +
+Response + +```json +{ + "tag": "string", + "source": "epilot", + "created_at": "1970-01-01T00:00:00.000Z", + "created_by": "string" +} +``` + +
+ +--- + +### `deleteSkill` + +Deletes a skill everywhere (in any letter case, see `Skill`): it is taken from every agent that has it and from every routing step +of every queue that accepts it in the phone system, then removed from + +`DELETE /v1/manager/skills/{tag}` + +```ts +const { data } = await client.deleteSkill({ + tag: 'example', +}) +``` + +
+Response + +```json +{ + "tag": "string", + "agents_updated": 0, + "queues_updated": 0 +} +``` + +
+ +--- + +### `setQueueSkill` + +The queue accepts the skill: every agent with it can take the queue's calls. epilot adds the +skill to the queue's FIRST enabled routing step of the organization's own in the phone system +(lowest order + +`PUT /v1/manager/queues/{queue_id}/skills/{tag}` + +```ts +const { data } = await client.setQueueSkill({ + queue_id: 'example', + tag: 'example', +}) +``` + +
+Response + +```json +{ + "queue": { + "id": "string", + "name": "string" + }, + "tag": "string", + "accepted": true, + "step": { + "id": "string", + "label": "string" + } +} +``` + +
+ +--- + +### `removeQueueSkill` + +The queue no longer accepts the skill: it is removed from every routing step of the queue that +lists it (enabled or not). Idempotent. Requires `phone:manage`. + +`DELETE /v1/manager/queues/{queue_id}/skills/{tag}` + +```ts +const { data } = await client.removeQueueSkill({ + queue_id: 'example', + tag: 'example', +}) +``` + +
+Response + +```json +{ + "queue": { + "id": "string", + "name": "string" + }, + "tag": "string", + "accepted": true, + "step": { + "id": "string", + "label": "string" + } +} +``` + +
+ +--- + +### `listProviderSetups` + +Every organization that has a telephony provider tenant, for the admin portal's overview: the +provider's sub-accounts (one per organization, keyed by the organization id) joined with this +service's se + +`GET /v1/operator/provider-setups` + +```ts +const { data } = await client.listProviderSetups() +``` + +
+Response + +```json +{ + "results": [ + { + "org_id": "string", + "provider": "babelforce", + "ready": true, + "setup_recorded": true, + "tenant": { + "id": "string", + "name": "string", + "org_key": "string" + }, + "sso_identity_client_id": "string", + "last_setup_by": "string", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `getProviderSetup` + +What has been set up at the telephony provider for this organization. + +`GET /v1/operator/organizations/{org_id}/provider` + +```ts +const { data } = await client.getProviderSetup({ + org_id: 'example', +}) +``` + +
+Response + +```json +{ + "provider": "babelforce", + "org_id": "string", + "ready": true, + "tenant": { + "id": "string", + "name": "string", + "org_key": "string", + "created_at": "1970-01-01T00:00:00.000Z" + }, + "scim": { + "configured": true, + "roles_enabled": true + }, + "sso": { + "configured": true, + "identity_client_id": "string", + "configured_at": "1970-01-01T00:00:00.000Z" + }, + "last_setup_by": "string" +} +``` + +
+ +--- + +### `setupProvider` + +Prepares the telephony provider for an organization, idempotently and in order: the provider +tenant (Babelforce sub-account keyed by the organization id), its SCIM configuration with role +management o + +`POST /v1/operator/organizations/{org_id}/provider:setup` + +```ts +const { data } = await client.setupProvider( + { + org_id: 'example', + }, + { + account_name: 'string', + identity_client_id: 'string', + identity_client_secret: 'stringstring' + }, +) +``` + +
+Response + +```json +{ + "provider": "babelforce", + "org_id": "string", + "ready": true, + "tenant": { + "id": "string", + "name": "string", + "org_key": "string", + "created_at": "1970-01-01T00:00:00.000Z" + }, + "scim": { + "configured": true, + "roles_enabled": true + }, + "sso": { + "configured": true, + "identity_client_id": "string", + "configured_at": "1970-01-01T00:00:00.000Z" + }, + "last_setup_by": "string" +} +``` + +
+ +--- + +## Schemas + +### `ManagerStatus` + +```ts +type ManagerStatus = { + provider: "babelforce" + ready: boolean + reasons: "provider_tenant_missing" | "sso_not_configured" | "scim_not_configured" | "identity_enablement_missing"[] +} +``` + +### `PhoneAgent` + +```ts +type PhoneAgent = { + user_id: string + email: string + display_name?: string + status: "active" | "pending" | "disabled" | "missing_provider" | "missing_role" + provider_user_id?: string + provider_roles?: string[] + assigned_at?: string // date-time + assigned_by?: string +} +``` + +### `AssignPhoneAgentRequest` + +```ts +type AssignPhoneAgentRequest = { + user_id: string +} +``` + +### `ProviderSetup` + +```ts +type ProviderSetup = { + provider: "babelforce" + org_id: string + ready: boolean + tenant: { + id: string + name: string + org_key: string + created_at?: string // date-time + } + scim: { + configured: boolean + roles_enabled: boolean + } + sso: { + configured: boolean + identity_client_id?: string + configured_at?: string // date-time + } + last_setup_by?: string +} +``` + +### `ProviderSetupSummary` + +One organization's provider setup, as listed in the overview (no live SCIM or SSO reads). + +```ts +type ProviderSetupSummary = { + org_id: string + provider: "babelforce" + ready: boolean + setup_recorded: boolean + tenant: { + id: string + name: string + org_key: string + } + sso_identity_client_id?: string + last_setup_by?: string + updated_at?: string // date-time +} +``` + +### `ProviderSetupRequest` + +```ts +type ProviderSetupRequest = { + account_name?: string + identity_client_id: string + identity_client_secret: string +} +``` + +### `CustomerBatchSearchResult` + +```ts +type CustomerBatchSearchResult = { + results: Array<{ + identifier: { + type: { ... } + value: { ... } + } + status: "found" | "not_found" | "ambiguous" | "invalid" | "error" + customer?: { + id: { ... } + name: { ... } + customer_number?: { ... } + } + }> +} +``` + +### `CustomerSearchResult` + +```ts +type CustomerSearchResult = { + identifier: { + type: "id" | "customer_number" | "external_id" | "phone_number" | "email" + value: string + } + status: "found" | "not_found" | "ambiguous" | "invalid" | "error" + customer?: { + id: string + name: string + customer_number?: string + } +} +``` + +### `CustomerIdentifier` + +```ts +type CustomerIdentifier = { + type: "id" | "customer_number" | "external_id" | "phone_number" | "email" + value: string +} +``` + +### `CustomerSummary` + +Present when `status` is `found` + +```ts +type CustomerSummary = { + id: string + name: string + customer_number?: string +} +``` + +### `ActiveCall` + +The phone call a user is on right now. + +```ts +type ActiveCall = { + on_call: boolean + conversation_id?: string + started_at?: string // date-time + source?: "softphone" | "provider" + expires_at?: string // date-time +} +``` + +### `ActiveCallReport` + +```ts +type ActiveCallReport = { + conversation_id: string + started_at?: string +} +``` + +### `AgentState` + +The agent's live line state as the provider reports it, plus `busy` for anyone who cannot take a +queue call for a reason other than a call: on a presence that takes no calls (e.g. Busy, Break), +without a presence, or disabled at the provider; `busy` also covers the provider's busy line +state. `unkno + +```ts +type AgentState = "available" | "ringing" | "in_call" | "wrap_up" | "busy" | "declined" | "unreachable" | "selected" | "offline" | "unknown" +``` + +### `AgentPresence` + +The provider presence the agent has selected (e.g. Available, Break, Meeting) + +```ts +type AgentPresence = { + name: string + label: string + available: boolean +} +``` + +### `AgentPresenceRequest` + +```ts +type AgentPresenceRequest = { + presence: string +} +``` + +### `AgentPresenceChange` + +```ts +type AgentPresenceChange = { + provider_agent_id: string + presence: { + name: string + label: string + available: boolean + } +} +``` + +### `Skill` + +A skill as the phone system holds it (Babelforce: an agent tag). epilot's convention for skills is +`:`
+ +--- + +### `$getConditionSets` + +Returns the condition sets built in for one conditional entity type, ready to copy into that schema's `conditions` array. Read-only, and the same for every organization. + +`GET /v1/conditional-pricing/{slug}/condition-sets` + +```ts +const { data } = await client.$getConditionSets({ + slug: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "delivery_area", + "label": "Delivery Area", + "description": "string", + "conditions": [ + { + "id": "d5839b94-ba20-4225-a78e-76951d352bd6", + "name": "postal_code", + "label": "Postal Code", + "type": "string", + "options": [ + "private", { - "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" + "value": "commercial", + "title": "Commercial customers" } - ] + ], + "format": "postal_code" + } + ] + } + ] +} +``` + +
+ +--- + +### `$getConditionUsage` + +Returns, for each condition the schema declares and each option a `select` condition +declares, how many variants pin it, and for the schema as a whole how many conditional +entities and variants it has + +`GET /v1/conditional-pricing/{slug}/conditions:usage` + +```ts +const { data } = await client.$getConditionUsage({ + slug: 'example', +}) +``` + +
+Response + +```json +{ + "total": { + "variants": 1252, + "entities": 38 + }, + "conditions": [ + { + "name": "delivery_area", + "variants": 1240, + "entities": 37 + }, + { + "name": "customer_type", + "variants": 12, + "entities": 3, + "options": [ + { + "value": "private", + "variants": 12 }, - "_org": "728", - "_created_at": "2022-06-03T16:04:10.369Z", - "_updated_at": "2022-06-03T16:04:10.369Z", - "pricing_model": "per_unit" - }, - "_product": { - "name": "Cool box", - "type": "product", - "_id": "73f857a4-0fbc-4aa6-983f-87c0d6d410a6", - "_title": "Cool box" - } + { + "value": "business", + "variants": 0 + } + ], + "undeclared_options": [] + } + ], + "undeclared": [ + { + "name": "legacy_customer_type", + "type": "select", + "variants": 1, + "entities": 1, + "options": [ + { + "value": "private", + "variants": 1 + } + ] } ] } @@ -1736,30 +2101,2758 @@ const { data } = await client.$productRecommendations( --- -## Schemas +### `$getConditionalPricingOrganization` -### `IntegrationId` +Returns whether the calling organization has Conditional Pricing on, whether its search +collection is ready or still being deleted, and, once it is on, whether it is in use. While it +is in use, or whi + +`GET /v1/conditional-pricing/organization` ```ts -type IntegrationId = "getag" | "external-catalog" +const { data } = await client.$getConditionalPricingOrganization() ``` -### `Error` +
+Response + +```json +{ + "status": "NOT_ENABLED" +} +``` + +
+ +--- + +### `$resolveConditionalEntity` + +Returns the variants of one conditional entity that apply, each composed: the base entity +overlaid with the version in effect at `as_of`. + +`POST /v1/conditional-pricing:resolve` ```ts -type Error = { - message: string - status?: number - cause?: string +const { data } = await client.$resolveConditionalEntity( + null, + { + schema: 'product', + entity_id: 'price-sp26d1yo', + context: { + postal_code: '46045', + consumption: { + lt: 5000 + } + }, + as_of: '2027-03-15T00:00:00Z', + options: { + resolve_one: false, + hydrate: false + } + }, +) +``` + +
+Response + +```json +{ + "results": [ + { + "_id": "price-sp26d1yo", + "_variant_id": "var-46045", + "_version_valid_from": "2027-01-01", + "_conditions": { + "postal_code": "46045", + "default": false + }, + "_inert_overrides": [ + { + "attribute": "unit_amount", + "reason": "ATTRIBUTE_NOT_OVERRIDABLE" + } + ] + } + ] } ``` -### `Product` +
+ +--- + +### `$createConditionalVariant` -The product entity +Creates one variant together with its first version. + +`POST /v1/conditional-pricing/{slug}/entities/{entity_id}/variants` ```ts -type Product = { +const { data } = await client.$createConditionalVariant( + { + slug: 'example', + entity_id: 'example', + }, + { + conditions: { + postal_code: '46045' + }, + default: false, + valid_from: '2027-01-01', + values: { + unit_amount: 2499, + unit_amount_decimal: '24.99' + } + }, +) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 0, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$listConditionalVariants` + +Lists a conditional entity's variants and the conditions each one pins. A `POST` because the +condition filter is a structured object; nothing is written. The body is required, so send +`{}` for the fir + +`POST /v1/conditional-pricing/{slug}/entities/{entity_id}/variants:list` + +```ts +const { data } = await client.$listConditionalVariants( + { + slug: 'example', + entity_id: 'example', + }, + { + conditions: { + postal_code: '46045', + consumption: { + lt: 5000 + } + }, + search: '460', + sort: 'conditions.postal_code:asc', + from: 0, + size: 10, + cursor: 'eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0' + }, +) +``` + +
+Response + +```json +{ + "hits": 8128, + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + } + } + ], + "next": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" +} +``` + +
+ +--- + +### `$getConditionalVariantTree` + +The variants list, each row carrying the version in effect at `as_of` and a `status` saying +whether that version is `active` or still `scheduled`. + +`POST /v1/conditional-pricing/{slug}/entities/{entity_id}/variants:tree` + +```ts +const { data } = await client.$getConditionalVariantTree( + { + slug: 'example', + entity_id: 'example', + }, + { + conditions: { + postal_code: '46045', + consumption: { + lt: 5000 + } + }, + search: '460', + sort: 'conditions.postal_code:asc', + from: 0, + size: 10, + cursor: 'eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0', + as_of: '2027-03-15T00:00:00Z' + }, +) +``` + +
+Response + +```json +{ + "hits": 8128, + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "status": "active", + "version": { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string" + } + } + ], + "next": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" +} +``` + +
+ +--- + +### `$getActiveConditionalVariantVersion` + +Returns the version of this variant in effect today in the organization's timezone — the +latest `valid_from` on or before today — with the `_revision` a write to it must carry. + +`GET /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}` + +```ts +const { data } = await client.$getActiveConditionalVariantVersion({ + slug: 'example', + entity_id: 'example', + variant_id: 'example', +}) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3 +} +``` + +
+ +--- + +### `$replaceActiveConditionalVariantVersion` + +Replaces the values of the version in effect. The body is the complete set of overrides: an +overridable attribute absent from it stops being overridden, and one the variant may not +override keeps its + +`PUT /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}` + +```ts +const { data } = await client.$replaceActiveConditionalVariantVersion( + { + slug: 'example', + entity_id: 'example', + variant_id: 'example', + }, + { + values: { + unit_amount: 2499, + unit_amount_decimal: '24.99' + }, + _revision: 3, + valid_from: '1970-01-01', + conditions: { + postal_code: '46045' + } + }, +) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$patchActiveConditionalVariantVersion` + +Changes only the fields it names on the version in effect. `null` sets a value rather than +removing an override; use the replace operation to remove one. + +`PATCH /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}` + +```ts +const { data } = await client.$patchActiveConditionalVariantVersion( + { + slug: 'example', + entity_id: 'example', + variant_id: 'example', + }, + { + values: { + unit_amount: 2499, + unit_amount_decimal: '24.99' + }, + _revision: 3, + valid_from: '1970-01-01', + conditions: { + postal_code: '46045' + } + }, +) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$deleteConditionalVariant` + +Removes one variant: its condition tuple, its index entry and all its versions. The tuple +becomes reusable, and an interrupted delete is safe to send again. + +`DELETE /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}` + +```ts +const { data } = await client.$deleteConditionalVariant({ + slug: 'example', + entity_id: 'example', + variant_id: 'example', +}) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "tuple_released": true, + "versions_deleted": 0 +} +``` + +
+ +--- + +### `$listConditionalVariantVersions` + +Lists one variant's versions. Cursor paging only: a page may be short or empty and still +carry a `next`, so page until `next` is absent. A cursor is bound to one variant and one +`order`. + +`GET /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions` + +```ts +const { data } = await client.$listConditionalVariantVersions({ + slug: 'example', + entity_id: 'example', + variant_id: 'example', + limit: 1, + order: 'example', + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string" + } + ], + "next": "eyJzayI6IlYjcHJpY2Utc3AyNmQxeW8jdmFyLTQ2MDQ1IzIwMjYtMDEtMDFUMDA6MDA6MDAuMDAwWiIsIm9yZGVyIjoiYXNjIn0" +} +``` + +
+ +--- + +### `$appendConditionalVariantVersion` + +Appends a version taking effect on its own date. A variant has at most one version per +day. The version in effect at any `as_of` is the one with the latest `valid_from` on or +before its date in the or + +`POST /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions` + +```ts +const { data } = await client.$appendConditionalVariantVersion( + { + slug: 'example', + entity_id: 'example', + variant_id: 'example', + }, + { + valid_from: '2027-01-01', + values: { + unit_amount: 2499, + unit_amount_decimal: '24.99' + }, + conditions: { + postal_code: '46045' + } + }, +) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$getConditionalVariantVersion` + +Returns one version by the date it takes effect. Exact, never nearest. + +`GET /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}` + +```ts +const { data } = await client.$getConditionalVariantVersion({ + slug: 'example', + entity_id: 'example', + variant_id: 'example', + valid_from: 'example', +}) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3 +} +``` + +
+ +--- + +### `$replaceConditionalVariantVersion` + +Replaces one version's values, whatever its date. Attributes the variant may not override +keep their stored value. Writing a superseded version is reported in `warnings`. + +`PUT /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}` + +```ts +const { data } = await client.$replaceConditionalVariantVersion( + { + slug: 'example', + entity_id: 'example', + variant_id: 'example', + valid_from: 'example', + }, + { + values: { + unit_amount: 2499, + unit_amount_decimal: '24.99' + }, + _revision: 3, + valid_from: '1970-01-01', + conditions: { + postal_code: '46045' + } + }, +) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$patchConditionalVariantVersion` + +Changes only the fields it names on one version. + +`PATCH /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}` + +```ts +const { data } = await client.$patchConditionalVariantVersion( + { + slug: 'example', + entity_id: 'example', + variant_id: 'example', + valid_from: 'example', + }, + { + values: { + unit_amount: 2499, + unit_amount_decimal: '24.99' + }, + _revision: 3, + valid_from: '1970-01-01', + conditions: { + postal_code: '46045' + } + }, +) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01", + "values": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + }, + "_created_at": "string", + "_updated_at": "string", + "_revision": 3, + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$deleteConditionalVariantVersion` + +Removes one version. What the removal moves is reported in `warnings`. A variant's last +remaining version cannot be removed — delete the variant instead. + +`DELETE /v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}` + +```ts +const { data } = await client.$deleteConditionalVariantVersion({ + slug: 'example', + entity_id: 'example', + variant_id: 'example', + valid_from: 'example', + _revision: 1, +}) +``` + +
+Response + +```json +{ + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "product", + "valid_from": "2027-01-01", + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ] +} +``` + +
+ +--- + +### `$batchUpsertConditionalVariants` + +Writes up to 100 variants or versions in one call. Each item names its own entity, so one +call can span a tariff hierarchy, and addresses a variant by condition tuple rather than by +id — the id it cre + +`POST /v1/conditional-pricing/{slug}/variants:batchUpsert` + +```ts +const { data } = await client.$batchUpsertConditionalVariants( + { + slug: 'example', + }, + { + correlation_id: 'tariff-refresh-2027-01', + items: [ + { + entity_id: 'price-sp26d1yo', + conditions: { + postal_code: '46045' + }, + default: false, + valid_from: '2027-01-01', + values: { + unit_amount: 2499, + unit_amount_decimal: '24.99' + } + } + ] + }, +) +``` + +
+Response + +```json +{ + "correlation_id": "tariff-refresh-2027-01", + "counts": { + "variant_created": 1, + "version_created": 1, + "updated": 1, + "skipped": 1, + "error": 1 + }, + "results": [ + { + "outcome": "variant_created", + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045", + "valid_from": "2027-01-01", + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ], + "error": { + "code": "SCHEMA_NOT_FOUND", + "details": { + "schema": "price" + } + } + } + ] +} +``` + +
+ +--- + +### `$batchDeleteConditionalVariants` + +Removes up to 100 variants or versions in one call. An item carrying `valid_from` removes +that version; one without it removes the whole variant. + +`POST /v1/conditional-pricing/{slug}/variants:batchDelete` + +```ts +const { data } = await client.$batchDeleteConditionalVariants( + { + slug: 'example', + }, + { + correlation_id: 'postal-code-cleanup-2026-09', + items: [ + { + entity_id: 'price-sp26d1yo', + variant_id: 'var-46045', + valid_from: '2027-01-01' + } + ] + }, +) +``` + +
+Response + +```json +{ + "correlation_id": "postal-code-cleanup-2026-09", + "counts": { + "deleted": 1, + "skipped": 1, + "error": 1 + }, + "results": [ + { + "outcome": "deleted", + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045", + "valid_from": "2027-01-01", + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "string", + "details": { + "variant_count": 0, + "cap": 0 + } + } + ], + "error": { + "code": "SCHEMA_NOT_FOUND", + "details": { + "schema": "price" + } + } + } + ] +} +``` + +
+ +--- + +## Schemas + +### `IntegrationId` + +```ts +type IntegrationId = "getag" | "external-catalog" +``` + +### `ConditionalEntitySlug` + +Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. + +```ts +type ConditionalEntitySlug = "product" | "price" | "coupon" +``` + +### `ConditionType` + +The kind of value a condition holds, which decides how a pinned value is matched against a +resolve context. + +- `string`: an arbitrary string, matched exactly and case-sensitively +- `number`: a numeric value +- `date`: a single date +- `daterange`: a window from a `from` to an `until`, both included; e + +```ts +type ConditionType = "string" | "number" | "date" | "daterange" | "boolean" | "select" | "location" +``` + +### `LocationFormat` + +The value shape of a `location` condition. Absent for every other type. + +- `postal_code`: a postal code +- `postal_code_city`: a postal code and a city +- `power_grid_operator`: the code number of the power grid operator an address is connected to +- `gas_grid_operator`: the code number of the gas grid + +```ts +type LocationFormat = "postal_code" | "postal_code_city" | "power_grid_operator" | "gas_grid_operator" +``` + +### `ConditionDefinition` + +One condition dimension, in the shape a schema's `conditions` array holds it — copy it in verbatim. + +```ts +type ConditionDefinition = { + id: string // uuid + name: string + label: string + type: "string" | "number" | "date" | "daterange" | "boolean" | "select" | "location" + options?: Array + format?: "postal_code" | "postal_code_city" | "power_grid_operator" | "gas_grid_operator" +} +``` + +### `ConditionSet` + +A named bundle of condition definitions, built in for one entity type. + +```ts +type ConditionSet = { + id: string + label: string + description: string + conditions: Array<{ + id: string // uuid + name: string + label: string + type: "string" | "number" | "date" | "daterange" | "boolean" | "select" | "location" + options?: Array + format?: "postal_code" | "postal_code_city" | "power_grid_operator" | "gas_grid_operator" + }> +} +``` + +### `ConditionSetCatalog` + +```ts +type ConditionSetCatalog = { + results: Array<{ + id: string + label: string + description: string + conditions: Array<{ + id: { ... } + name: { ... } + label: { ... } + type: { ... } + options?: { ... } + format?: { ... } + }> + }> +} +``` + +### `ConditionalPricingOptIn` + +```ts +type ConditionalPricingOptIn = { + status: "PROVISIONING" | "ACTIVE" +} +``` + +### `ConditionUsage` + +```ts +type ConditionUsage = { + total: { + variants: number + entities: number + } + conditions: Array<{ + name: string + variants: number + entities: number + options?: Array<{ + value: { ... } + variants: { ... } + }> + undeclared_options?: Array<{ + value: { ... } + variants: { ... } + }> + }> + undeclared: Array<{ + name: string + type: "string" | "number" | "date" | "daterange" | "boolean" | "select" | "location" + format?: "postal_code" | "postal_code_city" | "power_grid_operator" | "gas_grid_operator" + variants: number + entities: number + options?: Array<{ + value: { ... } + variants: { ... } + }> + }> +} +``` + +### `DeclaredConditionUsage` + +A `select` condition always carries `options` and `undeclared_options`. A condition of any +other type carries neither. + + +```ts +type DeclaredConditionUsage = { + name: string + variants: number + entities: number + options?: Array<{ + value: string + variants: number + }> + undeclared_options?: Array<{ + value: string + variants: number + }> +} +``` + +### `UndeclaredConditionUsage` + +A condition variants pin under this name and type that the schema does not declare. A name +pinned under two types is listed once for each. + + +```ts +type UndeclaredConditionUsage = { + name: string + type: "string" | "number" | "date" | "daterange" | "boolean" | "select" | "location" + format?: "postal_code" | "postal_code_city" | "power_grid_operator" | "gas_grid_operator" + variants: number + entities: number + options?: Array<{ + value: string + variants: number + }> +} +``` + +### `ConditionOptionUsage` + +```ts +type ConditionOptionUsage = { + value: string + variants: number +} +``` + +### `ConditionalPricingOrganization` + +```ts +type ConditionalPricingOrganization = { + status: "NOT_ENABLED" | "DEPROVISIONING" +} | { + status: "PROVISIONING" | "ACTIVE" + in_use: boolean +} +``` + +### `ConditionalPricingErrorCode` + +Machine-readable failure mode of a conditional-pricing operation, so a client can branch on +the kind of failure instead of parsing the message. A `400` is about the request; a `409` is +about what is already stored. Refusals raised by request validation carry no `code` at all. + +- `SCHEMA_NOT_FOUND` ( + +```ts +type ConditionalPricingErrorCode = "SCHEMA_NOT_FOUND" | "ENTITY_NOT_FOUND" | "ENTITY_TYPE_MISMATCH" | "ENTITY_SOFT_DELETED" | "ENTITY_NOT_CONDITIONAL" | "VARIANT_NOT_FOUND" | "VERSION_NOT_FOUND" | "NO_MATCHES" | "NO_ACTIVE_VERSION" | "AMBIGUOUS_RESOLUTION" | "TUPLE_CONFLICT" | "VERSION_CONFLICT" | "CONDITION_UNDEFINED" | "VARIANT_PIN_UNDECLARED" | "OPERATOR_UNSUPPORTED" | "CONTEXT_FORMAT_INVALID" | "CONDITION_VALUE_INVALID" | "CONDITION_UNCONFIGURED" | "TOO_MANY_MATCHES" | "WRITE_CONFLICT" | "OFFSET_WINDOW_EXCEEDED" | "CURSOR_INVALID" | "VARIANT_LIMIT_REACHED" | "PIN_FORMAT_INVALID" | "VARIANT_UNPINNED" | "LAST_VERSION_UNDELETABLE" | "CONDITION_UNREADABLE" | "SORT_INVALID" | "DEFAULT_MARKER_RESERVED" | "DEFAULT_VARIANT_PINS_CONDITIONS" | "VALID_FROM_IMMUTABLE" | "VARIANT_CONDITIONS_IMMUTABLE" | "IDENTIFIER_INVALID" | "VALID_FROM_INVALID" | "VALUE_UNSTORABLE" | "OVERRIDE_VALUE_INVALID" | "CONDITIONAL_PRICING_NOT_ENABLED" | "CONDITIONAL_PRICING_NOT_READY" | "CONDITIONAL_PRICING_IN_USE" | "CONDITIONAL_PRICING_OPT_OUT_IN_PROGRESS" | "CONDITIONAL_PRICING_OPT_IN_IN_PROGRESS" +``` + +### `ResolveConditionalEntityRequest` + +A resolve names one conditional entity and selects its variants either by `context` or by +`variant_id`, never both. `context: {}` matches nothing and so returns the `default` +variant, which is how to ask for it without knowing its id. + + +```ts +type ResolveConditionalEntityRequest = { + schema: "product" | "price" | "coupon" + entity_id: string + context: Record + as_of?: string + options?: { + resolve_one?: boolean + hydrate?: boolean + } +} | { + schema: "product" | "price" | "coupon" + entity_id: string + variant_id: string + as_of?: string + options?: { + hydrate?: boolean + } +} +``` + +### `ResolveByContextRequest` + +Resolve by matching a situation: which of this entity's variants apply to `context`, each +composed with the version in effect at `as_of`. + + +```ts +type ResolveByContextRequest = { + schema: "product" | "price" | "coupon" + entity_id: string + context: Record + as_of?: string + options?: { + resolve_one?: boolean + hydrate?: boolean + } +} +``` + +### `ResolveByPinRequest` + +Resolve by naming a variant: compose this one, whatever a context would have matched. + +```ts +type ResolveByPinRequest = { + schema: "product" | "price" | "coupon" + entity_id: string + variant_id: string + as_of?: string + options?: { + hydrate?: boolean + } +} +``` + +### `ResolveContext` + +The situation to resolve for: a flat map keyed by condition name. A condition left out +matches only variants that leave it unpinned; an empty map therefore returns the `default` +variant. A key naming no condition the schema declares is ignored, as if it were left out. + +Each value is an exact value, + +```ts +type ResolveContext = Record +``` + +### `ResolveOptions` + +The options a context resolve accepts. A pin takes `PinnedResolveOptions` instead. + +```ts +type ResolveOptions = { + resolve_one?: boolean + hydrate?: boolean +} +``` + +### `PinnedResolveOptions` + +The options a pinned resolve accepts — `hydrate` and nothing else. `resolve_one` has nothing +to change where the answer is one result or a 404, so a body sending it is a `400`. + + +```ts +type PinnedResolveOptions = { + hydrate?: boolean +} +``` + +### `ResolvedVariants` + +```ts +type ResolvedVariants = { + results: Array<{ + _id: string + _variant_id: string + _version_valid_from: string // date + _conditions: { + default: { ... } + } + _inert_overrides: Array<{ + attribute: { ... } + reason: { ... } + }> + }> +} +``` + +### `ResolvedVariant` + +The entity as this variant leaves it — every attribute of a plain entity read with the +applicable version's overrides applied — plus the discriminators below. + + +```ts +type ResolvedVariant = { + _id: string + _variant_id: string + _version_valid_from: string // date + _conditions: { + default: boolean + } + _inert_overrides: Array<{ + attribute: string + reason: "ATTRIBUTE_NOT_OVERRIDABLE" | "ATTRIBUTE_READONLY" | "ATTRIBUTE_HIDDEN" | "ATTRIBUTE_COMPUTED" | "ATTRIBUTE_UNDECLARED" | "TYPE_NOT_OVERRIDABLE" | "CAPABILITY_NOT_OVERRIDABLE" + }> +} +``` + +### `CreateVariantRequest` + +```ts +type CreateVariantRequest = { + conditions?: Record + default?: boolean + valid_from?: string // date + values: Record +} +``` + +### `VariantConditions` + +A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a +boolean `default` saying whether this is the entity's fallback. + + +```ts +type VariantConditions = { + default: boolean +} +``` + +### `PinnedConditions` + +The situation this variant applies to: a flat map keyed by condition name. A condition left +out is a wildcard, which is what makes adding a condition to a schema non-breaking for +existing variants. + +Exact values only; predicates belong to reads. Values are stored canonicalized for their +type: a `dat + +```ts +type PinnedConditions = Record +``` + +### `PinnedConditionValue` + +One condition's exact value. Which of these shapes a condition takes is set by its type in the +entity's schema, and a value of another shape is refused with `PIN_FORMAT_INVALID`. A +`location` of format `power_grid_operator` or `gas_grid_operator` takes a string of exactly +13 digits. + + +```ts +type PinnedConditionValue = string | number | boolean | { + from?: string + until?: string +} | { + postal_code: string + city: string +} +``` + +### `PostalCodeFilter` + +A listing filter on a `location` of format `postal_code_city` by its postal code alone: it +matches the variants pinned to that postal code, whatever their city. Only a listing filter +takes it; a resolve context must name the city too. + + +```ts +type PostalCodeFilter = { + postal_code: string +} +``` + +### `ConditionDateRange` + +The value of a `daterange` condition. Each bound is an RFC 3339 date or date-time, and both +are included. A date names the whole day in the organization's timezone: as `from` it starts +at midnight, as `until` it runs to the day's last millisecond. So +`{ "from": "2026-10-01", "until": "2026-10-31" }` + +```ts +type ConditionDateRange = { + from?: string + until?: string +} +``` + +### `PostalCodeCity` + +The value of a `location` condition of format `postal_code_city`, its parts named as an entity +address names them. + + +```ts +type PostalCodeCity = { + postal_code: string + city: string +} +``` + +### `ContextConditionValue` + +One condition's value in a resolve context or listing filter: an exact value, or a predicate. +Which of these a condition takes is set by its type in the entity's schema, and a value of +another shape is refused with `CONTEXT_FORMAT_INVALID`, or `OPERATOR_UNSUPPORTED` for a +predicate its type does not + +```ts +type ContextConditionValue = string | number | boolean | { + postal_code: string + city: string +} | { + lt: number | string +} | { + lte: number | string +} | { + gt: number | string +} | { + gte: number | string +} | { + in: string | number[] +} | { + between: string +} | { + exists: boolean +} +``` + +### `ConditionPredicate` + +A single-operator predicate. + +```ts +type ConditionPredicate = { + lt: number | string +} | { + lte: number | string +} | { + gt: number | string +} | { + gte: number | string +} | { + in: string | number[] +} | { + between: string +} | { + exists: boolean +} +``` + +### `OrderedConditionOperand` + +A number, or a date as an RFC 3339 date or date-time. A date is midnight of that day in the +organization's timezone. + + +```ts +type OrderedConditionOperand = number | string +``` + +### `VariantValues` + +The values this version overrides on the base entity, keyed by entity field name. + +A field is overridable if its attribute declares `overridable_attribute` — which readonly, +hidden, computed and metadata fields, and types no variant may override, cannot be given — +or if a capability declaring `overr + +```ts +type VariantValues = Record +``` + +### `CreatedVariant` + +```ts +type CreatedVariant = { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: boolean + } + valid_from: string // date + values: Record + _created_at: string + _updated_at: string + _revision: number + warnings: Array<{ + code: "VARIANT_COUNT_APPROACHING_CAP" + message: string + details: { + variant_count: { ... } + cap: { ... } + } + } | { + code: "ACTIVE_VERSION_CHANGED" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "SUPERSEDED_VERSION_WRITTEN" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "ATTRIBUTES_NOT_APPLIED" + message: string + details: { + attributes: { ... } + } + } | { + code: "VARIANT_NOT_INDEXED" + message: string + details: { + reason: { ... } + } + }> +} +``` + +### `WriteWarning` + +Something worth knowing that did not stop a write. One vocabulary for every write; `details` +is typed per `code`, and a write raises each code at most once. + + +```ts +type WriteWarning = { + code: "VARIANT_COUNT_APPROACHING_CAP" + message: string + details: { + variant_count: number + cap: number + } +} | { + code: "ACTIVE_VERSION_CHANGED" + message: string + details: { + valid_from: string // date + active_valid_from?: string // date + } +} | { + code: "SUPERSEDED_VERSION_WRITTEN" + message: string + details: { + valid_from: string // date + active_valid_from?: string // date + } +} | { + code: "ATTRIBUTES_NOT_APPLIED" + message: string + details: { + attributes: Array<{ + attribute: { ... } + reason: { ... } + }> + } +} | { + code: "VARIANT_NOT_INDEXED" + message: string + details: { + reason: "INDEX_WRITE_FAILED" + } +} +``` + +### `VersionMoved` + +Which version a write moved, and which one was in effect while it did. + +```ts +type VersionMoved = { + valid_from: string // date + active_valid_from?: string // date +} +``` + +### `InertOverride` + +One override that did not apply, and why — reported by a write for the attributes in its +body, and by a resolved payload for the stored overrides composition passed over. + + +```ts +type InertOverride = { + attribute: string + reason: "ATTRIBUTE_NOT_OVERRIDABLE" | "ATTRIBUTE_READONLY" | "ATTRIBUTE_HIDDEN" | "ATTRIBUTE_COMPUTED" | "ATTRIBUTE_UNDECLARED" | "TYPE_NOT_OVERRIDABLE" | "CAPABILITY_NOT_OVERRIDABLE" +} +``` + +### `InertOverrideReason` + +Why one override did not apply. + +- `ATTRIBUTE_NOT_OVERRIDABLE`: the schema declares the attribute without + `overridable_attribute`, which is an ordinary schema edit away +- `ATTRIBUTE_READONLY`: the attribute is readonly, and cannot be granted the flag +- `ATTRIBUTE_HIDDEN`: the attribute is hidden, + +```ts +type InertOverrideReason = "ATTRIBUTE_NOT_OVERRIDABLE" | "ATTRIBUTE_READONLY" | "ATTRIBUTE_HIDDEN" | "ATTRIBUTE_COMPUTED" | "ATTRIBUTE_UNDECLARED" | "TYPE_NOT_OVERRIDABLE" | "CAPABILITY_NOT_OVERRIDABLE" +``` + +### `DeletedVariant` + +```ts +type DeletedVariant = { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + tuple_released: boolean + versions_deleted: number +} +``` + +### `VariantVersion` + +One version of one variant: the overrides it carries, the date it takes effect, and the +variant it belongs to. These are the version's own overrides; `:resolve` composes them onto +the entity. + + +```ts +type VariantVersion = { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: boolean + } + valid_from: string // date + values: Record + _created_at: string + _updated_at: string + _revision: number +} +``` + +### `WrittenVariantVersion` + +A version as a write left it, together with anything the write moved. + +```ts +type WrittenVariantVersion = { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: boolean + } + valid_from: string // date + values: Record + _created_at: string + _updated_at: string + _revision: number + warnings: Array<{ + code: "VARIANT_COUNT_APPROACHING_CAP" + message: string + details: { + variant_count: { ... } + cap: { ... } + } + } | { + code: "ACTIVE_VERSION_CHANGED" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "SUPERSEDED_VERSION_WRITTEN" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "ATTRIBUTES_NOT_APPLIED" + message: string + details: { + attributes: { ... } + } + } | { + code: "VARIANT_NOT_INDEXED" + message: string + details: { + reason: { ... } + } + }> +} +``` + +### `DeletedVariantVersion` + +```ts +type DeletedVariantVersion = { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + valid_from: string // date + warnings: Array<{ + code: "VARIANT_COUNT_APPROACHING_CAP" + message: string + details: { + variant_count: { ... } + cap: { ... } + } + } | { + code: "ACTIVE_VERSION_CHANGED" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "SUPERSEDED_VERSION_WRITTEN" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "ATTRIBUTES_NOT_APPLIED" + message: string + details: { + attributes: { ... } + } + } | { + code: "VARIANT_NOT_INDEXED" + message: string + details: { + reason: { ... } + } + }> +} +``` + +### `AppendVersionRequest` + +```ts +type AppendVersionRequest = { + valid_from?: string // date + values: Record + conditions?: Record +} +``` + +### `ReplaceVersionRequest` + +```ts +type ReplaceVersionRequest = { + values: Record + _revision: number + valid_from?: string // date + conditions?: Record +} +``` + +### `PatchVersionRequest` + +```ts +type PatchVersionRequest = { + values: Record + _revision: number + valid_from?: string // date + conditions?: Record +} +``` + +### `ListVariantsRequest` + +How to narrow and page a variant listing. Every property is optional, so `{}` asks for the +first ten variants in `variant_id` order, but the body itself is required. `conditions` and +`search` narrow independently and a variant must satisfy both. + + +```ts +type ListVariantsRequest = { + conditions?: Record + search?: string + sort?: string + from?: number + size?: number + cursor?: string +} +``` + +### `VariantTreeRequest` + +The variants list's request plus `as_of`, the instant each row's version is selected at. +`size` is clamped at 100 here; every other property means what it means on the list. + + +```ts +type VariantTreeRequest = { + conditions?: Record + search?: string + sort?: string + from?: number + size?: number + cursor?: string + as_of?: string +} +``` + +### `VariantConditionFilter` + +Which pins a variant must carry to be listed: a flat map keyed by condition name, taking the +same exact values and predicates a resolve context does. A condition left out is not +filtered on. An `in` list carries at most 50,000 values. + +A variant matches only where it pins the condition — unlike `:re + +```ts +type VariantConditionFilter = Record +``` + +### `VariantList` + +```ts +type VariantList = { + hits: number + results: Array<{ + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: { ... } + } + }> + next?: string +} +``` + +### `VariantListRow` + +One variant as a listing reports it: which variant it is and what it pins. + +```ts +type VariantListRow = { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: boolean + } +} +``` + +### `VariantTree` + +```ts +type VariantTree = { + hits: number + results: Array<{ + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: { ... } + } + status: "active" | "scheduled" + version: { + variant_id: { ... } + entity_id: { ... } + schema: { ... } + conditions: { ... } + valid_from: { ... } + values: { ... } + _created_at: { ... } + _updated_at: { ... } + } + }> + next?: string +} +``` + +### `VariantTreeRow` + +A listing row plus the one version the tree shows for it, and the status saying which. + +```ts +type VariantTreeRow = { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: boolean + } + status: "active" | "scheduled" + version: { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: { ... } + } + valid_from: string // date + values: Record + _created_at: string + _updated_at: string + } +} +``` + +### `VariantTreeRowStatus` + +Whether a tree row's version is the one in effect at `as_of`, or one still ahead of it. + +- `active`: the version with the latest `valid_from` on or before `as_of`'s date in the + organization's timezone +- `scheduled`: the variant's first version, which is later than that date + + +```ts +type VariantTreeRowStatus = "active" | "scheduled" +``` + +### `VariantVersionSnapshot` + +One version of one variant as a listing reports it: `VariantVersion` without `_revision`. +Read the version through its own `GET` to get the revision a write must carry. + + +```ts +type VariantVersionSnapshot = { + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: boolean + } + valid_from: string // date + values: Record + _created_at: string + _updated_at: string +} +``` + +### `VariantVersionList` + +```ts +type VariantVersionList = { + results: Array<{ + variant_id: string + entity_id: string + schema: "product" | "price" | "coupon" + conditions: { + default: { ... } + } + valid_from: string // date + values: Record + _created_at: string + _updated_at: string + }> + next?: string +} +``` + +### `BatchUpsertVariantsRequest` + +A batch of variant writes under one schema, each item naming the entity it writes to. + +```ts +type BatchUpsertVariantsRequest = { + correlation_id?: string + items: Array<{ + entity_id: string + conditions?: Record + default?: boolean + valid_from?: string // date + values: Record + }> +} +``` + +### `BatchUpsertItem` + +One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An +existing condition tuple appends a version to the variant holding it rather than conflicting. + + +```ts +type BatchUpsertItem = { + entity_id: string + conditions?: Record + default?: boolean + valid_from?: string // date + values: Record +} +``` + +### `BatchDeleteVariantsRequest` + +A batch of variant and version deletes under one schema, each item naming the entity it removes from. + +```ts +type BatchDeleteVariantsRequest = { + correlation_id?: string + items: Array<{ + entity_id: string + variant_id: string + valid_from?: string // date + } | { + entity_id: string + conditions?: Record + default?: boolean + valid_from?: string // date + }> +} +``` + +### `BatchDeleteItem` + +One delete: the variant, addressed by id or by the condition tuple it pins, and optionally +the one version of it to remove. An item carrying both matches neither branch and is an +envelope `400`. + + +```ts +type BatchDeleteItem = { + entity_id: string + variant_id: string + valid_from?: string // date +} | { + entity_id: string + conditions?: Record + default?: boolean + valid_from?: string // date +} +``` + +### `BatchDeleteByVariantId` + +A delete addressing its variant by id. + +```ts +type BatchDeleteByVariantId = { + entity_id: string + variant_id: string + valid_from?: string // date +} +``` + +### `BatchDeleteByConditions` + +A delete addressing its variant by the situation it applies to. + +`conditions` is optional because the fallback variant pins nothing: address it with +`default: true` and no `conditions`. An item that ends up addressing no variant at all is a +per-item `VARIANT_UNPINNED`, and one marking `default` besi + +```ts +type BatchDeleteByConditions = { + entity_id: string + conditions?: Record + default?: boolean + valid_from?: string // date +} +``` + +### `BatchUpsertResult` + +What a batch upsert did: one entry per item, in request order, and a count per outcome. + +```ts +type BatchUpsertResult = { + correlation_id?: string + counts: { + variant_created: number + version_created: number + updated: number + skipped: number + error: number + } + results: Array<{ + outcome: "variant_created" | "version_created" | "updated" | "skipped" | "error" + entity_id: string + variant_id?: string + valid_from?: string // date + warnings: Array<{ + code: { ... } + message: { ... } + details: { ... } + } | { + code: { ... } + message: { ... } + details: { ... } + } | { + code: { ... } + message: { ... } + details: { ... } + } | { + code: { ... } + message: { ... } + details: { ... } + } | { + code: { ... } + message: { ... } + details: { ... } + }> + error?: { + message: { ... } + status?: { ... } + cause?: { ... } + error?: { ... } + } + }> +} +``` + +### `BatchDeleteResult` + +What a batch delete did: one entry per item, in request order, and a count per outcome. + +```ts +type BatchDeleteResult = { + correlation_id?: string + counts: { + deleted: number + skipped: number + error: number + } + results: Array<{ + outcome: "deleted" | "skipped" | "error" + entity_id: string + variant_id?: string + valid_from?: string // date + warnings: Array<{ + code: { ... } + message: { ... } + details: { ... } + } | { + code: { ... } + message: { ... } + details: { ... } + } | { + code: { ... } + message: { ... } + details: { ... } + } | { + code: { ... } + message: { ... } + details: { ... } + } | { + code: { ... } + message: { ... } + details: { ... } + }> + error?: { + message: { ... } + status?: { ... } + cause?: { ... } + error?: { ... } + } + }> +} +``` + +### `BatchUpsertOutcome` + +What one upsert item did, derived from what was stored. + +- `variant_created`: the condition tuple was unknown, so a variant and its first version + were created +- `version_created`: the tuple was known and had no version at the item's `valid_from` +- `updated`: a version existed on that exact date an + +```ts +type BatchUpsertOutcome = "variant_created" | "version_created" | "updated" | "skipped" | "error" +``` + +### `BatchDeleteOutcome` + +What one delete item did. + +- `deleted`: the variant, or the one version the item named, is gone +- `skipped`: the item addressed no such variant or version; a missing entity is an `error` +- `error`: this item alone failed, and the entry's `error` says why + + +```ts +type BatchDeleteOutcome = "deleted" | "skipped" | "error" +``` + +### `BatchUpsertCounts` + +How many items reached each outcome. Keyed by exactly the values of `BatchUpsertOutcome`, +all present, and summing to the length of `results`. + + +```ts +type BatchUpsertCounts = { + variant_created: number + version_created: number + updated: number + skipped: number + error: number +} +``` + +### `BatchDeleteCounts` + +How many items reached each outcome. Keyed by exactly the values of `BatchDeleteOutcome`, +all present, and summing to the length of `results`. + + +```ts +type BatchDeleteCounts = { + deleted: number + skipped: number + error: number +} +``` + +### `BatchUpsertResultEntry` + +What one upsert item did. Position in `results` maps it back to its source row. + +```ts +type BatchUpsertResultEntry = { + outcome: "variant_created" | "version_created" | "updated" | "skipped" | "error" + entity_id: string + variant_id?: string + valid_from?: string // date + warnings: Array<{ + code: "VARIANT_COUNT_APPROACHING_CAP" + message: string + details: { + variant_count: { ... } + cap: { ... } + } + } | { + code: "ACTIVE_VERSION_CHANGED" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "SUPERSEDED_VERSION_WRITTEN" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "ATTRIBUTES_NOT_APPLIED" + message: string + details: { + attributes: { ... } + } + } | { + code: "VARIANT_NOT_INDEXED" + message: string + details: { + reason: { ... } + } + }> + error?: { + message: string + status?: number + cause?: string + error?: string | Record[] + } +} +``` + +### `BatchDeleteResultEntry` + +What one delete item did. Position in `results` maps it back to its source row. + +```ts +type BatchDeleteResultEntry = { + outcome: "deleted" | "skipped" | "error" + entity_id: string + variant_id?: string + valid_from?: string // date + warnings: Array<{ + code: "VARIANT_COUNT_APPROACHING_CAP" + message: string + details: { + variant_count: { ... } + cap: { ... } + } + } | { + code: "ACTIVE_VERSION_CHANGED" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "SUPERSEDED_VERSION_WRITTEN" + message: string + details: { + valid_from: { ... } + active_valid_from?: { ... } + } + } | { + code: "ATTRIBUTES_NOT_APPLIED" + message: string + details: { + attributes: { ... } + } + } | { + code: "VARIANT_NOT_INDEXED" + message: string + details: { + reason: { ... } + } + }> + error?: { + message: string + status?: number + cause?: string + error?: string | Record[] + } +} +``` + +### `Error` + +```ts +type Error = { + message: string + status?: number + cause?: string +} +``` + +### `RefusedLineItem` + +The line item a checkout refusal is about, named as the item names itself. + +```ts +type RefusedLineItem = { + price_id: string + product_id?: string +} +``` + +### `ReportedError` + +The `error` field of an error response: the message, or — where the request failed +validation before any handler ran — the validation errors themselves. + + +```ts +type ReportedError = string | Record[] +``` + +### `ConditionalPricingError` + +An error from a conditional-pricing operation, carrying a `code` plus the structured data +that code explains. `details` is typed per code: narrow on `code` and the object under it +declares exactly the fields that code sends. + +A request these schemas reject is answered by the request validator with a + +```ts +type ConditionalPricingError = { + message: string + status?: number + cause?: string + error?: string | Record[] +} +``` + +### `CatalogReferenceErrorCode` + +Why an order operation refused a catalog reference. Other refusals carry no `code`. + +- `CATALOG_REFERENCE_MISSING` (400): a line item whose product or price is conditional carries no `catalog_reference`, or one with no variant for that member +- `CATALOG_REFERENCE_SIGNATURE_INVALID` (400): a `catalog + +```ts +type CatalogReferenceErrorCode = "CATALOG_REFERENCE_MISSING" | "CATALOG_REFERENCE_SIGNATURE_INVALID" | "CATALOG_REFERENCE_UNRESOLVABLE" +``` + +### `CatalogReferenceError` + +An error from an order operation that prices line items. A catalog-reference refusal carries +`code` and `details`, typed per code. Every other refusal carries neither. + + +```ts +type CatalogReferenceError = { + message: string + status?: number + cause?: string + error?: string | Record[] +} +``` + +### `BaseProduct` + +The product's own attributes — everything but the two relations whose shape depends on +whether the product was hydrated, which `Product` and `HydratedProduct` add. + + +```ts +type BaseProduct = { + description?: string + code?: string + type?: "product" | "service" + name?: string + categories?: string[] + feature?: Array<{ + _tags?: string[] + feature?: string + }> + product_images?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } | Array<{ + _id: string + filename: string + mime_type: string + versions: Array<{ + s3ref: { ... } + }> + _schema: string + _org: string + _created_at: string // date-time + _updated_at: string // date-time + _title?: string + $relation?: { + entity_id?: { ... } + _tags?: { ... } + } + }> + product_downloads?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } | Array<{ + _id: string + filename: string + mime_type: string + versions: Array<{ + s3ref: { ... } + }> + _schema: string + _org: string + _created_at: string // date-time + _updated_at: string // date-time + _title?: string + $relation?: { + entity_id?: { ... } + _tags?: { ... } + } + }> + is_conditional?: boolean + _availability_files?: Array<{ + _id: string + filename: string + mime_type: string + versions: Array<{ + s3ref: { ... } + }> + _schema: string + _org: string + _created_at: string // date-time + _updated_at: string // date-time + _title?: string + $relation?: { + entity_id?: { ... } + _tags?: { ... } + } + }> + _id?: string + _title?: string + _org_id?: string + _created_at?: string + _updated_at?: string +} +``` + +### `Product` + +The product entity, its relations as stored. + +```ts +type Product = { + description?: string + code?: string + type?: "product" | "service" + name?: string + categories?: string[] + feature?: Array<{ + _tags?: string[] + feature?: string + }> + product_images?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } | Array<{ + _id: string + filename: string + mime_type: string + versions: Array<{ + s3ref: { ... } + }> + _schema: string + _org: string + _created_at: string // date-time + _updated_at: string // date-time + _title?: string + $relation?: { + entity_id?: { ... } + _tags?: { ... } + } + }> + product_downloads?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } | Array<{ + _id: string + filename: string + mime_type: string + versions: Array<{ + s3ref: { ... } + }> + _schema: string + _org: string + _created_at: string // date-time + _updated_at: string // date-time + _title?: string + $relation?: { + entity_id?: { ... } + _tags?: { ... } + } + }> + is_conditional?: boolean + _availability_files?: Array<{ + _id: string + filename: string + mime_type: string + versions: Array<{ + s3ref: { ... } + }> + _schema: string + _org: string + _created_at: string // date-time + _updated_at: string // date-time + _title?: string + $relation?: { + entity_id?: { ... } + _tags?: { ... } + } + }> + _id?: string + _title?: string + _org_id?: string + _created_at?: string + _updated_at?: string +} +``` + +### `HydratedProduct` + +The product entity hydrated one level deep, as the v2 public catalog serves it: each +relation holds the entities it referenced, sanitised, with their own relations as stored. + + +```ts +type HydratedProduct = { description?: string code?: string type?: "product" | "service" @@ -1769,12 +4862,6 @@ type Product = { _tags?: string[] feature?: string }> - cross_sellable_products?: { - $relation?: Array<{ - entity_id?: { ... } - _tags?: { ... } - }> - } product_images?: { $relation?: Array<{ entity_id?: { ... } @@ -1819,12 +4906,7 @@ type Product = { _tags?: { ... } } }> - price_options?: { - $relation?: Array<{ - entity_id?: { ... } - _tags?: { ... } - }> - } + is_conditional?: boolean _availability_files?: Array<{ _id: string filename: string @@ -2014,10 +5096,9 @@ type Order = { name?: { ... } categories?: { ... } feature?: { ... } - cross_sellable_products?: { ... } product_images?: { ... } product_downloads?: { ... } - price_options?: { ... } + is_conditional?: { ... } _availability_files?: { ... } _id?: { ... } _title?: { ... } @@ -2025,10 +5106,11 @@ type Order = { _created_at?: { ... } _updated_at?: { ... } } - } | { - metadata?: Array<{ - key?: { ... } - value?: { ... } + catalog_reference?: { + product: { ... } + price: { ... } + price_components?: { ... } + coupons?: { ... } // ... } ``` @@ -2172,145 +5254,638 @@ type PriceInputMapping = { } ``` -### `PriceConditions` +### `PriceConditions` + +```ts +type PriceConditions = { + billing_duration_amount?: number + billing_duration_unit?: "days" | "weeks" | "months" | "years" + notice_time_amount?: number + notice_time_unit?: "days" | "weeks" | "months" | "years" + termination_time_amount?: number + termination_time_unit?: "days" | "weeks" | "months" | "years" + renewal_duration_amount?: number + renewal_duration_unit?: "days" | "weeks" | "months" | "years" +} +``` + +### `ExternalFeeMetadata` + +```ts +type ExternalFeeMetadata = { + amount_total: number + amount_total_decimal: string + amount_static?: number + amount_static_decimal?: unknown + amount_variable_ht?: number + amount_variable_decimal_ht?: string + unit_amount_variable_ht?: number + unit_amount_variable_decimal_ht?: string + amount_variable_nt?: number + amount_variable_decimal_nt?: string + unit_amount_variable_nt?: number + unit_amount_variable_decimal_nt?: string + currency: string + billing_period: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" + breakdown: { + static?: Record + variable?: Record + variable_ht?: Record + variable_nt?: Record + } + inputs?: { + type?: "power" | "gas" + consumptionHT?: number + consumptionNT?: number + consumptionType?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter" + zipCode?: string + city?: string + providerId?: string + billingPeriod?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" + referenceDate?: string // date + } + _meta?: { + signature: string + timestamp: number + } +} +``` + +### `ExternalLocationMetadata` + +```ts +type ExternalLocationMetadata = { + name: string + code: string + type: "gas" | "power" + additionalData: { + gridOperators: Array<{ + name: { ... } + codeNumber: { ... } + validFrom?: { ... } + validUntil?: { ... } + }> + defaultSuppliers: Array<{ + name: { ... } + codeNumber: { ... } + validFrom?: { ... } + validUntil?: { ... } + }> + marketAreaDetails: { + gasType?: { ... } + marketArea?: { ... } + virtualTradingPoint?: { ... } + } | { + controlZone?: { ... } + balancingZone?: { ... } + } + } + _meta?: { + signature: string + timestamp: number + } +} +``` + +### `ExternalPriceMetadata` + +```ts +type ExternalPriceMetadata = { + market: "day_ahead" + bidding_zone: "AT" | "DE-LU" + price: { + unit_amount: number + unit_amount_decimal: string + unit_amount_currency: string + timestamp: string + } + _meta?: { + signature: string + timestamp: number + } +} +``` + +### `ExternalFeeMappings` + +```ts +type ExternalFeeMappings = Array<{ + price_id?: string + frequency_unit?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" + amount_total?: number + amount_total_decimal?: string +}> +``` + +### `ExternalFeeMapping` + +```ts +type ExternalFeeMapping = { + price_id?: string + frequency_unit?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" + amount_total?: number + amount_total_decimal?: string +} +``` + +### `PublicCatalogSearch` + +A public catalog search payload + +```ts +type PublicCatalogSearch = { + q: string + sort?: string + from?: number + size?: number + hydrate?: boolean + availability?: { + location: { + street?: { ... } + street_number?: { ... } + postal_code?: { ... } + city?: { ... } + country?: { ... } + } + available_date?: string // date + } +} +``` + +### `CatalogSearch` + +A catalog search payload + +```ts +type CatalogSearch = { + q: string + sort?: string + from?: number + size?: number + hydrate?: boolean + availability?: { + location: { + street?: { ... } + street_number?: { ... } + postal_code?: { ... } + city?: { ... } + country?: { ... } + } + available_date?: string // date + } + fields?: string[] +} +``` + +### `CatalogFieldsParam` + +List of entity fields to include or exclude from the results. + + +```ts +type CatalogFieldsParam = string[] +``` + +### `CatalogSearchResult` + +The query result payload + +```ts +type CatalogSearchResult = { + hits?: number + results?: Array<{ + description?: string + code?: string + type?: "product" | "service" + name?: string + categories?: string[] + feature?: Array<{ + _tags?: { ... } + feature?: { ... } + }> + product_images?: { + $relation?: { ... } + } | Array<{ + _id: { ... } + filename: { ... } + mime_type: { ... } + versions: { ... } + _schema: { ... } + _org: { ... } + _created_at: { ... } + _updated_at: { ... } + _title?: { ... } + $relation?: { ... } + }> + product_downloads?: { + $relation?: { ... } + } | Array<{ + _id: { ... } + filename: { ... } + mime_type: { ... } + versions: { ... } + _schema: { ... } + _org: { ... } + _created_at: { ... } + _updated_at: { ... } + _title?: { ... } + $relation?: { ... } + }> + is_conditional?: boolean + _availability_files?: Array<{ + _id: { ... } + filename: { ... } + mime_type: { ... } + versions: { ... } + _schema: { ... } + _org: { ... } + _created_at: { ... } + _updated_at: { ... } + _title?: { ... } + $relation?: { ... } + }> + _id?: string + _title?: string + _org_id?: string + _created_at?: string + _updated_at?: string + } | { + billing_duration_amount?: number + billing_duration_unit?: "days" | "weeks" | "months" | "years" + notice_time_amount?: number + notice_time_unit?: "days" | "weeks" | "months" | "years" + termination_time_amount?: number + termination_time_unit?: "days" | "weeks" | "months" | "years" + renewal_duration_amount?: number + renewal_duration_unit?: "days" | "weeks" | "months" | "years" + } | { + _id: string // uuid + _title: string + _org: string + _schema: "coupon" + _tags?: string[] + _created_at: string // date-time + _updated_at: string // date-time + name: string + description?: string + type: "fixed" | "percentage" + category: "discount" | "cashback" + percentage_value?: string + fixed_value?: number + fixed_value_decimal?: string + fixed_value_currency?: string + cashback_period?: "0" | "12" + active?: boolean + is_conditional?: boolean + requires_promo_code?: boolean + }> +} +``` + +### `ResolveCatalogRequest` -```ts -type PriceConditions = { - billing_duration_amount?: number - billing_duration_unit?: "days" | "weeks" | "months" | "years" - notice_time_amount?: number - notice_time_unit?: "days" | "weeks" | "months" | "years" - termination_time_amount?: number - termination_time_unit?: "days" | "weeks" | "months" | "years" - renewal_duration_amount?: number - renewal_duration_unit?: "days" | "weeks" | "months" | "years" -} -``` +The entries of one journey block, and the situation to resolve them for. Every member of +every pair is resolved for its entity type's context at the same `as_of`. -### `ExternalFeeMetadata` ```ts -type ExternalFeeMetadata = { - amount_total: number - amount_total_decimal: string - amount_static?: number - amount_static_decimal?: unknown - amount_variable_ht?: number - amount_variable_decimal_ht?: string - unit_amount_variable_ht?: number - unit_amount_variable_decimal_ht?: string - amount_variable_nt?: number - amount_variable_decimal_nt?: string - unit_amount_variable_nt?: number - unit_amount_variable_decimal_nt?: string - currency: string - billing_period: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" - breakdown: { - static?: Record - variable?: Record + context: { + product?: Record - variable_ht?: Record - variable_nt?: Record } - _meta?: { - signature: string - timestamp: number - } + as_of?: string } ``` -### `ExternalPriceMetadata` +### `CatalogContext` + +One context per entity type, each the authenticated resolve's context and checked against +that type's schema alone. A product resolves against `product`, and a price and each of a +composite's components against `price`. A type left out resolves against an empty context, +which serves the `default` va ```ts -type ExternalPriceMetadata = { - market: "day_ahead" - bidding_zone: "AT" | "DE-LU" - price: { - unit_amount: number - unit_amount_decimal: string - unit_amount_currency: string - timestamp: string - } - _meta?: { - signature: string - timestamp: number - } +type CatalogContext = { + product?: Record + price?: Record + coupon?: Record } ``` -### `ExternalFeeMappings` +### `CatalogEntry` -```ts -type ExternalFeeMappings = Array<{ - price_id?: string - frequency_unit?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" - amount_total?: number - amount_total_decimal?: string -}> -``` +A product and, optionally, one of its prices. With `price_id` the entry is the author's +pair, served as named; without it the entry is served from the resolved product's +`price_options`, one pair per price. -### `ExternalFeeMapping` ```ts -type ExternalFeeMapping = { +type CatalogEntry = { + product_id: string price_id?: string - frequency_unit?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" - amount_total?: number - amount_total_decimal?: string } ``` -### `CatalogSearch` - -A catalog search payload +### `ResolveCatalogResult` ```ts -type CatalogSearch = { - q: string - sort?: string - from?: number - size?: number - hydrate?: boolean - availability?: { - location: { - street?: { ... } - street_number?: { ... } - postal_code?: { ... } - city?: { ... } - country?: { ... } +type ResolveCatalogResult = { + pairs: Array<{ + product: { + cross_sellable_products?: { ... } + price_options?: { ... } + _id: { ... } + _variant_id: { ... } + _version_valid_from: { ... } + _conditions: { ... } + _inert_overrides: { ... } + } | { + description?: { ... } + code?: { ... } + type?: { ... } + name?: { ... } + categories?: { ... } + feature?: { ... } + product_images?: { ... } + product_downloads?: { ... } + is_conditional?: { ... } + _availability_files?: { ... } + _id?: { ... } + _title?: { ... } + _org_id?: { ... } + _created_at?: { ... } + _updated_at?: { ... } } - available_date?: string // date - } + price: { + active?: { ... } + is_composite_price?: { ... } + is_conditional?: { ... } + pricing_model: { ... } + tiers?: { ... } + description?: { ... } + long_description?: { ... } + sales_tax?: { ... } + tax?: { ... } + is_tax_inclusive?: { ... } + type?: { ... } + billing_period?: { ... } + unit_amount?: { ... } + unit_amount_decimal?: { ... } + unit_amount_currency?: { ... } + price_display_in_journeys?: { ... } + variable_price?: { ... } + unit?: { ... } + get_ag?: { ... } + dynamic_tariff?: { ... } + _created_at?: { ... } + _id: { ... } + _title?: { ... } + _updated_at?: { ... } + _org_id?: { ... } + _tags?: { ... } + _variant_id: { ... } + _version_valid_from: { ... } + _conditions: { ... } + _inert_overrides: { ... } + } | { + price_components?: { ... } + _id: { ... } + _variant_id: { ... } + _version_valid_from: { ... } + _conditions: { ... } + _inert_overrides: { ... } + } | { + billing_duration_amount?: { ... } + billing_duration_unit?: { ... } + notice_time_amount?: { ... } + notice_time_unit?: { ... } + termination_time_amount?: { ... } + termination_time_unit?: { ... } + renewal_duration_amount?: { ... } + renewal_duration_unit?: { ... } + } | { + price_components?: { ... } + } + coupons: Array<{ + _id: { ... } + _title: { ... } + _org: { ... } + _schema: { ... } + _tags?: { ... } + _created_at: { ... } + _updated_at: { ... } + name: { ... } + description?: { ... } + type: { ... } + category: { ... } + percentage_value?: { ... } + fixed_value?: { ... } + fixed_value_decimal?: { ... } + fixed_value_currency?: { ... } + cashback_period?: { ... } + active?: { ... } + is_conditional?: { ... } + requires_promo_code?: { ... } + }> + catalog_reference: { + product: { ... } + // ... } ``` -### `CatalogSearchResult` +### `CatalogPair` + +A product and one of its prices, resolved for the request's `context` at its `as_of`, with +the coupons that apply and the reference checkout prices from. -The query result payload ```ts -type CatalogSearchResult = { - hits?: number - results?: Array<{ +type CatalogPair = { + product: { + cross_sellable_products?: Array<{ + description?: { ... } + code?: { ... } + type?: { ... } + name?: { ... } + categories?: { ... } + feature?: { ... } + product_images?: { ... } + product_downloads?: { ... } + is_conditional?: { ... } + _availability_files?: { ... } + _id?: { ... } + _title?: { ... } + _org_id?: { ... } + _created_at?: { ... } + _updated_at?: { ... } + }> + price_options?: Array<{ + billing_duration_amount?: { ... } + billing_duration_unit?: { ... } + notice_time_amount?: { ... } + notice_time_unit?: { ... } + termination_time_amount?: { ... } + termination_time_unit?: { ... } + renewal_duration_amount?: { ... } + renewal_duration_unit?: { ... } + } | { + billing_duration_amount?: { ... } + billing_duration_unit?: { ... } + notice_time_amount?: { ... } + notice_time_unit?: { ... } + termination_time_amount?: { ... } + termination_time_unit?: { ... } + renewal_duration_amount?: { ... } + renewal_duration_unit?: { ... } + } | { + billing_duration_amount?: { ... } + billing_duration_unit?: { ... } + notice_time_amount?: { ... } + notice_time_unit?: { ... } + termination_time_amount?: { ... } + termination_time_unit?: { ... } + renewal_duration_amount?: { ... } + renewal_duration_unit?: { ... } + }> + _id: string + _variant_id: string + _version_valid_from: string // date + _conditions: { + default: { ... } + } + _inert_overrides: Array<{ + attribute: { ... } + reason: { ... } + }> + } | { description?: string code?: string type?: "product" | "service" @@ -2320,9 +5895,6 @@ type CatalogSearchResult = { _tags?: { ... } feature?: { ... } }> - cross_sellable_products?: { - $relation?: { ... } - } product_images?: { $relation?: { ... } } | Array<{ @@ -2351,55 +5923,171 @@ type CatalogSearchResult = { _title?: { ... } $relation?: { ... } }> - price_options?: { - $relation?: { ... } - } + is_conditional?: boolean _availability_files?: Array<{ _id: { ... } filename: { ... } mime_type: { ... } - versions: { ... } - _schema: { ... } + // ... +} +``` + +### `ResolvedPriceComponents` + +The components of a composite price as the v2 catalog serves them: hydrated in place, and +a component that is itself conditional resolved against the same context, carrying the +discriminators a resolved payload carries. A conditional component with no variant in +effect — nothing matches and there is + +```ts +type ResolvedPriceComponents = { + price_components?: Array<{ + active?: boolean + is_composite_price?: false + is_conditional?: boolean + pricing_model: "per_unit" | "tiered_graduated" | "tiered_volume" | "tiered_flatfee" | "dynamic_tariff" | "external_getag" + tiers?: Array<{ + up_to?: { ... } + flat_fee_amount?: { ... } + flat_fee_amount_decimal?: { ... } + unit_amount?: { ... } + unit_amount_decimal?: { ... } + display_mode?: { ... } + }> + description?: string + long_description?: string + sales_tax?: "nontaxable" | "reduced" | "standard" + tax?: { + $relation?: { ... } + } | Array<{ + _id: { ... } + _title: { ... } _org: { ... } + _schema: { ... } + _tags?: { ... } _created_at: { ... } _updated_at: { ... } - _title?: { ... } - $relation?: { ... } + type: { ... } + description?: { ... } + rate: { ... } + active?: { ... } + region?: { ... } + region_label?: { ... } }> - _id?: string - _title?: string - _org_id?: string + is_tax_inclusive?: boolean + type?: "one_time" | "recurring" + billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" + unit_amount?: number + unit_amount_decimal?: string + unit_amount_currency?: string + price_display_in_journeys?: "show_price" | "show_as_starting_price" | "show_as_on_request" | "estimated_price" + variable_price?: boolean + unit?: "kw" | "kwh" | "m" | "m2" | "l" | "cubic-meter" | "cubic-meter-h" | "ls" | "a" | "kva" | "w" | "wp" | "kwp" | string + get_ag?: { + category: { ... } + markup_pricing_model?: { ... } + type?: { ... } + tariff_type?: { ... } + consumption_type?: { ... } + concession_type?: { ... } + meter_type?: { ... } + markup_tiers?: { ... } + markup_amount: { ... } + markup_amount_decimal: { ... } + markup_amount_net?: { ... } + markup_amount_net_decimal?: { ... } + markup_amount_gross?: { ... } + markup_amount_gross_decimal?: { ... } + markup_total_amount_net?: { ... } + markup_total_amount_net_decimal?: { ... } + markup_total_amount_gross?: { ... } + markup_total_amount_gross_decimal?: { ... } + additional_markups_enabled?: { ... } + additional_markups?: { ... } + unit_amount_gross: { ... } + unit_amount_gross_decimal?: { ... } + unit_amount_net: { ... } + unit_amount_net_decimal?: { ... } + } + dynamic_tariff?: { + mode: { ... } + interval?: { ... } + average_price: { ... } + average_price_decimal: { ... } + markup_amount?: { ... } + markup_amount_decimal?: { ... } + markup_amount_net?: { ... } + markup_amount_net_decimal?: { ... } + markup_amount_gross?: { ... } + markup_amount_gross_decimal?: { ... } + unit_amount_net?: { ... } + unit_amount_net_decimal?: { ... } + unit_amount_gross?: { ... } + unit_amount_gross_decimal?: { ... } + } _created_at?: string + _id: string + _title?: string _updated_at?: string - } | { - billing_duration_amount?: number - billing_duration_unit?: "days" | "weeks" | "months" | "years" - notice_time_amount?: number - notice_time_unit?: "days" | "weeks" | "months" | "years" - termination_time_amount?: number - termination_time_unit?: "days" | "weeks" | "months" | "years" - renewal_duration_amount?: number - renewal_duration_unit?: "days" | "weeks" | "months" | "years" - } | { - _id: string // uuid - _title: string - _org: string - _schema: "coupon" + _org_id?: string _tags?: string[] - _created_at: string // date-time - _updated_at: string // date-time - name: string - description?: string - type: "fixed" | "percentage" - category: "discount" | "cashback" - percentage_value?: string - fixed_value?: number - fixed_value_decimal?: string - fixed_value_currency?: string - cashback_period?: "0" | "12" - active?: boolean - requires_promo_code?: boolean + _variant_id: string + _version_valid_from: string // date + _conditions: { + default: { ... } + } + _inert_overrides: Array<{ + attribute: { ... } + reason: { ... } + }> + // ... +} +``` + +### `CatalogReference` + +Names the variant each member of a catalog pair was resolved from, and the instant `as_of` +they were resolved at. Checkout prices each conditional member from that variant, using the +version in effect on `as_of`'s date in the organization's timezone. + +The catalog signs every reference, classic pair + +```ts +type CatalogReference = { + product: { + id: string + variant?: string + } + price: { + id: string + variant?: string + } + price_components?: Array<{ + id: string + variant?: string }> + coupons?: Array<{ + id: string + variant?: string + }> + as_of: string + _meta?: { + signature: string + timestamp: number + } +} +``` + +### `CatalogReferenceMember` + +One member of a catalog reference: the entity, and the variant that produced it. `variant` +is absent for a classic entity. + + +```ts +type CatalogReferenceMember = { + id: string + variant?: string } ``` @@ -2414,6 +6102,7 @@ type SearchProvidersParams = { city?: string street?: string street_number?: string + grid_filter?: "all" | "exclude_closed" | "only_closed" } ``` @@ -2539,6 +6228,7 @@ type ComputePriceParamsBase = { association_id?: string billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" reference_date?: string // date + city?: string } ``` @@ -2554,6 +6244,7 @@ type ComputePriceParamsPower = { association_id?: string billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" reference_date?: string // date + city?: string type: "power" meter_type?: "classic" | "smart" | "digital" } @@ -2571,6 +6262,7 @@ type ComputePriceParamsGas = { association_id?: string billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" reference_date?: string // date + city?: string type: "gas" concession_type?: "standard" | "special" } @@ -2614,6 +6306,7 @@ type ComputePriceParams = { association_id?: string billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" reference_date?: string // date + city?: string type: "power" meter_type?: "classic" | "smart" | "digital" } | { @@ -2625,6 +6318,7 @@ type ComputePriceParams = { association_id?: string billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" reference_date?: string // date + city?: string type: "gas" concession_type?: "standard" | "special" } @@ -2752,6 +6446,17 @@ type ComputePriceResult = { unit_amount_decimal?: { ... } }> } + inputs?: { + type?: "power" | "gas" + consumptionHT?: number + consumptionNT?: number + consumptionType?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter" + zipCode?: string + city?: string + providerId?: string + billingPeriod?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" + referenceDate?: string // date + } _meta?: { signature: string timestamp: number @@ -2759,6 +6464,24 @@ type ComputePriceResult = { } ``` +### `ComputePriceInputs` + +Echo of the request parameters used to compute the price, in the caller-facing shape. + +```ts +type ComputePriceInputs = { + type?: "power" | "gas" + consumptionHT?: number + consumptionNT?: number + consumptionType?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter" + zipCode?: string + city?: string + providerId?: string + billingPeriod?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" + referenceDate?: string // date +} +``` + ### `SpotMarketBiddingZone` The bidding zone for a spot market price. @@ -2903,65 +6626,184 @@ type OAuthIntegration = { access_token_expires_in?: number access_token_expires_at?: number } - base_url?: string + base_url?: string +} +``` + +### `IntegrationAuthCredentials` + +The auth credentials for external integrations + +```ts +type IntegrationAuthCredentials = { + username: string + password: string + auth_type?: "basic_auth" + base_url?: string +} | { + auth_type: "oauth" + oauth: { + client_id: string + client_secret: string + authorization_url: string + grant_type: "client_credentials" + scope?: string + access_token?: string + access_token_expires_in?: number + access_token_expires_at?: number + } + base_url?: string +} +``` + +### `SearchStreetsResult` + +The search providers payload + +```ts +type SearchStreetsResult = Array<{ + street: string +}> +``` + +### `SearchProvidersResult` + +The search providers payload + +```ts +type SearchProvidersResult = Array<{ + name: string + code: string + type: "gas" | "power" + additionalData: { + gridOperators: Array<{ + name: { ... } + codeNumber: { ... } + validFrom?: { ... } + validUntil?: { ... } + }> + defaultSuppliers: Array<{ + name: { ... } + codeNumber: { ... } + validFrom?: { ... } + validUntil?: { ... } + }> + marketAreaDetails: { + gasType?: { ... } + marketArea?: { ... } + virtualTradingPoint?: { ... } + } | { + controlZone?: { ... } + balancingZone?: { ... } + } + } + _meta?: { + signature: string + timestamp: number + } +}> +``` + +### `Provider` + +The provider entity + +```ts +type Provider = { + name: string + code: string + type: "gas" | "power" + additionalData: { + gridOperators: Array<{ + name: { ... } + codeNumber: { ... } + validFrom?: { ... } + validUntil?: { ... } + }> + defaultSuppliers: Array<{ + name: { ... } + codeNumber: { ... } + validFrom?: { ... } + validUntil?: { ... } + }> + marketAreaDetails: { + gasType?: { ... } + marketArea?: { ... } + virtualTradingPoint?: { ... } + } | { + controlZone?: { ... } + balancingZone?: { ... } + } + } + _meta?: { + signature: string + timestamp: number + } } ``` -### `IntegrationAuthCredentials` +### `AdditionalProviderData` -The auth credentials for external integrations +Additional data included in the provider entity ```ts -type IntegrationAuthCredentials = { - username: string - password: string - auth_type?: "basic_auth" - base_url?: string -} | { - auth_type: "oauth" - oauth: { - client_id: string - client_secret: string - authorization_url: string - grant_type: "client_credentials" - scope?: string - access_token?: string - access_token_expires_in?: number - access_token_expires_at?: number +type AdditionalProviderData = { + gridOperators: Array<{ + name: string + codeNumber: string + validFrom?: string // date + validUntil?: string // date + }> + defaultSuppliers: Array<{ + name: string + codeNumber: string + validFrom?: string // date + validUntil?: string // date + }> + marketAreaDetails: { + gasType?: "L-Gas" | "H-Gas" + marketArea?: string + virtualTradingPoint?: string + } | { + controlZone?: string + balancingZone?: string } - base_url?: string } ``` -### `SearchStreetsResult` +### `MarketParticipant` -The search providers payload +Market participant data ```ts -type SearchStreetsResult = Array<{ - street: string -}> +type MarketParticipant = { + name: string + codeNumber: string + validFrom?: string // date + validUntil?: string // date +} ``` -### `SearchProvidersResult` +### `GasMarketAreaDetails` -The search providers payload +Market area details for gas ```ts -type SearchProvidersResult = Array<{ - name: string - code: string -}> +type GasMarketAreaDetails = { + gasType?: "L-Gas" | "H-Gas" + marketArea?: string + virtualTradingPoint?: string +} ``` -### `Provider` +### `PowerMarketAreaDetails` -The provider entity +Market area details for power ```ts -type Provider = { - name: string - code: string +type PowerMarketAreaDetails = { + controlZone?: string + balancingZone?: string } ``` @@ -3084,18 +6926,18 @@ type CartDto = { currency: { ... } billing_period: { ... } breakdown: { ... } + inputs?: { ... } _meta?: { ... } } - external_price_metadata?: { - market: { ... } - bidding_zone: { ... } - price: { ... } + external_location_metadata?: { + name: { ... } + code: { ... } + type: { ... } + additionalData: { ... } _meta?: { ... } } - _immutable_pricing_details?: { - items?: { ... } - amount_subtotal?: { ... } - amount_total?: { ... } + external_price_metadata?: { + market: { ... } // ... } ``` @@ -3174,6 +7016,7 @@ type CheckoutCart = { line_items: Array<{ external_fees_mappings?: { ... } external_fees_metadata?: { ... } + external_location_metadata?: { ... } external_price_metadata?: { ... } _immutable_pricing_details?: { ... } coupon_ids?: { ... } @@ -3192,6 +7035,7 @@ type CheckoutCart = { } | { external_fees_mappings?: { ... } external_fees_metadata?: { ... } + external_location_metadata?: { ... } external_price_metadata?: { ... } _immutable_pricing_details?: { ... } coupon_ids?: { ... } @@ -3203,8 +7047,6 @@ type CheckoutCart = { selected_price_component_ids?: { ... } price_component_coupon_ids?: { ... } _price?: { ... } - }> - files?: string[] // ... } ``` @@ -3282,6 +7124,7 @@ type CheckoutCartResult = { price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } } | { metadata?: { ... } quantity?: { ... } @@ -3293,6 +7136,7 @@ type CheckoutCartResult = { price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } }> products?: { $relation?: { ... } @@ -3312,8 +7156,6 @@ type CheckoutCartResult = { } _org_id?: string _id?: string - _created_at?: string - _updated_at?: string // ... } ``` @@ -3373,9 +7215,6 @@ type BasePriceItemCommon = { _tags?: { ... } feature?: { ... } }> - cross_sellable_products?: { - $relation?: { ... } - } product_images?: { $relation?: { ... } } | Array<{ @@ -3404,9 +7243,7 @@ type BasePriceItemCommon = { _title?: { ... } $relation?: { ... } }> - price_options?: { - $relation?: { ... } - } + is_conditional?: boolean _availability_files?: Array<{ _id: { ... } filename: { ... } @@ -3425,6 +7262,29 @@ type BasePriceItemCommon = { _created_at?: string _updated_at?: string } + catalog_reference?: { + product: { + id: { ... } + variant?: { ... } + } + price: { + id: { ... } + variant?: { ... } + } + price_components?: Array<{ + id: { ... } + variant?: { ... } + }> + coupons?: Array<{ + id: { ... } + variant?: { ... } + }> + as_of: string + _meta?: { + signature: { ... } + timestamp: { ... } + } + } } ``` @@ -3459,6 +7319,31 @@ type PriceItemDtoUnion = { variable_ht?: { ... } variable_nt?: { ... } } + inputs?: { + type?: { ... } + consumptionHT?: { ... } + consumptionNT?: { ... } + consumptionType?: { ... } + zipCode?: { ... } + city?: { ... } + providerId?: { ... } + billingPeriod?: { ... } + referenceDate?: { ... } + } + _meta?: { + signature: { ... } + timestamp: { ... } + } + } + external_location_metadata?: { + name: string + code: string + type: "gas" | "power" + additionalData: { + gridOperators: { ... } + defaultSuppliers: { ... } + marketAreaDetails: { ... } + } _meta?: { signature: { ... } timestamp: { ... } @@ -3490,6 +7375,7 @@ type PriceItemDtoUnion = { price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } } | { metadata?: { ... } quantity?: { ... } @@ -3501,36 +7387,10 @@ type PriceItemDtoUnion = { price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } }> amount_subtotal?: number amount_total?: number - unit_amount_gross?: number - unit_amount_net?: number - amount_tax?: number - total_details?: { - amount_shipping?: { ... } - amount_tax?: { ... } - breakdown?: { ... } - } - currency?: string - redeemed_promos?: Array<{ - code: { ... } - coupons: { ... } - }> - } - coupon_ids?: string[] - taxes?: Array<{ - rate?: string - tax?: { - _id: { ... } - _title: { ... } - _org: { ... } - _schema: { ... } - _tags?: { ... } - _created_at: { ... } - _updated_at: { ... } - type: { ... } - description?: { ... } // ... } ``` @@ -3568,6 +7428,31 @@ type PriceItemsDto = Array<{ variable_ht?: { ... } variable_nt?: { ... } } + inputs?: { + type?: { ... } + consumptionHT?: { ... } + consumptionNT?: { ... } + consumptionType?: { ... } + zipCode?: { ... } + city?: { ... } + providerId?: { ... } + billingPeriod?: { ... } + referenceDate?: { ... } + } + _meta?: { + signature: { ... } + timestamp: { ... } + } + } + external_location_metadata?: { + name: string + code: string + type: "gas" | "power" + additionalData: { + gridOperators: { ... } + defaultSuppliers: { ... } + marketAreaDetails: { ... } + } _meta?: { signature: { ... } timestamp: { ... } @@ -3599,6 +7484,7 @@ type PriceItemsDto = Array<{ price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } } | { metadata?: { ... } quantity?: { ... } @@ -3610,36 +7496,10 @@ type PriceItemsDto = Array<{ price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } }> amount_subtotal?: number amount_total?: number - unit_amount_gross?: number - unit_amount_net?: number - amount_tax?: number - total_details?: { - amount_shipping?: { ... } - amount_tax?: { ... } - breakdown?: { ... } - } - currency?: string - redeemed_promos?: Array<{ - code: { ... } - coupons: { ... } - }> - } - coupon_ids?: string[] - taxes?: Array<{ - rate?: string - tax?: { - _id: { ... } - _title: { ... } - _org: { ... } - _schema: { ... } - _tags?: { ... } - _created_at: { ... } - _updated_at: { ... } - type: { ... } - description?: { ... } // ... } ``` @@ -3678,9 +7538,6 @@ type BasePriceItemDto = { _tags?: { ... } feature?: { ... } }> - cross_sellable_products?: { - $relation?: { ... } - } product_images?: { $relation?: { ... } } | Array<{ @@ -3709,9 +7566,7 @@ type BasePriceItemDto = { _title?: { ... } $relation?: { ... } }> - price_options?: { - $relation?: { ... } - } + is_conditional?: boolean _availability_files?: Array<{ _id: { ... } filename: { ... } @@ -3730,6 +7585,29 @@ type BasePriceItemDto = { _created_at?: string _updated_at?: string } + catalog_reference?: { + product: { + id: { ... } + variant?: { ... } + } + price: { + id: { ... } + variant?: { ... } + } + price_components?: Array<{ + id: { ... } + variant?: { ... } + }> + coupons?: Array<{ + id: { ... } + variant?: { ... } + }> + as_of: string + _meta?: { + signature: { ... } + timestamp: { ... } + } + } } ``` @@ -3766,6 +7644,31 @@ type PriceItemDto = { variable_ht?: { ... } variable_nt?: { ... } } + inputs?: { + type?: { ... } + consumptionHT?: { ... } + consumptionNT?: { ... } + consumptionType?: { ... } + zipCode?: { ... } + city?: { ... } + providerId?: { ... } + billingPeriod?: { ... } + referenceDate?: { ... } + } + _meta?: { + signature: { ... } + timestamp: { ... } + } + } + external_location_metadata?: { + name: string + code: string + type: "gas" | "power" + additionalData: { + gridOperators: { ... } + defaultSuppliers: { ... } + marketAreaDetails: { ... } + } _meta?: { signature: { ... } timestamp: { ... } @@ -3797,6 +7700,7 @@ type PriceItemDto = { price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } } | { metadata?: { ... } quantity?: { ... } @@ -3808,36 +7712,10 @@ type PriceItemDto = { price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } }> amount_subtotal?: number amount_total?: number - unit_amount_gross?: number - unit_amount_net?: number - amount_tax?: number - total_details?: { - amount_shipping?: { ... } - amount_tax?: { ... } - breakdown?: { ... } - } - currency?: string - redeemed_promos?: Array<{ - code: { ... } - coupons: { ... } - }> - } - coupon_ids?: string[] - taxes?: Array<{ - rate?: string - tax?: { - _id: { ... } - _title: { ... } - _org: { ... } - _schema: { ... } - _tags?: { ... } - _created_at: { ... } - _updated_at: { ... } - type: { ... } - description?: { ... } // ... } ``` @@ -3875,6 +7753,31 @@ type CompositePriceItemDto = { variable_ht?: { ... } variable_nt?: { ... } } + inputs?: { + type?: { ... } + consumptionHT?: { ... } + consumptionNT?: { ... } + consumptionType?: { ... } + zipCode?: { ... } + city?: { ... } + providerId?: { ... } + billingPeriod?: { ... } + referenceDate?: { ... } + } + _meta?: { + signature: { ... } + timestamp: { ... } + } + } + external_location_metadata?: { + name: string + code: string + type: "gas" | "power" + additionalData: { + gridOperators: { ... } + defaultSuppliers: { ... } + marketAreaDetails: { ... } + } _meta?: { signature: { ... } timestamp: { ... } @@ -3901,52 +7804,27 @@ type CompositePriceItemDto = { product_id?: { ... } price_id?: { ... } description?: { ... } - product_description?: { ... } - product_name?: { ... } - price_mappings?: { ... } - is_tax_inclusive?: { ... } - _product?: { ... } - } | { - metadata?: { ... } - quantity?: { ... } - product_id?: { ... } - price_id?: { ... } - description?: { ... } - product_description?: { ... } - product_name?: { ... } - price_mappings?: { ... } - is_tax_inclusive?: { ... } - _product?: { ... } - }> - amount_subtotal?: number - amount_total?: number - unit_amount_gross?: number - unit_amount_net?: number - amount_tax?: number - total_details?: { - amount_shipping?: { ... } - amount_tax?: { ... } - breakdown?: { ... } - } - currency?: string - redeemed_promos?: Array<{ - code: { ... } - coupons: { ... } - }> - } - coupon_ids?: string[] - taxes?: Array<{ - rate?: string - tax?: { - _id: { ... } - _title: { ... } - _org: { ... } - _schema: { ... } - _tags?: { ... } - _created_at: { ... } - _updated_at: { ... } - type: { ... } + product_description?: { ... } + product_name?: { ... } + price_mappings?: { ... } + is_tax_inclusive?: { ... } + _product?: { ... } + catalog_reference?: { ... } + } | { + metadata?: { ... } + quantity?: { ... } + product_id?: { ... } + price_id?: { ... } description?: { ... } + product_description?: { ... } + product_name?: { ... } + price_mappings?: { ... } + is_tax_inclusive?: { ... } + _product?: { ... } + catalog_reference?: { ... } + }> + amount_subtotal?: number + amount_total?: number // ... } ``` @@ -3972,6 +7850,10 @@ type TaxAmountDto = { active?: boolean region?: string region_label?: string + } | { + type: "VAT" | "GST" | "Custom" + rate: number + description?: string } } ``` @@ -4074,6 +7956,14 @@ type OrderPayload = { currency: { ... } billing_period: { ... } breakdown: { ... } + inputs?: { ... } + _meta?: { ... } + } + external_location_metadata?: { + name: { ... } + code: { ... } + type: { ... } + additionalData: { ... } _meta?: { ... } } external_price_metadata?: { @@ -4134,21 +8024,13 @@ type OrderPayload = { fixed_value_currency?: { ... } cashback_period?: { ... } active?: { ... } + is_conditional?: { ... } requires_promo_code?: { ... } }> type?: "one_time" | "recurring" billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" unit_amount?: number unit_amount_gross?: number - unit_amount_currency?: string - unit_amount_decimal?: string - is_composite_price?: false - pricing_model?: "per_unit" | "tiered_graduated" | "tiered_volume" | "tiered_flatfee" | "dynamic_tariff" | "external_getag" - _price?: { - billing_duration_amount?: { ... } - billing_duration_unit?: { ... } - notice_time_amount?: { ... } - notice_time_unit?: { ... } // ... } ``` @@ -4187,9 +8069,6 @@ type PriceItems = Array<{ _tags?: { ... } feature?: { ... } }> - cross_sellable_products?: { - $relation?: { ... } - } product_images?: { $relation?: { ... } } | Array<{ @@ -4218,9 +8097,7 @@ type PriceItems = Array<{ _title?: { ... } $relation?: { ... } }> - price_options?: { - $relation?: { ... } - } + is_conditional?: boolean _availability_files?: Array<{ _id: { ... } filename: { ... } @@ -4239,25 +8116,30 @@ type PriceItems = Array<{ _created_at?: string _updated_at?: string } + catalog_reference?: { + product: { + id: { ... } + variant?: { ... } + } + price: { + id: { ... } + variant?: { ... } + } + price_components?: Array<{ + id: { ... } + variant?: { ... } + }> + coupons?: Array<{ + id: { ... } + variant?: { ... } + }> + as_of: string + _meta?: { + signature: { ... } + timestamp: { ... } + } + } } | { - metadata?: Array<{ - key?: string - value?: string - }> - quantity?: number - product_id?: string - price_id?: string - description?: string - product_description?: string - product_name?: string - price_mappings?: Array<{ - price_id?: string - frequency_unit?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" - name?: string - value?: number - metadata?: Record - }> - is_tax_inclusive?: boolean // ... } ``` @@ -4296,9 +8178,6 @@ type CompositePriceItem = { _tags?: { ... } feature?: { ... } }> - cross_sellable_products?: { - $relation?: { ... } - } product_images?: { $relation?: { ... } } | Array<{ @@ -4327,9 +8206,7 @@ type CompositePriceItem = { _title?: { ... } $relation?: { ... } }> - price_options?: { - $relation?: { ... } - } + is_conditional?: boolean _availability_files?: Array<{ _id: { ... } filename: { ... } @@ -4348,6 +8225,29 @@ type CompositePriceItem = { _created_at?: string _updated_at?: string } + catalog_reference?: { + product: { + id: { ... } + variant?: { ... } + } + price: { + id: { ... } + variant?: { ... } + } + price_components?: Array<{ + id: { ... } + variant?: { ... } + }> + coupons?: Array<{ + id: { ... } + variant?: { ... } + }> + as_of: string + _meta?: { + signature: { ... } + timestamp: { ... } + } + } } ``` @@ -4385,9 +8285,6 @@ type BasePriceItem = { _tags?: { ... } feature?: { ... } }> - cross_sellable_products?: { - $relation?: { ... } - } product_images?: { $relation?: { ... } } | Array<{ @@ -4416,9 +8313,7 @@ type BasePriceItem = { _title?: { ... } $relation?: { ... } }> - price_options?: { - $relation?: { ... } - } + is_conditional?: boolean _availability_files?: Array<{ _id: { ... } filename: { ... } @@ -4437,6 +8332,29 @@ type BasePriceItem = { _created_at?: string _updated_at?: string } + catalog_reference?: { + product: { + id: { ... } + variant?: { ... } + } + price: { + id: { ... } + variant?: { ... } + } + price_components?: Array<{ + id: { ... } + variant?: { ... } + }> + coupons?: Array<{ + id: { ... } + variant?: { ... } + }> + as_of: string + _meta?: { + signature: { ... } + timestamp: { ... } + } + } } ``` @@ -4534,9 +8452,6 @@ type PriceItem = { _tags?: { ... } feature?: { ... } }> - cross_sellable_products?: { - $relation?: { ... } - } product_images?: { $relation?: { ... } } | Array<{ @@ -4565,9 +8480,7 @@ type PriceItem = { _title?: { ... } $relation?: { ... } }> - price_options?: { - $relation?: { ... } - } + is_conditional?: boolean _availability_files?: Array<{ _id: { ... } filename: { ... } @@ -4586,6 +8499,29 @@ type PriceItem = { _created_at?: string _updated_at?: string } + catalog_reference?: { + product: { + id: { ... } + variant?: { ... } + } + price: { + id: { ... } + variant?: { ... } + } + price_components?: Array<{ + id: { ... } + variant?: { ... } + }> + coupons?: Array<{ + id: { ... } + variant?: { ... } + }> + as_of: string + _meta?: { + signature: { ... } + timestamp: { ... } + } + } } ``` @@ -4612,6 +8548,10 @@ type TaxAmount = { active?: boolean region?: string region_label?: string + } | { + type: "VAT" | "GST" | "Custom" + rate: number + description?: string } } ``` @@ -4660,10 +8600,11 @@ type RecurrenceAmount = { ### `CashbackAmount` -An amount associated with a specific cashback period. +A detail associated with a specific cashback. ```ts type CashbackAmount = { + cashback_name?: string cashback_period: "0" | "12" amount_total: number } @@ -4727,6 +8668,7 @@ type TotalDetails = { before_discount_amount_subtotal_decimal?: { ... } }> cashbacks?: Array<{ + cashback_name?: { ... } cashback_period: { ... } amount_total: { ... } }> @@ -4774,10 +8716,9 @@ type PricingDetails = { name?: { ... } categories?: { ... } feature?: { ... } - cross_sellable_products?: { ... } product_images?: { ... } product_downloads?: { ... } - price_options?: { ... } + is_conditional?: { ... } _availability_files?: { ... } _id?: { ... } _title?: { ... } @@ -4785,6 +8726,14 @@ type PricingDetails = { _created_at?: { ... } _updated_at?: { ... } } + catalog_reference?: { + product: { ... } + price: { ... } + price_components?: { ... } + coupons?: { ... } + as_of: { ... } + _meta?: { ... } + } } | { metadata?: Array<{ key?: { ... } @@ -4811,10 +8760,9 @@ type PricingDetails = { name?: { ... } categories?: { ... } feature?: { ... } - cross_sellable_products?: { ... } product_images?: { ... } product_downloads?: { ... } - price_options?: { ... } + is_conditional?: { ... } _availability_files?: { ... } _id?: { ... } _title?: { ... } @@ -4822,6 +8770,14 @@ type PricingDetails = { _created_at?: { ... } _updated_at?: { ... } } + catalog_reference?: { + product: { ... } + price: { ... } + price_components?: { ... } + coupons?: { ... } + as_of: { ... } + _meta?: { ... } + } }> amount_subtotal?: number amount_total?: number @@ -4833,20 +8789,6 @@ type PricingDetails = { amount_tax?: number breakdown?: { taxes?: { ... } - recurrences?: { ... } - cashbacks?: { ... } - recurrencesByTax?: { ... } - } - } - currency?: string - redeemed_promos?: Array<{ - code: string - coupons: Array<{ - _id: { ... } - _title: { ... } - _org: { ... } - _schema: { ... } - _tags?: { ... } // ... } ``` @@ -4875,6 +8817,7 @@ type PromoCodeValidationResponse = { fixed_value_currency?: string cashback_period?: "0" | "12" active?: boolean + is_conditional?: boolean requires_promo_code?: boolean }> } @@ -4912,10 +8855,9 @@ type PricingDetailsResponse = { name?: { ... } categories?: { ... } feature?: { ... } - cross_sellable_products?: { ... } product_images?: { ... } product_downloads?: { ... } - price_options?: { ... } + is_conditional?: { ... } _availability_files?: { ... } _id?: { ... } _title?: { ... } @@ -4923,6 +8865,14 @@ type PricingDetailsResponse = { _created_at?: { ... } _updated_at?: { ... } } + catalog_reference?: { + product: { ... } + price: { ... } + price_components?: { ... } + coupons?: { ... } + as_of: { ... } + _meta?: { ... } + } } | { metadata?: Array<{ key?: { ... } @@ -4949,10 +8899,9 @@ type PricingDetailsResponse = { name?: { ... } categories?: { ... } feature?: { ... } - cross_sellable_products?: { ... } product_images?: { ... } product_downloads?: { ... } - price_options?: { ... } + is_conditional?: { ... } _availability_files?: { ... } _id?: { ... } _title?: { ... } @@ -4960,6 +8909,14 @@ type PricingDetailsResponse = { _created_at?: { ... } _updated_at?: { ... } } + catalog_reference?: { + product: { ... } + price: { ... } + price_components?: { ... } + coupons?: { ... } + as_of: { ... } + _meta?: { ... } + } }> amount_subtotal?: number amount_total?: number @@ -4971,20 +8928,6 @@ type PricingDetailsResponse = { amount_tax?: number breakdown?: { taxes?: { ... } - recurrences?: { ... } - cashbacks?: { ... } - recurrencesByTax?: { ... } - } - } - currency?: string - redeemed_promos?: Array<{ - code: string - coupons: Array<{ - _id: { ... } - _title: { ... } - _org: { ... } - _schema: { ... } - _tags?: { ... } // ... } ``` @@ -5158,6 +9101,22 @@ type Tax = { } ``` +### `TaxItem` + +A minimal, ad-hoc tax rate for line items with no backing tax entity +in the catalog (e.g. a fully custom/composite price component built +by a client with no product/price reference to resolve tax from). +Mirrors how PriceItem relates to Price: unlike Tax, this has no +entity identity — it isn't persis + +```ts +type TaxItem = { + type: "VAT" | "GST" | "Custom" + rate: number + description?: string +} +``` + ### `TaxBreakdownInfo` ```ts @@ -5191,6 +9150,7 @@ type BaseCouponCommon = { fixed_value_currency?: string cashback_period?: "0" | "12" active?: boolean + is_conditional?: boolean requires_promo_code?: boolean } ``` @@ -5218,6 +9178,7 @@ type CouponWithoutPromoCodes = { fixed_value_currency?: string cashback_period?: "0" | "12" active?: boolean + is_conditional?: boolean requires_promo_code?: boolean } ``` @@ -5245,6 +9206,7 @@ type Coupon = { fixed_value_currency?: string cashback_period?: "0" | "12" active?: boolean + is_conditional?: boolean requires_promo_code?: boolean } ``` @@ -5270,6 +9232,7 @@ type CouponItem = { fixed_value_currency?: string cashback_period?: "0" | "12" active?: boolean + is_conditional?: boolean requires_promo_code?: boolean } ``` @@ -5308,6 +9271,7 @@ type RedeemedPromo = { fixed_value_currency?: string cashback_period?: "0" | "12" active?: boolean + is_conditional?: boolean requires_promo_code?: boolean }> } @@ -5538,71 +9502,21 @@ The request payload for the external catalog service with a portal context. type ExternalCatalogPortalRequest = { origin: "portal" context: { - contract: { - _id?: { ... } - contract_name?: { ... } - contract_number?: { ... } - assignee?: { ... } - status?: { ... } - description?: { ... } - billing_account?: { ... } - account_number?: { ... } - branch?: { ... } - move_in_date?: { ... } - move_out_date?: { ... } - billing_address?: { ... } - delivery_address?: { ... } - additional_addresses?: { ... } - termination_date?: { ... } - termination_reason?: { ... } - start_date?: { ... } - end_date?: { ... } - customer?: { ... } - order?: { ... } - type?: { ... } - billing_period?: { ... } - billing_duration_amount?: { ... } - billing_duration_unit?: { ... } - notice_time_amount?: { ... } - notice_time_unit?: { ... } - termination_time_amount?: { ... } - termination_time_unit?: { ... } - renewal_duration_amount?: { ... } - renewal_duration_unit?: { ... } - billing_due_day?: { ... } - installment_amount?: { ... } - balance?: { ... } - meters?: { ... } - payment?: { ... } - last_sync_at?: { ... } - external_id?: { ... } - } - contact: { - _id?: { ... } - salutation?: { ... } - title?: { ... } - first_name?: { ... } - last_name?: { ... } - customer_number?: { ... } - birthdate?: { ... } - email?: { ... } - phone?: { ... } - communication_preference?: { ... } - address?: { ... } - payment?: { ... } - account?: { ... } - marketing_permission?: { ... } - contact_owner?: { ... } - consent_email_marketing?: { ... } - consent_sms_marketing?: { ... } - consent_phone_call?: { ... } - consent_print_marketing?: { ... } - portal_users?: { ... } - opportunities?: { ... } - orders?: { ... } - contracts?: { ... } - external_id?: { ... } + contract: Record + contact: Record + availability_address?: { + postal_code?: { ... } + city?: { ... } + street?: { ... } + street_number?: { ... } + journey_target_block?: { ... } } + variable_inputs?: Array<{ + value?: { ... } + unit?: { ... } + frequency_unit?: { ... } + journey_target_block?: { ... } + }> } } ``` @@ -5649,92 +9563,21 @@ type JourneyContext = { ```ts type PortalContext = { - contract: { - _id?: string - contract_name?: string - contract_number?: string - assignee?: string - status?: "draft" | "in_approval_process" | "approved" | "active" | "deactivated" | "revoked" | "terminated" | "expired" - description?: string - billing_account?: string - account_number?: string - branch?: "power" | "gas" | "water" | "waste_water" | "district_heating" - move_in_date?: string // date - move_out_date?: string // date - billing_address?: object - delivery_address?: object - additional_addresses?: object[] - termination_date?: string // date - termination_reason?: string - start_date?: string // date - end_date?: string // date - customer?: string[] - order?: string - type?: "one_time" | "recurring" - billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" - billing_duration_amount?: number - billing_duration_unit?: "weeks" | "months" | "years" - notice_time_amount?: number - notice_time_unit?: "weeks" | "months" | "years" - termination_time_amount?: number - termination_time_unit?: "weeks" | "months" | "years" - renewal_duration_amount?: number - renewal_duration_unit?: "weeks" | "months" | "years" - billing_due_day?: number - installment_amount?: { - value?: { ... } - currency?: { ... } - } - balance?: { - value?: { ... } - currency?: { ... } - } - meters?: string[] - payment?: string - last_sync_at?: string // date - external_id?: string - } - contact: { - _id?: string - salutation?: "Mr." | "Ms. / Mrs." | "Company" | "Contact Person" | "Company/Contact Person" | "Spouse" | "Family" | "Ownership" | "Assembly" | "Other" - title?: "Dr." | "Prof." | "Prof. Dr." - first_name?: string - last_name?: string - customer_number?: string - birthdate?: string // date - email?: Array<{ - email?: { ... } - _primary?: { ... } - }> - phone?: Array<{ - phone?: { ... } - _primary?: { ... } - }> - communication_preference?: "postal" | "portal" - address?: Array<{ - _primary?: { ... } - postal_code?: { ... } - city?: { ... } - street?: { ... } - street_number?: { ... } - country?: { ... } - }> - payment?: Array<{ - _primary?: { ... } - }> - account?: string[] - marketing_permission?: boolean - contact_owner?: string - consent_email_marketing?: object - consent_sms_marketing?: object - consent_phone_call?: object - consent_print_marketing?: object - portal_users?: string[] - opportunities?: string[] - orders?: string[] - contracts?: string[] - external_id?: string + contract: Record + contact: Record + availability_address?: { + postal_code?: string + city?: string + street?: string + street_number?: string + journey_target_block?: string } + variable_inputs?: Array<{ + value?: number + unit?: string + frequency_unit?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time" + journey_target_block?: string + }> } ``` @@ -5822,6 +9665,7 @@ type ExternalCatalogItem = { price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } } | { metadata?: { ... } quantity?: { ... } @@ -5833,6 +9677,7 @@ type ExternalCatalogItem = { price_mappings?: { ... } is_tax_inclusive?: { ... } _product?: { ... } + catalog_reference?: { ... } }> amount_subtotal?: number amount_total?: number @@ -5898,6 +9743,47 @@ type ProductRecommendationResponse = { _created_at: string // date-time _updated_at: string // date-time }> + source?: { + item?: { + metadata?: { ... } + quantity?: { ... } + product_id?: { ... } + price_id?: { ... } + description?: { ... } + product_description?: { ... } + product_name?: { ... } + price_mappings?: { ... } + is_tax_inclusive?: { ... } + _product?: { ... } + catalog_reference?: { ... } + } | { + metadata?: { ... } + quantity?: { ... } + product_id?: { ... } + price_id?: { ... } + description?: { ... } + product_description?: { ... } + product_name?: { ... } + price_mappings?: { ... } + is_tax_inclusive?: { ... } + _product?: { ... } + catalog_reference?: { ... } + } + } +} +``` + +### `OfferHighlightConfig` + +```ts +type OfferHighlightConfig = { + unique_selling_point?: string + unique_selling_point_icon?: string + total?: { + enabled?: boolean + format?: "absolute" | "relative" + only_if_better?: boolean + } } ``` @@ -5909,6 +9795,11 @@ type Offer = { items?: Array<{ price_id: string product_id: string + highlight_config?: { + unique_selling_point?: { ... } + unique_selling_point_icon?: { ... } + total?: { ... } + } }> } ``` diff --git a/docs/sdk/clients/query.md b/docs/sdk/clients/query.md new file mode 100644 index 00000000..237364f7 --- /dev/null +++ b/docs/sdk/clients/query.md @@ -0,0 +1,1614 @@ +--- +title: "Query API" +description: "TypeScript SDK client for the epilot Query API: usage with @epilot/sdk, all operations and schemas." +--- + +# Query API + +- **Base URL:** `https://query.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/query](https://docs.epilot.io/api/query) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.query.createOrUpdateView(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/query' + +const queryClient = getClient() +authorize(queryClient, () => '') +const { data } = await queryClient.createOrUpdateView(...) +``` + +## Operations + +**Datalake V2** +- [`createOrUpdateView`](#createorupdateview) +- [`getAllViews`](#getallviews) +- [`getView`](#getview) +- [`createOrUpdateRelationship`](#createorupdaterelationship) +- [`getAllRelationships`](#getallrelationships) + +**Datasets** +- [`listAvailableDatasetsV2`](#listavailabledatasetsv2) + +**Query** +- [`executeEntitiesQuery`](#executeentitiesquery) +- [`executeWorkflowsQuery`](#executeworkflowsquery) +- [`executeAutomationQuery`](#executeautomationquery) +- [`listWorkflowPhasesByDefinitionId`](#listworkflowphasesbydefinitionid) +- [`listWorkflowDefinitions`](#listworkflowdefinitions) +- [`listPhaseNames`](#listphasenames) + +**V1** +- [`listDatasets`](#listdatasets) +- [`executeQuery`](#executequery) + +**CredentialsV2** +- [`generateCredentialsV2`](#generatecredentialsv2) +- [`listCredentialsV2`](#listcredentialsv2) +- [`revokeCredentialsV2`](#revokecredentialsv2) + +**V2** +- [`executeQueryV2`](#executequeryv2) +- [`getSemanticModel`](#getsemanticmodel) +- [`autocomplete`](#autocomplete) +- [`workflowsAutocomplete`](#workflowsautocomplete) + +**Schemas** +- [`ErrorResponse`](#errorresponse) +- [`ViewRequest`](#viewrequest) +- [`CurrentEntitiesViewRequest`](#currententitiesviewrequest) +- [`TaxonomiesViewRequest`](#taxonomiesviewrequest) +- [`WorkflowExecutionsViewRequest`](#workflowexecutionsviewrequest) +- [`ViewResponse`](#viewresponse) +- [`ViewsListResponse`](#viewslistresponse) +- [`RelationshipRequest`](#relationshiprequest) +- [`RelationshipResponse`](#relationshipresponse) +- [`RelationshipsListResponse`](#relationshipslistresponse) +- [`NoCache`](#nocache) +- [`CacheExpiration`](#cacheexpiration) +- [`UserId`](#userid) +- [`DatasetDomain`](#datasetdomain) +- [`Dataset`](#dataset) +- [`DatalakeQueryOptions`](#datalakequeryoptions) +- [`DatalakeQuery`](#datalakequery) +- [`AutomationQueryOptions`](#automationqueryoptions) +- [`DatasetOptions.AutomationExecutionsOverview`](#datasetoptions.automationexecutionsoverview) +- [`DatasetOptions.ListAutomationDefinitions`](#datasetoptions.listautomationdefinitions) +- [`WorkflowsQueryOptions`](#workflowsqueryoptions) +- [`DatasetOptions.TotalCountOfWorkflowExecutions`](#datasetoptions.totalcountofworkflowexecutions) +- [`DatasetOptions.WorkflowExecutionTimeSeries`](#datasetoptions.workflowexecutiontimeseries) +- [`DatasetOptions.CumulativeSumOfWorkflows`](#datasetoptions.cumulativesumofworkflows) +- [`DatasetOptions.CancellationReasons`](#datasetoptions.cancellationreasons) +- [`DatasetOptions.WorkflowTasksOverview`](#datasetoptions.workflowtasksoverview) +- [`Response.WorkflowTaskOverview`](#response.workflowtaskoverview) +- [`ECPDetails`](#ecpdetails) +- [`WorkflowContext`](#workflowcontext) +- [`WorkflowStatus`](#workflowstatus) +- [`AutomationConfig`](#automationconfig) +- [`DynamicDueDate`](#dynamicduedate) +- [`TaskStatus`](#taskstatus) +- [`TaskRequirement`](#taskrequirement) +- [`TaskType`](#tasktype) +- [`Task`](#task) +- [`WorkflowsQueryOptions.WorkflowDefinitionIDs`](#workflowsqueryoptions.workflowdefinitionids) +- [`WorkflowsQueryOptions.EntitySchema`](#workflowsqueryoptions.entityschema) +- [`WorkflowsQueryOptions.RelativeTimeRange`](#workflowsqueryoptions.relativetimerange) +- [`WorkflowsQueryOptions.TimeRangeFrom`](#workflowsqueryoptions.timerangefrom) +- [`WorkflowsQueryOptions.TimeRangeTo`](#workflowsqueryoptions.timerangeto) +- [`WorkflowsQueryOptions.GroupTimeBy`](#workflowsqueryoptions.grouptimeby) +- [`WorkflowsQueryOptions.WorkflowStates`](#workflowsqueryoptions.workflowstates) +- [`DatasetName`](#datasetname) +- [`EntityDataset`](#entitydataset) +- [`AutomationExecutionDataset`](#automationexecutiondataset) +- [`WorkflowDataset`](#workflowdataset) +- [`WorkflowStates`](#workflowstates) +- [`PhaseStates`](#phasestates) +- [`TaskStates`](#taskstates) +- [`SortBy`](#sortby) +- [`TimeGroups`](#timegroups) +- [`RelativeTimeRange`](#relativetimerange) +- [`WorkflowsQueryResult`](#workflowsqueryresult) +- [`AutomationExecutionResponse`](#automationexecutionresponse) +- [`ListAutomationDefinitionsResponse`](#listautomationdefinitionsresponse) +- [`SemanticModel`](#semanticmodel) +- [`QueryResults`](#queryresults) +- [`TimeSeriesSettings`](#timeseriessettings) +- [`NameDurationSettings`](#namedurationsettings) + +### `createOrUpdateView` + +Create or update a materialized SQL view in the epilot data lake. + +`POST /datalake/views` + +```ts +const { data } = await client.createOrUpdateView( + null, + { + view_name: 'some_view', + source_dataset: 'current_entities', + config: { + schema: 'some_schema', + include_purpose_view: true, + include_label_view: true, + include_relation_view: true, + relationship_attribute: ['some_relationship_attribute'] + } + }, +) +``` + +
+Response + +```json +{ + "view_name": "some_view", + "source_dataset": "current_entities", + "attributes": [ + { + "name": "some_attribute", + "type": "string", + "description": "some description" + } + ] +} +``` + +
+ +--- + +### `getAllViews` + +Retrieve all materialized data lake views configured for the organization. + +`GET /datalake/views` + +```ts +const { data } = await client.getAllViews() +``` + +
+Response + +```json +{ + "views": [ + { + "view_name": "some_view", + "source_dataset": "current_entities", + "view_slug": "some_view", + "attributes": [ + { + "name": "some_attribute", + "type": "string", + "description": "some description" + } + ] + }, + { + "view_name": "another_view", + "source_dataset": "taxonomies", + "view_slug": "another_view", + "attributes": [ + { + "name": "taxonomy_attribute", + "type": "string", + "description": "taxonomy attribute description" + } + ] + } + ] +} +``` + +
+ +--- + +### `getView` + +Retrieve the definition and attributes of a specific data lake view by its slug. + +`GET /datalake/views/{view_slug}` + +```ts +const { data } = await client.getView({ + view_slug: 'example', +}) +``` + +
+Response + +```json +{ + "view_name": "some_view", + "source_dataset": "current_entities", + "attributes": [ + { + "name": "some_attribute", + "type": "string", + "description": "some description" + } + ] +} +``` + +
+ +--- + +### `createOrUpdateRelationship` + +Define or update a relationship between two tables in the data lake. + +`POST /datalake/relationships` + +```ts +const { data } = await client.createOrUpdateRelationship( + null, + { + relationship_name: 'some_relationship', + from_table: 'some_table', + to_table: 'some_table', + from_column: 'some_column', + to_column: 'some_column', + type: 'one_to_many' + }, +) +``` + +
+Response + +```json +{ + "relationship_name": "some_relationship", + "from_table": "some_table", + "to_table": "some_table", + "from_column": "some_column", + "to_column": "some_column", + "type": "one_to_many" +} +``` + +
+ +--- + +### `getAllRelationships` + +Retrieve all table relationships configured for the organization's data lake. + +`GET /datalake/relationships` + +```ts +const { data } = await client.getAllRelationships() +``` + +
+Response + +```json +{ + "relationships": [ + { + "relationship_name": "some_relationship", + "from_table": "some_table", + "to_table": "some_table", + "from_column": "some_column", + "to_column": "some_column", + "type": "one_to_many" + }, + { + "relationship_name": "another_relationship", + "from_table": "table_a", + "to_table": "table_b", + "from_column": "column_a", + "to_column": "column_b", + "type": "many_to_many" + } + ] +} +``` + +
+ +--- + +### `listAvailableDatasetsV2` + +Lists all available datasets grouped by domain + +`GET /v2/query/datasets` + +```ts +const { data } = await client.listAvailableDatasetsV2() +``` + +
+Response + +```json +{ + "results": [ + { + "domain": "entities", + "dataset": "entity_operations", + "endpoint": "/v2/query/domain/entities:execute" + }, + { + "domain": "workflows", + "dataset": "workflow_execution_time_series", + "endpoint": "/v2/query/domain/workflows:execute" + } + ] +} +``` + +
+ +--- + +### `executeEntitiesQuery` + +Execute queries against entities datasets. + +`POST /v2/query/domain/entities:execute` + +```ts +const { data } = await client.executeEntitiesQuery( + { + cache_expiration: 'example', + no_cache: true, + }, + { + query: {} + }, +) +``` + +
+Response + +```json +{ + "status": "FINISHED", + "timestamp": "1715621496068", + "results": [ + {} + ] +} +``` + +
+ +--- + +### `executeWorkflowsQuery` + +Query Workflow Analytics Datasets. + +`POST /v2/query/domain/workflows:execute` + +```ts +const { data } = await client.executeWorkflowsQuery( + { + mock: true, + cache_expiration: 'example', + no_cache: true, + }, + { + dataset: 'total_count_of_workflow_executions', + workflow_definition_ids: ['string'], + entity_schemas: ['string'], + states: ['string'], + group_time_by: 'M', + relative_time_range: 'string', + time_range_from: 'string', + time_range_to: 'string', + duration_threshold: 0 + }, +) +``` + +
+Response + +```json +{ + "data": [0, 1], + "labels": ["label1", "label2"], + "timestamp": "1715621496068" +} +``` + +
+ +--- + +### `executeAutomationQuery` + +Query Automation Analytics Datasets. + +`POST /v2/query/domain/automations:execute` + +```ts +const { data } = await client.executeAutomationQuery( + { + from: 1, + size: 1, + }, + { + dataset: 'automation_executions_overview', + flow_ids: ['string'], + execution_states: ['success', 'failed', 'scheduled'], + relative_time_range: 'all_time', + time_range_from: 'string', + time_range_to: 'string' + }, +) +``` + +
+Response + +```json +{ + "hits": 100, + "results": [ + { + "flow_id": "1234567890", + "flow_name": "flow_name", + "execution_id": "execution_id", + "execution_status": "execution_status", + "entity_schema": "opportunity", + "entity_id": "entity_id", + "created_at": "execution_created_at", + "updated_at": "execution_updated_at", + "error": { + "message": "error_message", + "error_code": "error_code" + }, + "trigger_event": { + "type": "EntityOperation", + "trigger_type": "createEntity" + } + } + ] +} +``` + +
+ +--- + +### `listWorkflowPhasesByDefinitionId` + +Retrieves the workflow phases associated with a given workflow definition ID. + +`GET /v2/query/domain/workflows/definitions/{workflowDefinitionId}/phases` + +```ts +const { data } = await client.listWorkflowPhasesByDefinitionId({ + workflowDefinitionId: 'example', +}) +``` + +
+Response + +```json +[ + { + "id": "y0UdVCOI", + "name": "Initial Phase" + } +] +``` + +
+ +--- + +### `listWorkflowDefinitions` + +Lists available worflow definitions with their ids, names and start times + +`GET /v2/query/domain/workflows/definitions` + +```ts +const { data } = await client.listWorkflowDefinitions({ + mock: true, +}) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "y0UdVCOI", + "name": "PV Kauf", + "max_date": "2023-05-31T00:00:00.000Z", + "min_date": "2023-01-00T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `listPhaseNames` + +Lists phase names of an org. + +`GET /v2/query/domain/workflows/phases` + +```ts +const { data } = await client.listPhaseNames({ + org_id: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "id": "y0UdVCOI", + "name": "PV Kauf", + "max_date": "2023-05-31T00:00:00.000Z", + "min_date": "2023-01-00T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `listDatasets` + +Get list of available datasets + +`GET /v1/query/datasets` + +```ts +const { data } = await client.listDatasets() +``` + +
+Response + +```json +{ + "results": [ + { + "dataset": "entity_operations" + }, + { + "dataset": "entities_timemachine" + } + ] +} +``` + +
+ +--- + +### `executeQuery` + +Execute queries against datasets. + +`POST /v1/query:execute` + +```ts +const { data } = await client.executeQuery( + { + cache_expiration: 'example', + no_cache: true, + }, + { + query: {} + }, +) +``` + +
+Response + +```json +{ + "status": "FINISHED", + "timestamp": "1715621496068", + "results": [ + {} + ] +} +``` + +
+ +--- + +### `generateCredentialsV2` + +Generate credentials for the epilot datalake for connecting other BI tools with ClickHouse + +`POST /v2/query/credentials:generate` + +```ts +const { data } = await client.generateCredentialsV2() +``` + +
+Response + +```json +{ + "username": "datalakeuser_sfsdfs_66", + "password": "***", + "endpoints": { + "host": "qjjcxsy87t.eu-central-1.aws.clickhouse.cloud", + "port": 8443 + }, + "database": "datawarehouse" +} +``` + +
+ +--- + +### `listCredentialsV2` + +List all the credentialof Clickhouse for the organization here + +`GET /v2/query/credentials:list` + +```ts +const { data } = await client.listCredentialsV2() +``` + +
+Response + +```json +{ + "users": [ + { + "user_id": "string" + } + ] +} +``` + +
+ +--- + +### `revokeCredentialsV2` + +Revoke credentials for the epilot datalake for connecting other BI tools with Clickhouse + +`POST /v2/query/credentials:revoke` + +```ts +const { data } = await client.revokeCredentialsV2({ + user_id: 'example', +}) +``` + +
+Response + +```json +{ + "success": true +} +``` + +
+ +--- + +### `executeQueryV2` + +Execute queries against datasets. + +`POST /v2/query:execute` + +```ts +const { data } = await client.executeQueryV2( + null, + {}, +) +``` + +
+Response + +```json +{ + "status": "FINISHED", + "timestamp": "1715621496068", + "results": [ + {} + ] +} +``` + +
+ +--- + +### `getSemanticModel` + +Get the semantic model for agent/tool consumption. + +`GET /v2/query/semantic-model` + +```ts +const { data } = await client.getSemanticModel() +``` + +
+Response + +```json +{ + "entities": [ + { + "name": "current_contacts", + "displayName": "Contacts", + "schema": "entity" + } + ], + "relationships": [ + { + "from": "current_contacts", + "to": "opportunity_account_contact_relation", + "relationship": "hasMany", + "displayName": "Contact has many Opportunities" + } + ], + "capabilities": { + "aggregations": ["count", "count_distinct", "sum", "average", "min", "max", "median"], + "calculationTypes": [ + { + "type": "string", + "description": "string", + "parameters": {} + } + ], + "granularities": ["day", "week", "month", "quarter", "year"], + "filterOperators": [ + { + "operator": "string", + "description": "string" + } + ] + } +} +``` + +
+ +--- + +### `autocomplete` + +Generic autocomplete endpoint for querying distinct values across datasets. +Use the dataset parameter to specify which data category to query. + +`GET /v2/query/autocomplete` + +```ts +const { data } = await client.autocomplete({ + dataset: 'example', + input: 'example', + attribute: 'example', + size: 1, +}) +``` + +
+Response + +```json +{ + "results": ["value"] +} +``` + +
+ +--- + +### `workflowsAutocomplete` + +Autocomplete Workflows data + +`GET /v2/query/workflows:autocomplete` + +```ts +const { data } = await client.workflowsAutocomplete({ + input: 'example', + attribute: 'example', + size: 1, +}) +``` + +
+Response + +```json +{ + "results": ["value"] +} +``` + +
+ +--- + +## Schemas + +### `ErrorResponse` + +Standard error response body + +```ts +type ErrorResponse = { + status?: number + error?: string + message?: string +} +``` + +### `ViewRequest` + +```ts +type ViewRequest = { + view_name?: string + source_dataset: "current_entities" + config: { + schema: string + include_purpose_view?: boolean + include_label_view?: boolean + include_relation_view?: boolean + relationship_attribute?: string[] + } +} | { + view_name?: string + source_dataset: "taxonomies" +} | { + view_name?: string + source_dataset: "workflow_executions" +} +``` + +### `CurrentEntitiesViewRequest` + +```ts +type CurrentEntitiesViewRequest = { + view_name?: string + source_dataset: "current_entities" + config: { + schema: string + include_purpose_view?: boolean + include_label_view?: boolean + include_relation_view?: boolean + relationship_attribute?: string[] + } +} +``` + +### `TaxonomiesViewRequest` + +```ts +type TaxonomiesViewRequest = { + view_name?: string + source_dataset: "taxonomies" +} +``` + +### `WorkflowExecutionsViewRequest` + +```ts +type WorkflowExecutionsViewRequest = { + view_name?: string + source_dataset: "workflow_executions" +} +``` + +### `ViewResponse` + +```ts +type ViewResponse = { + view_name: string + source_dataset: "current_entities" | "taxonomies" | "workflow_executions" + attributes: Array<{ + name: string + type: string + description?: string + }> +} +``` + +### `ViewsListResponse` + +```ts +type ViewsListResponse = { + views?: Array<{ + view_name: string + source_dataset: "current_entities" | "taxonomies" | "workflow_executions" + view_slug?: string + attributes: Array<{ + name: { ... } + type: { ... } + description?: { ... } + }> + }> +} +``` + +### `RelationshipRequest` + +```ts +type RelationshipRequest = { + relationship_name: string + from_table: string + to_table: string + from_column: string + to_column: string + type: "one_to_many" | "many_to_many" | "many_to_one" | "one_to_one" +} +``` + +### `RelationshipResponse` + +```ts +type RelationshipResponse = { + relationship_name?: string + from_table?: string + to_table?: string + from_column?: string + to_column?: string + type?: "one_to_many" | "many_to_many" | "many_to_one" | "one_to_one" +} +``` + +### `RelationshipsListResponse` + +```ts +type RelationshipsListResponse = { + relationships?: Array<{ + relationship_name?: string + from_table?: string + to_table?: string + from_column?: string + to_column?: string + type?: "one_to_many" | "many_to_many" | "many_to_one" | "one_to_one" + }> +} +``` + +### `NoCache` + +```ts +type NoCache = boolean +``` + +### `CacheExpiration` + +Cache Expiration timestamp + +```ts +type CacheExpiration = string // timestamp +``` + +### `UserId` + +Execution Id for the query + +```ts +type UserId = string +``` + +### `DatasetDomain` + +```ts +type DatasetDomain = "entities" | "workflows" +``` + +### `Dataset` + +```ts +type Dataset = { + dataset?: string + domain?: "entities" | "workflows" + endpoint?: string +} +``` + +### `DatalakeQueryOptions` + +```ts +type DatalakeQueryOptions = { + dataset?: string + measure?: string + dimensions?: Record[] + filters?: Record[] + exclude_deleted?: boolean +} +``` + +### `DatalakeQuery` + +```ts +type DatalakeQuery = { + dataset?: string + measure?: string + dimensions?: Record[] + filters?: Record[] + exclude_deleted?: boolean +} +``` + +### `AutomationQueryOptions` + +```ts +type AutomationQueryOptions = { + dataset: "automation_executions_overview" | "list_automation_definitions" +} +``` + +### `DatasetOptions.AutomationExecutionsOverview` + +```ts +type DatasetOptions.AutomationExecutionsOverview = { + dataset: "automation_executions_overview" | "list_automation_definitions" + flow_ids?: string[] + execution_states?: string[] + relative_time_range?: "all_time" | "this_week" | "last_week" | "last_7_days" | "this_month" | "last_month" | "last_30_days" | "last_3_months" | "last_6_months" | "this_year" | "last_year" + time_range_from?: string + time_range_to?: string +} +``` + +### `DatasetOptions.ListAutomationDefinitions` + +```ts +type DatasetOptions.ListAutomationDefinitions = { + dataset: "automation_executions_overview" | "list_automation_definitions" + search?: string +} +``` + +### `WorkflowsQueryOptions` + +Settings for the data of the chart that is being queried. + +```ts +type WorkflowsQueryOptions = { + dataset?: "total_count_of_workflow_executions" | "workflow_execution_time_series" | "cumulative_sum_of_workflows" | "cancellation_reasons" | "phases_count" | "phases_duration" | "tasks_duration" | "task_duration" | "workflow_tasks_overview" + workflow_definition_ids?: string[] + entity_schemas?: string[] + states?: string[] + group_time_by?: string + relative_time_range?: string + time_range_from?: string + time_range_to?: string + duration_threshold?: number +} +``` + +### `DatasetOptions.TotalCountOfWorkflowExecutions` + +See the total of workflow executions in a pie chart. + +```ts +type DatasetOptions.TotalCountOfWorkflowExecutions = { + workflow_definition_ids?: string[] + entity_schema?: string + relative_time_range?: string + time_range_from?: string + time_range_to?: string +} +``` + +### `DatasetOptions.WorkflowExecutionTimeSeries` + +```ts +type DatasetOptions.WorkflowExecutionTimeSeries = { + workflow_definition_ids?: string[] + entity_schema?: string + relative_time_range?: string + time_range_from?: string + time_range_to?: string + workflow_states?: string[] + group_time_by?: string +} +``` + +### `DatasetOptions.CumulativeSumOfWorkflows` + +```ts +type DatasetOptions.CumulativeSumOfWorkflows = { + workflow_definition_ids?: string[] + entity_schema?: string + relative_time_range?: string + time_range_from?: string + time_range_to?: string + workflow_states?: string[] + group_time_by?: string +} +``` + +### `DatasetOptions.CancellationReasons` + +See the cancellation reasons of workflows in a pie chart. + +```ts +type DatasetOptions.CancellationReasons = { + workflow_definition_ids?: string[] + entity_schema?: string + relative_time_range?: string + time_range_from?: string + time_range_to?: string +} +``` + +### `DatasetOptions.WorkflowTasksOverview` + +Get a list of tasks to help organize executing users their day. + +```ts +type DatasetOptions.WorkflowTasksOverview = { + dataset: "total_count_of_workflow_executions" | "workflow_execution_time_series" | "cumulative_sum_of_workflows" | "cancellation_reasons" | "phases_count" | "phases_duration" | "tasks_duration" | "task_duration" | "workflow_tasks_overview" + workflow_definition_ids?: string[] + entity_schema?: string + relative_time_range?: string + time_range_from?: string + time_range_to?: string + assignee_ids?: string[] + include_unassigned?: boolean + due_date_from?: string + due_date_to?: string + sort_by?: string + page_number?: number + page_size?: number +} +``` + +### `Response.WorkflowTaskOverview` + +```ts +type Response.WorkflowTaskOverview = { + results?: Array<{ + orgId?: string + id?: string + definitionId?: string + phaseId?: string + entityRefId?: string + name?: string + type?: "MANUAL" | "AUTOMATION" + ecp?: { + label?: { ... } + } + requirements?: Array<{ + definitionId?: { ... } + type?: { ... } + condition?: { ... } + }> + executionType?: "MANUAL" | "AUTOMATION" + executionId?: string + assignedTo?: string[] + assignedToInProgress?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" + executionStatus?: "STARTED" | "DONE" | "CLOSED" + created?: string + lastUpdated?: string + dueDate?: string + dynamicDueDate?: { + numberOfUnits: { ... } + timePeriod: { ... } + actionTypeCondition?: { ... } + stepId?: { ... } + } + manuallyCreated?: boolean + enabled?: boolean + automationConfig?: { + flowId: { ... } + executionId?: { ... } + executionStatus?: { ... } + } + executionName?: string + contexts?: Array<{ + id: { ... } + title: { ... } + schema: { ... } + }> + }> + hits?: number +} +``` + +### `ECPDetails` + +Details regarding ECP for the workflow step + +```ts +type ECPDetails = { + label?: string +} +``` + +### `WorkflowContext` + +```ts +type WorkflowContext = { + id: string + title: string + schema: string +} +``` + +### `WorkflowStatus` + +```ts +type WorkflowStatus = "STARTED" | "DONE" | "CLOSED" +``` + +### `AutomationConfig` + +Configuration for automation execution to run + +```ts +type AutomationConfig = { + flowId: string + executionId?: string + executionStatus?: string +} +``` + +### `DynamicDueDate` + +set a Duedate for a step then a specific + +```ts +type DynamicDueDate = { + numberOfUnits: number + timePeriod: "days" | "weeks" | "months" + actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" + stepId?: string +} +``` + +### `TaskStatus` + +```ts +type TaskStatus = "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" +``` + +### `TaskRequirement` + +describe the requirement for step enablement + +```ts +type TaskRequirement = { + definitionId?: string + type?: "STEP" + condition?: "CLOSED" +} +``` + +### `TaskType` + +```ts +type TaskType = "MANUAL" | "AUTOMATION" +``` + +### `Task` + +```ts +type Task = { + orgId?: string + id?: string + definitionId?: string + phaseId?: string + entityRefId?: string + name?: string + type?: "MANUAL" | "AUTOMATION" + ecp?: { + label?: string + } + requirements?: Array<{ + definitionId?: string + type?: "STEP" + condition?: "CLOSED" + }> + executionType?: "MANUAL" | "AUTOMATION" + executionId?: string + assignedTo?: string[] + assignedToInProgress?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" + executionStatus?: "STARTED" | "DONE" | "CLOSED" + created?: string + lastUpdated?: string + dueDate?: string + dynamicDueDate?: { + numberOfUnits: number + timePeriod: "days" | "weeks" | "months" + actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" + stepId?: string + } + manuallyCreated?: boolean + enabled?: boolean + automationConfig?: { + flowId: string + executionId?: string + executionStatus?: string + } + executionName?: string + contexts?: Array<{ + id: string + title: string + schema: string + }> +} +``` + +### `WorkflowsQueryOptions.WorkflowDefinitionIDs` + +Filter by specific workflows by passing a list of workflow definition ids. + +```ts +type WorkflowsQueryOptions.WorkflowDefinitionIDs = string[] +``` + +### `WorkflowsQueryOptions.EntitySchema` + +Workflows can be applied to different kinds of entities, e.g. on Opportunities or Orders. +You can choose to limit your results to workflow executions to specific entity schemas / types. + + +```ts +type WorkflowsQueryOptions.EntitySchema = string +``` + +### `WorkflowsQueryOptions.RelativeTimeRange` + +A combination of two worde that describe a time range, e.g. "this year" or "last month" + +```ts +type WorkflowsQueryOptions.RelativeTimeRange = string +``` + +### `WorkflowsQueryOptions.TimeRangeFrom` + +Set a specific start of a time range, e.g. "2023-01-01" + +```ts +type WorkflowsQueryOptions.TimeRangeFrom = string +``` + +### `WorkflowsQueryOptions.TimeRangeTo` + +Set a specific end of a time range, e.g. "2023-06-30" + +```ts +type WorkflowsQueryOptions.TimeRangeTo = string +``` + +### `WorkflowsQueryOptions.GroupTimeBy` + +If chosen a time series, this parameter sets by which time the data is grouped, e.g. quarterly, monthly or weekly. Available values: "D","W","M","Q","Y" + +```ts +type WorkflowsQueryOptions.GroupTimeBy = string +``` + +### `WorkflowsQueryOptions.WorkflowStates` + +Filter by the states of the workflow executions. + +```ts +type WorkflowsQueryOptions.WorkflowStates = string[] +``` + +### `DatasetName` + +```ts +type DatasetName = string +``` + +### `EntityDataset` + +```ts +type EntityDataset = "entity_operations" | "entities_timemachine" | "datalake_raw_sql" +``` + +### `AutomationExecutionDataset` + +```ts +type AutomationExecutionDataset = "automation_executions_overview" | "list_automation_definitions" +``` + +### `WorkflowDataset` + +```ts +type WorkflowDataset = "total_count_of_workflow_executions" | "workflow_execution_time_series" | "cumulative_sum_of_workflows" | "cancellation_reasons" | "phases_count" | "phases_duration" | "tasks_duration" | "task_duration" | "workflow_tasks_overview" +``` + +### `WorkflowStates` + +```ts +type WorkflowStates = "STARTED" | "CLOSED" | "DONE" +``` + +### `PhaseStates` + +```ts +type PhaseStates = "OPEN" | "COMPLETED" | "IN_PROGRESS" +``` + +### `TaskStates` + +```ts +type TaskStates = "OPEN" | "COMPLETED" | "IN_PROGRESS" +``` + +### `SortBy` + +```ts +type SortBy = "due_date_ascending" | "due_date_descending" | "creation_date_ascending" | "creation_date_descending" +``` + +### `TimeGroups` + +```ts +type TimeGroups = "Y" | "Q" | "M" | "W" | "D" +``` + +### `RelativeTimeRange` + +```ts +type RelativeTimeRange = "all_time" | "this_week" | "last_week" | "last_7_days" | "this_month" | "last_month" | "last_30_days" | "last_3_months" | "last_6_months" | "this_year" | "last_year" +``` + +### `WorkflowsQueryResult` + +```ts +type WorkflowsQueryResult = { + data?: string | number | Record | Record[][] | Record | string | number + labels?: string[] + timestamp?: string +} +``` + +### `AutomationExecutionResponse` + +```ts +type AutomationExecutionResponse = { + hits?: number + results?: Array<{ + flow_id: string + flow_name?: string + execution_id: string + execution_status: string + entity_schema?: string + entity_id?: string + created_at: string + updated_at?: string + error?: { + message?: { ... } + error_code?: { ... } + } + trigger_event?: { + type?: { ... } + trigger_type?: { ... } + } + }> +} +``` + +### `ListAutomationDefinitionsResponse` + +```ts +type ListAutomationDefinitionsResponse = { + hits?: number + results?: Array<{ + flow_id: string + flow_name: string + entity_schema?: string + }> +} +``` + +### `SemanticModel` + +The semantic model exposing entities, relationships, and query capabilities + +```ts +type SemanticModel = { + entities?: Array<{ + name?: string + displayName?: string + schema?: string + }> + relationships?: Array<{ + from?: string + to?: string + relationship?: "hasMany" | "belongsTo" | "hasOne" + displayName?: string + }> + capabilities?: { + aggregations?: string[] + calculationTypes?: Array<{ + type?: { ... } + description?: { ... } + parameters?: { ... } + }> + granularities?: string[] + filterOperators?: Array<{ + operator?: { ... } + description?: { ... } + }> + } +} +``` + +### `QueryResults` + +```ts +type QueryResults = { + status?: string + timestamp?: string + results?: Record[] +} +``` + +### `TimeSeriesSettings` + +```ts +type TimeSeriesSettings = { + dataset?: "time_series" + from?: string // date-time + to?: string // date-time + time_grouper?: string + workflow_names?: string[] +} +``` + +### `NameDurationSettings` + +```ts +type NameDurationSettings = { + dataset?: "name_duration" + from?: string // date-time + to?: string // date-time + workflow_name?: string +} +``` diff --git a/docs/sdk/clients/snapshot.md b/docs/sdk/clients/snapshot.md new file mode 100644 index 00000000..726a33e1 --- /dev/null +++ b/docs/sdk/clients/snapshot.md @@ -0,0 +1,770 @@ +--- +title: "Snapshot API" +description: "TypeScript SDK client for the epilot Snapshot API: usage with @epilot/sdk, all operations and schemas." +--- + +# Snapshot API + +- **Base URL:** `https://snapshot.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/snapshot](https://docs.epilot.io/api/snapshot) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.snapshot.createSnapshot(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/snapshot' + +const snapshotClient = getClient() +authorize(snapshotClient, () => '') +const { data } = await snapshotClient.createSnapshot(...) +``` + +## Operations + +**Snapshots** +- [`createSnapshot`](#createsnapshot) +- [`listSnapshots`](#listsnapshots) +- [`captureOrgSnapshot`](#captureorgsnapshot) +- [`getSnapshot`](#getsnapshot) +- [`deleteSnapshot`](#deletesnapshot) +- [`restoreSnapshot`](#restoresnapshot) +- [`listSnapshotResources`](#listsnapshotresources) +- [`getSnapshotResource`](#getsnapshotresource) +- [`listDependencies`](#listdependencies) + +**ScheduledSnapshots** +- [`getOrgSnapshotSchedule`](#getorgsnapshotschedule) +- [`putOrgSnapshotSchedule`](#putorgsnapshotschedule) +- [`deleteOrgSnapshotSchedule`](#deleteorgsnapshotschedule) + +**Schemas** +- [`Error`](#error) +- [`ResourceRef`](#resourceref) +- [`SnapshotResourceSummary`](#snapshotresourcesummary) +- [`SnapshotResourceList`](#snapshotresourcelist) +- [`SnapshotResourceDetail`](#snapshotresourcedetail) +- [`CreateSnapshotRequest`](#createsnapshotrequest) +- [`CreateOrgSnapshotRequest`](#createorgsnapshotrequest) +- [`CreateSnapshotResponse`](#createsnapshotresponse) +- [`RestoreSnapshotRequest`](#restoresnapshotrequest) +- [`RestoreSnapshotResponse`](#restoresnapshotresponse) +- [`Snapshot`](#snapshot) +- [`Operation`](#operation) +- [`CallerIdentity`](#calleridentity) +- [`RetentionConfig`](#retentionconfig) +- [`PutOrgSnapshotScheduleRequest`](#putorgsnapshotschedulerequest) +- [`OrgSnapshotSchedule`](#orgsnapshotschedule) + +### `createSnapshot` + +Create a new snapshot of the given resources. Async — returns immediately +with a snapshot ID; client polls `getSnapshot` until `create.status` +moves from `in_progress` to `completed` or `failed`. + +`POST /v1/snapshots` + +```ts +const { data } = await client.createSnapshot( + null, + { + name: 'string', + description: 'string', + trigger: 'manual', + blueprint_instance_id: 'string', + resources: [ + { + type: 'string', + id: 'string' + } + ] + }, +) +``` + +--- + +### `listSnapshots` + +List snapshots for the caller's organization, newest first. + +`GET /v1/snapshots` + +```ts +const { data } = await client.listSnapshots({ + cursor: 'example', + size: 1, + resource: ['...'], + trigger: 'example', +}) +``` + +
+Response + +```json +{ + "page_size": 0, + "cursor": "string", + "results": [ + { + "id": "string", + "org_id": "string", + "name": "string", + "description": "string", + "trigger": "manual", + "blueprint_instance_id": "string", + "resource_counts": {}, + "create": { + "type": "create", + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status": "in_progress", + "error": "string", + "triggered_by": { + "name": "string", + "user_id": "string", + "token_id": "string" + } + }, + "restores": [ + { + "type": "create", + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status": "in_progress", + "error": "string", + "triggered_by": { + "name": "string", + "user_id": "string", + "token_id": "string" + } + } + ], + "matched_count": 0, + "scope": "selection", + "expires_at": "1970-01-01T00:00:00.000Z", + "capture_summary": { + "total": 0, + "captured": 0, + "skipped": 0, + "failed": 0 + } + } + ] +} +``` + +
+ +--- + +### `captureOrgSnapshot` + +Snapshot the caller's whole organization now. Creates a `scope: "org"` +snapshot row and starts a chunked capture Step Function, then returns +immediately. The capture asynchronously fetches a fresh inv + +`POST /v1/snapshots:capture-org` + +```ts +const { data } = await client.captureOrgSnapshot( + null, + { + name: 'string', + retention: { + value: 1, + unit: 'days' + }, + excluded_types: ['string'] + }, +) +``` + +--- + +### `getSnapshot` + +Fetch a snapshot's metadata. Poll this endpoint to track create/restore progress. + +`GET /v1/snapshots/{id}` + +```ts +const { data } = await client.getSnapshot({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "id": "string", + "org_id": "string", + "name": "string", + "description": "string", + "trigger": "manual", + "blueprint_instance_id": "string", + "resource_counts": {}, + "create": { + "type": "create", + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status": "in_progress", + "error": "string", + "triggered_by": { + "name": "string", + "user_id": "string", + "token_id": "string" + } + }, + "restores": [ + { + "type": "create", + "started_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status": "in_progress", + "error": "string", + "triggered_by": { + "name": "string", + "user_id": "string", + "token_id": "string" + } + } + ], + "matched_count": 0, + "scope": "selection", + "expires_at": "1970-01-01T00:00:00.000Z", + "capture_summary": { + "total": 0, + "captured": 0, + "skipped": 0, + "failed": 0 + } +} +``` + +
+ +--- + +### `deleteSnapshot` + +Delete a snapshot's metadata and S3 manifest. + +`DELETE /v1/snapshots/{id}` + +```ts +const { data } = await client.deleteSnapshot({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +--- + +### `restoreSnapshot` + +Restore a snapshot to the org. Async — returns immediately; client polls +`getSnapshot` until the latest entry in `restores` moves from +`in_progress` to one of `completed | partial | failed`. + +`POST /v1/snapshots/{id}:restore` + +```ts +const { data } = await client.restoreSnapshot( + { + id: '123e4567-e89b-12d3-a456-426614174000', + }, + { + exclude_target_ids: ['string'] + }, +) +``` + +--- + +### `listSnapshotResources` + +List the resources captured in this snapshot. Returns lightweight +identity fields per resource — payloads are fetched via the +single-resource endpoint when needed. + +`GET /v1/snapshots/{id}/resources` + +```ts +const { data } = await client.listSnapshotResources({ + id: '123e4567-e89b-12d3-a456-426614174000', +}) +``` + +
+Response + +```json +{ + "resources": [ + { + "lineage_id": "string", + "target_id": "string", + "type": "string", + "name": "string" + } + ] +} +``` + +
+ +--- + +### `getSnapshotResource` + +Fetch one captured resource with its full payload. For UI views +that diff the captured state against the current destination. + +`GET /v1/snapshots/{id}/resources/{lineage_id}` + +```ts +const { data } = await client.getSnapshotResource({ + id: '123e4567-e89b-12d3-a456-426614174000', + lineage_id: 'example', +}) +``` + +
+Response + +```json +{ + "lineage_id": "string", + "target_id": "string", + "type": "string", + "name": "string", + "captured": {} +} +``` + +
+ +--- + +### `getOrgSnapshotSchedule` + +Return the scheduled-snapshot enrollment config for the caller's org. +Returns 404 when the org has not yet enrolled. + +`GET /v1/org-snapshot-schedule` + +```ts +const { data } = await client.getOrgSnapshotSchedule() +``` + +
+Response + +```json +{ + "org_id": "string", + "enabled": true, + "cron_expression": "cron(0 2 * * ? *)", + "timezone": "string", + "retention": { + "value": 1, + "unit": "days" + }, + "excluded_types": ["string"], + "schedule_name": "string", + "last_started_at": "1970-01-01T00:00:00.000Z", + "last_completed_at": "1970-01-01T00:00:00.000Z", + "last_status": "completed", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `putOrgSnapshotSchedule` + +Create or update the scheduled-snapshot enrollment config for the +caller's org (upsert). The cron expression and retention window are +validated server-side; invalid values are rejected with 400. + +`PUT /v1/org-snapshot-schedule` + +```ts +const { data } = await client.putOrgSnapshotSchedule( + null, + { + enabled: true, + cron_expression: 'cron(0 2 * * ? *)', + timezone: 'Europe/Berlin', + retention: { + value: 1, + unit: 'days' + }, + excluded_types: ['string'] + }, +) +``` + +
+Response + +```json +{ + "org_id": "string", + "enabled": true, + "cron_expression": "cron(0 2 * * ? *)", + "timezone": "string", + "retention": { + "value": 1, + "unit": "days" + }, + "excluded_types": ["string"], + "schedule_name": "string", + "last_started_at": "1970-01-01T00:00:00.000Z", + "last_completed_at": "1970-01-01T00:00:00.000Z", + "last_status": "completed", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteOrgSnapshotSchedule` + +Remove the scheduled-snapshot enrollment for the caller's org. +Returns 404 when no schedule exists. +The corresponding EventBridge schedule is removed by a reconcile +step (Task 6). + +`DELETE /v1/org-snapshot-schedule` + +```ts +const { data } = await client.deleteOrgSnapshotSchedule() +``` + +--- + +### `listDependencies` + +Walk the dependency tree for a set of resources and return the full +transitive closure, topologically sorted. + +`POST /v1/snapshots:list-dependencies` + +```ts +const { data } = await client.listDependencies( + null, + { + resources: [ + { + type: 'string', + id: 'string' + } + ] + }, +) +``` + +
+Response + +```json +{ + "dependencies": [ + { + "type": "string", + "id": "string" + } + ] +} +``` + +
+ +--- + +## Schemas + +### `Error` + +```ts +type Error = { + status: number + error: string +} +``` + +### `ResourceRef` + +```ts +type ResourceRef = { + type: string + id: string +} +``` + +### `SnapshotResourceSummary` + +Lightweight identity for a captured resource. Returned by +`listSnapshotResources`; the full payload is fetched separately via +`getSnapshotResource` when needed. + + +```ts +type SnapshotResourceSummary = { + lineage_id: string + target_id: string + type: string + name?: string +} +``` + +### `SnapshotResourceList` + +```ts +type SnapshotResourceList = { + resources: Array<{ + lineage_id: string + target_id: string + type: string + name?: string + }> +} +``` + +### `SnapshotResourceDetail` + +A single captured resource with its full payload. The identity fields +match `SnapshotResourceSummary`; the `captured` payload is the +pre-install state at snapshot time. + + +```ts +type SnapshotResourceDetail = { + lineage_id: string + target_id: string + type: string + name?: string + captured: Record +} +``` + +### `CreateSnapshotRequest` + +```ts +type CreateSnapshotRequest = { + name: string + description?: string + trigger?: "manual" | "sync" | "blueprint_install" | "scheduled" + blueprint_instance_id?: string + resources: Array<{ + type: string + id: string + }> +} +``` + +### `CreateOrgSnapshotRequest` + +Request body for `captureOrgSnapshot`. All fields optional — an empty body +snapshots the whole org with a default name and the 90-day default TTL. + + +```ts +type CreateOrgSnapshotRequest = { + name?: string + retention?: { + value: number + unit: "days" | "weeks" | "months" + } + excluded_types?: string[] +} +``` + +### `CreateSnapshotResponse` + +```ts +type CreateSnapshotResponse = { + id: string + name: string + status: "creating" + created_at: string // date-time +} +``` + +### `RestoreSnapshotRequest` + +Apply a captured snapshot to its source org. snapshot-api applies the +manifest verbatim minus any target ids the caller pre-decided to skip. +Drift detection (skip modified-since-install) is the caller's +responsibility — blueprint-manifest-api owns that logic for blueprint +restores; Config Hub's manu + +```ts +type RestoreSnapshotRequest = { + exclude_target_ids?: string[] +} +``` + +### `RestoreSnapshotResponse` + +```ts +type RestoreSnapshotResponse = { + id: string + status: "restoring" +} +``` + +### `Snapshot` + +```ts +type Snapshot = { + id: string + org_id: string + name: string + description?: string + trigger: "manual" | "sync" | "blueprint_install" | "scheduled" + blueprint_instance_id?: string + resource_counts: Record + create: { + type: "create" | "restore" + started_at: string // date-time + completed_at?: string // date-time + status: "in_progress" | "completed" | "partial" | "failed" + error?: string + triggered_by: { + name: { ... } + user_id?: { ... } + token_id?: { ... } + } + } + restores: Array<{ + type: "create" | "restore" + started_at: string // date-time + completed_at?: string // date-time + status: "in_progress" | "completed" | "partial" | "failed" + error?: string + triggered_by: { + name: { ... } + user_id?: { ... } + token_id?: { ... } + } + }> + matched_count?: number + scope?: "selection" | "org" + expires_at?: string // date-time + capture_summary?: { + total: number + captured: number + skipped: number + failed: number + } +} +``` + +### `Operation` + +```ts +type Operation = { + type: "create" | "restore" + started_at: string // date-time + completed_at?: string // date-time + status: "in_progress" | "completed" | "partial" | "failed" + error?: string + triggered_by: { + name: string + user_id?: string + token_id?: string + } +} +``` + +### `CallerIdentity` + +```ts +type CallerIdentity = { + name: string + user_id?: string + token_id?: string +} +``` + +### `RetentionConfig` + +Flat retention window for a scheduled snapshot. +Converted to a `ttl` epoch at capture time. Capped at ~24 months. + + +```ts +type RetentionConfig = { + value: number + unit: "days" | "weeks" | "months" +} +``` + +### `PutOrgSnapshotScheduleRequest` + +Body for `putOrgSnapshotSchedule`. All fields optional; unset fields +receive defaults on first create and are left unchanged on updates +(except `updated_at`). + + +```ts +type PutOrgSnapshotScheduleRequest = { + enabled?: boolean + cron_expression?: string + timezone?: string + retention?: { + value: number + unit: "days" | "weeks" | "months" + } + excluded_types?: string[] +} +``` + +### `OrgSnapshotSchedule` + +Enrollment record for a scheduled org snapshot. One row per org. +This table — not EventBridge — is the source of truth; the EventBridge +schedule entry is the materialization of this row (reconciled on write +by Task 6). + + +```ts +type OrgSnapshotSchedule = { + org_id: string + enabled: boolean + cron_expression: string + timezone: string + retention: { + value: number + unit: "days" | "weeks" | "months" + } + excluded_types?: string[] + schedule_name: string + last_started_at?: string // date-time + last_completed_at?: string // date-time + last_status?: "completed" | "partial" | "failed" + created_by: string + created_at: string // date-time + updated_at: string // date-time +} +``` diff --git a/docs/sdk/clients/target.md b/docs/sdk/clients/target.md new file mode 100644 index 00000000..43018d05 --- /dev/null +++ b/docs/sdk/clients/target.md @@ -0,0 +1,746 @@ +--- +title: "Target API" +description: "TypeScript SDK client for the epilot Target API: usage with @epilot/sdk, all operations and schemas." +--- + +# Target API + +- **Base URL:** `https://target.sls.epilot.io` +- **Full API Docs:** [https://docs.epilot.io/api/target](https://docs.epilot.io/api/target) + +## Usage + +```ts +import { epilot } from '@epilot/sdk' + +epilot.authorize(() => '') +const { data } = await epilot.target.createTarget(...) +``` + +### Tree-shakeable import + +```ts +import { getClient, authorize } from '@epilot/sdk/target' + +const targetClient = getClient() +authorize(targetClient, () => '') +const { data } = await targetClient.createTarget(...) +``` + +## Operations + +**Target** +- [`createTarget`](#createtarget) +- [`getTarget`](#gettarget) +- [`deleteTarget`](#deletetarget) +- [`patchTarget`](#patchtarget) +- [`updateTarget`](#updatetarget) + +**Schemas** +- [`BaseError`](#baseerror) +- [`ServerError`](#servererror) +- [`ClientError`](#clienterror) +- [`BaseUUID`](#baseuuid) +- [`BaseTags`](#basetags) +- [`BasePurpose`](#basepurpose) +- [`BaseRelation`](#baserelation) +- [`BaseEntityOwner`](#baseentityowner) +- [`BaseEntityAcl`](#baseentityacl) +- [`BaseSystemFields`](#basesystemfields) +- [`BaseSystemReadonlyFields`](#basesystemreadonlyfields) +- [`BaseSystemFieldsRequired`](#basesystemfieldsrequired) +- [`BaseTarget`](#basetarget) +- [`BaseTargetRequired`](#basetargetrequired) +- [`Target`](#target) +- [`TargetCreate`](#targetcreate) +- [`TargetPatch`](#targetpatch) + +### `createTarget` + +Create a new target entity + +`POST /v1/target` + +```ts +const { data } = await client.createTarget( + null, + { + _schema: 'target', + name: 'string', + description: 'string', + entity_schema: 'string', + entity_filters: { + filter: { + items: [ + { + key: 'string', + operator: 'string', + value: 'string' + } + ], + combination: 'string' + } + }, + _tags: ['string'], + _purpose: ['string'], + _files: { + $relation: [ + { + entity_id: '123e4567-e89b-12d3-a456-426614174000', + _tags: ['string'] + } + ] + }, + _manifest: ['123e4567-e89b-12d3-a456-426614174000'], + __additional: {} + }, +) +``` + +
+Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +### `getTarget` + +Read a specific target entity by a given id + +`GET /v1/target/{targetId}` + +```ts +const { data } = await client.getTarget({ + targetId: 'example', + hydrate: true, + strict: true, +}) +``` + +
+Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +### `deleteTarget` + +Delete a specific target entity by a given id + +`DELETE /v1/target/{targetId}` + +```ts +const { data } = await client.deleteTarget({ + targetId: 'example', +}) +``` + +
+Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +### `patchTarget` + +Partially update a specific target entity's properties by a given id and a given payload + +`PATCH /v1/target/{targetId}` + +```ts +const { data } = await client.patchTarget( + { + targetId: 'example', + }, + { + _schema: 'target', + name: 'string', + description: 'string', + entity_schema: 'string', + entity_filters: { + filter: { + items: [ + { + key: 'string', + operator: 'string', + value: 'string' + } + ], + combination: 'string' + } + }, + _tags: ['string'], + _purpose: ['string'], + _files: { + $relation: [ + { + entity_id: '123e4567-e89b-12d3-a456-426614174000', + _tags: ['string'] + } + ] + }, + _manifest: ['123e4567-e89b-12d3-a456-426614174000'], + __additional: {} + }, +) +``` + +
+Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +### `updateTarget` + +Completly replace a specific target entity's properties by a given id and a given payload + +`PUT /v1/target/{targetId}` + +```ts +const { data } = await client.updateTarget( + { + targetId: 'example', + }, + { + _schema: 'target', + name: 'string', + description: 'string', + entity_schema: 'string', + entity_filters: { + filter: { + items: [ + { + key: 'string', + operator: 'string', + value: 'string' + } + ], + combination: 'string' + } + }, + _tags: ['string'], + _purpose: ['string'], + _files: { + $relation: [ + { + entity_id: '123e4567-e89b-12d3-a456-426614174000', + _tags: ['string'] + } + ] + }, + _manifest: ['123e4567-e89b-12d3-a456-426614174000'], + __additional: {} + }, +) +``` + +
+Response + +```json +{ + "_id": "123e4567-e89b-12d3-a456-426614174000", + "_schema": "target", + "_org": "string", + "_tags": ["string"], + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": ["string"] + } + ] + }, + "_owners": [ + { + "org_id": "123", + "user_id": "123" + } + ], + "_title": "string", + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z", + "_acl": { + "view": ["org:456"], + "edit": ["org:456"], + "delete": ["org:456"] + }, + "name": "string", + "description": "string", + "entity_schema": "string", + "entity_filters": { + "filter": { + "items": [ + { + "key": "string", + "operator": "string", + "value": "string" + } + ], + "combination": "string" + } + }, + "_purpose": ["string"], + "_manifest": ["123e4567-e89b-12d3-a456-426614174000"], + "__additional": {} +} +``` + +
+ +--- + +## Schemas + +### `BaseError` + +```ts +type BaseError = { + status: number + message: string +} +``` + +### `ServerError` + +```ts +type ServerError = { + status: number + message: string +} +``` + +### `ClientError` + +```ts +type ClientError = { + status: number + message: string +} +``` + +### `BaseUUID` + +```ts +type BaseUUID = string // uuid +``` + +### `BaseTags` + +```ts +type BaseTags = string[] +``` + +### `BasePurpose` + +```ts +type BasePurpose = string[] +``` + +### `BaseRelation` + +```ts +type BaseRelation = { + $relation?: Array<{ + entity_id?: string // uuid + _tags?: string[] + }> +} +``` + +### `BaseEntityOwner` + +The user / organization owning this entity. + +Note: Owner implicitly has access to the entity regardless of ACLs. + + +```ts +type BaseEntityOwner = { + org_id: string + user_id?: string +} +``` + +### `BaseEntityAcl` + +Access control list (ACL) for an entity. Defines sharing access to external orgs or users. + +```ts +type BaseEntityAcl = { + view?: string[] + edit?: string[] + delete?: string[] +} +``` + +### `BaseSystemFields` + +```ts +type BaseSystemFields = { + _tags?: string[] + _purpose?: string[] + _files?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } + _manifest?: string // uuid[] + __additional?: Record +} +``` + +### `BaseSystemReadonlyFields` + +```ts +type BaseSystemReadonlyFields = { + _id?: string // uuid + _schema?: string + _org?: string + _tags?: string[] + _files?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } + _owners?: Array<{ + org_id: string + user_id?: string + }> + _title?: string + _created_at?: string // date-time + _updated_at?: string // date-time + _acl?: { + view?: string[] + edit?: string[] + delete?: string[] + } +} +``` + +### `BaseSystemFieldsRequired` + +```ts +type BaseSystemFieldsRequired = object +``` + +### `BaseTarget` + +```ts +type BaseTarget = { + _schema?: "target" + name?: string + description?: string + entity_schema?: string + entity_filters?: { + filter?: { + items?: { ... } + combination?: { ... } + } + } +} +``` + +### `BaseTargetRequired` + +```ts +type BaseTargetRequired = object +``` + +### `Target` + +```ts +type Target = { + _id?: string // uuid + _schema: "target" + _org: string + _tags?: string[] + _files?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } + _owners?: Array<{ + org_id: string + user_id?: string + }> + _title?: string + _created_at?: string // date-time + _updated_at?: string // date-time + _acl?: { + view?: string[] + edit?: string[] + delete?: string[] + } + name: string + description?: string + entity_schema?: string + entity_filters?: { + filter?: { + items?: { ... } + combination?: { ... } + } + } + _purpose?: string[] + _manifest?: string // uuid[] + __additional?: Record +} +``` + +### `TargetCreate` + +```ts +type TargetCreate = { + _schema?: "target" + name: string + description?: string + entity_schema?: string + entity_filters?: { + filter?: { + items?: { ... } + combination?: { ... } + } + } + _tags?: string[] + _purpose?: string[] + _files?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } + _manifest?: string // uuid[] + __additional?: Record +} +``` + +### `TargetPatch` + +```ts +type TargetPatch = { + _schema?: "target" + name?: string + description?: string + entity_schema?: string + entity_filters?: { + filter?: { + items?: { ... } + combination?: { ... } + } + } + _tags?: string[] + _purpose?: string[] + _files?: { + $relation?: Array<{ + entity_id?: { ... } + _tags?: { ... } + }> + } + _manifest?: string // uuid[] + __additional?: Record +} +``` diff --git a/docs/sdk/clients/targeting.md b/docs/sdk/clients/targeting.md index 9987fa29..5703c8b3 100644 --- a/docs/sdk/clients/targeting.md +++ b/docs/sdk/clients/targeting.md @@ -33,7 +33,9 @@ const { data } = await targetingClient.changeCampaignStatus(...) - [`changeCampaignStatus`](#changecampaignstatus) - [`getCampaignJobStatus`](#getcampaignjobstatus) - [`getCampaignPortals`](#getcampaignportals) +- [`setupCampaign`](#setupcampaign) - [`matchCampaigns`](#matchcampaigns) +- [`discoverCampaigns`](#discovercampaigns) **Campaign Delivery** - [`retriggerCampaignAutomations`](#retriggercampaignautomations) @@ -46,7 +48,10 @@ const { data } = await targetingClient.changeCampaignStatus(...) - [`createRecipient`](#createrecipient) - [`updateRecipient`](#updaterecipient) - [`updateRecipientPortalStatus`](#updaterecipientportalstatus) +- [`updateRecipientEntityUiStatus`](#updaterecipiententityuistatus) +- [`restoreRecipientEntityUiStatus`](#restorerecipiententityuistatus) - [`getRecipients`](#getrecipients) +- [`getEmailStats`](#getemailstats) **Schemas** - [`BaseError`](#baseerror) @@ -66,12 +71,20 @@ const { data } = await targetingClient.changeCampaignStatus(...) - [`JobStatus`](#jobstatus) - [`Campaign`](#campaign) - [`Target`](#target) +- [`TargetEntityFilters`](#targetentityfilters) +- [`TargetSortItem`](#targetsortitem) - [`MatchCampaignParams`](#matchcampaignparams) +- [`NextBestAction`](#nextbestaction) +- [`DiscoverCampaignsParams`](#discovercampaignsparams) +- [`DiscoverResult`](#discoverresult) - [`MatchTargetParams`](#matchtargetparams) - [`GetTargetQueriesParams`](#gettargetqueriesparams) - [`TargetQueryResult`](#targetqueryresult) - [`AutomationStatus`](#automationstatus) - [`PortalStatus`](#portalstatus) +- [`EntityUiStatus`](#entityuistatus) +- [`EmailStatus`](#emailstatus) +- [`EmailBounceType`](#emailbouncetype) - [`Recipient`](#recipient) - [`BaseRecipientPayload`](#baserecipientpayload) - [`AutomationRecipientPayload`](#automationrecipientpayload) @@ -81,10 +94,14 @@ const { data } = await targetingClient.changeCampaignStatus(...) - [`RetriggerAutomationsRequest`](#retriggerautomationsrequest) - [`RetriggerAutomationsResult`](#retriggerautomationsresult) - [`UpdatePortalStatusRequest`](#updateportalstatusrequest) +- [`UpdateEntityUiStatusRequest`](#updateentityuistatusrequest) +- [`SetupCampaignRequest`](#setupcampaignrequest) +- [`SetupTariffChangeCampaignRequest`](#setuptariffchangecampaignrequest) +- [`SetupTariffChangeCampaignResponse`](#setuptariffchangecampaignresponse) ### `changeCampaignStatus` -Change the status of a campaign +Moves a campaign to its next status, depending on its current one: `POST /v1/campaign/{campaign_id}/status` @@ -121,8 +138,8 @@ const { data } = await client.changeCampaignStatus({ "name": "string", "goal": "string", "status": "draft", - "start_date": "string", - "end_date": "string", + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", "flow_id": "string", "job_id": "string", "target": { @@ -174,7 +191,7 @@ const { data } = await client.getCampaignJobStatus({ ### `getCampaignPortals` -Get portals usage info for a campaign +Get the list of portals and its widgets where the campaign is used. `GET /v1/campaign/{campaign_id}/portals` @@ -214,7 +231,7 @@ const { data } = await client.getCampaignPortals({ ### `retriggerCampaignAutomations` -Retrigger automations for campaign recipients +Retrigger automation executions for specific campaign recipients that have failed. `POST /v1/campaign/{campaign_id}/automations:retrigger` @@ -250,9 +267,100 @@ const { data } = await client.retriggerCampaignAutomations( --- +### `setupCampaign` + +Creates a `campaign` entity together with its related entities and configurations in a single call. +Used by the campaign wizard UI, but not restricted to it. + +`POST /v1/campaign:setup` + +```ts +const { data } = await client.setupCampaign( + null, + { + type: 'tariff_change', + product_recommendation: { + name: 'string', + source_product_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84', + source_price_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84', + offers: [ + { + target_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84', + items: [ + { + product_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84', + price_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84', + highlight_config: {} + } + ] + } + ] + }, + campaign: { + name: 'string', + goal: 'string', + target_ids: ['b8c01433-5556-4e2b-aad4-6f5348d1df84'], + start_date: '1970-01-01T00:00:00.000Z', + end_date: '1970-01-01T00:00:00.000Z' + }, + journey: { + journey_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84' + }, + channels: { + portal_widget: { + portal_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84', + block_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84' + }, + email: { + automation_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84', + template_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84' + }, + entity_ui: { + category: 'string', + icon: { + name: 'string', + color: 'string' + }, + title: 'string', + body: 'string', + priority: 'medium', + is_dismissable: true, + cta: { + type: 'journey', + target: 'string', + context_params: [ + { + key: 'string', + value: 'string' + } + ] + } + } + } + }, +) +``` + +
+Response + +```json +{ + "type": "tariff_change", + "product_recommendation_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "campaign_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "journey_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "portal_widget_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84" +} +``` + +
+ +--- + ### `matchCampaigns` -Match campaigns +Match campaigns based on target entities. `POST /v1/campaign:match` @@ -301,8 +409,8 @@ const { data } = await client.matchCampaigns( "name": "string", "goal": "string", "status": "draft", - "start_date": "string", - "end_date": "string", + "start_date": "1970-01-01T00:00:00.000Z", + "end_date": "1970-01-01T00:00:00.000Z", "flow_id": "string", "job_id": "string", "target": { @@ -323,9 +431,94 @@ const { data } = await client.matchCampaigns( --- +### `discoverCampaigns` + +Given an entity, returns the Next Best Actions it should see on the Entity-UI channel. + +`POST /v1/campaign:discover` + +```ts +const { data } = await client.discoverCampaigns( + null, + { + entity_id: 'b8c01433-5556-4e2b-aad4-6f5348d1df84', + entity_schema: 'string' + }, +) +``` + +
+Response + +```json +{ + "hits": 0, + "results": [ + { + "campaign_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "nba": { + "category": "string", + "icon": { + "name": "string", + "color": "string" + }, + "title": "string", + "body": "string", + "priority": "medium", + "is_dismissable": true, + "cta": { + "type": "journey", + "target": "string", + "context_params": [ + { + "key": "string", + "value": "string" + } + ] + } + }, + "status": "seen", + "status_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "dismissed": [ + { + "campaign_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "nba": { + "category": "string", + "icon": { + "name": "string", + "color": "string" + }, + "title": "string", + "body": "string", + "priority": "medium", + "is_dismissable": true, + "cta": { + "type": "journey", + "target": "string", + "context_params": [ + { + "key": "string", + "value": "string" + } + ] + } + }, + "status": "seen", + "status_updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + ### `matchTargets` -Match targets +Find targets from the provided list that include the provide entities. `POST /v1/target:match` @@ -374,7 +567,17 @@ const { data } = await client.matchTargets( "name": "string", "description": "string", "entity_schema": "string", - "entity_filters": {} + "entity_filters": { + "filter": {}, + "search": "string", + "sort": [ + { + "key": "billing_address.postal_code", + "order": "asc" + } + ], + "limit": 1 + } } } ] @@ -387,7 +590,9 @@ const { data } = await client.matchTargets( ### `getTargetQueries` -Get target queries +Transform target filters into Lucene queries for the provided target IDs. +Returns the transformed query string for each target along with any errors encountered. +If the target defines a sort order or `POST /v1/target/queries` @@ -409,7 +614,9 @@ const { data } = await client.getTargetQueries( { "target_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", "query": "string", - "error": "string" + "error": "string", + "sort": ["billing_date:desc", "_title.keyword:asc", "_id:desc"], + "limit": 1 } ] } @@ -421,7 +628,7 @@ const { data } = await client.getTargetQueries( ### `createRecipient` -Create a recipient associated with a campaign +Creates a new recipient associated with a campaign. `POST /v1/campaign/{campaign_id}/recipient` @@ -452,6 +659,29 @@ const { data } = await client.createRecipient( "portal_status": "sent", "portal_status_updated_at": "1970-01-01T00:00:00.000Z", "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], "updated_at": "1970-01-01T00:00:00.000Z" } ``` @@ -462,7 +692,7 @@ const { data } = await client.createRecipient( ### `updateRecipient` -Update a recipient +Updates a recipient's attributes. `PATCH /v1/campaign/{campaign_id}/recipient/{recipient_id}` @@ -494,6 +724,29 @@ const { data } = await client.updateRecipient( "portal_status": "sent", "portal_status_updated_at": "1970-01-01T00:00:00.000Z", "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], "updated_at": "1970-01-01T00:00:00.000Z" } ``` @@ -504,7 +757,8 @@ const { data } = await client.updateRecipient( ### `updateRecipientPortalStatus` -Update portal status for a campaign recipient +Updates the portal status for a specific campaign recipient. +The portal_status_updated_at timestamp is automatically set when the status changes. `PATCH /v1/campaign/{campaign_id}/recipient/{recipient_id}/portal:status` @@ -533,6 +787,149 @@ const { data } = await client.updateRecipientPortalStatus( "portal_status": "sent", "portal_status_updated_at": "1970-01-01T00:00:00.000Z", "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `updateRecipientEntityUiStatus` + +Records a Next Best Action interaction for a recipient on the Entity-UI channel. + +`PATCH /v1/campaign/{campaign_id}/recipient/{recipient_id}/entity_ui:status` + +```ts +const { data } = await client.updateRecipientEntityUiStatus( + { + campaign_id: 'example', + recipient_id: 'example', + }, + { + status: 'seen', + entity_schema: 'string' + }, +) +``` + +
+Response + +```json +{ + "entity_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "entity_schema": "string", + "title": "string", + "automation_status": "pending", + "automation_execution_id": "string", + "portal_status": "sent", + "portal_status_updated_at": "1970-01-01T00:00:00.000Z", + "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `restoreRecipientEntityUiStatus` + +Undo a dismissal on the Entity-UI (Next Best Action) channel + +`POST /v1/campaign/{campaign_id}/recipient/{recipient_id}/entity_ui:restore` + +```ts +const { data } = await client.restoreRecipientEntityUiStatus({ + campaign_id: 'example', + recipient_id: 'example', +}) +``` + +
+Response + +```json +{ + "entity_id": "b8c01433-5556-4e2b-aad4-6f5348d1df84", + "entity_schema": "string", + "title": "string", + "automation_status": "pending", + "automation_execution_id": "string", + "portal_status": "sent", + "portal_status_updated_at": "1970-01-01T00:00:00.000Z", + "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], "updated_at": "1970-01-01T00:00:00.000Z" } ``` @@ -543,7 +940,7 @@ const { data } = await client.updateRecipientPortalStatus( ### `getRecipients` -Get campaign recipients +Get a paginated list of recipients for a campaign. `GET /v1/campaign/{campaign_id}/recipients` @@ -553,8 +950,10 @@ const { data } = await client.getRecipients({ limit: 1, next: 'example', q: 'example', - automation_status: 'example', + automation_status: ['...'], portal_status: 'example', + email_status: 'example', + entity_ui_status: 'example', }) ``` @@ -573,6 +972,29 @@ const { data } = await client.getRecipients({ "portal_status": "sent", "portal_status_updated_at": "1970-01-01T00:00:00.000Z", "portal_state": {}, + "entity_ui_status": "seen", + "entity_ui_status_updated_at": "1970-01-01T00:00:00.000Z", + "entity_ui_status_before_dismiss": "seen", + "message_entity_id": "string", + "email_status": "sent", + "email_status_updated_at": "1970-01-01T00:00:00.000Z", + "email_bounce_type": "permanent", + "email_bounce_subtype": "string", + "email_complaint_type": "string", + "email_bounce_reason": "string", + "email_send_error": {}, + "email_unsubscribed_at": "1970-01-01T00:00:00.000Z", + "email_open_count": 0, + "email_first_opened_at": "1970-01-01T00:00:00.000Z", + "email_last_opened_at": "1970-01-01T00:00:00.000Z", + "email_click_count": 0, + "email_first_clicked_at": "1970-01-01T00:00:00.000Z", + "email_clicked_links": [ + { + "url": "string", + "clicked_at": "1970-01-01T00:00:00.000Z" + } + ], "updated_at": "1970-01-01T00:00:00.000Z" } ], @@ -585,6 +1007,45 @@ const { data } = await client.getRecipients({ --- +### `getEmailStats` + +Aggregate email delivery counts for a campaign, for the KPI summary on the campaign UI. +Counts cover the email (automation) channel only; `total_emailed` is the number of +recipients with a recorded em + +`GET /v1/campaign/{campaign_id}/email-stats` + +```ts +const { data } = await client.getEmailStats({ + campaign_id: 'example', +}) +``` + +
+Response + +```json +{ + "total_emailed": 0, + "sent": 0, + "delivered": 0, + "bounced": 0, + "bounced_hard": 0, + "bounced_soft": 0, + "complained": 0, + "failed": 0, + "unsubscribed": 0, + "opened": 0, + "clicked": 0, + "total_opens": 0, + "total_clicks": 0 +} +``` + +
+ +--- + ## Schemas ### `BaseError` @@ -616,7 +1077,7 @@ Describes the structure of a client error response, which can be one of several type ClientError = { message: string } | { - code: "CAMPAIGN_NOT_FOUND" | "CAMPAIGN_HAS_NO_TARGET" | "CAMPAIGN_HAS_NO_DELIVERY_METHOD" | "CAMPAIGN_HAS_JOB_IN_PROGRESS" | "CAMPAIGN_HAS_UNEXPECTED_STATUS" | "JOB_TOKEN_MISSING" | "TARGET_WITHOUT_FILTERS" + code: "CAMPAIGN_NOT_FOUND" | "CAMPAIGN_HAS_NO_TARGET" | "CAMPAIGN_HAS_NO_DELIVERY_METHOD" | "INVALID_NEXT_BEST_ACTION" | "CAMPAIGN_HAS_JOB_IN_PROGRESS" | "CAMPAIGN_HAS_UNEXPECTED_STATUS" | "JOB_TOKEN_MISSING" | "TARGET_WITHOUT_FILTERS" } | { error: string status: number @@ -717,8 +1178,16 @@ type BaseSystemFieldsRequired = object ### `CampaignStatus` +Lifecycle status of a campaign. + +- `draft`: not launched yet. +- `scheduled`: launched with a `start_date` still in the future. It collects no recipients and + appears through no delivery method until it starts on its own at `start_date`. +- `activating`: launching; recipients are being collected. +- ` + ```ts -type CampaignStatus = "draft" | "activating" | "active" | "inactive" +type CampaignStatus = "draft" | "scheduled" | "activating" | "active" | "inactive" ``` ### `ExecutionSummaryItem` @@ -764,9 +1233,9 @@ type Campaign = { } name?: string goal?: string - status?: "draft" | "activating" | "active" | "inactive" - start_date?: string // date - end_date?: string // date + status?: "draft" | "scheduled" | "activating" | "active" | "inactive" + start_date?: string // date-time + end_date?: string // date-time flow_id?: string job_id?: string target?: { @@ -801,7 +1270,42 @@ type Target = { name?: string description?: string entity_schema?: string - entity_filters?: Record + entity_filters?: { + filter?: Record + search?: string + sort?: Array<{ + key: { ... } + order: { ... } + }> + limit?: number + } +} +``` + +### `TargetEntityFilters` + +Search state of the target. `filter` and `search` use the same shape as the search state of entity views. +Besides the filters, it optionally defines the order and maximum number of results. + + +```ts +type TargetEntityFilters = { + filter?: Record + search?: string + sort?: Array<{ + key: string + order: "asc" | "desc" + }> + limit?: number +} +``` + +### `TargetSortItem` + +```ts +type TargetSortItem = { + key: string + order: "asc" | "desc" } ``` @@ -817,6 +1321,72 @@ type MatchCampaignParams = { } ``` +### `NextBestAction` + +A Next Best Action configured on a campaign's Entity-UI channel. +This is the canonical NBA contract shared by discovery (this API), authoring, and rendering. +NBA content is single-language in v1; text fields may contain `{{placeholders}}` resolved at render time. + + +```ts +type NextBestAction = { + category?: string + icon?: { + name: string + color?: string + } + title: string + body?: string + priority?: "low" | "medium" | "high" + is_dismissable?: boolean + cta: { + type: "journey" | "workflow" | "flow" + target: string + context_params?: Array<{ + key: { ... } + value: { ... } + }> + } +} +``` + +### `DiscoverCampaignsParams` + +```ts +type DiscoverCampaignsParams = { + entity_id: string // uuid + entity_schema: string +} +``` + +### `DiscoverResult` + +One discovered Next Best Action, plus this entity's interaction state for it. + +```ts +type DiscoverResult = { + campaign_id: string // uuid + nba: { + category?: string + icon?: { + name: { ... } + color?: { ... } + } + title: string + body?: string + priority?: "low" | "medium" | "high" + is_dismissable?: boolean + cta: { + type: { ... } + target: { ... } + context_params?: { ... } + } + } + status?: "seen" | "dismissed" | "clicked" + status_updated_at?: string // date-time +} +``` + ### `MatchTargetParams` ```ts @@ -844,6 +1414,8 @@ type TargetQueryResult = { target_id: string // uuid query: string error?: string + sort?: string[] + limit?: number } ``` @@ -859,6 +1431,36 @@ type AutomationStatus = "pending" | "in_progress" | "success" | "failed" | "canc type PortalStatus = "sent" | "seen" | "dismissed" | "clicked" ``` +### `EntityUiStatus` + +Lifecycle status of a Next Best Action on the Entity-UI channel. Unlike the portal +channel there is no `sent` state: an NBA recipient is born at `seen`, the moment the +action is first rendered to an agent. + + +```ts +type EntityUiStatus = "seen" | "dismissed" | "clicked" +``` + +### `EmailStatus` + +Delivery status of the email a campaign's automation sends to a recipient. Set to `sent` +once the automation hands the email off, then updated asynchronously as SES notifications +arrive (`bounced` / `complained`; an SES Reject maps to `bounced`). `failed` is a send-time +failure (the automation execu + +```ts +type EmailStatus = "sent" | "delivered" | "bounced" | "complained" | "failed" +``` + +### `EmailBounceType` + +SES bounce classification: `permanent` (hard) or `transient` (soft). + +```ts +type EmailBounceType = "permanent" | "transient" +``` + ### `Recipient` ```ts @@ -871,6 +1473,27 @@ type Recipient = { portal_status?: "sent" | "seen" | "dismissed" | "clicked" portal_status_updated_at?: string // date-time portal_state?: Record + entity_ui_status?: "seen" | "dismissed" | "clicked" + entity_ui_status_updated_at?: string // date-time + entity_ui_status_before_dismiss?: "seen" | "dismissed" | "clicked" + message_entity_id?: string + email_status?: "sent" | "delivered" | "bounced" | "complained" | "failed" + email_status_updated_at?: string // date-time + email_bounce_type?: "permanent" | "transient" + email_bounce_subtype?: string + email_complaint_type?: string + email_bounce_reason?: string + email_send_error?: Record + email_unsubscribed_at?: string // date-time + email_open_count?: number + email_first_opened_at?: string // date-time + email_last_opened_at?: string // date-time + email_click_count?: number + email_first_clicked_at?: string // date-time + email_clicked_links?: Array<{ + url: string + clicked_at: string // date-time + }> updated_at?: string // date-time } ``` @@ -962,3 +1585,120 @@ type UpdatePortalStatusRequest = { status: "sent" | "seen" | "dismissed" | "clicked" } ``` + +### `UpdateEntityUiStatusRequest` + +```ts +type UpdateEntityUiStatusRequest = { + status: "seen" | "dismissed" | "clicked" + entity_schema?: string +} +``` + +### `SetupCampaignRequest` + +Discriminated by `type`. Each campaign variant has its own request shape; +new variants are added by introducing a new schema and extending the `oneOf` list. + + +```ts +type SetupCampaignRequest = { + type: "tariff_change" + product_recommendation: { + name?: string + source_product_id?: string // uuid + source_price_id?: string // uuid + offers?: Array<{ + target_id?: { ... } + items: { ... } + }> + } + campaign: { + name: string + goal?: string + target_ids: string // uuid[] + start_date?: string // date-time + end_date?: string // date-time + } + journey?: { + journey_id: string // uuid + } + channels?: { + portal_widget?: { + portal_id: { ... } + block_id: { ... } + } + email?: { + automation_id?: { ... } + template_id?: { ... } + } + entity_ui?: { + category?: { ... } + icon?: { ... } + title: { ... } + body?: { ... } + priority?: { ... } + is_dismissable?: { ... } + cta: { ... } + } + } +} +``` + +### `SetupTariffChangeCampaignRequest` + +```ts +type SetupTariffChangeCampaignRequest = { + type: "tariff_change" + product_recommendation: { + name?: string + source_product_id?: string // uuid + source_price_id?: string // uuid + offers?: Array<{ + target_id?: { ... } + items: { ... } + }> + } + campaign: { + name: string + goal?: string + target_ids: string // uuid[] + start_date?: string // date-time + end_date?: string // date-time + } + journey?: { + journey_id: string // uuid + } + channels?: { + portal_widget?: { + portal_id: { ... } + block_id: { ... } + } + email?: { + automation_id?: { ... } + template_id?: { ... } + } + entity_ui?: { + category?: { ... } + icon?: { ... } + title: { ... } + body?: { ... } + priority?: { ... } + is_dismissable?: { ... } + cta: { ... } + } + } +} +``` + +### `SetupTariffChangeCampaignResponse` + +```ts +type SetupTariffChangeCampaignResponse = { + type: "tariff_change" + product_recommendation_id: string // uuid + campaign_id: string // uuid + journey_id?: string // uuid + portal_widget_id?: string // uuid +} +``` diff --git a/docs/sdk/clients/template-variables.md b/docs/sdk/clients/template-variables.md index f39aebd1..d5c74d16 100644 --- a/docs/sdk/clients/template-variables.md +++ b/docs/sdk/clients/template-variables.md @@ -151,6 +151,7 @@ const { data } = await client.getVariableContext( context_data: {}, template_name: 'string', template_tags: ['string'], + template_id: 'string', variables_version: '2' } }, @@ -255,6 +256,7 @@ const { data } = await client.replaceTemplates( context_data: {}, template_name: 'string', template_tags: ['string'], + template_id: 'string', variables_version: '2' } }, @@ -302,6 +304,7 @@ const { data } = await client.replaceTemplatesV2( context_data: {}, template_name: 'string', template_tags: ['string'], + template_id: 'string', variables_version: '2' } }, @@ -346,6 +349,7 @@ const { data } = await client.getCustomVariables() "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -383,6 +387,7 @@ const { data } = await client.createCustomVariable( name: 'My Custom table', key: 'my_custom_table', _tags: ['string'], + _manifest: ['string'], helper_params: ['param1', 'param2'], helper_logic: 'return param1 * param2;', config: { @@ -544,6 +549,7 @@ const { data } = await client.createCustomVariable( "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -624,6 +630,7 @@ const { data } = await client.searchCustomVariables( "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": {}, @@ -659,6 +666,7 @@ const { data } = await client.updateCustomVariable( name: 'My Custom table', key: 'my_custom_table', _tags: ['string'], + _manifest: ['string'], helper_params: ['param1', 'param2'], helper_logic: 'return param1 * param2;', config: { @@ -820,6 +828,7 @@ const { data } = await client.updateCustomVariable( "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -889,6 +898,7 @@ const { data } = await client.getCustomVariable({ "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -970,6 +980,7 @@ const { data } = await client.getBluePrintTableConfig() "name": "My Custom table", "key": "my_custom_table", "_tags": ["string"], + "_manifest": ["string"], "helper_params": ["param1", "param2"], "helper_logic": "return param1 * param2;", "config": { @@ -1044,6 +1055,7 @@ type VariableParameters = { context_data?: object template_name?: string template_tags?: string[] + template_id?: string variables_version?: string } ``` @@ -1134,6 +1146,7 @@ type CustomVariable = { name?: string key: string _tags?: string[] + _manifest?: string[] helper_params?: string[] helper_logic?: string config?: object diff --git a/docs/sdk/clients/user.md b/docs/sdk/clients/user.md index 0549fb8f..a474171a 100644 --- a/docs/sdk/clients/user.md +++ b/docs/sdk/clients/user.md @@ -32,14 +32,22 @@ const { data } = await userClient.signUpUser(...) **User V2** - [`signUpUser`](#signupuser) - [`getMeV2`](#getmev2) +- [`listUserSettings`](#listusersettings) +- [`getUserSettingsScope`](#getusersettingsscope) +- [`getUserSetting`](#getusersetting) +- [`putUserSetting`](#putusersetting) +- [`deleteUserSetting`](#deleteusersetting) - [`listUsersV2`](#listusersv2) - [`getUserV2`](#getuserv2) - [`updateUserV2`](#updateuserv2) - [`deleteUserV2`](#deleteuserv2) - [`inviteUser`](#inviteuser) - [`resendUserInvitation`](#resenduserinvitation) +- [`sendUserPasswordReset`](#senduserpasswordreset) - [`getGroupsForUser`](#getgroupsforuser) - [`verifyEmailWithToken`](#verifyemailwithtoken) +- [`requestPasswordReset`](#requestpasswordreset) +- [`resetPassword`](#resetpassword) - [`checkInviteToken`](#checkinvitetoken) - [`activateUser`](#activateuser) - [`rejectInvite`](#rejectinvite) @@ -96,6 +104,7 @@ const { data } = await userClient.signUpUser(...) - [`UserV2`](#userv2) - [`User`](#user) - [`LoginParameters`](#loginparameters) +- [`GroupImageUri`](#groupimageuri) - [`CreateGroupReq`](#creategroupreq) - [`UpdateGroupReq`](#updategroupreq) - [`Group`](#group) @@ -106,6 +115,12 @@ const { data } = await userClient.signUpUser(...) - [`Organization`](#organization) - [`DataPointsResponse`](#datapointsresponse) - [`DataPoint`](#datapoint) +- [`UserSettingScope`](#usersettingscope) +- [`UserSettingKey`](#usersettingkey) +- [`UserSettingValue`](#usersettingvalue) +- [`UserSetting`](#usersetting) +- [`UserSettingsListResponse`](#usersettingslistresponse) +- [`UserSettingsScopeResponse`](#usersettingsscoperesponse) - [`Passkey`](#passkey) - [`PasskeyAuthenticationOptions`](#passkeyauthenticationoptions) - [`PasskeyRegistrationOptions`](#passkeyregistrationoptions) @@ -224,10 +239,14 @@ const { data } = await client.getMeV2() "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -264,11 +283,46 @@ const { data } = await client.getMeV2() "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } + ], + "tags": ["non-billable"] +} +``` + +
+ +--- + +### `listUserSettings` + +List all setting scopes and keys available for the currently logged in user. Does not return setting values. + +`GET /v2/users/me/settings` + +```ts +const { data } = await client.listUserSettings() +``` + +
+Response + +```json +{ + "results": [ + { + "scope": "calendar", + "keys": ["visible_calendars"] + } ] } ``` @@ -277,6 +331,114 @@ const { data } = await client.getMeV2() --- +### `getUserSettingsScope` + +Get all setting values for one scope for the currently logged in user. + +`GET /v2/users/me/settings/{scope}` + +```ts +const { data } = await client.getUserSettingsScope({ + scope: 'example', +}) +``` + +
+Response + +```json +{ + "scope": "calendar", + "settings": { + "visible_calendars": { + "calendar_ids": ["holidays"] + } + } +} +``` + +
+ +--- + +### `getUserSetting` + +Get one setting value by scope and key for the currently logged in user. + +`GET /v2/users/me/settings/{scope}/{key}` + +```ts +const { data } = await client.getUserSetting({ + scope: 'example', + key: 'example', +}) +``` + +
+Response + +```json +{ + "scope": "calendar", + "key": "visible_calendars", + "value": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `putUserSetting` + +Create or replace one setting value for the currently logged in user. + +`PUT /v2/users/me/settings/{scope}/{key}` + +```ts +const { data } = await client.putUserSetting( + { + scope: 'example', + key: 'example', + }, + {}, +) +``` + +
+Response + +```json +{ + "scope": "calendar", + "key": "visible_calendars", + "value": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z" +} +``` + +
+ +--- + +### `deleteUserSetting` + +Delete one setting value for the currently logged in user. + +`DELETE /v2/users/me/settings/{scope}/{key}` + +```ts +const { data } = await client.deleteUserSetting({ + scope: 'example', + key: 'example', +}) +``` + +--- + ### `listUsersV2` Get the list of organization users @@ -306,10 +468,14 @@ const { data } = await client.listUsersV2({ "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -346,12 +512,19 @@ const { data } = await client.listUsersV2({ "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] } ] } @@ -386,10 +559,14 @@ const { data } = await client.getUserV2({ "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -426,12 +603,19 @@ const { data } = await client.getUserV2({ "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] } ``` @@ -459,10 +643,14 @@ const { data } = await client.updateUserV2( status: 'Active', email: 'user@example.com', draft_email: 'user@example.com', + draft_email_expires_at: '1970-01-01T00:00:00.000Z', + password_reset_token_hash: 'string', + password_reset_token_expires_at: '1970-01-01T00:00:00.000Z', department: 'Sales', phone: 1234567890, secondary_phone: 1234567890, mfa_enabled: false, + has_passkeys: false, phone_verified: true, token: 'string', signature: '

Thanks

', @@ -499,12 +687,19 @@ const { data } = await client.updateUserV2( created_opportunity_auto: true, deleted_opportunity: true }, + in_app_notification_setting: { + integration_critical_error: true, + integration_error_threshold: true, + assigned_opportunity: true, + assigned_task: true + }, properties: [ { name: 'profileImageName', value: 'avatar.png' } - ] + ], + tags: ['non-billable'] }, ) ``` @@ -522,10 +717,14 @@ const { data } = await client.updateUserV2( "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -562,12 +761,19 @@ const { data } = await client.updateUserV2( "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] } ``` @@ -648,10 +854,14 @@ const { data } = await client.inviteUser( "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -688,12 +898,19 @@ const { data } = await client.inviteUser( "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] } ``` @@ -730,10 +947,14 @@ const { data } = await client.resendUserInvitation( "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -770,12 +991,48 @@ const { data } = await client.resendUserInvitation( "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ { "name": "profileImageName", "value": "avatar.png" } - ] + ], + "tags": ["non-billable"] +} +``` + +
+ +--- + +### `sendUserPasswordReset` + +Send a password reset email to a user in your organization. +Requires `user:edit` on the target user. + +`POST /v2/users:sendPasswordReset` + +```ts +const { data } = await client.sendUserPasswordReset( + null, + { + email: 'test@example.com' + }, +) +``` + +
+Response + +```json +{ + "success": true } ``` @@ -816,10 +1073,14 @@ const { data } = await client.getGroupsForUser({ "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -832,12 +1093,18 @@ const { data } = await client.getGroupsForUser({ "image_uri": {}, "favorites": {}, "email_notification_setting": {}, + "in_app_notification_setting": {}, "properties": [], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ {} - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ] ``` @@ -876,7 +1143,9 @@ const { data } = await client.getGroups({ "updated_at": "2024-02-08T04:44:32.246Z", "created_by": "123", "crt_assignee": {}, - "users": [] + "users": [], + "image_uri": {}, + "abbreviation": "FN" } ] } @@ -897,7 +1166,11 @@ const { data } = await client.createGroup( null, { name: 'Finance', - user_ids: ['123', '456'] + user_ids: ['123', '456'], + image_uri: { + gradient_colors: ['#0588f0', '#3358d4'] + }, + abbreviation: 'FN' }, ) ``` @@ -922,10 +1195,14 @@ const { data } = await client.createGroup( "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -959,9 +1236,16 @@ const { data } = await client.createGroup( "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ {} ], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ @@ -974,10 +1258,14 @@ const { data } = await client.createGroup( "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -990,9 +1278,15 @@ const { data } = await client.createGroup( "image_uri": {}, "favorites": {}, "email_notification_setting": {}, - "properties": [] + "in_app_notification_setting": {}, + "properties": [], + "tags": ["non-billable"] } - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ``` @@ -1033,10 +1327,14 @@ const { data } = await client.getGroup({ "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1070,9 +1368,16 @@ const { data } = await client.getGroup({ "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ {} ], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ @@ -1085,10 +1390,14 @@ const { data } = await client.getGroup({ "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1101,9 +1410,15 @@ const { data } = await client.getGroup({ "image_uri": {}, "favorites": {}, "email_notification_setting": {}, - "properties": [] + "in_app_notification_setting": {}, + "properties": [], + "tags": ["non-billable"] } - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ``` @@ -1124,7 +1439,11 @@ const { data } = await client.updateGroup( }, { name: 'Finance', - user_ids: ['123', '456'] + user_ids: ['123', '456'], + image_uri: { + gradient_colors: ['#0588f0', '#3358d4'] + }, + abbreviation: 'FN' }, ) ``` @@ -1149,10 +1468,14 @@ const { data } = await client.updateGroup( "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1186,9 +1509,16 @@ const { data } = await client.updateGroup( "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ {} ], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ @@ -1201,10 +1531,14 @@ const { data } = await client.updateGroup( "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1217,9 +1551,15 @@ const { data } = await client.updateGroup( "image_uri": {}, "favorites": {}, "email_notification_setting": {}, - "properties": [] + "in_app_notification_setting": {}, + "properties": [], + "tags": ["non-billable"] } - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ``` @@ -1273,10 +1613,14 @@ const { data } = await client.advanceUserAssignment({ "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1310,9 +1654,16 @@ const { data } = await client.advanceUserAssignment({ "created_opportunity_auto": true, "deleted_opportunity": true }, + "in_app_notification_setting": { + "integration_critical_error": true, + "integration_error_threshold": true, + "assigned_opportunity": true, + "assigned_task": true + }, "properties": [ {} ], + "tags": ["non-billable"], "crt_index": 3 }, "users": [ @@ -1325,10 +1676,14 @@ const { data } = await client.advanceUserAssignment({ "status": "Active", "email": "user@example.com", "draft_email": "user@example.com", + "draft_email_expires_at": "1970-01-01T00:00:00.000Z", + "password_reset_token_hash": "string", + "password_reset_token_expires_at": "1970-01-01T00:00:00.000Z", "department": "Sales", "phone": 1234567890, "secondary_phone": 1234567890, "mfa_enabled": false, + "has_passkeys": false, "phone_verified": true, "token": "string", "signature": "

Thanks

", @@ -1341,9 +1696,15 @@ const { data } = await client.advanceUserAssignment({ "image_uri": {}, "favorites": {}, "email_notification_setting": {}, - "properties": [] + "in_app_notification_setting": {}, + "properties": [], + "tags": ["non-billable"] } - ] + ], + "image_uri": { + "gradient_colors": ["#0588f0", "#3358d4"] + }, + "abbreviation": "FN" } ``` @@ -1504,6 +1865,67 @@ const { data } = await client.verifyEmailWithToken( --- +### `requestPasswordReset` + +Request a password reset email for the given email address. Always +returns a success response whether or not an account exists with that +email. + +`POST /v2/users/public/requestPasswordReset` + +```ts +const { data } = await client.requestPasswordReset( + null, + { + email: 'test@example.com' + }, +) +``` + +
+Response + +```json +{ + "message": "If an account exists, a password reset email has been sent." +} +``` + +
+ +--- + +### `resetPassword` + +Set a new password using a reset token from the password reset email. +The token is single-use and time-limited. + +`POST /v2/users/public/resetPassword` + +```ts +const { data } = await client.resetPassword( + null, + { + email: 'test@example.com', + token: 'string', + password: 'string' + }, +) +``` + +
+Response + +```json +{ + "success": true +} +``` + +
+ +--- + ### `checkInviteToken` Check an invite token @@ -1608,7 +2030,8 @@ const { data } = await client.getUserLoginParametersV2({ "cognito_oauth_domain": "epilot-org-123", "cognito_oauth_scopes": ["openid"], "oauth_response_type": "code", - "passkey_enabled": true + "passkey_enabled": true, + "passkeys_registered": true } ] } @@ -1707,7 +2130,8 @@ const { data } = await client.resolveDiscoverableCredential( "cognito_oauth_domain": "epilot-org-123", "cognito_oauth_scopes": ["openid"], "oauth_response_type": "code", - "passkey_enabled": true + "passkey_enabled": true, + "passkeys_registered": true } ] } @@ -2016,7 +2440,8 @@ const { data } = await client.getUserLoginParameters({ "cognito_oauth_domain": "epilot-org-123", "cognito_oauth_scopes": ["openid"], "oauth_response_type": "code", - "passkey_enabled": true + "passkey_enabled": true, + "passkeys_registered": true } ] } @@ -2240,10 +2665,14 @@ type UserV2 = { status?: "Active" | "Pending" | "Deactivated" | "Deleted" email?: string // email draft_email?: string // email + draft_email_expires_at?: string // date-time + password_reset_token_hash?: string + password_reset_token_expires_at?: string // date-time department?: string phone?: string secondary_phone?: string mfa_enabled?: boolean + has_passkeys?: boolean phone_verified?: boolean token?: string signature?: string @@ -2259,10 +2688,12 @@ type UserV2 = { } favorites?: Record email_notification_setting?: Record + in_app_notification_setting?: Record properties?: Array<{ name: string value: string }> + tags?: string[] } ``` @@ -2305,6 +2736,20 @@ type LoginParameters = { cognito_oauth_scopes?: string[] oauth_response_type?: "code" | "token" passkey_enabled?: boolean + passkeys_registered?: boolean +} +``` + +### `GroupImageUri` + +Group's profile image or gradient colors. Supports uploaded image URLs and generated gradient avatars. + +```ts +type GroupImageUri = { + original?: string // uri + thumbnail_32?: string // uri + thumbnail_64?: string // uri + gradient_colors?: string[] } ``` @@ -2314,6 +2759,13 @@ type LoginParameters = { type CreateGroupReq = { name: string user_ids?: string[] + image_uri?: { + original?: string // uri + thumbnail_32?: string // uri + thumbnail_64?: string // uri + gradient_colors?: string[] + } + abbreviation?: string } ``` @@ -2323,6 +2775,13 @@ type CreateGroupReq = { type UpdateGroupReq = { name?: string user_ids?: string[] + image_uri?: { + original?: string // uri + thumbnail_32?: string // uri + thumbnail_64?: string // uri + gradient_colors?: string[] + } + abbreviation?: string } ``` @@ -2345,10 +2804,14 @@ type Group = { status?: "Active" | "Pending" | "Deactivated" | "Deleted" email?: string // email draft_email?: string // email + draft_email_expires_at?: string // date-time + password_reset_token_hash?: string + password_reset_token_expires_at?: string // date-time department?: string phone?: string secondary_phone?: string mfa_enabled?: boolean + has_passkeys?: boolean phone_verified?: boolean token?: string signature?: string @@ -2364,10 +2827,12 @@ type Group = { } favorites?: Record email_notification_setting?: Record + in_app_notification_setting?: Record properties?: Array<{ name: { ... } value: { ... } }> + tags?: string[] crt_index?: number } users?: Array<{ @@ -2379,10 +2844,14 @@ type Group = { status?: "Active" | "Pending" | "Deactivated" | "Deleted" email?: string // email draft_email?: string // email + draft_email_expires_at?: string // date-time + password_reset_token_hash?: string + password_reset_token_expires_at?: string // date-time department?: string phone?: string secondary_phone?: string mfa_enabled?: boolean + has_passkeys?: boolean phone_verified?: boolean token?: string signature?: string @@ -2398,11 +2867,20 @@ type Group = { } favorites?: Record email_notification_setting?: Record + in_app_notification_setting?: Record properties?: Array<{ name: { ... } value: { ... } }> + tags?: string[] }> + image_uri?: { + original?: string // uri + thumbnail_32?: string // uri + thumbnail_64?: string // uri + gradient_colors?: string[] + } + abbreviation?: string } ``` @@ -2519,6 +2997,62 @@ type DataPoint = { } ``` +### `UserSettingScope` + +User setting scope. Values are limited to 64 characters. + +```ts +type UserSettingScope = string +``` + +### `UserSettingKey` + +User setting key. Values are limited to 128 characters. + +```ts +type UserSettingKey = string +``` + +### `UserSettingValue` + +The JSON value of a user setting. Objects are recommended for extensibility, but any JSON value is accepted up to 64 KiB when serialized as JSON. + +```ts +type UserSettingValue = unknown +``` + +### `UserSetting` + +```ts +type UserSetting = { + scope: string + key: string + value: unknown + created_at: string // date-time + updated_at: string // date-time +} +``` + +### `UserSettingsListResponse` + +```ts +type UserSettingsListResponse = { + results: Array<{ + scope: string + keys: string[] + }> +} +``` + +### `UserSettingsScopeResponse` + +```ts +type UserSettingsScopeResponse = { + scope: string + settings: Record +} +``` + ### `Passkey` ```ts diff --git a/docs/sdk/clients/validation-rules.md b/docs/sdk/clients/validation-rules.md index df3b2900..09ec9038 100644 --- a/docs/sdk/clients/validation-rules.md +++ b/docs/sdk/clients/validation-rules.md @@ -57,10 +57,34 @@ const { data } = await validationRulesClient.getValidationRules(...) - [`NumericCondition`](#numericcondition) - [`NumericNestedCondition`](#numericnestedcondition) - [`NumericFactCondition`](#numericfactcondition) +- [`ComparisonRuleType`](#comparisonruletype) +- [`Condition`](#condition) +- [`Operator`](#operator) +- [`ConditionValue`](#conditionvalue) +- [`ScalarValue`](#scalarvalue) +- [`ValueReference`](#valuereference) +- [`EnvironmentValue`](#environmentvalue) +- [`ExternalValue`](#externalvalue) +- [`ParameterValue`](#parametervalue) +- [`StaticValue`](#staticvalue) +- [`ContextValue`](#contextvalue) +- [`ValueAdjustment`](#valueadjustment) +- [`RelativeDateValue`](#relativedatevalue) +- [`RangeValue`](#rangevalue) +- [`NoValue`](#novalue) +- [`DocumentRuleType`](#documentruletype) +- [`DocumentCheck`](#documentcheck) +- [`DocumentCondition`](#documentcondition) +- [`DocumentOperator`](#documentoperator) +- [`DocumentConditionValue`](#documentconditionvalue) +- [`FileTypesValue`](#filetypesvalue) +- [`CriteriaValue`](#criteriavalue) +- [`AppliesWhen`](#applieswhen) +- [`ContextRequirement`](#contextrequirement) ### `getValidationRules` -Get all validation rules by organization Id +Returns all validation rules belonging to the authenticated user's organization. `GET /v1/validation-rules` @@ -80,8 +104,7 @@ const { data } = await client.getValidationRules() "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -111,6 +134,11 @@ const { data } = await client.getValidationRules() ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -129,7 +157,7 @@ const { data } = await client.getValidationRules() ### `createValidationRule` -Create Validation Rule +Creates a new validation rule for the authenticated organization. `POST /v1/validation-rules` @@ -142,8 +170,7 @@ const { data } = await client.createValidationRule( used_by: [ { type: 'journey', - schema_slug: 'string', - source_id: 'string' + source_id: 'journey-xyz789' } ], rule: { @@ -172,7 +199,12 @@ const { data } = await client.createValidationRule( } ] } - } + }, + contexts: [ + { + schema: 'contract' + } + ] }, ) ``` @@ -187,8 +219,7 @@ const { data } = await client.createValidationRule( "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -218,6 +249,11 @@ const { data } = await client.createValidationRule( ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -234,7 +270,7 @@ const { data } = await client.createValidationRule( ### `getValidationRuleById` -Get validation rule by ID +Retrieves a specific validation rule by its unique ID. `GET /v1/validation-rules/{ruleId}` @@ -254,8 +290,7 @@ const { data } = await client.getValidationRuleById({ "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -285,6 +320,11 @@ const { data } = await client.getValidationRuleById({ ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -301,7 +341,7 @@ const { data } = await client.getValidationRuleById({ ### `updateValidationRule` -Update Validation Rule (partial update) +Partially updates an existing validation rule by ID. Only the fields provided in the request body are updated. `PATCH /v1/validation-rules/{ruleId}` @@ -316,8 +356,7 @@ const { data } = await client.updateValidationRule( used_by: [ { type: 'journey', - schema_slug: 'string', - source_id: 'string' + source_id: 'journey-xyz789' } ], rule: { @@ -346,7 +385,12 @@ const { data } = await client.updateValidationRule( } ] } - } + }, + contexts: [ + { + schema: 'contract' + } + ] }, ) ``` @@ -361,8 +405,7 @@ const { data } = await client.updateValidationRule( "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -392,6 +435,11 @@ const { data } = await client.updateValidationRule( ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -408,7 +456,7 @@ const { data } = await client.updateValidationRule( ### `deleteValidationRule` -Delete Validation Rule +Permanently deletes a validation rule by ID. Any journeys or entity attributes referencing this rule should be updated before deletion. `DELETE /v1/validation-rules/{ruleId}` @@ -422,7 +470,7 @@ const { data } = await client.deleteValidationRule({ ### `addUsedByReference` -Add a reference to the usedBy array +Adds a single `used_by` reference to an existing validation rule. `POST /v1/validation-rules/{ruleId}/used-by` @@ -433,8 +481,7 @@ const { data } = await client.addUsedByReference( }, { type: 'journey', - schema_slug: 'string', - source_id: 'string' + source_id: 'journey-xyz789' }, ) ``` @@ -449,8 +496,7 @@ const { data } = await client.addUsedByReference( "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -480,6 +526,11 @@ const { data } = await client.addUsedByReference( ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -496,7 +547,7 @@ const { data } = await client.addUsedByReference( ### `removeUsedByReference` -Remove a reference from the usedBy array +Removes a specific `used_by` reference from an existing validation rule. `DELETE /v1/validation-rules/{ruleId}/used-by` @@ -507,8 +558,7 @@ const { data } = await client.removeUsedByReference( }, { type: 'journey', - schema_slug: 'string', - source_id: 'string' + source_id: 'journey-xyz789' }, ) ``` @@ -523,8 +573,7 @@ const { data } = await client.removeUsedByReference( "used_by": [ { "type": "journey", - "schema_slug": "string", - "source_id": "string" + "source_id": "journey-xyz789" } ], "rule": { @@ -554,6 +603,11 @@ const { data } = await client.removeUsedByReference( ] } }, + "contexts": [ + { + "schema": "contract" + } + ], "_schema_version": "string", "_id": "string", "_organization_id": "string", @@ -572,6 +626,8 @@ const { data } = await client.removeUsedByReference( ### `GetValidationRulesResponse` +Response envelope for listing all validation rules within an organization. + ```ts type GetValidationRulesResponse = { results?: Array<{ @@ -599,7 +655,7 @@ type UpdateValidationRuleRequest = { title?: string placeholder?: string used_by?: Array<{ - type: "journey" | "entity" + type: "journey" | "entity" | "portal" schema_slug?: string source_id?: string }> @@ -630,7 +686,32 @@ type UpdateValidationRuleRequest = { } | { not: { ... } } + } | { + input_type: "number" | "date" | "text" + conditions: Array<{ + id: { ... } + operator: { ... } + value: { ... } + error_message: { ... } + applies_when?: { ... } + allow_failure?: { ... } + }> + } | { + input_type: "document" + check: { + level: { ... } + } + conditions: Array<{ + id: { ... } + operator: { ... } + value: { ... } + error_message: { ... } + allow_failure?: { ... } + }> } + contexts?: Array<{ + schema: string + }> } ``` @@ -641,7 +722,7 @@ type ValidationRuleBase = { title?: string placeholder?: string used_by?: Array<{ - type: "journey" | "entity" + type: "journey" | "entity" | "portal" schema_slug?: string source_id?: string }> @@ -672,7 +753,32 @@ type ValidationRuleBase = { } | { not: { ... } } + } | { + input_type: "number" | "date" | "text" + conditions: Array<{ + id: { ... } + operator: { ... } + value: { ... } + error_message: { ... } + applies_when?: { ... } + allow_failure?: { ... } + }> + } | { + input_type: "document" + check: { + level: { ... } + } + conditions: Array<{ + id: { ... } + operator: { ... } + value: { ... } + error_message: { ... } + allow_failure?: { ... } + }> } + contexts?: Array<{ + schema: string + }> } ``` @@ -694,11 +800,11 @@ type ValidationRule = { ### `UsedBy` -Describes where and how a validation rule is applied. +Describes where and how a validation rule is applied. Used to track associations between rules and the journeys, entity schemas or portals that reference them. ```ts type UsedBy = { - type: "journey" | "entity" + type: "journey" | "entity" | "portal" schema_slug?: string source_id?: string } @@ -1600,3 +1706,1225 @@ type NumericFactCondition = { } } ``` + +### `ComparisonRuleType` + +Declarative validation rule (schema version v2). Supports predefined comparison operators +over number, date and text inputs, with static, dynamic (context path), relative-date and +external (app-provided) comparison values. + + +```ts +type ComparisonRuleType = { + input_type: "number" | "date" | "text" + conditions: Array<{ + id: string + operator: "equal" | "notEqual" | "greaterThan" | "greaterThanInclusive" | "lessThan" | "lessThanInclusive" | "between" | "dateBefore" | "dateOnOrBefore" | "dateAfter" | "dateOnOrAfter" | "dateBetween" | "notInFuture" | "notInPast" | "contains" | "doesNotContain" | "startsWith" | "endsWith" | "regexMatch" | "lengthBetween" | "maxDigits" | "maxDecimals" + value: { + source: { ... } + data: { ... } + } | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + offset: { ... } + unit: { ... } + anchor?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } | { + source: { ... } + min: { ... } + max: { ... } + } | { + source: { ... } + } + error_message: string + applies_when?: { + path: { ... } + operator: { ... } + value?: { ... } + } + allow_failure?: boolean + }> +} +``` + +### `Condition` + +A single comparison the input value must satisfy. + +```ts +type Condition = { + id: string + operator: "equal" | "notEqual" | "greaterThan" | "greaterThanInclusive" | "lessThan" | "lessThanInclusive" | "between" | "dateBefore" | "dateOnOrBefore" | "dateAfter" | "dateOnOrAfter" | "dateBetween" | "notInFuture" | "notInPast" | "contains" | "doesNotContain" | "startsWith" | "endsWith" | "regexMatch" | "lengthBetween" | "maxDigits" | "maxDecimals" + value: { + source: "static" + data: number | string | boolean + } | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "relative_date" + offset: number | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + unit: "days" | "months" | "years" + anchor?: "today" | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "parameter" + name: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "range" + min: { + source: { ... } + data: { ... } + } | { + source: { ... } + path: { ... } + // ... +} +``` + +### `Operator` + +Predefined comparison operator. Compatibility (enforced at write time): +- number: equal, notEqual, greaterThan, greaterThanInclusive, lessThan, lessThanInclusive, between, regexMatch, + maxDigits, maxDecimals +- date: dateBefore, dateOnOrBefore, dateAfter, dateOnOrAfter, dateBetween, notInFuture, not + +```ts +type Operator = "equal" | "notEqual" | "greaterThan" | "greaterThanInclusive" | "lessThan" | "lessThanInclusive" | "between" | "dateBefore" | "dateOnOrBefore" | "dateAfter" | "dateOnOrAfter" | "dateBetween" | "notInFuture" | "notInPast" | "contains" | "doesNotContain" | "startsWith" | "endsWith" | "regexMatch" | "lengthBetween" | "maxDigits" | "maxDecimals" +``` + +### `ConditionValue` + +The comparison value of a condition - a scalar, a range of scalars, or nothing (unary operators). + +```ts +type ConditionValue = { + source: "static" + data: number | string | boolean +} | { + source: "context" + path: string + adjust?: { + type: "percent" | "absolute" + value: number | { ... } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + direction: "increase" | "decrease" + rounding?: "up" | "down" + } +} | { + source: "relative_date" + offset: number | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "parameter" + name: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } + unit: "days" | "months" | "years" + anchor?: "today" | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "parameter" + name: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } + unit: "days" | "months" | "years" + anchor?: "today" | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: "percent" | "absolute" + value: number | { ... } + direction: "increase" | "decrease" + rounding?: "up" | "down" + } +} | { + source: "parameter" + name: string + adjust?: { + type: "percent" | "absolute" + value: number | { ... } + direction: "increase" | "decrease" + rounding?: "up" | "down" + } +} +``` + +### `EnvironmentValue` + +A comparison value resolved at evaluation time from an organisation environment variable +(environments-api). The rule stores the key, never the value, so one change to the variable +reaches every rule that references it and a blueprint install never overwrites the +organisation's own value. + +Only brow + +```ts +type EnvironmentValue = { + source: "environment" + key: string + adjust?: { + type: "percent" | "absolute" + value: number | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { ... } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + direction: "increase" | "decrease" + rounding?: "up" | "down" + } +} +``` + +### `ExternalValue` + +A comparison value produced at evaluation time by an External Values hook of an installed +app (component type `EXTERNAL_VALUES`). The rule stores the reference only; the value is +resolved server-side by the external-values-api, which executes the hook's HTTP call with +the app's credentials and retur + +```ts +type ExternalValue = { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: "percent" | "absolute" + value: number | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { ... } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + direction: "increase" | "decrease" + rounding?: "up" | "down" + } +} +``` + +### `ParameterValue` + +A comparison value supplied by the consumer that evaluates the rule, identified by a name +the rule chooses (e.g. `start_date`). The rule stores the name only. The consumer binds the +name to a source of its own - a journey binds it to the value of another block - and +resolves it at evaluation time, s + +```ts +type ParameterValue = { + source: "parameter" + name: string + adjust?: { + type: "percent" | "absolute" + value: number | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { ... } + direction: "increase" | "decrease" + rounding?: "up" | "down" + } +} +``` + +### `StaticValue` + +A fixed comparison value. + +```ts +type StaticValue = { + source: "static" + data: number | string | boolean +} +``` + +### `ContextValue` + +A dynamic comparison value resolved from runtime context, e.g. `contract.installment_amount` +or `previous_reading.value`. The first path segment must match the `name` of a declared +context requirement. + + +```ts +type ContextValue = { + source: "context" + path: string + adjust?: { + type: "percent" | "absolute" + value: number | { ... } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + direction: "increase" | "decrease" + rounding?: "up" | "down" + } +} +``` + +### `ValueAdjustment` + +Adjusts a context-resolved numeric value before comparison, e.g. "context value plus 10 percent". +Used to express tolerance bands such as "at most 10% above the current instalment amount". + + +```ts +type ValueAdjustment = { + type: "percent" | "absolute" + value: number | { + source: "context" + path: string + adjust?: { ... } + } | { + source: "environment" + key: string + adjust?: { ... } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { ... } + } | { + source: "parameter" + name: string + adjust?: { ... } + } + direction: "increase" | "decrease" + rounding?: "up" | "down" +} +``` + +### `RelativeDateValue` + +A date relative to the evaluation moment, e.g. "today minus 30 days". Only valid for date rules. + +```ts +type RelativeDateValue = { + source: "relative_date" + offset: number | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "parameter" + name: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } + unit: "days" | "months" | "years" + anchor?: "today" | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "parameter" + name: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } +} +``` + +### `RangeValue` + +A lower and upper bound for range operators (between, dateBetween, lengthBetween). Bounds are inclusive. + +```ts +type RangeValue = { + source: "range" + min: { + source: "static" + data: number | string | boolean + } | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "relative_date" + offset: number | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + unit: "days" | "months" | "years" + anchor?: "today" | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "parameter" + name: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } + max: { + source: "static" + data: number | string | boolean + } | { + source: "context" + path: string + adjust?: { + type: { ... } + // ... +} +``` + +### `NoValue` + +No comparison value - used by unary operators such as notInFuture / notInPast. + +```ts +type NoValue = { + source: "none" +} +``` + +### `DocumentRuleType` + +Declarative validation rule (schema version v2) for uploaded files. The rule declares how deep +the check goes (`check.level`) and the conditions the file must satisfy. Property conditions +(file type, size, page count, image resolution, blank and password-protected detection) are +deterministic and av + +```ts +type DocumentRuleType = { + input_type: "document" + check: { + level: "basic" | "standard" | "advanced" + } + conditions: Array<{ + id: string + operator: "fileTypeIn" | "sizeBelow" | "pageCountBetween" | "resolutionAtLeast" | "resolutionAtMost" | "isNotBlank" | "isNotPasswordProtected" | "meetsCriteria" + value: { + source: { ... } + data: { ... } + } | { + source: { ... } + min: { ... } + max: { ... } + } | { + source: { ... } + } | { + source: { ... } + types: { ... } + } | { + source: { ... } + text: { ... } + } + error_message: string + allow_failure?: boolean + }> +} +``` + +### `DocumentCheck` + +How deep the document check goes. Levels are cumulative. + +```ts +type DocumentCheck = { + level: "basic" | "standard" | "advanced" +} +``` + +### `DocumentCondition` + +A single check the uploaded file must satisfy. + +```ts +type DocumentCondition = { + id: string + operator: "fileTypeIn" | "sizeBelow" | "pageCountBetween" | "resolutionAtLeast" | "resolutionAtMost" | "isNotBlank" | "isNotPasswordProtected" | "meetsCriteria" + value: { + source: "static" + data: number | string | boolean + } | { + source: "range" + min: { + source: { ... } + data: { ... } + } | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + offset: { ... } + unit: { ... } + anchor?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + max: { + source: { ... } + data: { ... } + } | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + offset: { ... } + unit: { ... } + anchor?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + } | { + source: "none" + } | { + source: "file_types" + types: "image" | "pdf" | "document" | "spreadsheet"[] + } | { + source: "criteria" + text: string + } + error_message: string + allow_failure?: boolean +} +``` + +### `DocumentOperator` + +Predefined document check. Value compatibility (enforced at write time): +- fileTypeIn: `file_types` value listing the accepted file categories. +- sizeBelow: static integer, maximum file size in bytes. +- pageCountBetween: `range` of static non-negative integers (inclusive). +- resolutionAtLeast / reso + +```ts +type DocumentOperator = "fileTypeIn" | "sizeBelow" | "pageCountBetween" | "resolutionAtLeast" | "resolutionAtMost" | "isNotBlank" | "isNotPasswordProtected" | "meetsCriteria" +``` + +### `DocumentConditionValue` + +The value of a document condition - a static scalar, a range, nothing, accepted file categories, or a free-text criterion. + +```ts +type DocumentConditionValue = { + source: "static" + data: number | string | boolean +} | { + source: "range" + min: { + source: "static" + data: number | string | boolean + } | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "relative_date" + offset: number | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + unit: "days" | "months" | "years" + anchor?: "today" | { + source: { ... } + path: { ... } + adjust?: { ... } + } | { + source: { ... } + key: { ... } + adjust?: { ... } + } | { + source: { ... } + app_id: { ... } + hook_id: { ... } + result_id: { ... } + inputs?: { ... } + adjust?: { ... } + } | { + source: { ... } + name: { ... } + adjust?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "parameter" + name: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } + max: { + source: "static" + data: number | string | boolean + } | { + source: "context" + // ... +} +``` + +### `FileTypesValue` + +Accepted file categories; each category expands to a mime list at check time. + +```ts +type FileTypesValue = { + source: "file_types" + types: "image" | "pdf" | "document" | "spreadsheet"[] +} +``` + +### `CriteriaValue` + +A free-text requirement judged against the document's extracted content, e.g. "The photo shows +an electricity meter with the meter number and the current reading fully legible." One requirement +per condition keeps results specific and lets each requirement be graded separately. + + +```ts +type CriteriaValue = { + source: "criteria" + text: string +} +``` + +### `AppliesWhen` + +Optional precondition on a condition: the condition only takes part in the +validation when this comparison over context holds. Examples: apply the +dual-tariff reference only when `contract.htnt` is not empty, or run a +plausibility check only when a context value reaches a threshold. + + +```ts +type AppliesWhen = { + path: string + operator: "equal" | "notEqual" | "greaterThan" | "greaterThanInclusive" | "lessThan" | "lessThanInclusive" | "isEmpty" | "isNotEmpty" + value?: number | string | boolean | { + source: "context" + path: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "environment" + key: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "external" + app_id: string + hook_id: string + result_id: string + inputs?: Record + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } | { + source: "parameter" + name: string + adjust?: { + type: { ... } + value: { ... } + direction: { ... } + rounding?: { ... } + } + } +} +``` + +### `ContextRequirement` + +An entity context source the rule needs at evaluation time, referenced by `context` +value paths via the schema slug as their first segment (e.g. `contract.installment_amount`). +How the source is resolved (which entity instance) is decided by the consuming surface, +not by the rule. Meter reading comp + +```ts +type ContextRequirement = { + schema: string +} +``` diff --git a/docs/sdk/clients/webhooks.md b/docs/sdk/clients/webhooks.md index 03ae1143..2748f55d 100644 --- a/docs/sdk/clients/webhooks.md +++ b/docs/sdk/clients/webhooks.md @@ -37,6 +37,7 @@ const { data } = await webhooksClient.getPublicKey(...) - [`getConfig`](#getconfig) - [`updateConfig`](#updateconfig) - [`deleteConfig`](#deleteconfig) +- [`testOAuth`](#testoauth) - [`triggerWebhook`](#triggerwebhook) - [`batchReplayEvents`](#batchreplayevents) - [`getEventById`](#geteventbyid) @@ -53,6 +54,8 @@ const { data } = await webhooksClient.getPublicKey(...) - [`HttpMethod`](#httpmethod) - [`AuthType`](#authtype) - [`Filter`](#filter) +- [`WebhookCondition`](#webhookcondition) +- [`WebhookConditionGroup`](#webhookconditiongroup) - [`Auth`](#auth) - [`BasicAuthConfig`](#basicauthconfig) - [`OAuthConfig`](#oauthconfig) @@ -70,6 +73,8 @@ const { data } = await webhooksClient.getPublicKey(...) - [`WebhookEvent`](#webhookevent) - [`ExampleRequest`](#examplerequest) - [`ExampleResponse`](#exampleresponse) +- [`TestOAuthResponse`](#testoauthresponse) +- [`ReplayRequest`](#replayrequest) - [`BatchReplayRequest`](#batchreplayrequest) ### `getPublicKey` @@ -334,6 +339,34 @@ const { data } = await client.deleteConfig({ --- +### `testOAuth` + +Test OAuth connection + +`POST /v1/webhooks/configs/{configId}/test-oauth` + +```ts +const { data } = await client.testOAuth({ + configId: 'example', +}) +``` + +
+Response + +```json +{ + "success": true, + "expires_in": 3600, + "token_type": "Bearer", + "message": "OAuth token exchange successful" +} +``` + +
+ +--- + ### `triggerWebhook` triggers a webhook event either async or sync @@ -396,7 +429,8 @@ const { data } = await client.batchReplayEvents( configId: 'example', }, { - eventIds: ['2f1b7cf8-ff55-4359-966f-e56f39a52c94', '48c984bf-466b-470b-b743-d07cea168243'] + eventIds: ['2f1b7cf8-ff55-4359-966f-e56f39a52c94', '48c984bf-466b-470b-b743-d07cea168243'], + reapply_transform: false }, ) ``` @@ -448,7 +482,11 @@ const { data } = await client.getEventById({ }, "status": "succeeded", "http_method": "GET", - "payload": "string" + "payload": "string", + "original_payload": "string", + "retry_attempt": 0, + "can_reapply_transform": true, + "can_reapply_transform_reason": "available" } ``` @@ -463,10 +501,15 @@ Replay a webhook event `POST /v1/webhooks/configs/{configId}/events/{eventId}/replay` ```ts -const { data } = await client.replayEvent({ - configId: 'example', - eventId: 'example', -}) +const { data } = await client.replayEvent( + { + configId: 'example', + eventId: 'example', + }, + { + reapply_transform: false + }, +) ``` --- @@ -578,7 +621,11 @@ const { data } = await client.getWebhookEventsV2( }, "status": "succeeded", "http_method": "GET", - "payload": "string" + "payload": "string", + "original_payload": "string", + "retry_attempt": 0, + "can_reapply_transform": true, + "can_reapply_transform_reason": "available" } ], "next_cursor": { @@ -619,7 +666,7 @@ type SearchOptions = { to?: string // date-time } event_id?: string - status?: "succeeded" | "failed" + status?: "succeeded" | "failed" | "skipped" } ``` @@ -653,9 +700,13 @@ type EventListResponse = { execution_id?: { ... } action_id?: { ... } } - status?: "succeeded" | "failed" | "in_progress" + status?: "succeeded" | "failed" | "in_progress" | "skipped" http_method?: "GET" | "POST" | "PUT" payload?: string + original_payload?: string + retry_attempt?: number + can_reapply_transform?: boolean + can_reapply_transform_reason?: "available" | "no_transform_configured" | "no_original_source" }> next_cursor?: { created_at?: string // date-time @@ -686,6 +737,41 @@ type Filter = { } ``` +### `WebhookCondition` + +A condition that must be met for the webhook to fire. A condition is EITHER a classic field + operation comparison OR a single jsonata_expression evaluated against the event payload — the two forms are mutually exclusive. + +```ts +type WebhookCondition = { + field?: string + operation?: "equals" | "not_equals" | "any_of" | "none_of" | "contains" | "not_contains" | "starts_with" | "ends_with" | "greater_than" | "less_than" | "greater_than_or_equals" | "less_than_or_equals" | "is_empty" | "is_not_empty" | "length_equals" | "length_not_equals" | "length_greater_than" | "length_less_than" | "length_greater_than_or_equals" | "length_less_than_or_equals" + values?: string[] + field_type?: "string" | "number" | "boolean" | "date" | "datetime" + is_array_field?: boolean + repeatable_item_op?: boolean + jsonata_expression?: string +} +``` + +### `WebhookConditionGroup` + +A group of conditions with a logical operator. Multiple conditions are AND-ed by default. + +```ts +type WebhookConditionGroup = { + conditions?: Array<{ + field?: string + operation?: "equals" | "not_equals" | "any_of" | "none_of" | "contains" | "not_contains" | "starts_with" | "ends_with" | "greater_than" | "less_than" | "greater_than_or_equals" | "less_than_or_equals" | "is_empty" | "is_not_empty" | "length_equals" | "length_not_equals" | "length_greater_than" | "length_less_than" | "length_greater_than_or_equals" | "length_less_than_or_equals" + values?: string[] + field_type?: "string" | "number" | "boolean" | "date" | "datetime" + is_array_field?: boolean + repeatable_item_op?: boolean + jsonata_expression?: string + }> + logical_operator?: "AND" | "OR" +} +``` + ### `Auth` ```ts @@ -766,8 +852,10 @@ type WebhookConfig = { id?: string name: string eventName: string + eventVersion?: string url?: string creationTime?: string + updatedTime?: string httpMethod?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD" enabled?: boolean auth?: { @@ -800,11 +888,40 @@ type WebhookConfig = { include_relations?: boolean include_activity?: boolean include_changed_attributes?: boolean + apply_changesets?: boolean custom_headers?: Record } enableStaticIP?: boolean + protected?: boolean + secureProxy?: { + integration_id: string // uuid + use_case_slug: string + } status?: "active" | "inactive" | "incomplete" jsonataExpression?: string + deliveryMode?: "json_base64" | "binary_multipart" + multipartConfig?: { + fileFieldName?: string + fileFieldStrategy?: "single" | "multi" + fileSource?: string + extraFields?: Record + } + retryPolicy?: { + enabled: boolean + maxAttempts?: number + } + filterConditions?: { + conditions?: Array<{ + field?: { ... } + operation?: { ... } + values?: { ... } + field_type?: { ... } + is_array_field?: { ... } + repeatable_item_op?: { ... } + jsonata_expression?: { ... } + }> + logical_operator?: "AND" | "OR" + } _manifest?: string // uuid[] signingSecret?: string } @@ -861,6 +978,7 @@ type PayloadConfiguration = { include_relations?: boolean include_activity?: boolean include_changed_attributes?: boolean + apply_changesets?: boolean custom_headers?: Record } ``` @@ -956,9 +1074,13 @@ type WebhookEvent = { execution_id?: string action_id?: string } - status?: "succeeded" | "failed" | "in_progress" + status?: "succeeded" | "failed" | "in_progress" | "skipped" http_method?: "GET" | "POST" | "PUT" payload?: string + original_payload?: string + retry_attempt?: number + can_reapply_transform?: boolean + can_reapply_transform_reason?: "available" | "no_transform_configured" | "no_original_source" } ``` @@ -992,22 +1114,30 @@ type ExampleResponse = { } ``` +### `TestOAuthResponse` + +```ts +type TestOAuthResponse = { + success: boolean + expires_in?: number + token_type?: string + message: string +} +``` + +### `ReplayRequest` + +```ts +type ReplayRequest = { + reapply_transform?: boolean +} +``` + ### `BatchReplayRequest` ```ts type BatchReplayRequest = { eventIds: string[] + reapply_transform?: boolean } ``` - -### `Using Webhooks in Blueprints` -If webhooks are always reset to their default settings after a blueprint sync, this is because the blueprint overwrites the webhook data. To prevent this, we have introduced environment variables, which remain unchanged during a blueprint sync. - -Here is how to set them up: -1. Click the gear icon in the top bar to open the environment variables and secrets. -2. Add a variable for your webhook password by entering the key (variable name), the type (String or Secret), and the value. -3. Navigate to "Integrations" and select "Webhooks". -4. Change the authentication setting from "Default" to e.g. "Basic Auth". -5. Enter your username. -6. Click the brackets in the password field — the input will change accordingly. You can now select the relevant environment variable you defined for the password. -7. Save your settings. diff --git a/docs/sdk/clients/workflow-definition.md b/docs/sdk/clients/workflow-definition.md index 1d8e7fff..8a3da02c 100644 --- a/docs/sdk/clients/workflow-definition.md +++ b/docs/sdk/clients/workflow-definition.md @@ -47,8 +47,6 @@ const { data } = await workflowDefinitionClient.getMaxAllowedLimit(...) - [`updateFlowTemplate`](#updateflowtemplate) - [`deleteFlowTemplate`](#deleteflowtemplate) - [`duplicateFlowTemplate`](#duplicateflowtemplate) -- [`exportFlowTemplate`](#exportflowtemplate) -- [`importFlowTemplate`](#importflowtemplate) **Closing Reason** - [`getAllClosingReasons`](#getallclosingreasons) @@ -60,6 +58,8 @@ const { data } = await workflowDefinitionClient.getMaxAllowedLimit(...) **Schemas** - [`FlowTemplateBase`](#flowtemplatebase) +- [`FlowLimitWarning`](#flowlimitwarning) +- [`FlowStructuralWarning`](#flowstructuralwarning) - [`FlowTemplate`](#flowtemplate) - [`Version`](#version) - [`Trigger`](#trigger) @@ -74,7 +74,19 @@ const { data } = await workflowDefinitionClient.getMaxAllowedLimit(...) - [`Task`](#task) - [`ManualTask`](#manualtask) - [`AutomationTask`](#automationtask) +- [`AutomationFailurePolicy`](#automationfailurepolicy) - [`AutomationConfig`](#automationconfig) +- [`EmailReviewConfig`](#emailreviewconfig) +- [`AutomationInputContext`](#automationinputcontext) +- [`AutomationInputExtraContextRef`](#automationinputextracontextref) +- [`AutomationInputExtraTaskRef`](#automationinputextrataskref) +- [`FlowContextSettings`](#flowcontextsettings) +- [`MainContextSetting`](#maincontextsetting) +- [`FlowDisplayRule`](#flowdisplayrule) +- [`FlowRuleAnchor`](#flowruleanchor) +- [`MainContextAnchor`](#maincontextanchor) +- [`RuleAnchor`](#ruleanchor) +- [`AutomationOutputContext`](#automationoutputcontext) - [`AiAgentTask`](#aiagenttask) - [`AgentConfig`](#agentconfig) - [`TriggerMode`](#triggermode) @@ -83,8 +95,11 @@ const { data } = await workflowDefinitionClient.getMaxAllowedLimit(...) - [`DelayedSchedule`](#delayedschedule) - [`RelativeSchedule`](#relativeschedule) - [`DecisionTask`](#decisiontask) +- [`LoopDefinition`](#loopdefinition) +- [`TaskAudience`](#taskaudience) - [`TaskBase`](#taskbase) - [`Phase`](#phase) +- [`Stage`](#stage) - [`VariableAssignment`](#variableassignment) - [`TaskType`](#tasktype) - [`Edge`](#edge) @@ -93,8 +108,10 @@ const { data } = await workflowDefinitionClient.getMaxAllowedLimit(...) - [`EvaluationSource`](#evaluationsource) - [`Operator`](#operator) - [`DueDateConfig`](#duedateconfig) +- [`StartDateConfig`](#startdateconfig) - [`TimeUnit`](#timeunit) - [`EnableRequirement`](#enablerequirement) +- [`Subtask`](#subtask) - [`WorkflowDefinition`](#workflowdefinition) - [`Step`](#step) - [`Section`](#section) @@ -102,7 +119,12 @@ const { data } = await workflowDefinitionClient.getMaxAllowedLimit(...) - [`ItemType`](#itemtype) - [`StepType`](#steptype) - [`StepJourney`](#stepjourney) +- [`AiPrefillConfig`](#aiprefillconfig) +- [`AiPrefillExtractionField`](#aiprefillextractionfield) +- [`AiPrefillMapping`](#aiprefillmapping) +- [`JourneyContextParameter`](#journeycontextparameter) - [`ECPDetails`](#ecpdetails) +- [`PartnerDetails`](#partnerdetails) - [`StepDescription`](#stepdescription) - [`MaxAllowedLimit`](#maxallowedlimit) - [`DefinitionNotFoundResp`](#definitionnotfoundresp) @@ -118,8 +140,9 @@ const { data } = await workflowDefinitionClient.getMaxAllowedLimit(...) - [`EntitySync`](#entitysync) - [`DynamicDueDate`](#dynamicduedate) - [`StepRequirement`](#steprequirement) -- [`FlowTemplateExport`](#flowtemplateexport) -- [`FlowTemplateImportResult`](#flowtemplateimportresult) +- [`JourneyContextUsagesReq`](#journeycontextusagesreq) +- [`JourneyContextUsage`](#journeycontextusage) +- [`JourneyContextUsagesResp`](#journeycontextusagesresp) ### `getMaxAllowedLimit` @@ -147,7 +170,7 @@ const { data } = await client.getMaxAllowedLimit() ### `getDefinitions` -Retrieve all Workflow Definitions from an Organization +Retrieve all V1 workflow definitions belonging to the authenticated organization. `GET /v1/workflows/definitions` @@ -189,7 +212,8 @@ const { data } = await client.getDefinitions() {} ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] } ] ``` @@ -200,7 +224,9 @@ const { data } = await client.getDefinitions() ### `createDefinition` -Create a Workflow Definition. +Create a new V1 workflow definition. The definition consists of sections and steps +that define the structure of the workflow. Once created, the definition can be used +to start workflow executions. `POST /v1/workflows/definitions` @@ -253,6 +279,7 @@ const { data } = await client.createDefinition( type: 'STEP', ecp: { /* ... */ }, installer: { /* ... */ }, + partner: { /* ... */ }, taxonomies: ['string'] } ], @@ -268,7 +295,8 @@ const { data } = await client.createDefinition( } ], taxonomies: ['string'], - singleClosingReasonSelection: true + singleClosingReasonSelection: true, + _manifest: ['string'] }, ) ``` @@ -323,6 +351,7 @@ const { data } = await client.createDefinition( "type": "STEP", "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"] } ], @@ -338,7 +367,8 @@ const { data } = await client.createDefinition( } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] } ``` @@ -371,6 +401,7 @@ const { data } = await client.listFlowTemplates({ "org_id": "string", "name": "string", "description": "string", + "portal_titles": {}, "trigger": {}, "enabled": true, "version": 2, @@ -382,12 +413,20 @@ const { data } = await client.listFlowTemplates({ "available_in_ecp": true, "additional_triggers": [], "phases": [], + "stages": [], "tasks": [], "edges": [], "closing_reasons": [], "entity_sync": [], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "context_settings": {}, + "limit_warnings": [], + "structural_warnings": [], + "keep_task_automations_in_sync": true, + "protected": true } ] } @@ -399,18 +438,25 @@ const { data } = await client.listFlowTemplates({ ### `createFlowTemplate` -Create a new Flow Template. +Create a new Flow Template (V2 workflow definition). `POST /v2/flows/templates` ```ts const { data } = await client.createFlowTemplate( - null, + { + enforce_limits: true, + client_supports_adv_loops: true, + }, { id: 'string', org_id: 'string', name: 'string', description: 'string', + portal_titles: { + ecp: 'string', + installer: 'string' + }, trigger: { type: 'automation', automation_id: 'g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg' @@ -439,7 +485,9 @@ const { data } = await client.createFlowTemplate( id: 'string', type: 'automation', automation_id: 'string', - trigger_config: [ /* ... */ ] + input_entity: 'thread', + trigger_config: [ /* ... */ ], + duplicated_automation_id: 'string' }, /* ... 2 more */ ], @@ -453,6 +501,18 @@ const { data } = await client.createFlowTemplate( taxonomies: ['string'] } ], + stages: [ + { + id: 'string', + name: 'string', + description: 'string', + entry_node_id: 'string', + cut_edge_ids: ['string'], + color: 'string', + portal_names: { /* ... */ }, + portal_descriptions: { /* ... */ } + } + ], tasks: [ { id: 'string', @@ -461,10 +521,17 @@ const { data } = await client.createFlowTemplate( journey: { /* ... */ }, due_date: '2021-04-27T12:00:00.000Z', due_date_config: { /* ... */ }, + start_date: '2021-04-27T12:00:00.000Z', + start_date_config: { /* ... */ }, requirements: [ /* ... */ ], + required: false, + only_assignee_can_complete: true, + subtasks: [ /* ... */ ], assigned_to: ['string'], ecp: { /* ... */ }, installer: { /* ... */ }, + partner: { /* ... */ }, + audience_order: ['description'], taxonomies: ['string'], phase_id: 'string', task_type: 'MANUAL' @@ -476,14 +543,22 @@ const { data } = await client.createFlowTemplate( journey: { /* ... */ }, due_date: '2021-04-27T12:00:00.000Z', due_date_config: { /* ... */ }, + start_date: '2021-04-27T12:00:00.000Z', + start_date_config: { /* ... */ }, requirements: [ /* ... */ ], + required: false, + only_assignee_can_complete: true, + subtasks: [ /* ... */ ], assigned_to: ['string'], ecp: { /* ... */ }, installer: { /* ... */ }, + partner: { /* ... */ }, + audience_order: ['description'], taxonomies: ['string'], phase_id: 'string', task_type: 'MANUAL', automation_config: { /* ... */ }, + on_failure: 'stop', trigger_mode: 'manual', schedule: { /* ... */ }, created_automatically: false @@ -496,6 +571,7 @@ const { data } = await client.createFlowTemplate( from_id: 'string', to_id: 'string', condition_id: 'string', + loop_id: 'string', none_met: true } ], @@ -516,7 +592,43 @@ const { data } = await client.createFlowTemplate( } ], taxonomies: ['string'], - singleClosingReasonSelection: true + singleClosingReasonSelection: true, + _manifest: ['string'], + linear: true, + context_settings: { + visibility: 'entity_views', + main_context: { + schema: 'string', + relation_labels: ['string'] + }, + displays: [ + { /* ... */ } + ] + }, + limit_warnings: [ + { + i18nKey: 'string', + message: 'string', + max: 0, + current: 0, + node_id: 'string', + task_name: 'string', + branch_name: 'string', + param_name: 'string', + path: [ /* ... */ ] + } + ], + structural_warnings: [ + { + i18nKey: 'string', + message: 'string', + node_id: 'string', + edge_id: 'string', + path: [ /* ... */ ] + } + ], + keep_task_automations_in_sync: true, + protected: true }, ) ``` @@ -530,6 +642,10 @@ const { data } = await client.createFlowTemplate( "org_id": "string", "name": "string", "description": "string", + "portal_titles": { + "ecp": "string", + "installer": "string" + }, "trigger": { "type": "automation", "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" @@ -558,7 +674,9 @@ const { data } = await client.createFlowTemplate( "id": "string", "type": "automation", "automation_id": "string", - "trigger_config": [] + "input_entity": "thread", + "trigger_config": [], + "duplicated_automation_id": "string" } ], "phases": [ @@ -571,6 +689,18 @@ const { data } = await client.createFlowTemplate( "taxonomies": ["string"] } ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "entry_node_id": "string", + "cut_edge_ids": ["string"], + "color": "string", + "portal_names": {}, + "portal_descriptions": {} + } + ], "tasks": [ { "id": "string", @@ -579,10 +709,17 @@ const { data } = await client.createFlowTemplate( "journey": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": false, + "only_assignee_can_complete": true, + "subtasks": [], "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -594,14 +731,22 @@ const { data } = await client.createFlowTemplate( "journey": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": false, + "only_assignee_can_complete": true, + "subtasks": [], "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", "automation_config": {}, + "on_failure": "stop", "trigger_mode": "manual", "schedule": {}, "created_automatically": false @@ -613,6 +758,7 @@ const { data } = await client.createFlowTemplate( "from_id": "string", "to_id": "string", "condition_id": "string", + "loop_id": "string", "none_met": true } ], @@ -633,7 +779,43 @@ const { data } = await client.createFlowTemplate( } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "context_settings": { + "visibility": "entity_views", + "main_context": { + "schema": "string", + "relation_labels": ["string"] + }, + "displays": [ + {} + ] + }, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ], + "structural_warnings": [ + { + "i18nKey": "string", + "message": "string", + "node_id": "string", + "edge_id": "string", + "path": [] + } + ], + "keep_task_automations_in_sync": true, + "protected": true } ``` @@ -675,6 +857,7 @@ const { data } = await client.searchFlowTemplates( "org_id": "string", "name": "string", "description": "string", + "portal_titles": {}, "trigger": {}, "enabled": true, "version": 2, @@ -686,12 +869,20 @@ const { data } = await client.searchFlowTemplates( "available_in_ecp": true, "additional_triggers": [], "phases": [], + "stages": [], "tasks": [], "edges": [], "closing_reasons": [], "entity_sync": [], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "context_settings": {}, + "limit_warnings": [], + "structural_warnings": [], + "keep_task_automations_in_sync": true, + "protected": true } ] } @@ -703,13 +894,14 @@ const { data } = await client.searchFlowTemplates( ### `getFlowTemplate` -Get specific FLow template for a customer +Retrieve a specific flow template by its unique identifier. `GET /v2/flows/templates/{flowId}` ```ts const { data } = await client.getFlowTemplate({ flowId: 'example', + skip_heal: true, }) ``` @@ -722,6 +914,10 @@ const { data } = await client.getFlowTemplate({ "org_id": "string", "name": "string", "description": "string", + "portal_titles": { + "ecp": "string", + "installer": "string" + }, "trigger": { "type": "automation", "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" @@ -750,7 +946,9 @@ const { data } = await client.getFlowTemplate({ "id": "string", "type": "automation", "automation_id": "string", - "trigger_config": [] + "input_entity": "thread", + "trigger_config": [], + "duplicated_automation_id": "string" } ], "phases": [ @@ -763,6 +961,18 @@ const { data } = await client.getFlowTemplate({ "taxonomies": ["string"] } ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "entry_node_id": "string", + "cut_edge_ids": ["string"], + "color": "string", + "portal_names": {}, + "portal_descriptions": {} + } + ], "tasks": [ { "id": "string", @@ -771,10 +981,17 @@ const { data } = await client.getFlowTemplate({ "journey": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": false, + "only_assignee_can_complete": true, + "subtasks": [], "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -786,14 +1003,22 @@ const { data } = await client.getFlowTemplate({ "journey": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": false, + "only_assignee_can_complete": true, + "subtasks": [], "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", "automation_config": {}, + "on_failure": "stop", "trigger_mode": "manual", "schedule": {}, "created_automatically": false @@ -805,6 +1030,7 @@ const { data } = await client.getFlowTemplate({ "from_id": "string", "to_id": "string", "condition_id": "string", + "loop_id": "string", "none_met": true } ], @@ -825,7 +1051,43 @@ const { data } = await client.getFlowTemplate({ } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "context_settings": { + "visibility": "entity_views", + "main_context": { + "schema": "string", + "relation_labels": ["string"] + }, + "displays": [ + {} + ] + }, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ], + "structural_warnings": [ + { + "i18nKey": "string", + "message": "string", + "node_id": "string", + "edge_id": "string", + "path": [] + } + ], + "keep_task_automations_in_sync": true, + "protected": true } ``` @@ -843,12 +1105,18 @@ Update Flow Template. const { data } = await client.updateFlowTemplate( { flowId: 'example', + enforce_limits: true, + client_supports_adv_loops: true, }, { id: 'string', org_id: 'string', name: 'string', description: 'string', + portal_titles: { + ecp: 'string', + installer: 'string' + }, trigger: { type: 'automation', automation_id: 'g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg' @@ -877,7 +1145,9 @@ const { data } = await client.updateFlowTemplate( id: 'string', type: 'automation', automation_id: 'string', - trigger_config: [ /* ... */ ] + input_entity: 'thread', + trigger_config: [ /* ... */ ], + duplicated_automation_id: 'string' }, /* ... 2 more */ ], @@ -891,6 +1161,18 @@ const { data } = await client.updateFlowTemplate( taxonomies: ['string'] } ], + stages: [ + { + id: 'string', + name: 'string', + description: 'string', + entry_node_id: 'string', + cut_edge_ids: ['string'], + color: 'string', + portal_names: { /* ... */ }, + portal_descriptions: { /* ... */ } + } + ], tasks: [ { id: 'string', @@ -899,10 +1181,17 @@ const { data } = await client.updateFlowTemplate( journey: { /* ... */ }, due_date: '2021-04-27T12:00:00.000Z', due_date_config: { /* ... */ }, + start_date: '2021-04-27T12:00:00.000Z', + start_date_config: { /* ... */ }, requirements: [ /* ... */ ], + required: false, + only_assignee_can_complete: true, + subtasks: [ /* ... */ ], assigned_to: ['string'], ecp: { /* ... */ }, installer: { /* ... */ }, + partner: { /* ... */ }, + audience_order: ['description'], taxonomies: ['string'], phase_id: 'string', task_type: 'MANUAL' @@ -914,14 +1203,22 @@ const { data } = await client.updateFlowTemplate( journey: { /* ... */ }, due_date: '2021-04-27T12:00:00.000Z', due_date_config: { /* ... */ }, + start_date: '2021-04-27T12:00:00.000Z', + start_date_config: { /* ... */ }, requirements: [ /* ... */ ], + required: false, + only_assignee_can_complete: true, + subtasks: [ /* ... */ ], assigned_to: ['string'], ecp: { /* ... */ }, installer: { /* ... */ }, + partner: { /* ... */ }, + audience_order: ['description'], taxonomies: ['string'], phase_id: 'string', task_type: 'MANUAL', automation_config: { /* ... */ }, + on_failure: 'stop', trigger_mode: 'manual', schedule: { /* ... */ }, created_automatically: false @@ -934,6 +1231,7 @@ const { data } = await client.updateFlowTemplate( from_id: 'string', to_id: 'string', condition_id: 'string', + loop_id: 'string', none_met: true } ], @@ -954,7 +1252,43 @@ const { data } = await client.updateFlowTemplate( } ], taxonomies: ['string'], - singleClosingReasonSelection: true + singleClosingReasonSelection: true, + _manifest: ['string'], + linear: true, + context_settings: { + visibility: 'entity_views', + main_context: { + schema: 'string', + relation_labels: ['string'] + }, + displays: [ + { /* ... */ } + ] + }, + limit_warnings: [ + { + i18nKey: 'string', + message: 'string', + max: 0, + current: 0, + node_id: 'string', + task_name: 'string', + branch_name: 'string', + param_name: 'string', + path: [ /* ... */ ] + } + ], + structural_warnings: [ + { + i18nKey: 'string', + message: 'string', + node_id: 'string', + edge_id: 'string', + path: [ /* ... */ ] + } + ], + keep_task_automations_in_sync: true, + protected: true }, ) ``` @@ -968,6 +1302,10 @@ const { data } = await client.updateFlowTemplate( "org_id": "string", "name": "string", "description": "string", + "portal_titles": { + "ecp": "string", + "installer": "string" + }, "trigger": { "type": "automation", "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" @@ -996,7 +1334,9 @@ const { data } = await client.updateFlowTemplate( "id": "string", "type": "automation", "automation_id": "string", - "trigger_config": [] + "input_entity": "thread", + "trigger_config": [], + "duplicated_automation_id": "string" } ], "phases": [ @@ -1009,6 +1349,18 @@ const { data } = await client.updateFlowTemplate( "taxonomies": ["string"] } ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "entry_node_id": "string", + "cut_edge_ids": ["string"], + "color": "string", + "portal_names": {}, + "portal_descriptions": {} + } + ], "tasks": [ { "id": "string", @@ -1017,10 +1369,17 @@ const { data } = await client.updateFlowTemplate( "journey": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": false, + "only_assignee_can_complete": true, + "subtasks": [], "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -1032,14 +1391,22 @@ const { data } = await client.updateFlowTemplate( "journey": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": false, + "only_assignee_can_complete": true, + "subtasks": [], "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", "automation_config": {}, + "on_failure": "stop", "trigger_mode": "manual", "schedule": {}, "created_automatically": false @@ -1051,6 +1418,7 @@ const { data } = await client.updateFlowTemplate( "from_id": "string", "to_id": "string", "condition_id": "string", + "loop_id": "string", "none_met": true } ], @@ -1071,7 +1439,43 @@ const { data } = await client.updateFlowTemplate( } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "context_settings": { + "visibility": "entity_views", + "main_context": { + "schema": "string", + "relation_labels": ["string"] + }, + "displays": [ + {} + ] + }, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ], + "structural_warnings": [ + { + "i18nKey": "string", + "message": "string", + "node_id": "string", + "edge_id": "string", + "path": [] + } + ], + "keep_task_automations_in_sync": true, + "protected": true } ``` @@ -1095,7 +1499,9 @@ const { data } = await client.deleteFlowTemplate({ ### `duplicateFlowTemplate` -Duplicate a Flow Template from an existing workflow. +Create a copy of an existing flow template. The duplicated template will have a new +unique identifier and can be modified independently of the original. This is useful +for creating variations of exist `POST /v2/flows/templates/{flowId}/duplicate` @@ -1114,6 +1520,10 @@ const { data } = await client.duplicateFlowTemplate({ "org_id": "string", "name": "string", "description": "string", + "portal_titles": { + "ecp": "string", + "installer": "string" + }, "trigger": { "type": "automation", "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" @@ -1142,7 +1552,9 @@ const { data } = await client.duplicateFlowTemplate({ "id": "string", "type": "automation", "automation_id": "string", - "trigger_config": [] + "input_entity": "thread", + "trigger_config": [], + "duplicated_automation_id": "string" } ], "phases": [ @@ -1155,6 +1567,18 @@ const { data } = await client.duplicateFlowTemplate({ "taxonomies": ["string"] } ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "entry_node_id": "string", + "cut_edge_ids": ["string"], + "color": "string", + "portal_names": {}, + "portal_descriptions": {} + } + ], "tasks": [ { "id": "string", @@ -1163,10 +1587,17 @@ const { data } = await client.duplicateFlowTemplate({ "journey": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": false, + "only_assignee_can_complete": true, + "subtasks": [], "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL" @@ -1178,14 +1609,22 @@ const { data } = await client.duplicateFlowTemplate({ "journey": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": false, + "only_assignee_can_complete": true, + "subtasks": [], "assigned_to": ["string"], "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", "automation_config": {}, + "on_failure": "stop", "trigger_mode": "manual", "schedule": {}, "created_automatically": false @@ -1197,6 +1636,7 @@ const { data } = await client.duplicateFlowTemplate({ "from_id": "string", "to_id": "string", "condition_id": "string", + "loop_id": "string", "none_met": true } ], @@ -1217,7 +1657,43 @@ const { data } = await client.duplicateFlowTemplate({ } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"], + "linear": true, + "context_settings": { + "visibility": "entity_views", + "main_context": { + "schema": "string", + "relation_labels": ["string"] + }, + "displays": [ + {} + ] + }, + "limit_warnings": [ + { + "i18nKey": "string", + "message": "string", + "max": 0, + "current": 0, + "node_id": "string", + "task_name": "string", + "branch_name": "string", + "param_name": "string", + "path": [] + } + ], + "structural_warnings": [ + { + "i18nKey": "string", + "message": "string", + "node_id": "string", + "edge_id": "string", + "path": [] + } + ], + "keep_task_automations_in_sync": true, + "protected": true } ``` @@ -1225,15 +1701,15 @@ const { data } = await client.duplicateFlowTemplate({ --- -### `exportFlowTemplate` +### `getDefinition` -Export a Flow Template with all referenced automations resolved and bundled alongside. +Get specific Definition by id from the Organization. -`GET /v2/flows/templates/{flowId}/export` +`GET /v1/workflows/definitions/{definitionId}` ```ts -const { data } = await client.exportFlowTemplate({ - flowId: 'example', +const { data } = await client.getDefinition({ + definitionId: 'example', }) ``` @@ -1243,114 +1719,68 @@ const { data } = await client.exportFlowTemplate({ ```json { "id": "string", - "org_id": "string", "name": "string", "description": "string", - "trigger": { - "type": "automation", - "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" - }, + "creationTime": "2021-04-27T12:01:13.000Z", "enabled": true, - "version": 2, - "created_at": "2021-04-27T12:01:13.000Z", - "updated_at": "2021-04-27T12:01:13.000Z", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" + "lastUpdateTime": "2021-04-27T12:01:13.000Z", + "dueDate": "2021-04-27T12:00:00.000Z", + "dynamicDueDate": { + "numberOfUnits": 0, + "timePeriod": "minutes", + "actionTypeCondition": "WORKFLOW_STARTED", + "stepId": "string", + "phaseId": "string" }, - "assigned_to": ["string"], - "available_in_ecp": true, - "additional_triggers": [ - { - "id": "string", - "type": "manual", - "entity_schema": "string" - }, - { - "id": "string", - "type": "automation", - "automation_id": "string", - "trigger_config": [] - } - ], - "phases": [ + "userIds": [0], + "assignedTo": ["string"], + "enableECPWorkflow": true, + "flow": [ { "id": "string", "name": "string", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, - "assigned_to": ["string"], + "order": 0, + "type": "STEP", + "dueDate": "2021-04-27T12:00:00.000Z", + "dynamicDueDate": {}, + "assignedTo": ["string"], + "steps": [], "taxonomies": ["string"] - } - ], - "tasks": [ - { - "id": "string", - "name": "string", - "description": {}, - "journey": {}, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, - "requirements": [], - "assigned_to": ["string"], - "ecp": {}, - "installer": {}, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL" }, { "id": "string", "name": "string", "description": {}, + "executionType": "MANUAL", + "automationConfig": {}, "journey": {}, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": {}, + "order": 0, + "dueDate": "2021-04-27T12:00:00.000Z", + "dynamicDueDate": {}, + "userIds": [0], "requirements": [], - "assigned_to": ["string"], + "assignedTo": ["string"], + "type": "STEP", "ecp": {}, "installer": {}, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL", - "automation_config": {}, - "trigger_mode": "manual", - "schedule": {}, - "created_automatically": false - } - ], - "edges": [ - { - "id": "string", - "from_id": "string", - "to_id": "string", - "condition_id": "string", - "none_met": true + "partner": {}, + "taxonomies": ["string"] } ], - "closing_reasons": [ + "closingReasons": [ { - "id": "string", - "title": "string", - "status": "ACTIVE", - "lastUpdateTime": "string", - "creationTime": "string" + "id": "x739cew" } ], - "entity_sync": [ + "updateEntityAttributes": [ { - "trigger": {}, - "target": {}, - "value": {} + "source": "workflow_status", + "target": {} } ], "taxonomies": ["string"], "singleClosingReasonSelection": true, - "_resolved_automations": {} + "_manifest": ["string"] } ``` @@ -1358,298 +1788,22 @@ const { data } = await client.exportFlowTemplate({ --- -### `importFlowTemplate` +### `updateDefinition` -Import a Flow Template from an export payload. Creates all automations and the flow in the caller's organization. +Update Workflow Definition. -`POST /v2/flows/templates/import` +`PUT /v1/workflows/definitions/{definitionId}` ```ts -const { data } = await client.importFlowTemplate( - null, +const { data } = await client.updateDefinition( + { + definitionId: 'example', + }, { id: 'string', - org_id: 'string', name: 'string', description: 'string', - trigger: { - type: 'automation', - automation_id: 'g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg' - }, - enabled: true, - version: 2, - created_at: '2021-04-27T12:01:13.000Z', - updated_at: '2021-04-27T12:01:13.000Z', - due_date: '2021-04-27T12:00:00.000Z', - due_date_config: { - duration: 0, - unit: 'minutes', - type: 'WORKFLOW_STARTED', - task_id: 'string', - phase_id: 'string' - }, - assigned_to: ['string'], - available_in_ecp: true, - additional_triggers: [ - { - id: 'string', - type: 'manual', - entity_schema: 'string' - }, - { - id: 'string', - type: 'automation', - automation_id: 'string', - trigger_config: [ /* ... */ ] - }, - /* ... 2 more */ - ], - phases: [ - { - id: 'string', - name: 'string', - due_date: '2021-04-27T12:00:00.000Z', - due_date_config: { /* ... */ }, - assigned_to: ['string'], - taxonomies: ['string'] - } - ], - tasks: [ - { - id: 'string', - name: 'string', - description: { /* ... */ }, - journey: { /* ... */ }, - due_date: '2021-04-27T12:00:00.000Z', - due_date_config: { /* ... */ }, - requirements: [ /* ... */ ], - assigned_to: ['string'], - ecp: { /* ... */ }, - installer: { /* ... */ }, - taxonomies: ['string'], - phase_id: 'string', - task_type: 'MANUAL' - }, - { - id: 'string', - name: 'string', - description: { /* ... */ }, - journey: { /* ... */ }, - due_date: '2021-04-27T12:00:00.000Z', - due_date_config: { /* ... */ }, - requirements: [ /* ... */ ], - assigned_to: ['string'], - ecp: { /* ... */ }, - installer: { /* ... */ }, - taxonomies: ['string'], - phase_id: 'string', - task_type: 'MANUAL', - automation_config: { /* ... */ }, - trigger_mode: 'manual', - schedule: { /* ... */ }, - created_automatically: false - }, - /* ... 2 more */ - ], - edges: [ - { - id: 'string', - from_id: 'string', - to_id: 'string', - condition_id: 'string', - none_met: true - } - ], - closing_reasons: [ - { - id: 'string', - title: 'string', - status: 'ACTIVE', - lastUpdateTime: 'string', - creationTime: 'string' - } - ], - entity_sync: [ - { - trigger: { /* ... */ }, - target: { /* ... */ }, - value: { /* ... */ } - } - ], - taxonomies: ['string'], - singleClosingReasonSelection: true, - _resolved_automations: {} - }, -) -``` - -
-Response - -```json -{ - "flow": { - "id": "string", - "org_id": "string", - "name": "string", - "description": "string", - "trigger": { - "type": "automation", - "automation_id": "g92j2-sg9ug92hjt1gh-9s9gajgs-a979gg" - }, - "enabled": true, - "version": 2, - "created_at": "2021-04-27T12:01:13.000Z", - "updated_at": "2021-04-27T12:01:13.000Z", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" - }, - "assigned_to": ["string"], - "available_in_ecp": true, - "additional_triggers": [ - {}, - {} - ], - "phases": [ - {} - ], - "tasks": [ - {}, - {} - ], - "edges": [ - {} - ], - "closing_reasons": [ - {} - ], - "entity_sync": [ - {} - ], - "taxonomies": ["string"], - "singleClosingReasonSelection": true - }, - "_id_mappings": { - "flow_id": { - "old": "string", - "new": "string" - }, - "task_ids": {}, - "automation_ids": {} - } -} -``` - -
- ---- - -### `getDefinition` - -Get specific Definition by id from the Organization. - -`GET /v1/workflows/definitions/{definitionId}` - -```ts -const { data } = await client.getDefinition({ - definitionId: 'example', -}) -``` - -
-Response - -```json -{ - "id": "string", - "name": "string", - "description": "string", - "creationTime": "2021-04-27T12:01:13.000Z", - "enabled": true, - "lastUpdateTime": "2021-04-27T12:01:13.000Z", - "dueDate": "2021-04-27T12:00:00.000Z", - "dynamicDueDate": { - "numberOfUnits": 0, - "timePeriod": "minutes", - "actionTypeCondition": "WORKFLOW_STARTED", - "stepId": "string", - "phaseId": "string" - }, - "userIds": [0], - "assignedTo": ["string"], - "enableECPWorkflow": true, - "flow": [ - { - "id": "string", - "name": "string", - "order": 0, - "type": "STEP", - "dueDate": "2021-04-27T12:00:00.000Z", - "dynamicDueDate": {}, - "assignedTo": ["string"], - "steps": [], - "taxonomies": ["string"] - }, - { - "id": "string", - "name": "string", - "description": {}, - "executionType": "MANUAL", - "automationConfig": {}, - "journey": {}, - "order": 0, - "dueDate": "2021-04-27T12:00:00.000Z", - "dynamicDueDate": {}, - "userIds": [0], - "requirements": [], - "assignedTo": ["string"], - "type": "STEP", - "ecp": {}, - "installer": {}, - "taxonomies": ["string"] - } - ], - "closingReasons": [ - { - "id": "x739cew" - } - ], - "updateEntityAttributes": [ - { - "source": "workflow_status", - "target": {} - } - ], - "taxonomies": ["string"], - "singleClosingReasonSelection": true -} -``` - -
- ---- - -### `updateDefinition` - -Update Workflow Definition. - -`PUT /v1/workflows/definitions/{definitionId}` - -```ts -const { data } = await client.updateDefinition( - { - definitionId: 'example', - }, - { - id: 'string', - name: 'string', - description: 'string', - creationTime: '2021-04-27T12:01:13.000Z', + creationTime: '2021-04-27T12:01:13.000Z', enabled: true, lastUpdateTime: '2021-04-27T12:01:13.000Z', dueDate: '2021-04-27T12:00:00.000Z', @@ -1691,6 +1845,7 @@ const { data } = await client.updateDefinition( type: 'STEP', ecp: { /* ... */ }, installer: { /* ... */ }, + partner: { /* ... */ }, taxonomies: ['string'] } ], @@ -1706,7 +1861,8 @@ const { data } = await client.updateDefinition( } ], taxonomies: ['string'], - singleClosingReasonSelection: true + singleClosingReasonSelection: true, + _manifest: ['string'] }, ) ``` @@ -1761,6 +1917,7 @@ const { data } = await client.updateDefinition( "type": "STEP", "ecp": {}, "installer": {}, + "partner": {}, "taxonomies": ["string"] } ], @@ -1776,7 +1933,8 @@ const { data } = await client.updateDefinition( } ], "taxonomies": ["string"], - "singleClosingReasonSelection": true + "singleClosingReasonSelection": true, + "_manifest": ["string"] } ``` @@ -2023,12 +2181,21 @@ const { data } = await client.setWorkflowClosingReasons( ### `FlowTemplateBase` +Base schema for V2 flow templates. A flow template defines the structure of a workflow +including phases, tasks, edges, triggers, and other configuration. Flow templates serve +as blueprints that can be instantiated as flow executions. + + ```ts type FlowTemplateBase = { id?: string org_id?: string name: string description?: string + portal_titles?: { + ecp?: string + installer?: string + } trigger?: { id?: string type: "manual" @@ -2037,10 +2204,12 @@ type FlowTemplateBase = { id?: string type: "automation" automation_id?: string + input_entity?: "thread" | "first_email" | "last_email" trigger_config?: Array<{ type: { ... } configuration?: { ... } }> + duplicated_automation_id?: string } | { id?: string type: "journey_submission" @@ -2059,14 +2228,14 @@ type FlowTemplateBase = { due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } assigned_to?: Array available_in_ecp?: boolean additional_triggers?: Array<{ @@ -2077,10 +2246,12 @@ type FlowTemplateBase = { id?: string type: "automation" automation_id?: string + input_entity?: "thread" | "first_email" | "last_email" trigger_config?: Array<{ type: { ... } configuration?: { ... } }> + duplicated_automation_id?: string } | { id?: string type: "journey_submission" @@ -2109,25 +2280,49 @@ type FlowTemplateBase = { }> taxonomies?: string[] }> - tasks: Array<{ + stages?: Array<{ id: string name: string - description?: { - enabled?: { ... } - value?: { ... } - } - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - due_date?: string - due_date_config?: { + description?: string + entry_node_id?: string + cut_edge_ids?: string[] + color?: string // ... } ``` +### `FlowLimitWarning` + +A configuration limit that the flow currently exceeds. Returned by the get-flow endpoint and by create/update responses so the UI can show a non-blocking banner. Size/count limit violations never cause a 400 — only structural errors do. The flow remains fully usable; users are encouraged to bring va + +```ts +type FlowLimitWarning = { + i18nKey: string + message: string + max: number + current?: number + node_id?: string + task_name?: string + branch_name?: string + param_name?: string + path: unknown[] +} +``` + +### `FlowStructuralWarning` + +A structural problem the flow has that does not block a save. Returned by the get-flow endpoint and by create/update responses. Today the only one is errors.loop_id_after_exit: a loop connection can be reached from its loop's exit branch, so leaving the loop leads back into it. + +```ts +type FlowStructuralWarning = { + i18nKey: string + message: string + node_id?: string + edge_id?: string + path: unknown[] +} +``` + ### `FlowTemplate` ```ts @@ -2136,6 +2331,10 @@ type FlowTemplate = { org_id?: string name: string description?: string + portal_titles?: { + ecp?: string + installer?: string + } trigger?: { id?: string type: "manual" @@ -2144,10 +2343,12 @@ type FlowTemplate = { id?: string type: "automation" automation_id?: string + input_entity?: "thread" | "first_email" | "last_email" trigger_config?: Array<{ type: { ... } configuration?: { ... } }> + duplicated_automation_id?: string } | { id?: string type: "journey_submission" @@ -2166,14 +2367,14 @@ type FlowTemplate = { due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } assigned_to?: Array available_in_ecp?: boolean additional_triggers?: Array<{ @@ -2184,10 +2385,12 @@ type FlowTemplate = { id?: string type: "automation" automation_id?: string + input_entity?: "thread" | "first_email" | "last_email" trigger_config?: Array<{ type: { ... } configuration?: { ... } }> + duplicated_automation_id?: string } | { id?: string type: "journey_submission" @@ -2216,21 +2419,13 @@ type FlowTemplate = { }> taxonomies?: string[] }> - tasks: Array<{ + stages?: Array<{ id: string name: string - description?: { - enabled?: { ... } - value?: { ... } - } - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - due_date?: string - due_date_config?: { + description?: string + entry_node_id?: string + cut_edge_ids?: string[] + color?: string // ... } ``` @@ -2239,9 +2434,9 @@ type FlowTemplate = { Version of the workflow schema. -- `v1` – *Deprecated*. The initial version of workflows with limited structure and automation capabilities. -- `v2` – Linear workflows. Supports sequential task execution with basic automation triggers. -- `v3` – Advanced workflows. Adds support for branching logic +- `v1` – *Deprecated*. The initial version of workflows with limited structure and automation capabilities. +- `v2` – Linear workflows. Supports sequential task execution with basic automation triggers. +- `v3` – Advanced workflows. Adds support for branching logic (co ```ts type Version = "v1" | "v2" | "v3" @@ -2258,10 +2453,12 @@ type Trigger = { id?: string type: "automation" automation_id?: string + input_entity?: "thread" | "first_email" | "last_email" trigger_config?: Array<{ type: string configuration?: Record }> + duplicated_automation_id?: string } | { id?: string type: "journey_submission" @@ -2292,10 +2489,12 @@ type AutomationTrigger = { id?: string type: "automation" automation_id?: string + input_entity?: "thread" | "first_email" | "last_email" trigger_config?: Array<{ type: string configuration?: Record }> + duplicated_automation_id?: string } ``` @@ -2329,6 +2528,10 @@ type CreateFlowTemplate = { org_id?: string name: string description?: string + portal_titles?: { + ecp?: string + installer?: string + } trigger?: { id?: string type: "manual" @@ -2337,10 +2540,12 @@ type CreateFlowTemplate = { id?: string type: "automation" automation_id?: string + input_entity?: "thread" | "first_email" | "last_email" trigger_config?: Array<{ type: { ... } configuration?: { ... } }> + duplicated_automation_id?: string } | { id?: string type: "journey_submission" @@ -2359,14 +2564,14 @@ type CreateFlowTemplate = { due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } assigned_to?: Array available_in_ecp?: boolean additional_triggers?: Array<{ @@ -2377,10 +2582,12 @@ type CreateFlowTemplate = { id?: string type: "automation" automation_id?: string + input_entity?: "thread" | "first_email" | "last_email" trigger_config?: Array<{ type: { ... } configuration?: { ... } }> + duplicated_automation_id?: string } | { id?: string type: "journey_submission" @@ -2409,21 +2616,13 @@ type CreateFlowTemplate = { }> taxonomies?: string[] }> - tasks: Array<{ + stages?: Array<{ id: string name: string - description?: { - enabled?: { ... } - value?: { ... } - } - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - due_date?: string - due_date_config?: { + description?: string + entry_node_id?: string + cut_edge_ids?: string[] + color?: string // ... } ``` @@ -2438,7 +2637,7 @@ type SearchFlowTemplates = { enabled?: boolean from?: number size?: number - sort_by?: "created_at" | "updated_at" + sort_by?: "created_at" | "updated_at" | "name" | "enabled" | "id" sort_order?: "asc" | "desc" } ``` @@ -2452,6 +2651,10 @@ type FlowTemplatesList = { org_id?: string name: string description?: string + portal_titles?: { + ecp?: { ... } + installer?: { ... } + } trigger?: { id?: { ... } type: { ... } @@ -2460,7 +2663,9 @@ type FlowTemplatesList = { id?: { ... } type: { ... } automation_id?: { ... } + input_entity?: { ... } trigger_config?: { ... } + duplicated_automation_id?: { ... } } | { id?: { ... } type: { ... } @@ -2497,7 +2702,9 @@ type FlowTemplatesList = { id?: { ... } type: { ... } automation_id?: { ... } + input_entity?: { ... } trigger_config?: { ... } + duplicated_automation_id?: { ... } } | { id?: { ... } type: { ... } @@ -2517,35 +2724,27 @@ type FlowTemplatesList = { assigned_to?: { ... } taxonomies?: { ... } }> - tasks: Array<{ + stages?: Array<{ id: { ... } name: { ... } description?: { ... } - journey?: { ... } - due_date?: { ... } - due_date_config?: { ... } - requirements?: { ... } - assigned_to?: { ... } - ecp?: { ... } - installer?: { ... } - taxonomies?: { ... } - phase_id?: { ... } - task_type: { ... } - } | { + entry_node_id?: { ... } + cut_edge_ids?: { ... } + color?: { ... } + portal_names?: { ... } + portal_descriptions?: { ... } + }> + tasks: Array<{ id: { ... } name: { ... } description?: { ... } journey?: { ... } due_date?: { ... } due_date_config?: { ... } + start_date?: { ... } + start_date_config?: { ... } requirements?: { ... } - assigned_to?: { ... } - ecp?: { ... } - installer?: { ... } - taxonomies?: { ... } - phase_id?: { ... } - task_type: { ... } - automation_config: { ... } + required?: { ... } // ... } ``` @@ -2572,24 +2771,53 @@ type Task = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> assigned_to?: Array ecp?: { enabled?: boolean @@ -2599,7 +2827,11 @@ type Task = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } installer?: { @@ -2610,57 +2842,24 @@ type Task = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } + partner?: { + enabled?: boolean + label?: string + description?: string + } + audience_order?: "description" | "ecp" | "installer" | "partner"[] taxonomies?: string[] phase_id?: string task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" } | { id: string - name: string - description?: { - enabled?: boolean - value?: string - } - journey?: { - id?: string - journeyId?: string - name?: string - complete_task_automatically?: boolean - } - due_date?: string - due_date_config?: { - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" - task_id?: string - phase_id?: string - } - requirements?: Array<{ - task_id?: string - phase_id?: string - when: "TASK_FINISHED" | "PHASE_FINISHED" - }> - assigned_to?: Array - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - installer?: { - enabled?: boolean - label?: string - description?: string // ... } ``` @@ -2679,24 +2878,53 @@ type ManualTask = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> assigned_to?: Array ecp?: { enabled?: boolean @@ -2706,7 +2934,11 @@ type ManualTask = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } installer?: { @@ -2717,9 +2949,19 @@ type ManualTask = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } + partner?: { + enabled?: boolean + label?: string + description?: string + } + audience_order?: "description" | "ecp" | "installer" | "partner"[] taxonomies?: string[] phase_id?: string task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" @@ -2740,24 +2982,53 @@ type AutomationTask = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> assigned_to?: Array ecp?: { enabled?: boolean @@ -2767,7 +3038,11 @@ type AutomationTask = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } installer?: { @@ -2778,42 +3053,36 @@ type AutomationTask = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } + partner?: { + enabled?: boolean + label?: string + description?: string + } + audience_order?: "description" | "ecp" | "installer" | "partner"[] taxonomies?: string[] phase_id?: string task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" automation_config: { flow_id?: string - action_config?: { - type: { ... } - config?: { ... } - } - } - trigger_mode?: "manual" | "automatic" - schedule?: { - mode?: "immediate" - } | { - mode: "delayed" - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - } | { - mode: "relative" - direction: "before" | "after" - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - reference: { - id: { ... } - origin: { ... } - schema?: { ... } - attribute?: { ... } - } - } - created_automatically?: boolean + // ... } ``` +### `AutomationFailurePolicy` + +What the flow does when this automation ends in a failed state. `stop` waits on the failed task until it is retried or skipped. `continue` proceeds to the next task. An absent value means `stop`. + +```ts +type AutomationFailurePolicy = "stop" | "continue" +``` + ### `AutomationConfig` Configuration for automation execution to run @@ -2825,6 +3094,193 @@ type AutomationConfig = { type: string config?: Record } + duplicated_flow_id?: string + input_context?: { + source: "main_context" | "task" | "trigger" + task_id?: string + trigger_id?: string + with_relations?: boolean + also_pass?: Array<{ + source: { ... } + } | { + source: { ... } + task_id: { ... } + }> + } + output_context?: { + set_as_primary?: boolean + attach_to_contexts?: boolean + } + eligible_closing_reason_ids?: string[] + email_review?: { + enabled?: boolean + allow_document_selection?: boolean + allow_subject_and_body_edit?: boolean + } + allow_execution_note?: boolean +} +``` + +### `EmailReviewConfig` + +Whether the person running a semi-automated send-email step may adjust the email before it goes out, and what they may adjust. Meaningful only on a task a person triggers — the engine's own dispatch has nobody to review — so the template healer clears it from an `automatic` task. With `enabled` fals + +```ts +type EmailReviewConfig = { + enabled?: boolean + allow_document_selection?: boolean + allow_subject_and_body_edit?: boolean +} +``` + +### `AutomationInputContext` + +Optional. Source of the entity fed into this automation task. If omitted, the run's current main context is used. + + +```ts +type AutomationInputContext = { + source: "main_context" | "task" | "trigger" + task_id?: string + trigger_id?: string + with_relations?: boolean + also_pass?: Array<{ + source: "main_context" + } | { + source: "task" + task_id: string + }> +} +``` + +### `AutomationInputExtraContextRef` + +One of the run's own entities. `main_context` = the run's current main context. + + +```ts +type AutomationInputExtraContextRef = { + source: "main_context" +} +``` + +### `AutomationInputExtraTaskRef` + +Every entity produced by an upstream task. + +```ts +type AutomationInputExtraTaskRef = { + source: "task" + task_id: string +} +``` + +### `FlowContextSettings` + +Where a flow runs, and where people see it. +A run is ALWAYS visible on the entities it runs on — the entity its trigger supplied and every context it picks up. That is not configurable: it is what running there means, and hiding a run from its own entity is what `visibility: background` is for. +`dis + +```ts +type FlowContextSettings = { + visibility?: "entity_views" | "background" + main_context?: { + schema: string + relation_labels?: string[] + } + displays?: Array<{ + id: string + entity_schema: string + from?: { + role: { ... } + } | { + role: { ... } + rule_id: { ... } + } + relation_labels?: string[] + attach_to_contexts?: boolean + }> +} +``` + +### `MainContextSetting` + +Which of a flow's contexts owns the run: the entity conditions, automations and entity sync resolve against by default. +ABSENT means the default — the primary trigger's entity. A flow has ONE main context, not one per trigger (STABLE360-13503): a run started by another trigger resolves the default a + +```ts +type MainContextSetting = { + schema: string + relation_labels?: string[] +} +``` + +### `FlowDisplayRule` + +One additional entity kind the flow should be visible on, found by relation from the main context or from an earlier entry. +An entity reached this way has no context of its own: it shows the main context's run, and acting on it acts on the main context. Nothing is copied and no second run starts. +Th + +```ts +type FlowDisplayRule = { + id: string + entity_schema: string + from?: { + role: "main_context" + } | { + role: "rule" + rule_id: string + } + relation_labels?: string[] + attach_to_contexts?: boolean +} +``` + +### `FlowRuleAnchor` + +Where an entry starts looking. Absent means `main_context`. +A ROLE, not a schema: an entry anchored on `main_context` follows the primary when a task promotes another entity, where naming a schema would freeze it on the old one. + + +```ts +type FlowRuleAnchor = { + role: "main_context" +} | { + role: "rule" + rule_id: string +} +``` + +### `MainContextAnchor` + +The run's primary context, whatever it currently is. + +```ts +type MainContextAnchor = { + role: "main_context" +} +``` + +### `RuleAnchor` + +An earlier entry in `displays`, by its id: this entry searches from whatever that one matched. Chaining ticket -> contact -> account this way keeps both hops DISPLAY-only; making the contact a real context first is a separate decision (`attach_to_contexts`), not a prerequisite for reaching the accou + +```ts +type RuleAnchor = { + role: "rule" + rule_id: string +} +``` + +### `AutomationOutputContext` + +Optional. What happens to the entity produced by this automation task (the last successful entity-producing action of its automation). + + +```ts +type AutomationOutputContext = { + set_as_primary?: boolean + attach_to_contexts?: boolean } ``` @@ -2842,24 +3298,53 @@ type AiAgentTask = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> assigned_to?: Array ecp?: { enabled?: boolean @@ -2869,7 +3354,11 @@ type AiAgentTask = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } installer?: { @@ -2880,15 +3369,25 @@ type AiAgentTask = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } + partner?: { + enabled?: boolean + label?: string + description?: string + } + audience_order?: "description" | "ecp" | "installer" | "partner"[] taxonomies?: string[] phase_id?: string task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" agent_config?: { agent_id: string - } + // ... } ``` @@ -2916,15 +3415,15 @@ type ActionSchedule = { } | { mode: "delayed" duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" } | { mode: "relative" direction: "before" | "after" duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" reference: { id: string - origin: "flow_started" | "task_completed" | "trigger_entity_attribute" + origin: "flow_started" | "task_completed" | "trigger_entity_attribute" | "all_preceding_tasks_completed" schema?: string attribute?: string } @@ -2945,7 +3444,7 @@ type ImmediateSchedule = { type DelayedSchedule = { mode: "delayed" duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" } ``` @@ -2956,10 +3455,10 @@ type RelativeSchedule = { mode: "relative" direction: "before" | "after" duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" reference: { id: string - origin: "flow_started" | "task_completed" | "trigger_entity_attribute" + origin: "flow_started" | "task_completed" | "trigger_entity_attribute" | "all_preceding_tasks_completed" schema?: string attribute?: string } @@ -2980,24 +3479,53 @@ type DecisionTask = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> assigned_to?: Array ecp?: { enabled?: boolean @@ -3007,7 +3535,11 @@ type DecisionTask = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } installer?: { @@ -3018,48 +3550,46 @@ type DecisionTask = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } + partner?: { + enabled?: boolean + label?: string + description?: string + } + audience_order?: "description" | "ecp" | "installer" | "partner"[] taxonomies?: string[] phase_id?: string task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" trigger_mode: "manual" | "automatic" conditions: Array<{ - id: string - branch_name: string - logical_operator: "AND" | "OR" - statements: Array<{ - id: { ... } - source: { ... } - operator: { ... } - values: { ... } - }> - }> - schedule?: { - mode: "delayed" - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - } | { - mode: "relative" - direction: "before" | "after" - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - reference: { - id: { ... } - origin: { ... } - schema?: { ... } - attribute?: { ... } - } - } - loop_config?: { - loop_branch_id: string - exit_branch_id: string - max_iterations: number - } + // ... +} +``` + +### `LoopDefinition` + +```ts +type LoopDefinition = { + entry_branch_ids: string[] + exit_branch_id: string + max_iterations: number } ``` +### `TaskAudience` + +A task audience, named after the task field holding its description: co-workers (description), end customers (ecp), installers and partners. + +```ts +type TaskAudience = "description" | "ecp" | "installer" | "partner" +``` + ### `TaskBase` ```ts @@ -3074,24 +3604,53 @@ type TaskBase = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> assigned_to?: Array ecp?: { enabled?: boolean @@ -3101,7 +3660,11 @@ type TaskBase = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } installer?: { @@ -3112,9 +3675,19 @@ type TaskBase = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } + partner?: { + enabled?: boolean + label?: string + description?: string + } + audience_order?: "description" | "ecp" | "installer" | "partner"[] taxonomies?: string[] phase_id?: string task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" @@ -3130,19 +3703,42 @@ type Phase = { due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } assigned_to?: Array taxonomies?: string[] } ``` +### `Stage` + +A customer-facing progress segment layered on top of the flow graph. Unlike phases (internal task grouping), stages exist to communicate progress to outside users (e.g. end customers) with a title and description. Stages form a strict total order; the array order is the boundary order and must match + +```ts +type Stage = { + id: string + name: string + description?: string + entry_node_id?: string + cut_edge_ids?: string[] + color?: string + portal_names?: { + ecp?: string + installer?: string + } + portal_descriptions?: { + ecp?: string + installer?: string + } +} +``` + ### `VariableAssignment` Represents a variable assignment with its expression and optional resolved value. Used for dynamic user assignments that get resolved during workflow execution. @@ -3150,7 +3746,7 @@ Represents a variable assignment with its expression and optional resolved value ```ts type VariableAssignment = { variable: string - value?: string + value?: string[] } ``` @@ -3166,8 +3762,9 @@ type TaskType = "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" type Edge = { id: string from_id: string - to_id: string + to_id?: string condition_id?: string + loop_id?: string none_met?: boolean } ``` @@ -3190,10 +3787,14 @@ type Condition = { attribute_type?: { ... } attribute_repeatable?: { ... } attribute_operation?: { ... } + attributes?: { ... } + attributes_match?: { ... } attribute_sub_field?: { ... } + date_offset?: { ... } } operator: "equals" | "not_equals" | "any_of" | "none_of" | "contains" | "not_contains" | "starts_with" | "ends_with" | "greater_than" | "less_than" | "greater_than_or_equals" | "less_than_or_equals" | "is_empty" | "is_not_empty" values: string[] + value_type?: "static" | "relative_date" }> } ``` @@ -3205,17 +3806,24 @@ type Statement = { id: string source: { id?: string - origin?: "trigger" | "action" - origin_type?: "entity" | "workflow" | "journey_block" + origin?: "trigger" | "action" | "flow_runtime" + origin_type?: "entity" | "workflow" | "journey_block" | "trigger_source" | "main_context" | "flow_trait" schema?: string attribute?: string attribute_type?: "string" | "text" | "number" | "boolean" | "date" | "datetime" | "tags" | "country" | "email" | "phone" | "product" | "price" | "status" | "relation" | "multiselect" | "select" | "radio" | "relation_user" | "purpose" | "label" | "message_email_address" attribute_repeatable?: boolean attribute_operation?: "all" | "updated" | "added" | "deleted" + attributes?: string[] + attributes_match?: "any" | "all" attribute_sub_field?: string + date_offset?: { + amount?: { ... } + unit?: { ... } + } } operator: "equals" | "not_equals" | "any_of" | "none_of" | "contains" | "not_contains" | "starts_with" | "ends_with" | "greater_than" | "less_than" | "greater_than_or_equals" | "less_than_or_equals" | "is_empty" | "is_not_empty" values: string[] + value_type?: "static" | "relative_date" } ``` @@ -3224,14 +3832,20 @@ type Statement = { ```ts type EvaluationSource = { id?: string - origin?: "trigger" | "action" - origin_type?: "entity" | "workflow" | "journey_block" + origin?: "trigger" | "action" | "flow_runtime" + origin_type?: "entity" | "workflow" | "journey_block" | "trigger_source" | "main_context" | "flow_trait" schema?: string attribute?: string attribute_type?: "string" | "text" | "number" | "boolean" | "date" | "datetime" | "tags" | "country" | "email" | "phone" | "product" | "price" | "status" | "relation" | "multiselect" | "select" | "radio" | "relation_user" | "purpose" | "label" | "message_email_address" attribute_repeatable?: boolean attribute_operation?: "all" | "updated" | "added" | "deleted" + attributes?: string[] + attributes_match?: "any" | "all" attribute_sub_field?: string + date_offset?: { + amount?: number + unit?: "days" | "months" | "years" + } } ``` @@ -3243,22 +3857,35 @@ type Operator = "equals" | "not_equals" | "any_of" | "none_of" | "contains" | "n ### `DueDateConfig` -Set due date for the task based on a dynamic condition +Set due date for the task based on a dynamic condition. `START_DATE` counts from the task's own start date (AL-3678) and is valid only on a task that has a start date. ```ts type DueDateConfig = { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } ``` +### `StartDateConfig` + +Relative start date of a task (AL-3678): `duration` `unit` after the most recent occurrence of the reference event. `THIS_TASK_LAST_COMPLETED` is the task's own previous completion (a loop's earlier pass); there is no wait while the reference event has not happened. Durations are positive whole numb + +```ts +type StartDateConfig = { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string +} +``` + ### `TimeUnit` ```ts -type TimeUnit = "minutes" | "hours" | "days" | "weeks" | "months" +type TimeUnit = "minutes" | "hours" | "days" | "weeks" | "months" | "years" ``` ### `EnableRequirement` @@ -3273,8 +3900,27 @@ type EnableRequirement = { } ``` +### `Subtask` + +One checklist item of a task, derived from the checklist markup in the party descriptions. Identity is the stable data-subtask-id the editor mints into the markup. + +```ts +type Subtask = { + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean +} +``` + ### `WorkflowDefinition` +V1 workflow definition schema. Defines a linear workflow structure with sections +and steps. Sections group related steps together, and steps represent individual +tasks that need to be completed. This is the legacy workflow model; for new +implementations, consider using V2 flow templates instead. + + ```ts type WorkflowDefinition = { id?: string @@ -3286,7 +3932,7 @@ type WorkflowDefinition = { dueDate?: string dynamicDueDate?: { numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" | "years" actionTypeCondition: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" stepId?: string phaseId?: string @@ -3324,6 +3970,7 @@ type WorkflowDefinition = { type: { ... } ecp?: { ... } installer?: { ... } + partner?: { ... } taxonomies?: { ... } }> taxonomies?: string[] @@ -3342,7 +3989,11 @@ type WorkflowDefinition = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } order: number dueDate?: string @@ -3371,11 +4022,6 @@ type WorkflowDefinition = { enabled?: { ... } label?: { ... } description?: { ... } - journey?: { ... } - } - taxonomies?: string[] - }> - closingReasons?: Array<{ // ... } ``` @@ -3400,13 +4046,27 @@ type Step = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } order: number dueDate?: string dynamicDueDate?: { numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" | "years" actionTypeCondition: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" stepId?: string phaseId?: string @@ -3427,7 +4087,11 @@ type Step = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } installer?: { @@ -3438,9 +4102,18 @@ type Step = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } + partner?: { + enabled?: boolean + label?: string + description?: string + } taxonomies?: string[] } ``` @@ -3458,7 +4131,7 @@ type Section = { dueDate?: string dynamicDueDate?: { numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" | "years" actionTypeCondition: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" stepId?: string phaseId?: string @@ -3479,7 +4152,11 @@ type Section = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } order: number dueDate?: string @@ -3510,6 +4187,11 @@ type Section = { description?: { ... } journey?: { ... } } + partner?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + } taxonomies?: string[] }> taxonomies?: string[] @@ -3541,7 +4223,99 @@ type StepJourney = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: string + value: string + }> + ai_prefill?: { + enabled?: boolean + source?: { + type?: { ... } + input_entity?: { ... } + } + extraction_fields?: Array<{ + key: { ... } + type: { ... } + description?: { ... } + description_overridden?: { ... } + enum?: { ... } + }> + mappings?: Array<{ + source: { ... } + block_id: { ... } + block_type: { ... } + block_field?: { ... } + country_code?: { ... } + }> + min_confidence?: number + instructions?: string + } +} +``` + +### `AiPrefillConfig` + +AI extraction + prefill configuration for the attached journey (Flows v2 only) + +```ts +type AiPrefillConfig = { + enabled?: boolean + source?: { + type?: "flow_context" + input_entity?: "thread" | "first_email" | "last_email" + } + extraction_fields?: Array<{ + key: string + type: "string" | "number" | "boolean" | "date" | "enum" + description?: string + description_overridden?: boolean + enum?: string[] + }> + mappings?: Array<{ + source: string + block_id: string + block_type: "text-input" | "number-input" | "personal-information" | "meter-reading" | "contact" | "single-choice" | "date-input" | "binary-input" | "address" | "payment-method" | "multiple-choice" | "availability-check" + block_field?: string + country_code?: string + }> + min_confidence?: number + instructions?: string +} +``` + +### `AiPrefillExtractionField` + +```ts +type AiPrefillExtractionField = { + key: string + type: "string" | "number" | "boolean" | "date" | "enum" + description?: string + description_overridden?: boolean + enum?: string[] +} +``` + +### `AiPrefillMapping` + +```ts +type AiPrefillMapping = { + source: string + block_id: string + block_type: "text-input" | "number-input" | "personal-information" | "meter-reading" | "contact" | "single-choice" | "date-input" | "binary-input" | "address" | "payment-method" | "multiple-choice" | "availability-check" + block_field?: string + country_code?: string +} +``` + +### `JourneyContextParameter` + +```ts +type JourneyContextParameter = { + key: string + value: string } ``` @@ -3558,11 +4332,37 @@ type ECPDetails = { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } } ``` +### `PartnerDetails` + +Details regarding partner for the workflow step + +```ts +type PartnerDetails = { + enabled?: boolean + label?: string + description?: string +} +``` + ### `StepDescription` Longer information regarding Task @@ -3585,7 +4385,7 @@ type MaxAllowedLimit = { ### `DefinitionNotFoundResp` -Definition could be not found +Error response returned when a workflow definition or flow template is not found. ```ts type DefinitionNotFoundResp = { @@ -3595,7 +4395,7 @@ type DefinitionNotFoundResp = { ### `ClosingReasonNotFoundResp` -Closing reason could be not found +Error response returned when a closing reason is not found. ```ts type ClosingReasonNotFoundResp = { @@ -3617,8 +4417,8 @@ type ChangeReasonStatusReq = { type ClosingReasons = { reasons: Array<{ id?: string - title: string - status: "ACTIVE" | "INACTIVE" + title?: string + status?: "ACTIVE" | "INACTIVE" lastUpdateTime?: string creationTime?: string }> @@ -3632,8 +4432,8 @@ One Closing reason for a workflow ```ts type ClosingReason = { id?: string - title: string - status: "ACTIVE" | "INACTIVE" + title?: string + status?: "ACTIVE" | "INACTIVE" lastUpdateTime?: string creationTime?: string } @@ -3665,6 +4465,8 @@ type ClosingReasonId = { ### `ErrorResp` +Standard error response returned when an API request fails. + ```ts type ErrorResp = { message?: string @@ -3707,12 +4509,16 @@ type EntitySync = { ### `DynamicDueDate` -set a Duedate for a step then a specific +Configuration for calculating a due date dynamically based on workflow events. +The due date is computed by adding a duration (numberOfUnits + timePeriod) to +a reference point defined by actionTypeCondition (e.g., when workflow started, +when a step closed, or when a phase finished). + ```ts type DynamicDueDate = { numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" | "years" actionTypeCondition: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" stepId?: string phaseId?: string @@ -3731,117 +4537,76 @@ type StepRequirement = { } ``` -### `FlowTemplateExport` +### `JourneyContextUsagesReq` + +Request payload for getJourneyContextUsages. ```ts -type FlowTemplateExport = { - _resolved_automations?: Record +type JourneyContextUsagesReq = { + journey_id: string + param_keys: string[] + param_ids?: string[] } ``` -### `FlowTemplateImportResult` +### `JourneyContextUsage` + +One place a flow template task presets one of the requested context parameters. ```ts -type FlowTemplateImportResult = { - flow?: { - id?: string - org_id?: string - name: string - description?: string - trigger?: { - id?: { ... } - type: { ... } - entity_schema?: { ... } - } | { - id?: { ... } - type: { ... } - automation_id?: { ... } - trigger_config?: { ... } - } | { - id?: { ... } - type: { ... } - journey_id: { ... } - journey_name?: { ... } - automation_id?: { ... } - } | { - id?: { ... } - type: { ... } - entity_schema?: { ... } +type JourneyContextUsage = { + kind: "workflow-task" + resource: { + type: "workflow_template" + id: string + name?: string + } + location?: { + task_id?: string + task_name?: string + } + matched_as: { + dialect: "name" + token: string + at: string + } + link_hint?: { + route: "workflows-hub-flow" + params: { + template_id: { ... } } - enabled?: boolean - version?: "v1" | "v2" | "v3" - created_at?: string - updated_at?: string - due_date?: string - due_date_config?: { - duration: { ... } - unit: { ... } + } +} +``` + +### `JourneyContextUsagesResp` + +Response payload for getJourneyContextUsages. + +```ts +type JourneyContextUsagesResp = { + usages: Array<{ + kind: "workflow-task" + resource: { type: { ... } + id: { ... } + name?: { ... } + } + location?: { task_id?: { ... } - phase_id?: { ... } + task_name?: { ... } } - assigned_to?: Array - available_in_ecp?: boolean - additional_triggers?: Array<{ - id?: { ... } - type: { ... } - entity_schema?: { ... } - } | { - id?: { ... } - type: { ... } - automation_id?: { ... } - trigger_config?: { ... } - } | { - id?: { ... } - type: { ... } - journey_id: { ... } - journey_name?: { ... } - automation_id?: { ... } - } | { - id?: { ... } - type: { ... } - entity_schema?: { ... } - }> - phases?: Array<{ - id: { ... } - name: { ... } - due_date?: { ... } - due_date_config?: { ... } - assigned_to?: { ... } - taxonomies?: { ... } - }> - tasks: Array<{ - id: { ... } - name: { ... } - description?: { ... } - journey?: { ... } - due_date?: { ... } - due_date_config?: { ... } - requirements?: { ... } - assigned_to?: { ... } - ecp?: { ... } - installer?: { ... } - taxonomies?: { ... } - phase_id?: { ... } - task_type: { ... } - } | { - id: { ... } - name: { ... } - description?: { ... } - journey?: { ... } - due_date?: { ... } - due_date_config?: { ... } - requirements?: { ... } - assigned_to?: { ... } - ecp?: { ... } - installer?: { ... } - taxonomies?: { ... } - phase_id?: { ... } - task_type: { ... } - automation_config: { ... } - // ... + matched_as: { + dialect: { ... } + token: { ... } + at: { ... } + } + link_hint?: { + route: { ... } + params: { ... } + } + }> + status: "ok" | "partial" + scanned: number } ``` diff --git a/docs/sdk/clients/workflow.md b/docs/sdk/clients/workflow.md index 2cda8316..7238ae23 100644 --- a/docs/sdk/clients/workflow.md +++ b/docs/sdk/clients/workflow.md @@ -50,12 +50,27 @@ const { data } = await workflowClient.getExecutions(...) - [`patchFlowExecution`](#patchflowexecution) - [`deleteFlowExecution`](#deleteflowexecution) - [`searchFlowExecutions`](#searchflowexecutions) +- [`bulkStartFlows`](#bulkstartflows) +- [`listBulkStartFlowsJobs`](#listbulkstartflowsjobs) +- [`getActiveBulkStartFlowsJob`](#getactivebulkstartflowsjob) +- [`getBulkStartFlowsJob`](#getbulkstartflowsjob) +- [`patchBulkStartFlowsJob`](#patchbulkstartflowsjob) +- [`listBulkStartFlowsJobItems`](#listbulkstartflowsjobitems) +- [`restartBulkStartFlowsJob`](#restartbulkstartflowsjob) - [`patchTask`](#patchtask) - [`runTaskAutomation`](#runtaskautomation) +- [`previewTaskEmail`](#previewtaskemail) - [`executeTask`](#executetask) - [`patchPhase`](#patchphase) - [`addTask`](#addtask) +- [`rescheduleTask`](#rescheduletask) - [`cancelTaskSchedule`](#canceltaskschedule) +- [`reconcileAutomationTask`](#reconcileautomationtask) +- [`runTaskScheduleNow`](#runtaskschedulenow) + +**Portal Workflows** +- [`searchPortalWorkflows`](#searchportalworkflows) +- [`searchPortalWorkflowsBatch`](#searchportalworkflowsbatch) **Schemas** - [`WorkflowExecutionCreateReq`](#workflowexecutioncreatereq) @@ -78,8 +93,14 @@ const { data } = await workflowClient.getExecutions(...) - [`SectionStatus`](#sectionstatus) - [`StepType`](#steptype) - [`StepJourney`](#stepjourney) +- [`JourneyContextParameter`](#journeycontextparameter) +- [`AiPrefillConfig`](#aiprefillconfig) +- [`AiPrefillExtractionField`](#aiprefillextractionfield) +- [`AiPrefillMapping`](#aiprefillmapping) +- [`JourneyPrefill`](#journeyprefill) - [`AutomationConfig`](#automationconfig) - [`ECPDetails`](#ecpdetails) +- [`PartnerDetails`](#partnerdetails) - [`StepDescription`](#stepdescription) - [`ItemType`](#itemtype) - [`TriggerType`](#triggertype) @@ -98,6 +119,7 @@ const { data } = await workflowClient.getExecutions(...) - [`ErrorResp`](#errorresp) - [`ClosingReasonResp`](#closingreasonresp) - [`PhaseInEntity`](#phaseinentity) +- [`TaskInEntity`](#taskinentity) - [`WorkflowInEntity`](#workflowinentity) - [`UpdateEntityAttributes`](#updateentityattributes) - [`EntitySync`](#entitysync) @@ -105,10 +127,39 @@ const { data } = await workflowClient.getExecutions(...) - [`StepRequirement`](#steprequirement) - [`StartFlowReq`](#startflowreq) - [`SearchFlowsReq`](#searchflowsreq) +- [`PortalWorkflowsSearchReq`](#portalworkflowssearchreq) +- [`PortalAudience`](#portalaudience) +- [`PortalWorkflowsSearchResp`](#portalworkflowssearchresp) +- [`BulkStartFlowsReq`](#bulkstartflowsreq) +- [`BulkStartEntitiesQuery`](#bulkstartentitiesquery) +- [`BulkStartEntityRef`](#bulkstartentityref) +- [`BulkStartFlowsJobStatus`](#bulkstartflowsjobstatus) +- [`BulkStartFlowsItemStatus`](#bulkstartflowsitemstatus) +- [`BulkStartFlowsItem`](#bulkstartflowsitem) +- [`BulkStartFlowsFlowSummary`](#bulkstartflowsflowsummary) +- [`BulkStartFlowsAutomaticTask`](#bulkstartflowsautomatictask) +- [`BulkStartFlowsJobFailure`](#bulkstartflowsjobfailure) +- [`BulkStartFlowsJobPreparation`](#bulkstartflowsjobpreparation) +- [`BulkStartFlowsJobCounts`](#bulkstartflowsjobcounts) +- [`BulkStartFlowsJob`](#bulkstartflowsjob) +- [`BulkStartFlowsJobSummary`](#bulkstartflowsjobsummary) +- [`ListBulkStartFlowsJobsResp`](#listbulkstartflowsjobsresp) +- [`ListBulkStartFlowsJobItemsResp`](#listbulkstartflowsjobitemsresp) +- [`ActiveBulkStartFlowsJobResp`](#activebulkstartflowsjobresp) +- [`PatchBulkStartFlowsJobReq`](#patchbulkstartflowsjobreq) +- [`PortalWorkflowsBatchSearchReq`](#portalworkflowsbatchsearchreq) +- [`PortalEntityRef`](#portalentityref) +- [`PortalWorkflowsBatchSearchResp`](#portalworkflowsbatchsearchresp) +- [`EntityPortalWorkflows`](#entityportalworkflows) +- [`PortalWorkflow`](#portalworkflow) +- [`PortalWorkflowTask`](#portalworkflowtask) +- [`PortalWorkflowStage`](#portalworkflowstage) - [`PatchFlowReq`](#patchflowreq) - [`FlowExecution`](#flowexecution) - [`FlowClosingReason`](#flowclosingreason) - [`FlowTrigger`](#flowtrigger) +- [`ConfiguredTrigger`](#configuredtrigger) +- [`VisibleEntity`](#visibleentity) - [`FlowContext`](#flowcontext) - [`EntityRef`](#entityref) - [`PhaseId`](#phaseid) @@ -117,35 +168,60 @@ const { data } = await workflowClient.getExecutions(...) - [`TaskType`](#tasktype) - [`ManualTask`](#manualtask) - [`AutomationTask`](#automationtask) +- [`AutomationFailurePolicy`](#automationfailurepolicy) - [`LoopInfo`](#loopinfo) +- [`LoopExecutionState`](#loopexecutionstate) +- [`LoopMembership`](#loopmembership) +- [`LoopOutcome`](#loopoutcome) - [`LoopConfig`](#loopconfig) - [`TriggerMode`](#triggermode) - [`ActionSchedule`](#actionschedule) - [`ImmediateSchedule`](#immediateschedule) - [`DelayedSchedule`](#delayedschedule) +- [`RescheduleTaskReq`](#rescheduletaskreq) +- [`ScheduleChange`](#schedulechange) - [`RelativeSchedule`](#relativeschedule) - [`DecisionTask`](#decisiontask) - [`AiAgentTask`](#aiagenttask) - [`AgentConfig`](#agentconfig) - [`AgentExecutionInfo`](#agentexecutioninfo) +- [`TaskAudience`](#taskaudience) - [`TaskBase`](#taskbase) +- [`Stage`](#stage) - [`Phase`](#phase) - [`Edge`](#edge) - [`AutomationInfo`](#automationinfo) +- [`JourneyExecutionInfo`](#journeyexecutioninfo) +- [`AutomationInputContext`](#automationinputcontext) +- [`AutomationInputExtraContextRef`](#automationinputextracontextref) +- [`AutomationInputExtraTaskRef`](#automationinputextrataskref) +- [`AutomationOutputContext`](#automationoutputcontext) - [`AnalyticsInfo`](#analyticsinfo) +- [`ConditionResult`](#conditionresult) +- [`TaskIteration`](#taskiteration) - [`ConditionId`](#conditionid) - [`Condition`](#condition) - [`Statement`](#statement) - [`EvaluationSource`](#evaluationsource) - [`Operator`](#operator) - [`DueDateConfig`](#duedateconfig) +- [`StartDateConfig`](#startdateconfig) - [`TimeUnit`](#timeunit) - [`EnableRequirement`](#enablerequirement) +- [`Subtask`](#subtask) +- [`SubtaskState`](#subtaskstate) - [`FlowTemplateId`](#flowtemplateid) - [`FlowExecutionId`](#flowexecutionid) - [`UserId`](#userid) +- [`EcpPlaceholderAssignees`](#ecpplaceholderassignees) - [`VariableAssignment`](#variableassignment) - [`Assignees`](#assignees) +- [`RunTaskAutomationReq`](#runtaskautomationreq) +- [`TaskAutomationActionInputs`](#taskautomationactioninputs) +- [`CancelFlowExecutionInputs`](#cancelflowexecutioninputs) +- [`TaskEmailPreview`](#taskemailpreview) +- [`EmailReviewConfig`](#emailreviewconfig) +- [`SendEmailInputs`](#sendemailinputs) - [`PatchTaskReq`](#patchtaskreq) - [`PatchPhaseReq`](#patchphasereq) - [`AddTaskReq`](#addtaskreq) @@ -212,7 +288,7 @@ const { data } = await client.getExecutions({ ### `createExecution` -Create a Workflow Execution. Start a new workflow execution, based on a workflow definition (template). +Creates a new V1 Workflow Execution from a workflow definition (template). `POST /v1/workflows/executions` @@ -286,7 +362,7 @@ const { data } = await client.createExecution( ### `getExecution` -Get a full workflow execution, included steps information, by execution id. +Retrieves a complete V1 workflow execution by ID, including all steps information. `GET /v1/workflows/executions/{executionId}` @@ -454,7 +530,11 @@ const { data } = await client.createStep( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} } }, "installer": { @@ -465,9 +545,18 @@ const { data } = await client.createStep( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, "enabled": true, "requirements": [ { @@ -482,6 +571,7 @@ const { data } = await client.createStep( "userIds": [0], "assignedTo": ["string"], "assignedToInProgress": "string", + "assignedToOnHold": "string", "status": "UNASSIGNED", "created": "string", "lastUpdated": "string", @@ -506,7 +596,20 @@ const { data } = await client.createStep( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [ + {} + ], + "ai_prefill": { + "enabled": false, + "source": {}, + "extraction_fields": [], + "mappings": [], + "min_confidence": 0.8, + "instructions": "string" + } }, "taxonomies": ["string"] } @@ -518,7 +621,7 @@ const { data } = await client.createStep( ### `updateStep` -Patches various changes to a workflow execution step. +Updates a workflow execution step with new values for status, assignees, due date, position, and more. `PATCH /v1/workflows/executions/{executionId}/steps/{stepId}` @@ -534,6 +637,7 @@ const { data } = await client.updateStep( userIds: [0], assignedTo: ['string'], assignedToInProgress: 'string', + assignedToOnHold: 'string', status: 'UNASSIGNED', dueDate: 'string', dynamicDueDate: { @@ -557,6 +661,47 @@ const { data } = await client.updateStep( executionId: 'string', executionStatus: 'string' }, + journey: { + id: 'string', + journeyId: 'string', + name: 'string', + portal_button_label: 'string', + complete_task_automatically: true, + journey_submission_required: true, + context_parameters: [ + { + key: 'string', + value: 'string' + } + ], + ai_prefill: { + enabled: false, + source: { + type: 'flow_context', + input_entity: 'last_email' + }, + extraction_fields: [ + { + key: 'string', + type: 'string', + description: 'string', + description_overridden: true, + enum: ['string'] + } + ], + mappings: [ + { + source: 'string', + block_id: 'string', + block_type: 'text-input', + block_field: 'string', + country_code: 'string' + } + ], + min_confidence: 0.8, + instructions: 'string' + } + }, startedTime: 'string', completedTime: 'string' }, @@ -585,7 +730,11 @@ const { data } = await client.updateStep( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} } }, "installer": { @@ -596,9 +745,18 @@ const { data } = await client.updateStep( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, "enabled": true, "requirements": [ { @@ -613,6 +771,7 @@ const { data } = await client.updateStep( "userIds": [0], "assignedTo": ["string"], "assignedToInProgress": "string", + "assignedToOnHold": "string", "status": "UNASSIGNED", "created": "string", "lastUpdated": "string", @@ -637,7 +796,20 @@ const { data } = await client.updateStep( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [ + {} + ], + "ai_prefill": { + "enabled": false, + "source": {}, + "extraction_fields": [], + "mappings": [], + "min_confidence": 0.8, + "instructions": "string" + } }, "taxonomies": ["string"] } @@ -696,7 +868,7 @@ const { data } = await client.getClosingReasonExecution({ ### `startFlowExecution` -Starts a new Flow Execution based on a flow template. +Starts a new Flow Execution based on a flow template (definition). `POST /v2/flows/executions` @@ -704,21 +876,63 @@ Starts a new Flow Execution based on a flow template. const { data } = await client.startFlowExecution( null, { - flow_template_id: 'string', + flow_template_id: 'tpl_abc123def456', trigger: { type: 'MANUAL', automation_config: { flow_id: 'string', execution_id: 'string', execution_status: 'string', - error_reason: 'string' - } + error_reason: 'string', + input_context: { + source: 'main_context', + task_id: 'string', + trigger_id: 'string', + with_relations: true, + also_pass: [ + { + source: 'main_context' + } + ] + }, + output_context: { + set_as_primary: true, + attach_to_contexts: true + }, + heal_attempts: 0, + run_for_user_id: 'string', + last_heal_attempted_at: '1970-01-01T00:00:00.000Z', + wait_for_journey_submission: true, + journey_id: 'string', + journey_execution: { + execution_id: 'string', + execution_status: 'string', + error_reason: 'string', + submission_entity_id: 'string', + submission_created_at: '1970-01-01T00:00:00.000Z', + wait_overridden_at: '1970-01-01T00:00:00.000Z', + wait_overridden_by: 'string' + }, + eligible_closing_reason_ids: ['string'], + allow_execution_note: true, + email_review: { + enabled: true, + allow_document_selection: true, + allow_subject_and_body_edit: true + } + }, + trigger_id: 'string', + bulk_job_id: 'string' }, contexts: [ { entity_id: 'string', entity_schema: 'string', - is_primary: false + is_primary: false, + promoted_by_task_id: 'string', + promoted_at: '1970-01-01T00:00:00.000Z', + demoted_by_task_id: 'string', + added_by_task_id: 'string' } ], purposes: ['string'] @@ -732,6 +946,7 @@ const { data } = await client.startFlowExecution( ```json { "id": "string", + "loop_source": "loops", "flow_template_id": "string", "org_id": "string", "name": "string", @@ -752,18 +967,35 @@ const { data } = await client.startFlowExecution( "completed_at": "string", "closed_at": "string", "started_by": "string", - "closed_by": "string" + "started_by_org_id": "string", + "closed_by": "string", + "completed_by": "string" }, "contexts": [ { "entity_id": "string", "entity_schema": "string", - "is_primary": false + "is_primary": false, + "promoted_by_task_id": "string", + "promoted_at": "1970-01-01T00:00:00.000Z", + "demoted_by_task_id": "string", + "added_by_task_id": "string" + } + ], + "visibility": "entity_views", + "visible_on": [ + { + "entity_id": "string", + "entity_schema": "string", + "kind": "context", + "anchor_entity_id": "string", + "rule_id": "string" } ], "crt_tasks": [ { - "id": "string" + "id": "string", + "crt_since": "1970-01-01T00:00:00.000Z" } ], "phases": [ @@ -778,28 +1010,60 @@ const { data } = await client.startFlowExecution( "assigned_to": ["string"], "analytics": {}, "taxonomies": ["string"], - "loop_config": {} + "loop_config": {}, + "loop_membership": [] + } + ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "entry_node_id": "string", + "cut_edge_ids": ["string"], + "color": "string", + "portal_names": {}, + "portal_descriptions": {} } ], + "portal_titles": { + "ecp": "string", + "installer": "string" + }, "tasks": [ { "id": "string", + "loop_membership": [], "template_id": "string", "name": "string", "description": {}, "status": "UNASSIGNED", "journey": {}, + "journey_prefill": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [], + "subtask_states": {}, + "journey_submission": {}, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", "assigned_to": ["string"], + "ecp_placeholder_assignees": {}, "analytics": {}, + "loop_iterations": {}, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "manually_created": true, "enabled": true, "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -812,7 +1076,8 @@ const { data } = await client.startFlowExecution( "from_id": "string", "to_id": "string", "condition_id": "abc123", - "none_met": true + "none_met": true, + "loop_id": "string" } ], "_execution_chain": { @@ -820,6 +1085,7 @@ const { data } = await client.startFlowExecution( "parent_task_id": "string", "depth": 0 }, + "_automation_chain": ["string"], "closing_reason": { "selected_reasons": [ {} @@ -844,10 +1110,34 @@ const { data } = await client.startFlowExecution( "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" - } + "error_reason": "string", + "input_context": {}, + "output_context": {}, + "heal_attempts": 0, + "run_for_user_id": "string", + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z", + "wait_for_journey_submission": true, + "journey_id": "string", + "journey_execution": {}, + "eligible_closing_reason_ids": ["string"], + "allow_execution_note": true, + "email_review": {} + }, + "trigger_id": "string", + "bulk_job_id": "string" }, - "singleClosingReasonSelection": true + "configured_triggers": [ + { + "id": "string", + "type": "string", + "primary": true, + "entity_schema": "string", + "automation_id": "string", + "journey_id": "string" + } + ], + "singleClosingReasonSelection": true, + "linear": true } ``` @@ -857,13 +1147,14 @@ const { data } = await client.startFlowExecution( ### `getFlowExecution` -Get a full flow execution, included tasks, phases, edges & analytics. +Retrieves a complete flow execution by ID, including all phases, tasks, edges, contexts, and analytics. `GET /v2/flows/executions/{execution_id}` ```ts const { data } = await client.getFlowExecution({ execution_id: 'example', + skip_heal: true, }) ``` @@ -873,6 +1164,7 @@ const { data } = await client.getFlowExecution({ ```json { "id": "string", + "loop_source": "loops", "flow_template_id": "string", "org_id": "string", "name": "string", @@ -893,18 +1185,35 @@ const { data } = await client.getFlowExecution({ "completed_at": "string", "closed_at": "string", "started_by": "string", - "closed_by": "string" + "started_by_org_id": "string", + "closed_by": "string", + "completed_by": "string" }, "contexts": [ { "entity_id": "string", "entity_schema": "string", - "is_primary": false + "is_primary": false, + "promoted_by_task_id": "string", + "promoted_at": "1970-01-01T00:00:00.000Z", + "demoted_by_task_id": "string", + "added_by_task_id": "string" + } + ], + "visibility": "entity_views", + "visible_on": [ + { + "entity_id": "string", + "entity_schema": "string", + "kind": "context", + "anchor_entity_id": "string", + "rule_id": "string" } ], "crt_tasks": [ { - "id": "string" + "id": "string", + "crt_since": "1970-01-01T00:00:00.000Z" } ], "phases": [ @@ -919,28 +1228,60 @@ const { data } = await client.getFlowExecution({ "assigned_to": ["string"], "analytics": {}, "taxonomies": ["string"], - "loop_config": {} + "loop_config": {}, + "loop_membership": [] + } + ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "entry_node_id": "string", + "cut_edge_ids": ["string"], + "color": "string", + "portal_names": {}, + "portal_descriptions": {} } ], + "portal_titles": { + "ecp": "string", + "installer": "string" + }, "tasks": [ { "id": "string", + "loop_membership": [], "template_id": "string", "name": "string", "description": {}, "status": "UNASSIGNED", "journey": {}, + "journey_prefill": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [], + "subtask_states": {}, + "journey_submission": {}, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", "assigned_to": ["string"], + "ecp_placeholder_assignees": {}, "analytics": {}, + "loop_iterations": {}, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "manually_created": true, "enabled": true, "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -953,7 +1294,8 @@ const { data } = await client.getFlowExecution({ "from_id": "string", "to_id": "string", "condition_id": "abc123", - "none_met": true + "none_met": true, + "loop_id": "string" } ], "_execution_chain": { @@ -961,6 +1303,7 @@ const { data } = await client.getFlowExecution({ "parent_task_id": "string", "depth": 0 }, + "_automation_chain": ["string"], "closing_reason": { "selected_reasons": [ {} @@ -985,10 +1328,34 @@ const { data } = await client.getFlowExecution({ "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" - } + "error_reason": "string", + "input_context": {}, + "output_context": {}, + "heal_attempts": 0, + "run_for_user_id": "string", + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z", + "wait_for_journey_submission": true, + "journey_id": "string", + "journey_execution": {}, + "eligible_closing_reason_ids": ["string"], + "allow_execution_note": true, + "email_review": {} + }, + "trigger_id": "string", + "bulk_job_id": "string" }, - "singleClosingReasonSelection": true + "configured_triggers": [ + { + "id": "string", + "type": "string", + "primary": true, + "entity_schema": "string", + "automation_id": "string", + "journey_id": "string" + } + ], + "singleClosingReasonSelection": true, + "linear": true } ``` @@ -1037,7 +1404,21 @@ const { data } = await client.patchFlowExecution( { entity_id: 'string', entity_schema: 'string', - is_primary: false + is_primary: false, + promoted_by_task_id: 'string', + promoted_at: '1970-01-01T00:00:00.000Z', + demoted_by_task_id: 'string', + added_by_task_id: 'string' + } + ], + visibility: 'entity_views', + visible_on: [ + { + entity_id: 'string', + entity_schema: 'string', + kind: 'context', + anchor_entity_id: 'string', + rule_id: 'string' } ] }, @@ -1050,6 +1431,7 @@ const { data } = await client.patchFlowExecution( ```json { "id": "string", + "loop_source": "loops", "flow_template_id": "string", "org_id": "string", "name": "string", @@ -1070,18 +1452,35 @@ const { data } = await client.patchFlowExecution( "completed_at": "string", "closed_at": "string", "started_by": "string", - "closed_by": "string" + "started_by_org_id": "string", + "closed_by": "string", + "completed_by": "string" }, "contexts": [ { "entity_id": "string", "entity_schema": "string", - "is_primary": false + "is_primary": false, + "promoted_by_task_id": "string", + "promoted_at": "1970-01-01T00:00:00.000Z", + "demoted_by_task_id": "string", + "added_by_task_id": "string" + } + ], + "visibility": "entity_views", + "visible_on": [ + { + "entity_id": "string", + "entity_schema": "string", + "kind": "context", + "anchor_entity_id": "string", + "rule_id": "string" } ], "crt_tasks": [ { - "id": "string" + "id": "string", + "crt_since": "1970-01-01T00:00:00.000Z" } ], "phases": [ @@ -1096,28 +1495,60 @@ const { data } = await client.patchFlowExecution( "assigned_to": ["string"], "analytics": {}, "taxonomies": ["string"], - "loop_config": {} + "loop_config": {}, + "loop_membership": [] + } + ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "entry_node_id": "string", + "cut_edge_ids": ["string"], + "color": "string", + "portal_names": {}, + "portal_descriptions": {} } ], + "portal_titles": { + "ecp": "string", + "installer": "string" + }, "tasks": [ { "id": "string", + "loop_membership": [], "template_id": "string", "name": "string", "description": {}, "status": "UNASSIGNED", "journey": {}, + "journey_prefill": {}, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, "requirements": [], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [], + "subtask_states": {}, + "journey_submission": {}, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", "assigned_to": ["string"], + "ecp_placeholder_assignees": {}, "analytics": {}, + "loop_iterations": {}, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "manually_created": true, "enabled": true, "ecp": {}, "installer": {}, + "partner": {}, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1130,7 +1561,8 @@ const { data } = await client.patchFlowExecution( "from_id": "string", "to_id": "string", "condition_id": "abc123", - "none_met": true + "none_met": true, + "loop_id": "string" } ], "_execution_chain": { @@ -1138,6 +1570,7 @@ const { data } = await client.patchFlowExecution( "parent_task_id": "string", "depth": 0 }, + "_automation_chain": ["string"], "closing_reason": { "selected_reasons": [ {} @@ -1162,10 +1595,34 @@ const { data } = await client.patchFlowExecution( "flow_id": "string", "execution_id": "string", "execution_status": "string", - "error_reason": "string" - } + "error_reason": "string", + "input_context": {}, + "output_context": {}, + "heal_attempts": 0, + "run_for_user_id": "string", + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z", + "wait_for_journey_submission": true, + "journey_id": "string", + "journey_execution": {}, + "eligible_closing_reason_ids": ["string"], + "allow_execution_note": true, + "email_review": {} + }, + "trigger_id": "string", + "bulk_job_id": "string" }, - "singleClosingReasonSelection": true + "configured_triggers": [ + { + "id": "string", + "type": "string", + "primary": true, + "entity_schema": "string", + "automation_id": "string", + "journey_id": "string" + } + ], + "singleClosingReasonSelection": true, + "linear": true } ``` @@ -1199,7 +1656,8 @@ const { data } = await client.searchFlowExecutions( null, { entity_id: 'string', - entity_schema: 'string' + entity_schema: 'string', + include_background: false }, ) ``` @@ -1212,6 +1670,7 @@ const { data } = await client.searchFlowExecutions( "results": [ { "id": "string", + "loop_source": "loops", "flow_template_id": "string", "org_id": "string", "name": "string", @@ -1223,17 +1682,24 @@ const { data } = await client.searchFlowExecutions( "assigned_to": ["string"], "analytics": {}, "contexts": [], + "visibility": "entity_views", + "visible_on": [], "crt_tasks": [], "phases": [], + "stages": [], + "portal_titles": {}, "tasks": [], "edges": [], "_execution_chain": {}, + "_automation_chain": ["string"], "closing_reason": {}, "available_in_ecp": true, "entity_sync": [], "taxonomies": ["string"], "trigger": {}, - "singleClosingReasonSelection": true + "configured_triggers": [], + "singleClosingReasonSelection": true, + "linear": true } ] } @@ -1243,65 +1709,21 @@ const { data } = await client.searchFlowExecutions( --- -### `patchTask` +### `searchPortalWorkflows` -Changes various attributes of a flow task, like assignees, status, due date, etc. +Returns all portal-relevant workflow executions for a given entity, linearized into a +flat, ordered list of portal-visible steps. Intended to be called by the Customer Portal +API (ECP / Installer Port -`PATCH /v2/flows/executions/{execution_id}/tasks/{task_id}` +`POST /v2/flows/executions:portal-search` ```ts -const { data } = await client.patchTask( - { - execution_id: 'example', - task_id: 'example', - }, +const { data } = await client.searchPortalWorkflows( + null, { - name: 'string', - status: 'UNASSIGNED', - due_date: '2021-04-27T12:00:00.000Z', - due_date_config: { - duration: 0, - unit: 'minutes', - type: 'WORKFLOW_STARTED', - task_id: 'string', - phase_id: 'string' - }, - assigned_to: ['string'], - enabled: true, - automation_config: { - flow_id: 'string', - execution_id: 'string', - execution_status: 'string', - error_reason: 'string' - }, - description: { - enabled: true, - value: 'string' - }, - ecp: { - enabled: true, - label: 'string', - description: 'string', - journey: { - id: 'string', - journeyId: 'string', - name: 'string', - complete_task_automatically: true - } - }, - installer: { - enabled: true, - label: 'string', - description: 'string', - journey: { - id: 'string', - journeyId: 'string', - name: 'string', - complete_task_automatically: true - } - }, - next_condition_id: 'string', - revert_execution: false + entity_id: 'string', + entity_schema: 'order', + audience: 'ecp' }, ) ``` @@ -1311,78 +1733,25 @@ const { data } = await client.patchTask( ```json { - "id": "string", - "template_id": "string", - "name": "string", - "description": { - "enabled": true, - "value": "string" - }, - "status": "UNASSIGNED", - "journey": { - "id": "string", - "journeyId": "string", - "name": "string", - "complete_task_automatically": true - }, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" - }, - "requirements": [ + "workflows": [ { - "task_id": "string", - "phase_id": "string", - "when": "TASK_FINISHED" - } - ], - "assigned_to": ["string"], - "analytics": { - "started_at": "1970-01-01T00:00:00.000Z", - "in_progress_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z", - "status_updated_at": "1970-01-01T00:00:00.000Z", - "in_progress_by": "string", - "completed_by": "string", - "skipped_by": "string" - }, - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "manually_created": true, - "enabled": true, - "ecp": { - "enabled": true, - "label": "string", - "description": "string", - "journey": { - "id": "string", - "journeyId": "string", - "name": "string", - "complete_task_automatically": true - } - }, - "installer": { - "enabled": true, - "label": "string", - "description": "string", - "journey": { "id": "string", - "journeyId": "string", + "definition_id": "string", "name": "string", - "complete_task_automatically": true + "status": "STARTED", + "version": 2, + "created_at": "string", + "updated_at": "string", + "completed_at": "string", + "due_date": "string", + "assigned_to": ["string"], + "contexts": [], + "is_path_complete": true, + "tasks": [], + "stages": [], + "portal_titles": {} } - }, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL", - "loop_config": { - "max_iterations": 3, - "crt_iterations": 0 - } + ] } ``` @@ -1390,17 +1759,27 @@ const { data } = await client.patchTask( --- -### `runTaskAutomation` +### `searchPortalWorkflowsBatch` -Runs configured automation for a flow task +Batch variant of `searchPortalWorkflows`: returns portal-relevant workflow +executions for MANY entities in a single call — schemas may differ — each +linearized into a flat, ordered list of portal-visi -`POST /v2/flows/executions/{execution_id}/tasks/{task_id}/automation:run` +`POST /v2/flows/executions:portal-search-batch` ```ts -const { data } = await client.runTaskAutomation({ - execution_id: 'example', - task_id: 'example', -}) +const { data } = await client.searchPortalWorkflowsBatch( + null, + { + entities: [ + { + entity_id: 'string', + entity_schema: 'order' + } + ], + audience: 'ecp' + }, +) ```
@@ -1408,89 +1787,12 @@ const { data } = await client.runTaskAutomation({ ```json { - "id": "string", - "template_id": "string", - "name": "string", - "description": { - "enabled": true, - "value": "string" - }, - "status": "UNASSIGNED", - "journey": { - "id": "string", - "journeyId": "string", - "name": "string", - "complete_task_automatically": true - }, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" - }, - "requirements": [ + "results": [ { - "task_id": "string", - "phase_id": "string", - "when": "TASK_FINISHED" - } - ], - "assigned_to": ["string"], - "analytics": { - "started_at": "1970-01-01T00:00:00.000Z", - "in_progress_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z", - "status_updated_at": "1970-01-01T00:00:00.000Z", - "in_progress_by": "string", - "completed_by": "string", - "skipped_by": "string" - }, - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "manually_created": true, - "enabled": true, - "ecp": { - "enabled": true, - "label": "string", - "description": "string", - "journey": { - "id": "string", - "journeyId": "string", - "name": "string", - "complete_task_automatically": true - } - }, - "installer": { - "enabled": true, - "label": "string", - "description": "string", - "journey": { - "id": "string", - "journeyId": "string", - "name": "string", - "complete_task_automatically": true + "entity_id": "string", + "workflows": [] } - }, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL", - "automation_config": { - "flow_id": "string", - "execution_id": "string", - "execution_status": "string", - "error_reason": "string" - }, - "automation_execution_id": "string", - "trigger_mode": "manual", - "schedule": { - "mode": "immediate" - }, - "loop_config": { - "max_iterations": 3, - "crt_iterations": 0 - } + ] } ``` @@ -1498,16 +1800,49 @@ const { data } = await client.runTaskAutomation({ --- -### `executeTask` +### `bulkStartFlows` -Executes any kind of flow task immediately. +Creates a job that starts one flow on many entities: the flow +`flow_template_id` is started on every entity in `entities`, or on every +entity `entities_query` matches. Every start is manual. -`POST /v2/flows/executions/{execution_id}/tasks/{task_id}/execute` +`POST /v2/flows/executions:bulk-start` ```ts -const { data } = await client.executeTask({ - execution_id: 'example', - task_id: 'example', +const { data } = await client.bulkStartFlows( + null, + { + flow_template_id: 'string', + flow_template_ids: ['string'], + entities: [ + { + entity_id: 'string', + entity_schema: 'opportunity' + } + ], + entities_query: { + entity_schema: 'opportunity', + q: 'string' + }, + purposes: ['string'] + }, +) +``` + +--- + +### `listBulkStartFlowsJobs` + +Lists the organization's approved bulk-start jobs, newest approval first, +with their counts but without items. Jobs never approved (still awaiting +approval, or expired) are not listed. Jobs are kept f + +`GET /v2/flows/bulk-jobs` + +```ts +const { data } = await client.listBulkStartFlowsJobs({ + size: 1, + cursor: 'example', }) ``` @@ -1516,78 +1851,70 @@ const { data } = await client.executeTask({ ```json { - "id": "string", - "template_id": "string", - "name": "string", - "description": { - "enabled": true, - "value": "string" - }, - "status": "UNASSIGNED", - "journey": { - "id": "string", - "journeyId": "string", - "name": "string", - "complete_task_automatically": true - }, - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" - }, - "requirements": [ + "results": [ { - "task_id": "string", - "phase_id": "string", - "when": "TASK_FINISHED" + "job_id": "string", + "org_id": "string", + "status": "preparing", + "created_by": "string", + "created_by_org_id": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "approved_at": "1970-01-01T00:00:00.000Z", + "approved_by": "string", + "finished_at": "1970-01-01T00:00:00.000Z", + "cancel_requested": true, + "restart_of": "string", + "restarted_by": "string", + "flow": { + "flow_template_id": "string", + "flow_name": "string", + "will_start": 0, + "skipped": 0, + "automatic_tasks": [ + { + "task_id": "string", + "task_name": "string", + "task_type": "AUTOMATION" + } + ] + }, + "flows": [ + { + "flow_template_id": "string", + "flow_name": "string", + "will_start": 0, + "skipped": 0, + "automatic_tasks": [ + { + "task_id": "string", + "task_name": "string", + "task_type": "AUTOMATION" + } + ] + } + ], + "entity_schema": "string", + "entity_ids": ["string"], + "entity_count": 0, + "entities_query": "string", + "entities_matched": 0, + "failure": { + "error_code": "string", + "message": "string" + }, + "counts": { + "total": 0, + "pending": 0, + "started": 0, + "failed": 0, + "skipped": 0, + "cancelled": 0 + } } ], - "assigned_to": ["string"], - "analytics": { - "started_at": "1970-01-01T00:00:00.000Z", - "in_progress_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z", - "status_updated_at": "1970-01-01T00:00:00.000Z", - "in_progress_by": "string", - "completed_by": "string", - "skipped_by": "string" - }, - "created_at": "1970-01-01T00:00:00.000Z", - "updated_at": "1970-01-01T00:00:00.000Z", - "manually_created": true, - "enabled": true, - "ecp": { - "enabled": true, - "label": "string", - "description": "string", - "journey": { - "id": "string", - "journeyId": "string", - "name": "string", - "complete_task_automatically": true - } - }, - "installer": { - "enabled": true, - "label": "string", - "description": "string", - "journey": { - "id": "string", - "journeyId": "string", - "name": "string", - "complete_task_automatically": true - } - }, - "taxonomies": ["string"], - "phase_id": "string", - "task_type": "MANUAL", - "loop_config": { - "max_iterations": 3, - "crt_iterations": 0 - } + "next_cursor": "string" } ``` @@ -1595,31 +1922,15 @@ const { data } = await client.executeTask({ --- -### `patchPhase` +### `getActiveBulkStartFlowsJob` -Apply updates to a phase within flow execution +Returns the caller's bulk-start job in flight (`queued` or `running`), or +`job: null` when there is none. -`PATCH /v2/flows/executions/{execution_id}/phases/{phase_id}` +`GET /v2/flows/bulk-jobs:active` ```ts -const { data } = await client.patchPhase( - { - execution_id: 'example', - phase_id: 'example', - }, - { - name: 'string', - due_date: '2021-04-27T12:00:00.000Z', - due_date_config: { - duration: 0, - unit: 'minutes', - type: 'WORKFLOW_STARTED', - task_id: 'string', - phase_id: 'string' - }, - assigned_to: ['string'] - }, -) +const { data } = await client.getActiveBulkStartFlowsJob() ```
@@ -1627,33 +1938,86 @@ const { data } = await client.patchPhase( ```json { - "id": "string", - "template_id": "string", - "name": "string", - "status": "OPEN", - "updated_at": "string", - "due_date": "2021-04-27T12:00:00.000Z", - "due_date_config": { - "duration": 0, - "unit": "minutes", - "type": "WORKFLOW_STARTED", - "task_id": "string", - "phase_id": "string" - }, - "assigned_to": ["string"], - "analytics": { - "started_at": "1970-01-01T00:00:00.000Z", - "in_progress_at": "1970-01-01T00:00:00.000Z", - "completed_at": "1970-01-01T00:00:00.000Z", - "status_updated_at": "1970-01-01T00:00:00.000Z", - "in_progress_by": "string", - "completed_by": "string", - "skipped_by": "string" - }, - "taxonomies": ["string"], - "loop_config": { - "max_iterations": 3, - "crt_iterations": 0 + "job": { + "job_id": "string", + "org_id": "string", + "status": "preparing", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "approved_at": "1970-01-01T00:00:00.000Z", + "approved_by": "string", + "finished_at": "1970-01-01T00:00:00.000Z", + "cancel_requested": true, + "restart_of": "string", + "restarted_by": "string", + "flow": { + "flow_template_id": "string", + "flow_name": "string", + "will_start": 0, + "skipped": 0, + "automatic_tasks": [ + { + "task_id": "string", + "task_name": "string", + "task_type": "AUTOMATION" + } + ] + }, + "flows": [ + { + "flow_template_id": "string", + "flow_name": "string", + "will_start": 0, + "skipped": 0, + "automatic_tasks": [ + { + "task_id": "string", + "task_name": "string", + "task_type": "AUTOMATION" + } + ] + } + ], + "entity_count": 0, + "entity_schema": "string", + "entities_query": "string", + "entities_matched": 0, + "failure": { + "error_code": "string", + "message": "string" + }, + "preparation": { + "phase": "resolving", + "matched": 0, + "resolved": 0, + "written": 0, + "total": 0, + "attempts": 0, + "updated_at": "1970-01-01T00:00:00.000Z" + }, + "cancelled_by": "string", + "counts": { + "total": 0, + "pending": 0, + "started": 0, + "failed": 0, + "skipped": 0, + "cancelled": 0 + }, + "items": [ + { + "flow_template_id": "string", + "entity_id": "string", + "entity_schema": "string", + "status": "pending", + "execution_id": "string", + "error_code": "string", + "error_message": "string", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] } } ``` @@ -1662,45 +2026,387 @@ const { data } = await client.patchPhase( --- -### `addTask` +### `getBulkStartFlowsJob` -Create a new task in current workflow execution. +Returns a bulk-start job with its counts. `items` is included for jobs of +at most 200 items only (deprecated); page through the items with +`GET /v2/flows/bulk-jobs/{job_id}/items`. -`POST /v2/flows/executions/{execution_id}/tasks` +`GET /v2/flows/bulk-jobs/{job_id}` ```ts -const { data } = await client.addTask( - { - execution_id: 'example', - }, - { - previous_task_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - next_task_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - task: { - id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', - name: 'string', - status: 'UNASSIGNED', - due_date: '2021-04-27T12:00:00.000Z', - due_date_config: { - duration: 0, - unit: 'minutes', - type: 'WORKFLOW_STARTED', - task_id: 'string', - phase_id: 'string' - }, - assigned_to: ['string'], - enabled: true, - automation_config: { - flow_id: 'string', - execution_id: 'string', - execution_status: 'string', - error_reason: 'string' - }, - phase_id: 'string', - task_type: 'MANUAL' - } - }, -) +const { data } = await client.getBulkStartFlowsJob({ + job_id: 'example', +}) +``` + +
+Response + +```json +{ + "job_id": "string", + "org_id": "string", + "status": "preparing", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "approved_at": "1970-01-01T00:00:00.000Z", + "approved_by": "string", + "finished_at": "1970-01-01T00:00:00.000Z", + "cancel_requested": true, + "restart_of": "string", + "restarted_by": "string", + "flow": { + "flow_template_id": "string", + "flow_name": "string", + "will_start": 0, + "skipped": 0, + "automatic_tasks": [ + { + "task_id": "string", + "task_name": "string", + "task_type": "AUTOMATION" + } + ] + }, + "flows": [ + { + "flow_template_id": "string", + "flow_name": "string", + "will_start": 0, + "skipped": 0, + "automatic_tasks": [ + { + "task_id": "string", + "task_name": "string", + "task_type": "AUTOMATION" + } + ] + } + ], + "entity_count": 0, + "entity_schema": "string", + "entities_query": "string", + "entities_matched": 0, + "failure": { + "error_code": "string", + "message": "string" + }, + "preparation": { + "phase": "resolving", + "matched": 0, + "resolved": 0, + "written": 0, + "total": 0, + "attempts": 0, + "updated_at": "1970-01-01T00:00:00.000Z" + }, + "cancelled_by": "string", + "counts": { + "total": 0, + "pending": 0, + "started": 0, + "failed": 0, + "skipped": 0, + "cancelled": 0 + }, + "items": [ + { + "flow_template_id": "string", + "entity_id": "string", + "entity_schema": "string", + "status": "pending", + "execution_id": "string", + "error_code": "string", + "error_message": "string", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `patchBulkStartFlowsJob` + +Approves or cancels a bulk-start job. + +`PATCH /v2/flows/bulk-jobs/{job_id}` + +```ts +const { data } = await client.patchBulkStartFlowsJob( + { + job_id: 'example', + }, + { + action: 'APPROVE' + }, +) +``` + +
+Response + +```json +{ + "job_id": "string", + "org_id": "string", + "status": "preparing", + "created_by": "string", + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "expires_at": "1970-01-01T00:00:00.000Z", + "approved_at": "1970-01-01T00:00:00.000Z", + "approved_by": "string", + "finished_at": "1970-01-01T00:00:00.000Z", + "cancel_requested": true, + "restart_of": "string", + "restarted_by": "string", + "flow": { + "flow_template_id": "string", + "flow_name": "string", + "will_start": 0, + "skipped": 0, + "automatic_tasks": [ + { + "task_id": "string", + "task_name": "string", + "task_type": "AUTOMATION" + } + ] + }, + "flows": [ + { + "flow_template_id": "string", + "flow_name": "string", + "will_start": 0, + "skipped": 0, + "automatic_tasks": [ + { + "task_id": "string", + "task_name": "string", + "task_type": "AUTOMATION" + } + ] + } + ], + "entity_count": 0, + "entity_schema": "string", + "entities_query": "string", + "entities_matched": 0, + "failure": { + "error_code": "string", + "message": "string" + }, + "preparation": { + "phase": "resolving", + "matched": 0, + "resolved": 0, + "written": 0, + "total": 0, + "attempts": 0, + "updated_at": "1970-01-01T00:00:00.000Z" + }, + "cancelled_by": "string", + "counts": { + "total": 0, + "pending": 0, + "started": 0, + "failed": 0, + "skipped": 0, + "cancelled": 0 + }, + "items": [ + { + "flow_template_id": "string", + "entity_id": "string", + "entity_schema": "string", + "status": "pending", + "execution_id": "string", + "error_code": "string", + "error_message": "string", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} +``` + +
+ +--- + +### `listBulkStartFlowsJobItems` + +Pages through the items of a bulk-start job (one per entity), in request +order, optionally only those in one status. An ended job reports items it +never got to as `cancelled`. + +`GET /v2/flows/bulk-jobs/{job_id}/items` + +```ts +const { data } = await client.listBulkStartFlowsJobItems({ + job_id: 'example', + status: 'example', + size: 1, + cursor: 'example', +}) +``` + +
+Response + +```json +{ + "results": [ + { + "flow_template_id": "string", + "entity_id": "string", + "entity_schema": "string", + "status": "pending", + "execution_id": "string", + "error_code": "string", + "error_message": "string", + "updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "next_cursor": "string" +} +``` + +
+ +--- + +### `restartBulkStartFlowsJob` + +Restarts what is left of an ended bulk-start job: creates a new job, in +`awaiting_approval`, from the job's `failed` and `skipped` items and the +items it never started (`cancelled`). Started items are + +`POST /v2/flows/bulk-jobs/{job_id}/restart` + +```ts +const { data } = await client.restartBulkStartFlowsJob({ + job_id: 'example', +}) +``` + +--- + +### `patchTask` + +Updates attributes of a flow task including status, assignees, due date, and more. + +`PATCH /v2/flows/executions/{execution_id}/tasks/{task_id}` + +```ts +const { data } = await client.patchTask( + { + execution_id: 'example', + task_id: 'example', + }, + { + name: 'Review customer application', + status: 'UNASSIGNED', + due_date: '2026-05-28T00:00:00.000', + due_date_config: { + duration: 0, + unit: 'minutes', + type: 'WORKFLOW_STARTED', + task_id: 'string', + phase_id: 'string' + }, + assigned_to: ['string'], + enabled: true, + automation_config: { + flow_id: 'string', + execution_id: 'string', + execution_status: 'string', + error_reason: 'string', + input_context: { + source: 'main_context', + task_id: 'string', + trigger_id: 'string', + with_relations: true, + also_pass: [ /* ... */ ] + }, + output_context: { + set_as_primary: true, + attach_to_contexts: true + }, + heal_attempts: 0, + run_for_user_id: 'string', + last_heal_attempted_at: '1970-01-01T00:00:00.000Z', + wait_for_journey_submission: true, + journey_id: 'string', + journey_execution: { + execution_id: 'string', + execution_status: 'string', + error_reason: 'string', + submission_entity_id: 'string', + submission_created_at: '1970-01-01T00:00:00.000Z', + wait_overridden_at: '1970-01-01T00:00:00.000Z', + wait_overridden_by: 'string' + }, + eligible_closing_reason_ids: ['string'], + allow_execution_note: true, + email_review: { + enabled: true, + allow_document_selection: true, + allow_subject_and_body_edit: true + } + }, + description: { + enabled: true, + value: 'string' + }, + ecp: { + enabled: true, + label: 'string', + description: 'string', + journey: { + id: 'string', + journeyId: 'string', + name: 'string', + portal_button_label: 'string', + complete_task_automatically: true, + journey_submission_required: true, + context_parameters: [ /* ... */ ], + ai_prefill: { /* ... */ } + } + }, + installer: { + enabled: true, + label: 'string', + description: 'string', + journey: { + id: 'string', + journeyId: 'string', + name: 'string', + portal_button_label: 'string', + complete_task_automatically: true, + journey_submission_required: true, + context_parameters: [ /* ... */ ], + ai_prefill: { /* ... */ } + } + }, + partner: { + enabled: true, + label: 'string', + description: 'string' + }, + subtask_states: {}, + next_condition_id: 'cond_branch_approved', + next_condition_ids: ['cond_branch_a', 'cond_branch_b'], + revert_execution: false, + completed_via_journey: false, + excluded_partner_org_ids: ['partner-org-1'] + }, +) ```
@@ -1709,6 +2415,12 @@ const { data } = await client.addTask( ```json { "id": "string", + "loop_membership": [ + { + "loop_id": "string", + "runs_in_loop": true + } + ], "template_id": "string", "name": "string", "description": { @@ -1720,7 +2432,31 @@ const { data } = await client.addTask( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [ + {} + ], + "ai_prefill": { + "enabled": false, + "source": {}, + "extraction_fields": [], + "mappings": [], + "min_confidence": 0.8, + "instructions": "string" + } + }, + "journey_prefill": { + "status": "PENDING", + "agent_execution_id": "string", + "dispatched_at": "1970-01-01T00:00:00.000Z", + "extracted_at": "1970-01-01T00:00:00.000Z", + "initial_state": {}, + "field_confidence": {}, + "dropped": [ + {} + ] }, "due_date": "2021-04-27T12:00:00.000Z", "due_date_config": { @@ -1730,6 +2466,13 @@ const { data } = await client.addTask( "task_id": "string", "phase_id": "string" }, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string" + }, "requirements": [ { "task_id": "string", @@ -1737,7 +2480,28 @@ const { data } = await client.addTask( "when": "TASK_FINISHED" } ], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [ + { + "id": "string", + "name": "string", + "party": "description", + "required": true + } + ], + "subtask_states": {}, + "journey_submission": { + "submission_entity_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + }, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", "assigned_to": ["string"], + "ecp_placeholder_assignees": { + "placeholder_ecp_customers": ["string"], + "placeholder_ecp_installers": ["string"] + }, "analytics": { "started_at": "1970-01-01T00:00:00.000Z", "in_progress_at": "1970-01-01T00:00:00.000Z", @@ -1745,8 +2509,11 @@ const { data } = await client.addTask( "status_updated_at": "1970-01-01T00:00:00.000Z", "in_progress_by": "string", "completed_by": "string", - "skipped_by": "string" + "skipped_at": "1970-01-01T00:00:00.000Z", + "skipped_by": "string", + "on_hold_by": "string" }, + "loop_iterations": {}, "created_at": "1970-01-01T00:00:00.000Z", "updated_at": "1970-01-01T00:00:00.000Z", "manually_created": true, @@ -1759,7 +2526,11 @@ const { data } = await client.addTask( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} } }, "installer": { @@ -1770,9 +2541,19 @@ const { data } = await client.addTask( "id": "string", "journeyId": "string", "name": "string", - "complete_task_automatically": true + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} } }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, + "audience_order": ["description"], "taxonomies": ["string"], "phase_id": "string", "task_type": "MANUAL", @@ -1787,50 +2568,2182 @@ const { data } = await client.addTask( --- -### `cancelTaskSchedule` - -Cancels a scheduled task, deleting the schedule and marking the task as skipped. - -`DELETE /v2/flows/executions/{execution_id}/tasks/{task_id}/schedule` - -```ts -const { data } = await client.cancelTaskSchedule({ - execution_id: 'example', - task_id: 'example', -}) -``` - ---- +### `runTaskAutomation` -## Schemas +Runs configured automation for a flow task. Running a `trigger_mode: manual` automation (an absent trigger mode counts as manual) is its person action, so it is permission-checked like completing a ta -### `WorkflowExecutionCreateReq` +`POST /v2/flows/executions/{execution_id}/tasks/{task_id}/automation:run` ```ts -type WorkflowExecutionCreateReq = { - workflowId: string - trigger?: "MANUAL" | "AUTOMATIC" - assignedTo?: string[] - contexts?: Array<{ - id: string - title: string - schema: string - }> - purposes?: string[] -} +const { data } = await client.runTaskAutomation( + { + execution_id: 'example', + task_id: 'example', + }, + { + action_inputs: { + cancel_flow_execution: { + selected_closing_reason_ids: ['string'], + extra_description: 'string' + }, + send_email: { + subject: 'string', + body: 'string', + attachment_entity_ids: ['string'] + } + } + }, +) ``` -### `WorkflowExecutionUpdateReq` +
+Response -```ts -type WorkflowExecutionUpdateReq = { - status?: "STARTED" | "DONE" | "CLOSED" - assignedTo?: string[] - selectedClosingReasons?: Array<{ - id: string - title: string +```json +{ + "id": "string", + "loop_membership": [ + { + "loop_id": "string", + "runs_in_loop": true + } + ], + "template_id": "string", + "name": "string", + "description": { + "enabled": true, + "value": "string" + }, + "status": "UNASSIGNED", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [ + {} + ], + "ai_prefill": { + "enabled": false, + "source": {}, + "extraction_fields": [], + "mappings": [], + "min_confidence": 0.8, + "instructions": "string" + } + }, + "journey_prefill": { + "status": "PENDING", + "agent_execution_id": "string", + "dispatched_at": "1970-01-01T00:00:00.000Z", + "extracted_at": "1970-01-01T00:00:00.000Z", + "initial_state": {}, + "field_confidence": {}, + "dropped": [ + {} + ] + }, + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string" + }, + "requirements": [ + { + "task_id": "string", + "phase_id": "string", + "when": "TASK_FINISHED" + } + ], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [ + { + "id": "string", + "name": "string", + "party": "description", + "required": true + } + ], + "subtask_states": {}, + "journey_submission": { + "submission_entity_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + }, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", + "assigned_to": ["string"], + "ecp_placeholder_assignees": { + "placeholder_ecp_customers": ["string"], + "placeholder_ecp_installers": ["string"] + }, + "analytics": { + "started_at": "1970-01-01T00:00:00.000Z", + "in_progress_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status_updated_at": "1970-01-01T00:00:00.000Z", + "in_progress_by": "string", + "completed_by": "string", + "skipped_at": "1970-01-01T00:00:00.000Z", + "skipped_by": "string", + "on_hold_by": "string" + }, + "loop_iterations": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "manually_created": true, + "enabled": true, + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, + "audience_order": ["description"], + "taxonomies": ["string"], + "phase_id": "string", + "task_type": "MANUAL", + "automation_config": { + "flow_id": "string", + "execution_id": "string", + "execution_status": "string", + "error_reason": "string", + "input_context": { + "source": "main_context", + "task_id": "string", + "trigger_id": "string", + "with_relations": true, + "also_pass": [] + }, + "output_context": { + "set_as_primary": true, + "attach_to_contexts": true + }, + "heal_attempts": 0, + "run_for_user_id": "string", + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z", + "wait_for_journey_submission": true, + "journey_id": "string", + "journey_execution": { + "execution_id": "string", + "execution_status": "string", + "error_reason": "string", + "submission_entity_id": "string", + "submission_created_at": "1970-01-01T00:00:00.000Z", + "wait_overridden_at": "1970-01-01T00:00:00.000Z", + "wait_overridden_by": "string" + }, + "eligible_closing_reason_ids": ["string"], + "allow_execution_note": true, + "email_review": { + "enabled": true, + "allow_document_selection": true, + "allow_subject_and_body_edit": true + } + }, + "automation_execution_id": "string", + "on_failure": "stop", + "trigger_mode": "manual", + "schedule": { + "mode": "immediate" + }, + "loop_config": { + "max_iterations": 3, + "crt_iterations": 0 + } +} +``` + +
+ +--- + +### `previewTaskEmail` + +Renders the email a semi-automated send-email task would send, so the person running it can review and adjust it first. + +`GET /v2/flows/executions/{execution_id}/tasks/{task_id}/email-preview` + +```ts +const { data } = await client.previewTaskEmail({ + execution_id: 'example', + task_id: 'example', +}) +``` + +
+Response + +```json +{ + "subject": "string", + "body": "string", + "to": ["string"], + "has_unresolved_send_time_variables": true, + "body_edit_locked": true, + "attachable_documents": [ + { + "id": "string", + "filename": "string" + } + ], + "inline_images": [ + { + "cid": "string", + "url": "string" + } + ] +} +``` + +
+ +--- + +### `executeTask` + +Executes any kind of flow task immediately. This is the scheduler's dispatch endpoint: when its timer fires on the SCHEDULED task it booked, in the scheduler's own name, the call is the engine dispatc + +`POST /v2/flows/executions/{execution_id}/tasks/{task_id}/execute` + +```ts +const { data } = await client.executeTask({ + execution_id: 'example', + task_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "string", + "loop_membership": [ + { + "loop_id": "string", + "runs_in_loop": true + } + ], + "template_id": "string", + "name": "string", + "description": { + "enabled": true, + "value": "string" + }, + "status": "UNASSIGNED", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [ + {} + ], + "ai_prefill": { + "enabled": false, + "source": {}, + "extraction_fields": [], + "mappings": [], + "min_confidence": 0.8, + "instructions": "string" + } + }, + "journey_prefill": { + "status": "PENDING", + "agent_execution_id": "string", + "dispatched_at": "1970-01-01T00:00:00.000Z", + "extracted_at": "1970-01-01T00:00:00.000Z", + "initial_state": {}, + "field_confidence": {}, + "dropped": [ + {} + ] + }, + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string" + }, + "requirements": [ + { + "task_id": "string", + "phase_id": "string", + "when": "TASK_FINISHED" + } + ], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [ + { + "id": "string", + "name": "string", + "party": "description", + "required": true + } + ], + "subtask_states": {}, + "journey_submission": { + "submission_entity_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + }, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", + "assigned_to": ["string"], + "ecp_placeholder_assignees": { + "placeholder_ecp_customers": ["string"], + "placeholder_ecp_installers": ["string"] + }, + "analytics": { + "started_at": "1970-01-01T00:00:00.000Z", + "in_progress_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status_updated_at": "1970-01-01T00:00:00.000Z", + "in_progress_by": "string", + "completed_by": "string", + "skipped_at": "1970-01-01T00:00:00.000Z", + "skipped_by": "string", + "on_hold_by": "string" + }, + "loop_iterations": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "manually_created": true, + "enabled": true, + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, + "audience_order": ["description"], + "taxonomies": ["string"], + "phase_id": "string", + "task_type": "MANUAL", + "loop_config": { + "max_iterations": 3, + "crt_iterations": 0 + } +} +``` + +
+ +--- + +### `patchPhase` + +Apply updates to a phase within flow execution + +`PATCH /v2/flows/executions/{execution_id}/phases/{phase_id}` + +```ts +const { data } = await client.patchPhase( + { + execution_id: 'example', + phase_id: 'example', + }, + { + name: 'string', + due_date: '2021-04-27T12:00:00.000Z', + due_date_config: { + duration: 0, + unit: 'minutes', + type: 'WORKFLOW_STARTED', + task_id: 'string', + phase_id: 'string' + }, + assigned_to: ['string'] + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "template_id": "string", + "name": "string", + "status": "OPEN", + "updated_at": "string", + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "assigned_to": ["string"], + "analytics": { + "started_at": "1970-01-01T00:00:00.000Z", + "in_progress_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status_updated_at": "1970-01-01T00:00:00.000Z", + "in_progress_by": "string", + "completed_by": "string", + "skipped_at": "1970-01-01T00:00:00.000Z", + "skipped_by": "string", + "on_hold_by": "string" + }, + "taxonomies": ["string"], + "loop_config": { + "max_iterations": 3, + "crt_iterations": 0 + }, + "loop_membership": [ + { + "loop_id": "string", + "runs_in_loop": true + } + ] +} +``` + +
+ +--- + +### `addTask` + +Create a new task in current workflow execution. + +`POST /v2/flows/executions/{execution_id}/tasks` + +```ts +const { data } = await client.addTask( + { + execution_id: 'example', + }, + { + previous_task_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + next_task_id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + task: { + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + status: 'UNASSIGNED', + due_date: '2021-04-27T12:00:00.000Z', + due_date_config: { + duration: 0, + unit: 'minutes', + type: 'WORKFLOW_STARTED', + task_id: 'string', + phase_id: 'string' + }, + assigned_to: ['string'], + enabled: true, + automation_config: { + flow_id: 'string', + execution_id: 'string', + execution_status: 'string', + error_reason: 'string', + input_context: { + source: 'main_context', + task_id: 'string', + trigger_id: 'string', + with_relations: true, + also_pass: [ + { + source: 'main_context' + } + ] + }, + output_context: { + set_as_primary: true, + attach_to_contexts: true + }, + heal_attempts: 0, + run_for_user_id: 'string', + last_heal_attempted_at: '1970-01-01T00:00:00.000Z', + wait_for_journey_submission: true, + journey_id: 'string', + journey_execution: { + execution_id: 'string', + execution_status: 'string', + error_reason: 'string', + submission_entity_id: 'string', + submission_created_at: '1970-01-01T00:00:00.000Z', + wait_overridden_at: '1970-01-01T00:00:00.000Z', + wait_overridden_by: 'string' + }, + eligible_closing_reason_ids: ['string'], + allow_execution_note: true, + email_review: { + enabled: true, + allow_document_selection: true, + allow_subject_and_body_edit: true + } + }, + phase_id: 'string', + task_type: 'MANUAL' + } + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "loop_membership": [ + { + "loop_id": "string", + "runs_in_loop": true + } + ], + "template_id": "string", + "name": "string", + "description": { + "enabled": true, + "value": "string" + }, + "status": "UNASSIGNED", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [ + {} + ], + "ai_prefill": { + "enabled": false, + "source": {}, + "extraction_fields": [], + "mappings": [], + "min_confidence": 0.8, + "instructions": "string" + } + }, + "journey_prefill": { + "status": "PENDING", + "agent_execution_id": "string", + "dispatched_at": "1970-01-01T00:00:00.000Z", + "extracted_at": "1970-01-01T00:00:00.000Z", + "initial_state": {}, + "field_confidence": {}, + "dropped": [ + {} + ] + }, + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string" + }, + "requirements": [ + { + "task_id": "string", + "phase_id": "string", + "when": "TASK_FINISHED" + } + ], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [ + { + "id": "string", + "name": "string", + "party": "description", + "required": true + } + ], + "subtask_states": {}, + "journey_submission": { + "submission_entity_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + }, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", + "assigned_to": ["string"], + "ecp_placeholder_assignees": { + "placeholder_ecp_customers": ["string"], + "placeholder_ecp_installers": ["string"] + }, + "analytics": { + "started_at": "1970-01-01T00:00:00.000Z", + "in_progress_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status_updated_at": "1970-01-01T00:00:00.000Z", + "in_progress_by": "string", + "completed_by": "string", + "skipped_at": "1970-01-01T00:00:00.000Z", + "skipped_by": "string", + "on_hold_by": "string" + }, + "loop_iterations": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "manually_created": true, + "enabled": true, + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, + "audience_order": ["description"], + "taxonomies": ["string"], + "phase_id": "string", + "task_type": "MANUAL", + "loop_config": { + "max_iterations": 3, + "crt_iterations": 0 + } +} +``` + +
+ +--- + +### `rescheduleTask` + +Moves the execution date of a scheduled task that has not run yet (AL-3774). The task must be SCHEDULED with a booked timer, and its flow open. The task's timer is replaced by one for the new date, so + +`PUT /v2/flows/executions/{execution_id}/tasks/{task_id}/schedule` + +```ts +const { data } = await client.rescheduleTask( + { + execution_id: 'example', + task_id: 'example', + }, + { + scheduled_at: 'string', + reason: 'string' + }, +) +``` + +
+Response + +```json +{ + "id": "string", + "loop_membership": [ + { + "loop_id": "string", + "runs_in_loop": true + } + ], + "template_id": "string", + "name": "string", + "description": { + "enabled": true, + "value": "string" + }, + "status": "UNASSIGNED", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [ + {} + ], + "ai_prefill": { + "enabled": false, + "source": {}, + "extraction_fields": [], + "mappings": [], + "min_confidence": 0.8, + "instructions": "string" + } + }, + "journey_prefill": { + "status": "PENDING", + "agent_execution_id": "string", + "dispatched_at": "1970-01-01T00:00:00.000Z", + "extracted_at": "1970-01-01T00:00:00.000Z", + "initial_state": {}, + "field_confidence": {}, + "dropped": [ + {} + ] + }, + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string" + }, + "requirements": [ + { + "task_id": "string", + "phase_id": "string", + "when": "TASK_FINISHED" + } + ], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [ + { + "id": "string", + "name": "string", + "party": "description", + "required": true + } + ], + "subtask_states": {}, + "journey_submission": { + "submission_entity_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + }, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", + "assigned_to": ["string"], + "ecp_placeholder_assignees": { + "placeholder_ecp_customers": ["string"], + "placeholder_ecp_installers": ["string"] + }, + "analytics": { + "started_at": "1970-01-01T00:00:00.000Z", + "in_progress_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status_updated_at": "1970-01-01T00:00:00.000Z", + "in_progress_by": "string", + "completed_by": "string", + "skipped_at": "1970-01-01T00:00:00.000Z", + "skipped_by": "string", + "on_hold_by": "string" + }, + "loop_iterations": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "manually_created": true, + "enabled": true, + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, + "audience_order": ["description"], + "taxonomies": ["string"], + "phase_id": "string", + "task_type": "MANUAL", + "loop_config": { + "max_iterations": 3, + "crt_iterations": 0 + } +} +``` + +
+ +--- + +### `cancelTaskSchedule` + +Cancels a scheduled task, deleting the schedule and marking the task as skipped. + +`DELETE /v2/flows/executions/{execution_id}/tasks/{task_id}/schedule` + +```ts +const { data } = await client.cancelTaskSchedule({ + execution_id: 'example', + task_id: 'example', +}) +``` + +--- + +### `reconcileAutomationTask` + +Reconciles an automation task's status against its linked automation execution. + +`POST /v2/flows/executions/{execution_id}/tasks/{task_id}/reconcile-automation` + +```ts +const { data } = await client.reconcileAutomationTask({ + execution_id: 'example', + task_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "string", + "loop_source": "loops", + "flow_template_id": "string", + "org_id": "string", + "name": "string", + "created_at": "string", + "updated_at": "string", + "due_date": "string", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "status": "STARTED", + "assigned_to": ["string"], + "analytics": { + "started_at": "string", + "completed_at": "string", + "closed_at": "string", + "started_by": "string", + "started_by_org_id": "string", + "closed_by": "string", + "completed_by": "string" + }, + "contexts": [ + { + "entity_id": "string", + "entity_schema": "string", + "is_primary": false, + "promoted_by_task_id": "string", + "promoted_at": "1970-01-01T00:00:00.000Z", + "demoted_by_task_id": "string", + "added_by_task_id": "string" + } + ], + "visibility": "entity_views", + "visible_on": [ + { + "entity_id": "string", + "entity_schema": "string", + "kind": "context", + "anchor_entity_id": "string", + "rule_id": "string" + } + ], + "crt_tasks": [ + { + "id": "string", + "crt_since": "1970-01-01T00:00:00.000Z" + } + ], + "phases": [ + { + "id": "string", + "template_id": "string", + "name": "string", + "status": "OPEN", + "updated_at": "string", + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": {}, + "assigned_to": ["string"], + "analytics": {}, + "taxonomies": ["string"], + "loop_config": {}, + "loop_membership": [] + } + ], + "stages": [ + { + "id": "string", + "name": "string", + "description": "string", + "entry_node_id": "string", + "cut_edge_ids": ["string"], + "color": "string", + "portal_names": {}, + "portal_descriptions": {} + } + ], + "portal_titles": { + "ecp": "string", + "installer": "string" + }, + "tasks": [ + { + "id": "string", + "loop_membership": [], + "template_id": "string", + "name": "string", + "description": {}, + "status": "UNASSIGNED", + "journey": {}, + "journey_prefill": {}, + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": {}, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": {}, + "requirements": [], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [], + "subtask_states": {}, + "journey_submission": {}, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", + "assigned_to": ["string"], + "ecp_placeholder_assignees": {}, + "analytics": {}, + "loop_iterations": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "manually_created": true, + "enabled": true, + "ecp": {}, + "installer": {}, + "partner": {}, + "audience_order": ["description"], + "taxonomies": ["string"], + "phase_id": "string", + "task_type": "MANUAL", + "loop_config": {} + } + ], + "edges": [ + { + "id": "string", + "from_id": "string", + "to_id": "string", + "condition_id": "abc123", + "none_met": true, + "loop_id": "string" + } + ], + "_execution_chain": { + "parent_execution_id": "string", + "parent_task_id": "string", + "depth": 0 + }, + "_automation_chain": ["string"], + "closing_reason": { + "selected_reasons": [ + {} + ], + "configured_reasons": [ + {} + ], + "extra_description": "string" + }, + "available_in_ecp": true, + "entity_sync": [ + { + "trigger": {}, + "target": {}, + "value": {} + } + ], + "taxonomies": ["string"], + "trigger": { + "type": "MANUAL", + "automation_config": { + "flow_id": "string", + "execution_id": "string", + "execution_status": "string", + "error_reason": "string", + "input_context": {}, + "output_context": {}, + "heal_attempts": 0, + "run_for_user_id": "string", + "last_heal_attempted_at": "1970-01-01T00:00:00.000Z", + "wait_for_journey_submission": true, + "journey_id": "string", + "journey_execution": {}, + "eligible_closing_reason_ids": ["string"], + "allow_execution_note": true, + "email_review": {} + }, + "trigger_id": "string", + "bulk_job_id": "string" + }, + "configured_triggers": [ + { + "id": "string", + "type": "string", + "primary": true, + "entity_schema": "string", + "automation_id": "string", + "journey_id": "string" + } + ], + "singleClosingReasonSelection": true, + "linear": true +} +``` + +
+ +--- + +### `runTaskScheduleNow` + +Cancels the pending schedule for a task and immediately triggers its automation execution. Always a person's request, so a `trigger_mode: manual` automation (an absent trigger mode counts as manual) i + +`POST /v2/flows/executions/{execution_id}/tasks/{task_id}/schedule/run-now` + +```ts +const { data } = await client.runTaskScheduleNow({ + execution_id: 'example', + task_id: 'example', +}) +``` + +
+Response + +```json +{ + "id": "string", + "loop_membership": [ + { + "loop_id": "string", + "runs_in_loop": true + } + ], + "template_id": "string", + "name": "string", + "description": { + "enabled": true, + "value": "string" + }, + "status": "UNASSIGNED", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [ + {} + ], + "ai_prefill": { + "enabled": false, + "source": {}, + "extraction_fields": [], + "mappings": [], + "min_confidence": 0.8, + "instructions": "string" + } + }, + "journey_prefill": { + "status": "PENDING", + "agent_execution_id": "string", + "dispatched_at": "1970-01-01T00:00:00.000Z", + "extracted_at": "1970-01-01T00:00:00.000Z", + "initial_state": {}, + "field_confidence": {}, + "dropped": [ + {} + ] + }, + "due_date": "2021-04-27T12:00:00.000Z", + "due_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string", + "phase_id": "string" + }, + "start_date": "2021-04-27T12:00:00.000Z", + "start_date_config": { + "duration": 0, + "unit": "minutes", + "type": "WORKFLOW_STARTED", + "task_id": "string" + }, + "requirements": [ + { + "task_id": "string", + "phase_id": "string", + "when": "TASK_FINISHED" + } + ], + "required": true, + "only_assignee_can_complete": true, + "subtasks": [ + { + "id": "string", + "name": "string", + "party": "description", + "required": true + } + ], + "subtask_states": {}, + "journey_submission": { + "submission_entity_id": "string", + "submitted_at": "1970-01-01T00:00:00.000Z" + }, + "completion_gates_reset_at": "1970-01-01T00:00:00.000Z", + "journey_gate_waived_at": "1970-01-01T00:00:00.000Z", + "assigned_to": ["string"], + "ecp_placeholder_assignees": { + "placeholder_ecp_customers": ["string"], + "placeholder_ecp_installers": ["string"] + }, + "analytics": { + "started_at": "1970-01-01T00:00:00.000Z", + "in_progress_at": "1970-01-01T00:00:00.000Z", + "completed_at": "1970-01-01T00:00:00.000Z", + "status_updated_at": "1970-01-01T00:00:00.000Z", + "in_progress_by": "string", + "completed_by": "string", + "skipped_at": "1970-01-01T00:00:00.000Z", + "skipped_by": "string", + "on_hold_by": "string" + }, + "loop_iterations": {}, + "created_at": "1970-01-01T00:00:00.000Z", + "updated_at": "1970-01-01T00:00:00.000Z", + "manually_created": true, + "enabled": true, + "ecp": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "installer": { + "enabled": true, + "label": "string", + "description": "string", + "journey": { + "id": "string", + "journeyId": "string", + "name": "string", + "portal_button_label": "string", + "complete_task_automatically": true, + "journey_submission_required": true, + "context_parameters": [], + "ai_prefill": {} + } + }, + "partner": { + "enabled": true, + "label": "string", + "description": "string" + }, + "audience_order": ["description"], + "taxonomies": ["string"], + "phase_id": "string", + "task_type": "MANUAL", + "loop_config": { + "max_iterations": 3, + "crt_iterations": 0 + } +} +``` + +
+ +--- + +## Schemas + +### `WorkflowExecutionCreateReq` + +```ts +type WorkflowExecutionCreateReq = { + workflowId: string + trigger?: "MANUAL" | "AUTOMATIC" + assignedTo?: string[] + contexts?: Array<{ + id: string + title: string + schema: string + }> + purposes?: string[] +} +``` + +### `WorkflowExecutionUpdateReq` + +```ts +type WorkflowExecutionUpdateReq = { + status?: "STARTED" | "DONE" | "CLOSED" + assignedTo?: string[] + selectedClosingReasons?: Array<{ + id: string + title: string + }> + closingReasonDescription?: string + dueDate?: string + dynamicDueDate?: { + numberOfUnits: number + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" + stepId?: string + phaseId?: string + } + closedBy?: string + contexts?: Array<{ + id: string + title: string + schema: string + }> + completedTime?: string +} +``` + +### `ClosingReason` + +```ts +type ClosingReason = { + id: string + title: string +} +``` + +### `WorkflowContext` + +```ts +type WorkflowContext = { + id: string + title: string + schema: string +} +``` + +### `WorkflowExecutionBase` + +```ts +type WorkflowExecutionBase = { + id?: string + definitionId?: string + orgId?: string + name?: string + creationTime?: string + lastUpdateTime?: string + dueDate?: string + completedTime?: string + dynamicDueDate?: { + numberOfUnits: number + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" + stepId?: string + phaseId?: string + } + status?: "STARTED" | "DONE" | "CLOSED" + trigger?: "MANUAL" | "AUTOMATIC" + assignedTo?: string[] + lastModifiedBy?: string + contexts?: Array<{ + id: string + title: string + schema: string + }> + nextOpenStep?: { + id?: string + entityRefId?: string + } + configuredClosingReasonSnapshot?: Array<{ + id: string + title: string + }> + selectedClosingReasons?: Array<{ + id: string + title: string + }> + closingReasonDescription?: string + enableECPWorkflow?: boolean + updateEntityAttributes?: Array<{ + source: "workflow_status" | "current_section" | "current_step" + target: { + entitySchema: { ... } + entityAttribute: { ... } + } + }> + version?: number + taxonomies?: string[] + singleClosingReasonSelection?: boolean +} +``` + +### `WorkflowExecutionSlim` + +```ts +type WorkflowExecutionSlim = { + id?: string + definitionId?: string + orgId?: string + name?: string + creationTime?: string + lastUpdateTime?: string + dueDate?: string + completedTime?: string + dynamicDueDate?: { + numberOfUnits: number + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" + stepId?: string + phaseId?: string + } + status?: "STARTED" | "DONE" | "CLOSED" + trigger?: "MANUAL" | "AUTOMATIC" + assignedTo?: string[] + lastModifiedBy?: string + contexts?: Array<{ + id: string + title: string + schema: string + }> + nextOpenStep?: { + id?: string + entityRefId?: string + } + configuredClosingReasonSnapshot?: Array<{ + id: string + title: string + }> + selectedClosingReasons?: Array<{ + id: string + title: string + }> + closingReasonDescription?: string + enableECPWorkflow?: boolean + updateEntityAttributes?: Array<{ + source: "workflow_status" | "current_section" | "current_step" + target: { + entitySchema: { ... } + entityAttribute: { ... } + } + }> + version?: number + taxonomies?: string[] + singleClosingReasonSelection?: boolean + flow: Array<{ + id: string + definitionId?: string + name: string + userIds?: number[] + assignedTo?: string[] + dueDate?: string + dynamicDueDate?: { + numberOfUnits: { ... } + timePeriod: { ... } + actionTypeCondition?: { ... } + stepId?: { ... } + phaseId?: { ... } + } + startedTime?: string + completedTime?: string + status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" + type: "STEP" | "SECTION" + steps: Array<{ + id: { ... } + definitionId?: { ... } + entityRefId?: { ... } + name: { ... } + description?: { ... } + type: { ... } + ecp?: { ... } + installer?: { ... } + partner?: { ... } + enabled?: { ... } + requirements?: { ... } + executionType?: { ... } + sectionId?: { ... } + executionId?: { ... } + userIds?: { ... } + assignedTo?: { ... } + assignedToInProgress?: { ... } + assignedToOnHold?: { ... } + status?: { ... } + created?: { ... } + lastUpdated?: { ... } + statusLastUpdated?: { ... } + startedTime?: { ... } + completedTime?: { ... } + dueDate?: { ... } + dynamicDueDate?: { ... } + manuallyCreated?: { ... } + automationConfig?: { ... } + journey?: { ... } + taxonomies?: { ... } + }> + taxonomies?: string[] + // ... +} +``` + +### `FlowSlim` + +```ts +type FlowSlim = { + flow: Array<{ + id: string + definitionId?: string + name: string + userIds?: number[] + assignedTo?: string[] + dueDate?: string + dynamicDueDate?: { + numberOfUnits: { ... } + timePeriod: { ... } + actionTypeCondition?: { ... } + stepId?: { ... } + phaseId?: { ... } + } + startedTime?: string + completedTime?: string + status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" + type: "STEP" | "SECTION" + steps: Array<{ + id: { ... } + definitionId?: { ... } + entityRefId?: { ... } + name: { ... } + description?: { ... } + type: { ... } + ecp?: { ... } + installer?: { ... } + partner?: { ... } + enabled?: { ... } + requirements?: { ... } + executionType?: { ... } + sectionId?: { ... } + executionId?: { ... } + userIds?: { ... } + assignedTo?: { ... } + assignedToInProgress?: { ... } + assignedToOnHold?: { ... } + status?: { ... } + created?: { ... } + lastUpdated?: { ... } + statusLastUpdated?: { ... } + startedTime?: { ... } + completedTime?: { ... } + dueDate?: { ... } + dynamicDueDate?: { ... } + manuallyCreated?: { ... } + automationConfig?: { ... } + journey?: { ... } + taxonomies?: { ... } + }> + taxonomies?: string[] + } | { + id: string + definitionId?: string + entityRefId?: string + name: string + description?: { + enabled?: { ... } + value?: { ... } + } + type: "STEP" | "SECTION" + ecp?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + installer?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + partner?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + } + enabled?: boolean + requirements?: Array<{ + definitionId: { ... } + type: { ... } + condition: { ... } + }> + executionType?: "MANUAL" | "AUTOMATION" + sectionId?: string + executionId?: string + userIds?: number[] + assignedTo?: string[] + assignedToInProgress?: string + assignedToOnHold?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + created?: string + lastUpdated?: string + statusLastUpdated?: string + startedTime?: string + completedTime?: string + dueDate?: string + dynamicDueDate?: { + // ... +} +``` + +### `Flow` + +```ts +type Flow = { + flow: Array<{ + id: string + definitionId?: string + name: string + userIds?: number[] + assignedTo?: string[] + dueDate?: string + dynamicDueDate?: { + numberOfUnits: { ... } + timePeriod: { ... } + actionTypeCondition?: { ... } + stepId?: { ... } + phaseId?: { ... } + } + startedTime?: string + completedTime?: string + status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" + type: "STEP" | "SECTION" + steps: Array<{ + id: { ... } + definitionId?: { ... } + entityRefId?: { ... } + name: { ... } + description?: { ... } + type: { ... } + ecp?: { ... } + installer?: { ... } + partner?: { ... } + enabled?: { ... } + requirements?: { ... } + executionType?: { ... } + sectionId?: { ... } + executionId?: { ... } + userIds?: { ... } + assignedTo?: { ... } + assignedToInProgress?: { ... } + assignedToOnHold?: { ... } + status?: { ... } + created?: { ... } + lastUpdated?: { ... } + statusLastUpdated?: { ... } + startedTime?: { ... } + completedTime?: { ... } + dueDate?: { ... } + dynamicDueDate?: { ... } + manuallyCreated?: { ... } + automationConfig?: { ... } + journey?: { ... } + taxonomies?: { ... } + }> + taxonomies?: string[] + } | { + id: string + definitionId?: string + entityRefId?: string + name: string + description?: { + enabled?: { ... } + value?: { ... } + } + type: "STEP" | "SECTION" + ecp?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + installer?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + partner?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + } + enabled?: boolean + requirements?: Array<{ + definitionId: { ... } + type: { ... } + condition: { ... } + }> + executionType?: "MANUAL" | "AUTOMATION" + sectionId?: string + executionId?: string + userIds?: number[] + assignedTo?: string[] + assignedToInProgress?: string + assignedToOnHold?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + created?: string + lastUpdated?: string + statusLastUpdated?: string + startedTime?: string + completedTime?: string + dueDate?: string + dynamicDueDate?: { + // ... +} +``` + +### `WorkflowExecution` + +```ts +type WorkflowExecution = { + id?: string + definitionId?: string + orgId?: string + name?: string + creationTime?: string + lastUpdateTime?: string + dueDate?: string + completedTime?: string + dynamicDueDate?: { + numberOfUnits: number + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" + stepId?: string + phaseId?: string + } + status?: "STARTED" | "DONE" | "CLOSED" + trigger?: "MANUAL" | "AUTOMATIC" + assignedTo?: string[] + lastModifiedBy?: string + contexts?: Array<{ + id: string + title: string + schema: string + }> + nextOpenStep?: { + id?: string + entityRefId?: string + } + configuredClosingReasonSnapshot?: Array<{ + id: string + title: string + }> + selectedClosingReasons?: Array<{ + id: string + title: string + }> + closingReasonDescription?: string + enableECPWorkflow?: boolean + updateEntityAttributes?: Array<{ + source: "workflow_status" | "current_section" | "current_step" + target: { + entitySchema: { ... } + entityAttribute: { ... } + } + }> + version?: number + taxonomies?: string[] + singleClosingReasonSelection?: boolean + flow: Array<{ + id: string + definitionId?: string + name: string + userIds?: number[] + assignedTo?: string[] + dueDate?: string + dynamicDueDate?: { + numberOfUnits: { ... } + timePeriod: { ... } + actionTypeCondition?: { ... } + stepId?: { ... } + phaseId?: { ... } + } + startedTime?: string + completedTime?: string + status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" + type: "STEP" | "SECTION" + steps: Array<{ + id: { ... } + definitionId?: { ... } + entityRefId?: { ... } + name: { ... } + description?: { ... } + type: { ... } + ecp?: { ... } + installer?: { ... } + partner?: { ... } + enabled?: { ... } + requirements?: { ... } + executionType?: { ... } + sectionId?: { ... } + executionId?: { ... } + userIds?: { ... } + assignedTo?: { ... } + assignedToInProgress?: { ... } + assignedToOnHold?: { ... } + status?: { ... } + created?: { ... } + lastUpdated?: { ... } + statusLastUpdated?: { ... } + startedTime?: { ... } + completedTime?: { ... } + dueDate?: { ... } + dynamicDueDate?: { ... } + manuallyCreated?: { ... } + automationConfig?: { ... } + journey?: { ... } + taxonomies?: { ... } + }> + taxonomies?: string[] + // ... +} +``` + +### `WorkflowStatus` + +```ts +type WorkflowStatus = "STARTED" | "DONE" | "CLOSED" +``` + +### `SectionSimplified` + +A group of Steps that define the progress of the Workflow + +```ts +type SectionSimplified = { + id: string + definitionId?: string + name: string + type: "STEP" | "SECTION" + steps: Array<{ + id: string + definitionId?: string + entityRefId?: string + name: string + description?: { + enabled?: { ... } + value?: { ... } + } + type: "STEP" | "SECTION" + ecp?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + installer?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + partner?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + } + enabled?: boolean + requirements?: Array<{ + definitionId: { ... } + type: { ... } + condition: { ... } + }> + executionType?: "MANUAL" | "AUTOMATION" + }> + assignedTo?: string[] +} +``` + +### `Section` + +A group of Steps that define the progress of the Workflow + +```ts +type Section = { + id: string + definitionId?: string + name: string + userIds?: number[] + assignedTo?: string[] + dueDate?: string + dynamicDueDate?: { + numberOfUnits: number + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" + stepId?: string + phaseId?: string + } + startedTime?: string + completedTime?: string + status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" + type: "STEP" | "SECTION" + steps: Array<{ + id: string + definitionId?: string + entityRefId?: string + name: string + description?: { + enabled?: { ... } + value?: { ... } + } + type: "STEP" | "SECTION" + ecp?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + installer?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + partner?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + } + enabled?: boolean + requirements?: Array<{ + definitionId: { ... } + type: { ... } + condition: { ... } + }> + executionType?: "MANUAL" | "AUTOMATION" + sectionId?: string + executionId?: string + userIds?: number[] + assignedTo?: string[] + assignedToInProgress?: string + assignedToOnHold?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + created?: string + lastUpdated?: string + statusLastUpdated?: string + startedTime?: string + completedTime?: string + dueDate?: string + dynamicDueDate?: { + numberOfUnits: { ... } + timePeriod: { ... } + actionTypeCondition?: { ... } + stepId?: { ... } + phaseId?: { ... } + } + manuallyCreated?: boolean + automationConfig?: { + flowId: { ... } + executionId?: { ... } + executionStatus?: { ... } + } + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } + taxonomies?: string[] + }> + taxonomies?: string[] +} +``` + +### `StepId` + +```ts +type StepId = { + id?: string + entityRefId?: string +} +``` + +### `StepSimplified` + +```ts +type StepSimplified = { + id: string + definitionId?: string + entityRefId?: string + name: string + description?: { + enabled?: boolean + value?: string + } + type: "STEP" | "SECTION" + ecp?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } + } + installer?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } + } + partner?: { + enabled?: boolean + label?: string + description?: string + } + enabled?: boolean + requirements?: Array<{ + definitionId: string + type: "STEP" | "SECTION" + condition: "CLOSED" }> - closingReasonDescription?: string + executionType?: "MANUAL" | "AUTOMATION" +} +``` + +### `Step` + +```ts +type Step = { + id: string + definitionId?: string + entityRefId?: string + name: string + description?: { + enabled?: boolean + value?: string + } + type: "STEP" | "SECTION" + ecp?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } + } + installer?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } + } + partner?: { + enabled?: boolean + label?: string + description?: string + } + enabled?: boolean + requirements?: Array<{ + definitionId: string + type: "STEP" | "SECTION" + condition: "CLOSED" + }> + executionType?: "MANUAL" | "AUTOMATION" + sectionId?: string + executionId?: string + userIds?: number[] + assignedTo?: string[] + assignedToInProgress?: string + assignedToOnHold?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + created?: string + lastUpdated?: string + statusLastUpdated?: string + startedTime?: string + completedTime?: string dueDate?: string dynamicDueDate?: { numberOfUnits: number @@ -1839,102 +4752,308 @@ type WorkflowExecutionUpdateReq = { stepId?: string phaseId?: string } - closedBy?: string + manuallyCreated?: boolean + automationConfig?: { + flowId: string + executionId?: string + executionStatus?: string + } + journey?: { + id?: string + journeyId?: string + name?: string + portal_button_label?: string + complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } + taxonomies?: string[] +} +``` + +### `StepExtended` + +```ts +type StepExtended = { + executionId: string + executionName: string + executionStatus: "STARTED" | "DONE" | "CLOSED" contexts?: Array<{ id: string title: string schema: string }> - completedTime?: string } ``` -### `ClosingReason` +### `StepStatus` + +**Note**: "UNASSIGNED" and "ASSIGNED" are deprecated and will be removed in a future version. Please use "PENDING" instead. Status values for workflow execution steps/tasks: +- **UNASSIGNED**: Step has not been assigned to any user (deprecated - use PENDING instead) +- **ASSIGNED**: Step has been assi ```ts -type ClosingReason = { - id: string - title: string +type StepStatus = "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" +``` + +### `SectionStatus` + +```ts +type SectionStatus = "OPEN" | "IN_PROGRESS" | "COMPLETED" +``` + +### `StepType` + +```ts +type StepType = "MANUAL" | "AUTOMATION" +``` + +### `StepJourney` + +```ts +type StepJourney = { + id?: string + journeyId?: string + name?: string + portal_button_label?: string + complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: string + value: string + }> + ai_prefill?: { + enabled?: boolean + source?: { + type?: { ... } + input_entity?: { ... } + } + extraction_fields?: Array<{ + key: { ... } + type: { ... } + description?: { ... } + description_overridden?: { ... } + enum?: { ... } + }> + mappings?: Array<{ + source: { ... } + block_id: { ... } + block_type: { ... } + block_field?: { ... } + country_code?: { ... } + }> + min_confidence?: number + instructions?: string + } } ``` -### `WorkflowContext` +### `JourneyContextParameter` ```ts -type WorkflowContext = { - id: string - title: string - schema: string +type JourneyContextParameter = { + key: string + value: string } ``` -### `WorkflowExecutionBase` +### `AiPrefillConfig` + +AI extraction + prefill configuration for the attached journey (Flows v2 only) + +```ts +type AiPrefillConfig = { + enabled?: boolean + source?: { + type?: "flow_context" + input_entity?: "thread" | "first_email" | "last_email" + } + extraction_fields?: Array<{ + key: string + type: "string" | "number" | "boolean" | "date" | "enum" + description?: string + description_overridden?: boolean + enum?: string[] + }> + mappings?: Array<{ + source: string + block_id: string + block_type: "text-input" | "number-input" | "personal-information" | "meter-reading" | "contact" | "single-choice" | "date-input" | "binary-input" | "address" | "payment-method" | "multiple-choice" | "availability-check" + block_field?: string + country_code?: string + }> + min_confidence?: number + instructions?: string +} +``` + +### `AiPrefillExtractionField` + +```ts +type AiPrefillExtractionField = { + key: string + type: "string" | "number" | "boolean" | "date" | "enum" + description?: string + description_overridden?: boolean + enum?: string[] +} +``` + +### `AiPrefillMapping` + +```ts +type AiPrefillMapping = { + source: string + block_id: string + block_type: "text-input" | "number-input" | "personal-information" | "meter-reading" | "contact" | "single-choice" | "date-input" | "binary-input" | "address" | "payment-method" | "multiple-choice" | "availability-check" + block_field?: string + country_code?: string +} +``` + +### `JourneyPrefill` + +Server-tracked outcome of an AI journey-prefill dispatch for this task (Flows v2 only). Absent when the task has no `journey.ai_prefill` config, or before the task becomes current. + +```ts +type JourneyPrefill = { + status: "PENDING" | "READY" | "FAILED" | "SKIPPED" + agent_execution_id?: string + dispatched_at?: string // date-time + extracted_at?: string // date-time + initial_state?: Record + field_confidence?: Record + dropped?: Array<{ + source?: string + block_id?: string + reason: string + }> +} +``` + +### `AutomationConfig` + +Configuration for automation execution to run + +```ts +type AutomationConfig = { + flowId: string + executionId?: string + executionStatus?: string +} +``` + +### `ECPDetails` + +Details regarding ECP for the workflow step + +```ts +type ECPDetails = { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: string + journeyId?: string + name?: string + portal_button_label?: string + complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } +} +``` + +### `PartnerDetails` + +Details regarding partner for the workflow step + +```ts +type PartnerDetails = { + enabled?: boolean + label?: string + description?: string +} +``` + +### `StepDescription` + +Longer information regarding Task + +```ts +type StepDescription = { + enabled?: boolean + value?: string +} +``` + +### `ItemType` + +```ts +type ItemType = "STEP" | "SECTION" +``` + +### `TriggerType` + +```ts +type TriggerType = "MANUAL" | "AUTOMATIC" +``` + +### `CreateStepReq` ```ts -type WorkflowExecutionBase = { - id?: string - definitionId?: string - orgId?: string - name?: string - creationTime?: string - lastUpdateTime?: string - dueDate?: string - completedTime?: string - dynamicDueDate?: { - numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" - actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" - stepId?: string - phaseId?: string +type CreateStepReq = { + insertionIndex: number + name: string + description?: { + enabled: boolean + value: string } - status?: "STARTED" | "DONE" | "CLOSED" - trigger?: "MANUAL" | "AUTOMATIC" - assignedTo?: string[] - lastModifiedBy?: string - contexts?: Array<{ - id: string - title: string - schema: string - }> - nextOpenStep?: { - id?: string - entityRefId?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + sectionId?: string + executionType?: "MANUAL" | "AUTOMATION" + automationConfig?: { + flowId: string + executionId?: string + executionStatus?: string } - configuredClosingReasonSnapshot?: Array<{ - id: string - title: string - }> - selectedClosingReasons?: Array<{ - id: string - title: string - }> - closingReasonDescription?: string - enableECPWorkflow?: boolean - updateEntityAttributes?: Array<{ - source: "workflow_status" | "current_section" | "current_step" - target: { - entitySchema: { ... } - entityAttribute: { ... } - } - }> - version?: number - taxonomies?: string[] - singleClosingReasonSelection?: boolean } ``` -### `WorkflowExecutionSlim` +### `UpdateStepReq` ```ts -type WorkflowExecutionSlim = { - id?: string - definitionId?: string - orgId?: string - name?: string - creationTime?: string - lastUpdateTime?: string +type UpdateStepReq = { + stepId?: string + entityRefId?: string + userIds?: number[] + assignedTo?: string[] + assignedToInProgress?: string + assignedToOnHold?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" dueDate?: string - completedTime?: string dynamicDueDate?: { numberOfUnits: number timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" @@ -1942,320 +5061,122 @@ type WorkflowExecutionSlim = { stepId?: string phaseId?: string } - status?: "STARTED" | "DONE" | "CLOSED" - trigger?: "MANUAL" | "AUTOMATIC" - assignedTo?: string[] - lastModifiedBy?: string - contexts?: Array<{ - id: string - title: string - schema: string - }> - nextOpenStep?: { - id?: string - entityRefId?: string + name?: string + description?: { + enabled: boolean + value: string } - configuredClosingReasonSnapshot?: Array<{ - id: string - title: string - }> - selectedClosingReasons?: Array<{ - id: string - title: string - }> - closingReasonDescription?: string - enableECPWorkflow?: boolean - updateEntityAttributes?: Array<{ - source: "workflow_status" | "current_section" | "current_step" - target: { - entitySchema: { ... } - entityAttribute: { ... } - } - }> - version?: number - taxonomies?: string[] - singleClosingReasonSelection?: boolean - flow: Array<{ - id: string - definitionId?: string - name: string - userIds?: number[] - assignedTo?: string[] - dueDate?: string - dynamicDueDate?: { - numberOfUnits: { ... } - timePeriod: { ... } - actionTypeCondition?: { ... } - stepId?: { ... } - phaseId?: { ... } - } - startedTime?: string - completedTime?: string - status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" - type: "STEP" | "SECTION" - steps: Array<{ - id: { ... } - definitionId?: { ... } - entityRefId?: { ... } - name: { ... } - description?: { ... } - type: { ... } - ecp?: { ... } - installer?: { ... } - enabled?: { ... } - requirements?: { ... } - executionType?: { ... } - sectionId?: { ... } - executionId?: { ... } - userIds?: { ... } - assignedTo?: { ... } - assignedToInProgress?: { ... } - status?: { ... } - created?: { ... } - lastUpdated?: { ... } - statusLastUpdated?: { ... } - startedTime?: { ... } - completedTime?: { ... } - dueDate?: { ... } - dynamicDueDate?: { ... } - manuallyCreated?: { ... } - automationConfig?: { ... } - journey?: { ... } - taxonomies?: { ... } - }> - taxonomies?: string[] - } | { - id: string - // ... -} -``` - -### `FlowSlim` - -```ts -type FlowSlim = { - flow: Array<{ - id: string - definitionId?: string - name: string - userIds?: number[] - assignedTo?: string[] - dueDate?: string - dynamicDueDate?: { - numberOfUnits: { ... } - timePeriod: { ... } - actionTypeCondition?: { ... } - stepId?: { ... } - phaseId?: { ... } - } - startedTime?: string - completedTime?: string - status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" - type: "STEP" | "SECTION" - steps: Array<{ - id: { ... } - definitionId?: { ... } - entityRefId?: { ... } - name: { ... } - description?: { ... } - type: { ... } - ecp?: { ... } - installer?: { ... } - enabled?: { ... } - requirements?: { ... } - executionType?: { ... } - sectionId?: { ... } - executionId?: { ... } - userIds?: { ... } - assignedTo?: { ... } - assignedToInProgress?: { ... } - status?: { ... } - created?: { ... } - lastUpdated?: { ... } - statusLastUpdated?: { ... } - startedTime?: { ... } - completedTime?: { ... } - dueDate?: { ... } - dynamicDueDate?: { ... } - manuallyCreated?: { ... } - automationConfig?: { ... } - journey?: { ... } - taxonomies?: { ... } - }> - taxonomies?: string[] - } | { - id: string - definitionId?: string - entityRefId?: string - name: string - description?: { - enabled?: { ... } - value?: { ... } - } - type: "STEP" | "SECTION" - ecp?: { - enabled?: { ... } - label?: { ... } - description?: { ... } - journey?: { ... } - } - installer?: { - enabled?: { ... } - label?: { ... } - description?: { ... } - journey?: { ... } - } - enabled?: boolean - requirements?: Array<{ - definitionId: { ... } - type: { ... } - condition: { ... } + position?: { + index: number + sectionId?: string + } + automationConfig?: { + flowId: string + executionId?: string + executionStatus?: string + } + journey?: { + id?: string + journeyId?: string + name?: string + portal_button_label?: string + complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } }> - executionType?: "MANUAL" | "AUTOMATION" - sectionId?: string - executionId?: string - userIds?: number[] - assignedTo?: string[] - assignedToInProgress?: string - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - created?: string - lastUpdated?: string - statusLastUpdated?: string - startedTime?: string - completedTime?: string - dueDate?: string - dynamicDueDate?: { - numberOfUnits: { ... } - timePeriod: { ... } - actionTypeCondition?: { ... } - stepId?: { ... } - phaseId?: { ... } + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } } - manuallyCreated?: boolean - automationConfig?: { - // ... + } + startedTime?: string + completedTime?: string } ``` -### `Flow` +### `StepPositionAt` ```ts -type Flow = { - flow: Array<{ - id: string - definitionId?: string - name: string - userIds?: number[] - assignedTo?: string[] - dueDate?: string - dynamicDueDate?: { - numberOfUnits: { ... } - timePeriod: { ... } - actionTypeCondition?: { ... } - stepId?: { ... } - phaseId?: { ... } - } - startedTime?: string - completedTime?: string - status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" - type: "STEP" | "SECTION" - steps: Array<{ - id: { ... } - definitionId?: { ... } - entityRefId?: { ... } - name: { ... } - description?: { ... } - type: { ... } - ecp?: { ... } - installer?: { ... } - enabled?: { ... } - requirements?: { ... } - executionType?: { ... } - sectionId?: { ... } - executionId?: { ... } - userIds?: { ... } - assignedTo?: { ... } - assignedToInProgress?: { ... } - status?: { ... } - created?: { ... } - lastUpdated?: { ... } - statusLastUpdated?: { ... } - startedTime?: { ... } - completedTime?: { ... } - dueDate?: { ... } - dynamicDueDate?: { ... } - manuallyCreated?: { ... } - automationConfig?: { ... } - journey?: { ... } - taxonomies?: { ... } - }> - taxonomies?: string[] - } | { - id: string - definitionId?: string - entityRefId?: string - name: string - description?: { - enabled?: { ... } - value?: { ... } - } - type: "STEP" | "SECTION" - ecp?: { - enabled?: { ... } - label?: { ... } - description?: { ... } - journey?: { ... } - } - installer?: { - enabled?: { ... } - label?: { ... } - description?: { ... } - journey?: { ... } - } - enabled?: boolean - requirements?: Array<{ - definitionId: { ... } - type: { ... } - condition: { ... } - }> - executionType?: "MANUAL" | "AUTOMATION" - sectionId?: string - executionId?: string - userIds?: number[] - assignedTo?: string[] - assignedToInProgress?: string - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - created?: string - lastUpdated?: string - statusLastUpdated?: string - startedTime?: string - completedTime?: string - dueDate?: string - dynamicDueDate?: { - numberOfUnits: { ... } - timePeriod: { ... } - actionTypeCondition?: { ... } - stepId?: { ... } - phaseId?: { ... } - } - manuallyCreated?: boolean - automationConfig?: { - // ... +type StepPositionAt = { + index: number + sectionId?: string } ``` -### `WorkflowExecution` +### `UpdateStepResp` ```ts -type WorkflowExecution = { - id?: string +type UpdateStepResp = { + id: string definitionId?: string - orgId?: string - name?: string - creationTime?: string - lastUpdateTime?: string - dueDate?: string + entityRefId?: string + name: string + description?: { + enabled?: boolean + value?: string + } + type: "STEP" | "SECTION" + ecp?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } + } + installer?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } + } + partner?: { + enabled?: boolean + label?: string + description?: string + } + enabled?: boolean + requirements?: Array<{ + definitionId: string + type: "STEP" | "SECTION" + condition: "CLOSED" + }> + executionType?: "MANUAL" | "AUTOMATION" + sectionId?: string + executionId?: string + userIds?: number[] + assignedTo?: string[] + assignedToInProgress?: string + assignedToOnHold?: string + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + created?: string + lastUpdated?: string + statusLastUpdated?: string + startedTime?: string completedTime?: string + dueDate?: string dynamicDueDate?: { numberOfUnits: number timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" @@ -2263,46 +5184,83 @@ type WorkflowExecution = { stepId?: string phaseId?: string } - status?: "STARTED" | "DONE" | "CLOSED" - trigger?: "MANUAL" | "AUTOMATIC" - assignedTo?: string[] - lastModifiedBy?: string - contexts?: Array<{ - id: string - title: string - schema: string + manuallyCreated?: boolean + automationConfig?: { + flowId: string + executionId?: string + executionStatus?: string + } + journey?: { + id?: string + journeyId?: string + name?: string + portal_button_label?: string + complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } + taxonomies?: string[] +} +``` + +### `SearchStepsResp` + +```ts +type SearchStepsResp = { + hits?: number + results?: Array<{ + executionId: string + executionName: string + executionStatus: "STARTED" | "DONE" | "CLOSED" + contexts?: Array<{ + id: { ... } + title: { ... } + schema: { ... } + }> }> - nextOpenStep?: { +} +``` + +### `SearchExecutionsReq` + +```ts +type SearchExecutionsReq = { + name?: string + status?: "STARTED" | "DONE" | "CLOSED" + includeDoneWorkflows?: boolean + assignedTo?: string + sorting?: "A_Z" | "Z_A" | "DUE_DATE_ASC" | "DUE_DATE_DESC" | "TRIGGER_DATE_ASC" | "TRIGGER_DATE_DESC" + pagination?: { + orgId?: string + creationTime?: string + } +} +``` + +### `SearchExecutionsResp` + +```ts +type SearchExecutionsResp = { + executions: Array<{ id?: string - entityRefId?: string - } - configuredClosingReasonSnapshot?: Array<{ - id: string - title: string - }> - selectedClosingReasons?: Array<{ - id: string - title: string - }> - closingReasonDescription?: string - enableECPWorkflow?: boolean - updateEntityAttributes?: Array<{ - source: "workflow_status" | "current_section" | "current_step" - target: { - entitySchema: { ... } - entityAttribute: { ... } - } - }> - version?: number - taxonomies?: string[] - singleClosingReasonSelection?: boolean - flow: Array<{ - id: string definitionId?: string - name: string - userIds?: number[] - assignedTo?: string[] + orgId?: string + name?: string + creationTime?: string + lastUpdateTime?: string dueDate?: string + completedTime?: string dynamicDueDate?: { numberOfUnits: { ... } timePeriod: { ... } @@ -2310,11 +5268,51 @@ type WorkflowExecution = { stepId?: { ... } phaseId?: { ... } } - startedTime?: string - completedTime?: string - status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" - type: "STEP" | "SECTION" - steps: Array<{ + status?: "STARTED" | "DONE" | "CLOSED" + trigger?: "MANUAL" | "AUTOMATIC" + assignedTo?: string[] + lastModifiedBy?: string + contexts?: Array<{ + id: { ... } + title: { ... } + schema: { ... } + }> + nextOpenStep?: { + id?: { ... } + entityRefId?: { ... } + } + configuredClosingReasonSnapshot?: Array<{ + id: { ... } + title: { ... } + }> + selectedClosingReasons?: Array<{ + id: { ... } + title: { ... } + }> + closingReasonDescription?: string + enableECPWorkflow?: boolean + updateEntityAttributes?: Array<{ + source: { ... } + target: { ... } + }> + version?: number + taxonomies?: string[] + singleClosingReasonSelection?: boolean + flow: Array<{ + id: { ... } + definitionId?: { ... } + name: { ... } + userIds?: { ... } + assignedTo?: { ... } + dueDate?: { ... } + dynamicDueDate?: { ... } + startedTime?: { ... } + completedTime?: { ... } + status?: { ... } + type: { ... } + steps: { ... } + taxonomies?: { ... } + } | { id: { ... } definitionId?: { ... } entityRefId?: { ... } @@ -2323,6 +5321,7 @@ type WorkflowExecution = { type: { ... } ecp?: { ... } installer?: { ... } + partner?: { ... } enabled?: { ... } requirements?: { ... } executionType?: { ... } @@ -2331,6 +5330,7 @@ type WorkflowExecution = { userIds?: { ... } assignedTo?: { ... } assignedToInProgress?: { ... } + assignedToOnHold?: { ... } status?: { ... } created?: { ... } lastUpdated?: { ... } @@ -2344,871 +5344,1082 @@ type WorkflowExecution = { journey?: { ... } taxonomies?: { ... } }> - taxonomies?: string[] - } | { - id: string - // ... + }> + lastEvaluatedKey?: { + orgId?: string + creationTime?: string + } } ``` -### `WorkflowStatus` +### `LastEvaluatedKey` ```ts -type WorkflowStatus = "STARTED" | "DONE" | "CLOSED" +type LastEvaluatedKey = { + orgId?: string + creationTime?: string +} ``` -### `SectionSimplified` - -A group of Steps that define the progress of the Workflow +### `SearchStepsReq` ```ts -type SectionSimplified = { - id: string - definitionId?: string - name: string - type: "STEP" | "SECTION" - steps: Array<{ - id: string - definitionId?: string - entityRefId?: string - name: string - description?: { - enabled?: { ... } - value?: { ... } - } - type: "STEP" | "SECTION" - ecp?: { - enabled?: { ... } - label?: { ... } - description?: { ... } - journey?: { ... } - } - installer?: { - enabled?: { ... } - label?: { ... } - description?: { ... } - journey?: { ... } - } - enabled?: boolean - requirements?: Array<{ - definitionId: { ... } - type: { ... } - condition: { ... } - }> - executionType?: "MANUAL" | "AUTOMATION" - }> - assignedTo?: string[] +type SearchStepsReq = { + executionName?: string + stepName?: string + assignedTo?: number + includeDoneWorkflows?: boolean + manuallyCreated?: boolean + status?: "OPEN" | "COMPLETE" | "NEXT_OPEN_ITEM_IN_WORKFLOW" + sorting?: "A_Z" | "Z_A" | "DUE_DATE_ASC" | "DUE_DATE_DESC" | "TRIGGER_DATE_ASC" | "TRIGGER_DATE_DESC" + pagination?: { + from?: number + size?: number + } } ``` -### `Section` +### `SearchSorting` -A group of Steps that define the progress of the Workflow +```ts +type SearchSorting = "A_Z" | "Z_A" | "DUE_DATE_ASC" | "DUE_DATE_DESC" | "TRIGGER_DATE_ASC" | "TRIGGER_DATE_DESC" +``` + +### `SearchPagination` ```ts -type Section = { - id: string - definitionId?: string - name: string - userIds?: number[] - assignedTo?: string[] - dueDate?: string - dynamicDueDate?: { - numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" - actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" - stepId?: string - phaseId?: string - } - startedTime?: string - completedTime?: string - status?: "OPEN" | "IN_PROGRESS" | "COMPLETED" - type: "STEP" | "SECTION" - steps: Array<{ - id: string - definitionId?: string - entityRefId?: string - name: string - description?: { - enabled?: { ... } - value?: { ... } - } - type: "STEP" | "SECTION" - ecp?: { - enabled?: { ... } - label?: { ... } - description?: { ... } - journey?: { ... } - } - installer?: { - enabled?: { ... } - label?: { ... } - description?: { ... } - journey?: { ... } - } - enabled?: boolean - requirements?: Array<{ - definitionId: { ... } - type: { ... } - condition: { ... } - }> - executionType?: "MANUAL" | "AUTOMATION" - sectionId?: string - executionId?: string - userIds?: number[] - assignedTo?: string[] - assignedToInProgress?: string - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - created?: string - lastUpdated?: string - statusLastUpdated?: string - startedTime?: string - completedTime?: string - dueDate?: string - dynamicDueDate?: { - numberOfUnits: { ... } - timePeriod: { ... } - actionTypeCondition?: { ... } - stepId?: { ... } - phaseId?: { ... } - } - manuallyCreated?: boolean - automationConfig?: { - flowId: { ... } - executionId?: { ... } - executionStatus?: { ... } - } - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - taxonomies?: string[] +type SearchPagination = { + from?: number + size?: number +} +``` + +### `ExecutionPaginationDynamo` + +```ts +type ExecutionPaginationDynamo = { + orgId?: string + creationTime?: string +} +``` + +### `ErrorResp` + +Standard error response returned when an API request fails. +Contains a human-readable message describing the error. + + +```ts +type ErrorResp = { + message: string +} +``` + +### `ClosingReasonResp` + +```ts +type ClosingReasonResp = { + reasons?: Array<{ + id: string + title: string }> - taxonomies?: string[] } ``` -### `StepId` +### `PhaseInEntity` ```ts -type StepId = { +type PhaseInEntity = { + phase_id?: string + phase_name?: string + phase_progress?: number + phase_assignees?: string[] +} +``` + +### `TaskInEntity` + +```ts +type TaskInEntity = { + task_id?: string + task_name?: string + task_assignees?: string[] + task_duedate?: string // date-time + task_start_date?: string + task_execution_type?: "MANUAL" | "AUTOMATION" + task_status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" +} +``` + +### `WorkflowInEntity` + +```ts +type WorkflowInEntity = { id?: string - entityRefId?: string + definition_id?: string + name?: string + status?: "STARTED" | "DONE" | "CLOSED" + assignees?: string[] + duedate?: string // date-time + last_update_time?: string // date-time + progress?: number + upcoming_tasks_assignees?: string[] + task_id?: string + task_name?: string + task_assignees?: string[] + task_duedate?: string // date-time + task_start_date?: string + task_execution_type?: "MANUAL" | "AUTOMATION" + task_status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + current_tasks?: Array<{ + task_id?: string + task_name?: string + task_assignees?: string[] + task_duedate?: string // date-time + task_start_date?: string + task_execution_type?: "MANUAL" | "AUTOMATION" + task_status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + }> + phase_id?: string + phase_name?: string + phase_assignees?: string[] + phase_progress?: number + phases_in_progress?: Array<{ + phase_id?: string + phase_name?: string + phase_progress?: number + phase_assignees?: string[] + }> + selected_closing_reasons?: Array<{ + id: string + title: string + }> + closing_reason_description?: string } ``` -### `StepSimplified` +### `UpdateEntityAttributes` ```ts -type StepSimplified = { - id: string - definitionId?: string - entityRefId?: string - name: string - description?: { - enabled?: boolean - value?: string +type UpdateEntityAttributes = { + source: "workflow_status" | "current_section" | "current_step" + target: { + entitySchema: string + entityAttribute: string } - type: "STEP" | "SECTION" - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } +} +``` + +### `EntitySync` + +```ts +type EntitySync = { + trigger: { + event: "FlowStarted" | "FlowCompleted" | "FlowCancelled" | "FlowReopened" | "FlowDeleted" | "FlowAssigned" | "FlowDueDateChanged" | "FlowContextsChanged" | "TaskUpdated" | "CurrTaskChanged" | "TaskCompleted" | "TaskSkipped" | "TaskMarkedInProgress" | "TaskMarkedOnHold" | "PhaseUpdated" | "PhaseCompleted" | "PhaseSkipped" | "PhaseMarkedInProgress" + filter?: { + task_template_id?: { ... } + phase_template_id?: { ... } } } - installer?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } + value: { + source: "workflow_name" | "workflow_status" | "workflow_assigned_to" | "task_name" | "task_status" | "task_assigned_to" | "phase_name" | "phase_status" | "phase_assigned_to" | "custom_value" + value?: string + } + target: { + entitySchema: string + entityAttribute: string } - enabled?: boolean - requirements?: Array<{ - definitionId: string - type: "STEP" | "SECTION" - condition: "CLOSED" - }> - executionType?: "MANUAL" | "AUTOMATION" } ``` -### `Step` +### `DynamicDueDate` + +set a Duedate for a step then a specific ```ts -type Step = { - id: string - definitionId?: string - entityRefId?: string - name: string - description?: { - enabled?: boolean - value?: string - } +type DynamicDueDate = { + numberOfUnits: number + timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" + actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" + stepId?: string + phaseId?: string +} +``` + +### `StepRequirement` + +describe the requirement for step enablement + +```ts +type StepRequirement = { + definitionId: string type: "STEP" | "SECTION" - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - installer?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } + condition: "CLOSED" +} +``` + +### `StartFlowReq` + +Request payload for starting a new flow execution from a template. + + +```ts +type StartFlowReq = { + flow_template_id: string + trigger?: { + type?: "MANUAL" | "AUTOMATIC" + automation_config?: { + flow_id: { ... } + execution_id?: { ... } + execution_status?: { ... } + error_reason?: { ... } + input_context?: { ... } + output_context?: { ... } + heal_attempts?: { ... } + run_for_user_id?: { ... } + last_heal_attempted_at?: { ... } + wait_for_journey_submission?: { ... } + journey_id?: { ... } + journey_execution?: { ... } + eligible_closing_reason_ids?: { ... } + allow_execution_note?: { ... } + email_review?: { ... } } + trigger_id?: string + bulk_job_id?: string } - enabled?: boolean - requirements?: Array<{ - definitionId: string - type: "STEP" | "SECTION" - condition: "CLOSED" + contexts: Array<{ + entity_id?: string + entity_schema?: string + is_primary?: boolean + promoted_by_task_id?: string + promoted_at?: string // date-time + demoted_by_task_id?: string + added_by_task_id?: string }> - executionType?: "MANUAL" | "AUTOMATION" - sectionId?: string - executionId?: string - userIds?: number[] - assignedTo?: string[] - assignedToInProgress?: string - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - created?: string - lastUpdated?: string - statusLastUpdated?: string - startedTime?: string - completedTime?: string - dueDate?: string - dynamicDueDate?: { - numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" - actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" - stepId?: string - phaseId?: string - } - manuallyCreated?: boolean - automationConfig?: { - flowId: string - executionId?: string - executionStatus?: string - } - journey?: { - id?: string - journeyId?: string - name?: string - complete_task_automatically?: boolean - } - taxonomies?: string[] + purposes?: string[] +} +``` + +### `SearchFlowsReq` + +```ts +type SearchFlowsReq = { + entity_id: string + entity_schema: string + include_background?: boolean +} +``` + +### `PortalWorkflowsSearchReq` + +```ts +type PortalWorkflowsSearchReq = { + entity_id: string + entity_schema: string + audience: "ecp" | "installer" | "all" } ``` -### `StepExtended` +### `PortalAudience` + +Which portal audience the workflows are loaded for. Controls which task-level +portal config (`ecp` or `installer`) determines task visibility. `all` returns +tasks enabled for any audience — callers must state the widest scope explicitly +rather than falling into it by omission. + ```ts -type StepExtended = { - executionId: string - executionName: string - executionStatus: "STARTED" | "DONE" | "CLOSED" - contexts?: Array<{ +type PortalAudience = "ecp" | "installer" | "all" +``` + +### `PortalWorkflowsSearchResp` + +```ts +type PortalWorkflowsSearchResp = { + workflows: Array<{ id: string - title: string - schema: string + definition_id?: string + name: string + status: "STARTED" | "DONE" | "CLOSED" + version: 2 | 3 + created_at?: string + updated_at?: string + completed_at?: string + due_date?: string + assigned_to?: string[] + contexts?: Array<{ + entity_id?: { ... } + entity_schema?: { ... } + is_primary?: { ... } + promoted_by_task_id?: { ... } + promoted_at?: { ... } + demoted_by_task_id?: { ... } + added_by_task_id?: { ... } + }> + is_path_complete: boolean + tasks?: Array<{ + id: { ... } + name: { ... } + status: { ... } + is_active: { ... } + start_date?: { ... } + ecp?: { ... } + installer?: { ... } + journey?: { ... } + assigned_to?: { ... } + phase_id?: { ... } + phase_name?: { ... } + stage_id?: { ... } + completed_at?: { ... } + updated_at?: { ... } + }> + stages?: Array<{ + id: { ... } + name: { ... } + description?: { ... } + status: { ... } + completed_at?: { ... } + portal_names?: { ... } + portal_descriptions?: { ... } + }> + portal_titles?: { + ecp?: { ... } + installer?: { ... } + } }> } ``` -### `StepStatus` +### `BulkStartFlowsReq` + +Start the flow `flow_template_id` on every entity in `entities`, or on +every entity `entities_query` matches. Exactly one of `flow_template_id` +and the deprecated `flow_template_ids` is required, and exactly one of +`entities` and `entities_query`. -**Note**: "UNASSIGNED" and "ASSIGNED" are deprecated and will be removed in a future version. Please use "PENDING" instead. Status values for workflow execution steps/tasks: -- **UNASSIGNED**: Step has not been assigned to any user (deprecated - use PENDING instead) -- **ASSIGNED**: Step has been assi ```ts -type StepStatus = "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" +type BulkStartFlowsReq = { + flow_template_id?: string + flow_template_ids?: string[] + entities?: Array<{ + entity_id: string + entity_schema: string + }> + entities_query?: { + entity_schema: string + q: string + } + purposes?: string[] +} ``` -### `SectionStatus` +### `BulkStartEntitiesQuery` -```ts -type SectionStatus = "OPEN" | "IN_PROGRESS" | "COMPLETED" -``` +The entities an entity search matches, as the entity table's "select all +matching" selects them. Resolved once, in the background, when the job is prepared: the +job holds the entities matching at that time (at most 80,000). -### `StepType` ```ts -type StepType = "MANUAL" | "AUTOMATION" +type BulkStartEntitiesQuery = { + entity_schema: string + q: string +} ``` -### `StepJourney` +### `BulkStartEntityRef` ```ts -type StepJourney = { - id?: string - journeyId?: string - name?: string - complete_task_automatically?: boolean +type BulkStartEntityRef = { + entity_id: string + entity_schema: string } ``` -### `AutomationConfig` +### `BulkStartFlowsJobStatus` -Configuration for automation execution to run +* `preparing`: the entities are being resolved; nothing started +* `awaiting_approval`: preflight done, nothing started; waits for `APPROVE` +* `queued`: approved, waiting for a worker +* `running`: starts in progress +* `completed`: every start that was not skipped succeeded +* `completed_with_errors`: ```ts -type AutomationConfig = { - flowId: string - executionId?: string - executionStatus?: string -} +type BulkStartFlowsJobStatus = "preparing" | "awaiting_approval" | "queued" | "running" | "completed" | "completed_with_errors" | "failed" | "cancelled" | "expired" ``` -### `ECPDetails` - -Details regarding ECP for the workflow step +### `BulkStartFlowsItemStatus` ```ts -type ECPDetails = { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: string - journeyId?: string - name?: string - complete_task_automatically?: boolean - } -} +type BulkStartFlowsItemStatus = "pending" | "started" | "failed" | "skipped" | "cancelled" ``` -### `StepDescription` +### `BulkStartFlowsItem` -Longer information regarding Task +One entity's start of a bulk-start job's flow. ```ts -type StepDescription = { - enabled?: boolean - value?: string +type BulkStartFlowsItem = { + flow_template_id: string + entity_id: string + entity_schema: string + status: "pending" | "started" | "failed" | "skipped" | "cancelled" + execution_id?: string + error_code?: string + error_message?: string + updated_at?: string // date-time } ``` -### `ItemType` +### `BulkStartFlowsFlowSummary` ```ts -type ItemType = "STEP" | "SECTION" +type BulkStartFlowsFlowSummary = { + flow_template_id: string + flow_name: string + will_start: number + skipped: number + automatic_tasks?: Array<{ + task_id: string + task_name: string + task_type: "AUTOMATION" | "AI_AGENT" + }> +} ``` -### `TriggerType` +### `BulkStartFlowsAutomaticTask` ```ts -type TriggerType = "MANUAL" | "AUTOMATIC" +type BulkStartFlowsAutomaticTask = { + task_id: string + task_name: string + task_type: "AUTOMATION" | "AI_AGENT" +} ``` -### `CreateStepReq` +### `BulkStartFlowsJobFailure` + +Why a job failed while it was being prepared. ```ts -type CreateStepReq = { - insertionIndex: number - name: string - description?: { - enabled: boolean - value: string - } - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - sectionId?: string - executionType?: "MANUAL" | "AUTOMATION" - automationConfig?: { - flowId: string - executionId?: string - executionStatus?: string - } +type BulkStartFlowsJobFailure = { + error_code: string + message: string } ``` -### `UpdateStepReq` +### `BulkStartFlowsJobPreparation` + +Progress of a `preparing` job: finding its entities (`resolving`), then +writing one item per entity (`writing`). Updated after every page and +every chunk, so an `updated_at` that stops moving means the server is +waiting to retry. + ```ts -type UpdateStepReq = { - stepId?: string - entityRefId?: string - userIds?: number[] - assignedTo?: string[] - assignedToInProgress?: string - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - dueDate?: string - dynamicDueDate?: { - numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" - actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" - stepId?: string - phaseId?: string - } - name?: string - description?: { - enabled: boolean - value: string - } - position?: { - index: number - sectionId?: string - } - automationConfig?: { - flowId: string - executionId?: string - executionStatus?: string - } - startedTime?: string - completedTime?: string +type BulkStartFlowsJobPreparation = { + phase: "resolving" | "writing" + matched?: number + resolved: number + written: number + total?: number + attempts: number + updated_at: string // date-time } ``` -### `StepPositionAt` +### `BulkStartFlowsJobCounts` ```ts -type StepPositionAt = { - index: number - sectionId?: string +type BulkStartFlowsJobCounts = { + total: number + pending: number + started: number + failed: number + skipped: number + cancelled: number } ``` -### `UpdateStepResp` +### `BulkStartFlowsJob` ```ts -type UpdateStepResp = { - id: string - definitionId?: string - entityRefId?: string - name: string - description?: { - enabled?: boolean - value?: string - } - type: "STEP" | "SECTION" - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - installer?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } +type BulkStartFlowsJob = { + job_id: string + org_id: string + status: "preparing" | "awaiting_approval" | "queued" | "running" | "completed" | "completed_with_errors" | "failed" | "cancelled" | "expired" + created_by: string + created_at: string // date-time + updated_at: string // date-time + expires_at: string // date-time + approved_at?: string // date-time + approved_by?: string + finished_at?: string // date-time + cancel_requested?: boolean + restart_of?: string + restarted_by?: string + flow: { + flow_template_id: string + flow_name: string + will_start: number + skipped: number + automatic_tasks?: Array<{ + task_id: { ... } + task_name: { ... } + task_type: { ... } + }> } - enabled?: boolean - requirements?: Array<{ - definitionId: string - type: "STEP" | "SECTION" - condition: "CLOSED" + flows?: Array<{ + flow_template_id: string + flow_name: string + will_start: number + skipped: number + automatic_tasks?: Array<{ + task_id: { ... } + task_name: { ... } + task_type: { ... } + }> }> - executionType?: "MANUAL" | "AUTOMATION" - sectionId?: string - executionId?: string - userIds?: number[] - assignedTo?: string[] - assignedToInProgress?: string - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - created?: string - lastUpdated?: string - statusLastUpdated?: string - startedTime?: string - completedTime?: string - dueDate?: string - dynamicDueDate?: { - numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" - actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" - stepId?: string - phaseId?: string + entity_count: number + entity_schema?: string + entities_query?: string + entities_matched?: number + failure?: { + error_code: string + message: string } - manuallyCreated?: boolean - automationConfig?: { - flowId: string - executionId?: string - executionStatus?: string + preparation?: { + phase: "resolving" | "writing" + matched?: number + resolved: number + written: number + total?: number + attempts: number + updated_at: string // date-time } - journey?: { - id?: string - journeyId?: string - name?: string - complete_task_automatically?: boolean + cancelled_by?: string + counts: { + total: number + pending: number + started: number + failed: number + skipped: number + cancelled: number } - taxonomies?: string[] -} -``` - -### `SearchStepsResp` - -```ts -type SearchStepsResp = { - hits?: number - results?: Array<{ - executionId: string - executionName: string - executionStatus: "STARTED" | "DONE" | "CLOSED" - contexts?: Array<{ - id: { ... } - title: { ... } - schema: { ... } - }> + items?: Array<{ + flow_template_id: string + entity_id: string + entity_schema: string + status: "pending" | "started" | "failed" | "skipped" | "cancelled" + execution_id?: string + error_code?: string + error_message?: string + updated_at?: string // date-time }> } ``` -### `SearchExecutionsReq` +### `BulkStartFlowsJobSummary` + +A bulk-start job as listed in the history, without its items. ```ts -type SearchExecutionsReq = { - name?: string - status?: "STARTED" | "DONE" | "CLOSED" - includeDoneWorkflows?: boolean - assignedTo?: string - sorting?: "A_Z" | "Z_A" | "DUE_DATE_ASC" | "DUE_DATE_DESC" | "TRIGGER_DATE_ASC" | "TRIGGER_DATE_DESC" - pagination?: { - orgId?: string - creationTime?: string +type BulkStartFlowsJobSummary = { + job_id: string + org_id: string + status: "preparing" | "awaiting_approval" | "queued" | "running" | "completed" | "completed_with_errors" | "failed" | "cancelled" | "expired" + created_by: string + created_by_org_id?: string + created_at: string // date-time + updated_at: string // date-time + expires_at: string // date-time + approved_at?: string // date-time + approved_by?: string + finished_at?: string // date-time + cancel_requested?: boolean + restart_of?: string + restarted_by?: string + flow: { + flow_template_id: string + flow_name: string + will_start: number + skipped: number + automatic_tasks?: Array<{ + task_id: { ... } + task_name: { ... } + task_type: { ... } + }> + } + flows?: Array<{ + flow_template_id: string + flow_name: string + will_start: number + skipped: number + automatic_tasks?: Array<{ + task_id: { ... } + task_name: { ... } + task_type: { ... } + }> + }> + entity_schema?: string + entity_ids?: string[] + entity_count: number + entities_query?: string + entities_matched?: number + failure?: { + error_code: string + message: string + } + counts: { + total: number + pending: number + started: number + failed: number + skipped: number + cancelled: number } } ``` -### `SearchExecutionsResp` +### `ListBulkStartFlowsJobsResp` ```ts -type SearchExecutionsResp = { - executions: Array<{ - id?: string - definitionId?: string - orgId?: string - name?: string - creationTime?: string - lastUpdateTime?: string - dueDate?: string - completedTime?: string - dynamicDueDate?: { - numberOfUnits: { ... } - timePeriod: { ... } - actionTypeCondition?: { ... } - stepId?: { ... } - phaseId?: { ... } +type ListBulkStartFlowsJobsResp = { + results: Array<{ + job_id: string + org_id: string + status: "preparing" | "awaiting_approval" | "queued" | "running" | "completed" | "completed_with_errors" | "failed" | "cancelled" | "expired" + created_by: string + created_by_org_id?: string + created_at: string // date-time + updated_at: string // date-time + expires_at: string // date-time + approved_at?: string // date-time + approved_by?: string + finished_at?: string // date-time + cancel_requested?: boolean + restart_of?: string + restarted_by?: string + flow: { + flow_template_id: { ... } + flow_name: { ... } + will_start: { ... } + skipped: { ... } + automatic_tasks?: { ... } } - status?: "STARTED" | "DONE" | "CLOSED" - trigger?: "MANUAL" | "AUTOMATIC" - assignedTo?: string[] - lastModifiedBy?: string - contexts?: Array<{ - id: { ... } - title: { ... } - schema: { ... } + flows?: Array<{ + flow_template_id: { ... } + flow_name: { ... } + will_start: { ... } + skipped: { ... } + automatic_tasks?: { ... } }> - nextOpenStep?: { - id?: { ... } - entityRefId?: { ... } + entity_schema?: string + entity_ids?: string[] + entity_count: number + entities_query?: string + entities_matched?: number + failure?: { + error_code: { ... } + message: { ... } + } + counts: { + total: { ... } + pending: { ... } + started: { ... } + failed: { ... } + skipped: { ... } + cancelled: { ... } } - configuredClosingReasonSnapshot?: Array<{ - id: { ... } - title: { ... } - }> - selectedClosingReasons?: Array<{ - id: { ... } - title: { ... } - }> - closingReasonDescription?: string - enableECPWorkflow?: boolean - updateEntityAttributes?: Array<{ - source: { ... } - target: { ... } - }> - version?: number - taxonomies?: string[] - singleClosingReasonSelection?: boolean - flow: Array<{ - id: { ... } - definitionId?: { ... } - name: { ... } - userIds?: { ... } - assignedTo?: { ... } - dueDate?: { ... } - dynamicDueDate?: { ... } - startedTime?: { ... } - completedTime?: { ... } - status?: { ... } - type: { ... } - steps: { ... } - taxonomies?: { ... } - } | { - id: { ... } - definitionId?: { ... } - entityRefId?: { ... } - name: { ... } - description?: { ... } - type: { ... } - ecp?: { ... } - installer?: { ... } - enabled?: { ... } - requirements?: { ... } - executionType?: { ... } - sectionId?: { ... } - executionId?: { ... } - userIds?: { ... } - assignedTo?: { ... } - assignedToInProgress?: { ... } - status?: { ... } - created?: { ... } - lastUpdated?: { ... } - statusLastUpdated?: { ... } - startedTime?: { ... } - completedTime?: { ... } - dueDate?: { ... } - dynamicDueDate?: { ... } - manuallyCreated?: { ... } - automationConfig?: { ... } - journey?: { ... } - taxonomies?: { ... } - }> }> - lastEvaluatedKey?: { - orgId?: string - creationTime?: string - } + next_cursor?: string } ``` -### `LastEvaluatedKey` +### `ListBulkStartFlowsJobItemsResp` ```ts -type LastEvaluatedKey = { - orgId?: string - creationTime?: string +type ListBulkStartFlowsJobItemsResp = { + results: Array<{ + flow_template_id: string + entity_id: string + entity_schema: string + status: "pending" | "started" | "failed" | "skipped" | "cancelled" + execution_id?: string + error_code?: string + error_message?: string + updated_at?: string // date-time + }> + next_cursor?: string } ``` -### `SearchStepsReq` +### `ActiveBulkStartFlowsJobResp` ```ts -type SearchStepsReq = { - executionName?: string - stepName?: string - assignedTo?: number - includeDoneWorkflows?: boolean - manuallyCreated?: boolean - status?: "OPEN" | "COMPLETE" | "NEXT_OPEN_ITEM_IN_WORKFLOW" - sorting?: "A_Z" | "Z_A" | "DUE_DATE_ASC" | "DUE_DATE_DESC" | "TRIGGER_DATE_ASC" | "TRIGGER_DATE_DESC" - pagination?: { - from?: number - size?: number +type ActiveBulkStartFlowsJobResp = { + job: { + job_id: string + org_id: string + status: "preparing" | "awaiting_approval" | "queued" | "running" | "completed" | "completed_with_errors" | "failed" | "cancelled" | "expired" + created_by: string + created_at: string // date-time + updated_at: string // date-time + expires_at: string // date-time + approved_at?: string // date-time + approved_by?: string + finished_at?: string // date-time + cancel_requested?: boolean + restart_of?: string + restarted_by?: string + flow: { + flow_template_id: { ... } + flow_name: { ... } + will_start: { ... } + skipped: { ... } + automatic_tasks?: { ... } + } + flows?: Array<{ + flow_template_id: { ... } + flow_name: { ... } + will_start: { ... } + skipped: { ... } + automatic_tasks?: { ... } + }> + entity_count: number + entity_schema?: string + entities_query?: string + entities_matched?: number + failure?: { + error_code: { ... } + message: { ... } + } + preparation?: { + phase: { ... } + matched?: { ... } + resolved: { ... } + written: { ... } + total?: { ... } + attempts: { ... } + updated_at: { ... } + } + cancelled_by?: string + counts: { + total: { ... } + pending: { ... } + started: { ... } + failed: { ... } + skipped: { ... } + cancelled: { ... } + } + items?: Array<{ + flow_template_id: { ... } + entity_id: { ... } + entity_schema: { ... } + status: { ... } + execution_id?: { ... } + error_code?: { ... } + error_message?: { ... } + updated_at?: { ... } + }> } } ``` -### `SearchSorting` +### `PatchBulkStartFlowsJobReq` ```ts -type SearchSorting = "A_Z" | "Z_A" | "DUE_DATE_ASC" | "DUE_DATE_DESC" | "TRIGGER_DATE_ASC" | "TRIGGER_DATE_DESC" +type PatchBulkStartFlowsJobReq = { + action: "APPROVE" | "CANCEL" +} ``` -### `SearchPagination` +### `PortalWorkflowsBatchSearchReq` ```ts -type SearchPagination = { - from?: number - size?: number +type PortalWorkflowsBatchSearchReq = { + entities: Array<{ + entity_id: string + entity_schema: string + }> + audience: "ecp" | "installer" | "all" } ``` -### `ExecutionPaginationDynamo` +### `PortalEntityRef` ```ts -type ExecutionPaginationDynamo = { - orgId?: string - creationTime?: string +type PortalEntityRef = { + entity_id: string + entity_schema: string } ``` -### `ErrorResp` +### `PortalWorkflowsBatchSearchResp` ```ts -type ErrorResp = { - message?: string +type PortalWorkflowsBatchSearchResp = { + results: Array<{ + entity_id: string + workflows: Array<{ + id: { ... } + definition_id?: { ... } + name: { ... } + status: { ... } + version: { ... } + created_at?: { ... } + updated_at?: { ... } + completed_at?: { ... } + due_date?: { ... } + assigned_to?: { ... } + contexts?: { ... } + is_path_complete: { ... } + tasks?: { ... } + stages?: { ... } + portal_titles?: { ... } + }> + }> } ``` -### `ClosingReasonResp` +### `EntityPortalWorkflows` + +Linearized portal workflows of a single entity ```ts -type ClosingReasonResp = { - reasons?: Array<{ +type EntityPortalWorkflows = { + entity_id: string + workflows: Array<{ id: string - title: string + definition_id?: string + name: string + status: "STARTED" | "DONE" | "CLOSED" + version: 2 | 3 + created_at?: string + updated_at?: string + completed_at?: string + due_date?: string + assigned_to?: string[] + contexts?: Array<{ + entity_id?: { ... } + entity_schema?: { ... } + is_primary?: { ... } + promoted_by_task_id?: { ... } + promoted_at?: { ... } + demoted_by_task_id?: { ... } + added_by_task_id?: { ... } + }> + is_path_complete: boolean + tasks?: Array<{ + id: { ... } + name: { ... } + status: { ... } + is_active: { ... } + start_date?: { ... } + ecp?: { ... } + installer?: { ... } + journey?: { ... } + assigned_to?: { ... } + phase_id?: { ... } + phase_name?: { ... } + stage_id?: { ... } + completed_at?: { ... } + updated_at?: { ... } + }> + stages?: Array<{ + id: { ... } + name: { ... } + description?: { ... } + status: { ... } + completed_at?: { ... } + portal_names?: { ... } + portal_descriptions?: { ... } + }> + portal_titles?: { + ecp?: { ... } + installer?: { ... } + } }> } ``` -### `PhaseInEntity` +### `PortalWorkflow` -```ts -type PhaseInEntity = { - phase_id?: string - phase_name?: string - phase_progress?: number - phase_assignees?: string[] -} -``` +A portal-facing projection of a workflow execution (V1 or V2), with the execution +graph already linearized into a flat, ordered list of portal-visible steps. -### `WorkflowInEntity` ```ts -type WorkflowInEntity = { - id?: string +type PortalWorkflow = { + id: string definition_id?: string - name?: string - status?: "STARTED" | "DONE" | "CLOSED" - assignees?: string[] - duedate?: string // date-time - last_update_time?: string // date-time - progress?: number - upcoming_tasks_assignees?: string[] - task_id?: string - task_name?: string - task_assignees?: string[] - task_duedate?: string // date-time - task_execution_type?: "MANUAL" | "AUTOMATION" - task_status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - phase_id?: string - phase_name?: string - phase_assignees?: string[] - phase_progress?: number - phases_in_progress?: Array<{ + name: string + status: "STARTED" | "DONE" | "CLOSED" + version: 2 | 3 + created_at?: string + updated_at?: string + completed_at?: string + due_date?: string + assigned_to?: string[] + contexts?: Array<{ + entity_id?: string + entity_schema?: string + is_primary?: boolean + promoted_by_task_id?: string + promoted_at?: string // date-time + demoted_by_task_id?: string + added_by_task_id?: string + }> + is_path_complete: boolean + tasks?: Array<{ + id: string + name: string + status: "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "PENDING" + is_active: boolean + start_date?: string + ecp?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + installer?: { + enabled?: { ... } + label?: { ... } + description?: { ... } + journey?: { ... } + } + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } + assigned_to?: string[] phase_id?: string phase_name?: string - phase_progress?: number - phase_assignees?: string[] + stage_id?: string + completed_at?: string + updated_at?: string }> - selected_closing_reasons?: Array<{ + stages?: Array<{ id: string - title: string - }> - closing_reason_description?: string -} -``` - -### `UpdateEntityAttributes` - -```ts -type UpdateEntityAttributes = { - source: "workflow_status" | "current_section" | "current_step" - target: { - entitySchema: string - entityAttribute: string + name: string + description?: string + status: "COMPLETED" | "IN_PROGRESS" | "UPCOMING" | "NOT_REACHED" + completed_at?: string + portal_names?: { + ecp?: { ... } + installer?: { ... } + } + portal_descriptions?: { + ecp?: { ... } + installer?: { ... } + } + }> + portal_titles?: { + ecp?: string + installer?: string } } ``` -### `EntitySync` +### `PortalWorkflowTask` + +A single portal-visible step of a linearized workflow execution ```ts -type EntitySync = { - trigger: { - event: "FlowStarted" | "FlowCompleted" | "FlowCancelled" | "FlowReopened" | "FlowDeleted" | "FlowAssigned" | "FlowDueDateChanged" | "FlowContextsChanged" | "TaskUpdated" | "CurrTaskChanged" | "TaskCompleted" | "TaskSkipped" | "TaskMarkedInProgress" | "TaskMarkedOnHold" | "PhaseUpdated" | "PhaseCompleted" | "PhaseSkipped" | "PhaseMarkedInProgress" - filter?: { - task_template_id?: { ... } - phase_template_id?: { ... } +type PortalWorkflowTask = { + id: string + name: string + status: "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "PENDING" + is_active: boolean + start_date?: string + ecp?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } - value: { - source: "workflow_name" | "workflow_status" | "workflow_assigned_to" | "task_name" | "task_status" | "task_assigned_to" | "phase_name" | "phase_status" | "phase_assigned_to" | "custom_value" - value?: string + installer?: { + enabled?: boolean + label?: string + description?: string + journey?: { + id?: { ... } + journeyId?: { ... } + name?: { ... } + portal_button_label?: { ... } + complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } + } } - target: { - entitySchema: string - entityAttribute: string + journey?: { + id?: string + journeyId?: string + name?: string + portal_button_label?: string + complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } } + assigned_to?: string[] + phase_id?: string + phase_name?: string + stage_id?: string + completed_at?: string + updated_at?: string } ``` -### `DynamicDueDate` - -set a Duedate for a step then a specific - -```ts -type DynamicDueDate = { - numberOfUnits: number - timePeriod: "minutes" | "hours" | "days" | "weeks" | "months" - actionTypeCondition?: "WORKFLOW_STARTED" | "STEP_CLOSED" | "PHASE_FINISHED" - stepId?: string - phaseId?: string -} -``` - -### `StepRequirement` - -describe the requirement for step enablement - -```ts -type StepRequirement = { - definitionId: string - type: "STEP" | "SECTION" - condition: "CLOSED" -} -``` +### `PortalWorkflowStage` -### `StartFlowReq` +A customer-facing stage of a flow execution as shown in portals, with a progress status derived from the execution's tasks. Stages form a strict total order; the array order is the stage order. ```ts -type StartFlowReq = { - flow_template_id: string - trigger?: { - type?: "MANUAL" | "AUTOMATIC" - automation_config?: { - flow_id: { ... } - execution_id?: { ... } - execution_status?: { ... } - error_reason?: { ... } - } +type PortalWorkflowStage = { + id: string + name: string + description?: string + status: "COMPLETED" | "IN_PROGRESS" | "UPCOMING" | "NOT_REACHED" + completed_at?: string + portal_names?: { + ecp?: string + installer?: string + } + portal_descriptions?: { + ecp?: string + installer?: string } - contexts: Array<{ - entity_id?: string - entity_schema?: string - is_primary?: boolean - }> - purposes?: string[] -} -``` - -### `SearchFlowsReq` - -```ts -type SearchFlowsReq = { - entity_id: string - entity_schema: string } ``` @@ -3235,8 +6446,8 @@ type PatchFlowReq = { due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } @@ -3244,6 +6455,18 @@ type PatchFlowReq = { entity_id?: string entity_schema?: string is_primary?: boolean + promoted_by_task_id?: string + promoted_at?: string // date-time + demoted_by_task_id?: string + added_by_task_id?: string + }> + visibility?: "entity_views" | "background" + visible_on?: Array<{ + entity_id: string + entity_schema?: string + kind: "context" | "display" + anchor_entity_id?: string + rule_id?: string }> } ``` @@ -3253,6 +6476,7 @@ type PatchFlowReq = { ```ts type FlowExecution = { id: string + loop_source?: "loops" | "loop_config" flow_template_id: string org_id: string name: string @@ -3261,8 +6485,8 @@ type FlowExecution = { due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } @@ -3276,15 +6500,30 @@ type FlowExecution = { completed_at?: string closed_at?: string started_by?: string + started_by_org_id?: string closed_by?: string + completed_by?: string } contexts: Array<{ entity_id?: string entity_schema?: string is_primary?: boolean + promoted_by_task_id?: string + promoted_at?: string // date-time + demoted_by_task_id?: string + added_by_task_id?: string + }> + visibility?: "entity_views" | "background" + visible_on?: Array<{ + entity_id: string + entity_schema?: string + kind: "context" | "display" + anchor_entity_id?: string + rule_id?: string }> crt_tasks: Array<{ id?: string + crt_since?: string // date-time }> phases?: Array<{ id: string @@ -3311,46 +6550,30 @@ type FlowExecution = { status_updated_at?: { ... } in_progress_by?: { ... } completed_by?: { ... } + skipped_at?: { ... } skipped_by?: { ... } + on_hold_by?: { ... } } taxonomies?: string[] loop_config?: { max_iterations: { ... } crt_iterations?: { ... } } + loop_membership?: Array<{ + loop_id: { ... } + runs_in_loop: { ... } + }> }> - tasks: Array<{ + stages?: Array<{ id: string - template_id: string name: string - description?: { - enabled?: { ... } - value?: { ... } - } - status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - due_date?: string - due_date_config?: { - duration: { ... } - unit: { ... } - type: { ... } - task_id?: { ... } - phase_id?: { ... } - } - requirements?: Array<{ - task_id?: { ... } - phase_id?: { ... } - when: { ... } - }> - assigned_to?: Array + description?: string + entry_node_id?: string + cut_edge_ids?: string[] + color?: string + portal_names?: { + ecp?: { ... } + installer?: { ... } // ... } ``` @@ -3381,7 +6604,70 @@ type FlowTrigger = { execution_id?: string execution_status?: string error_reason?: string + input_context?: { + source: { ... } + task_id?: { ... } + trigger_id?: { ... } + with_relations?: { ... } + also_pass?: { ... } + } + output_context?: { + set_as_primary?: { ... } + attach_to_contexts?: { ... } + } + heal_attempts?: number + run_for_user_id?: string + last_heal_attempted_at?: string // date-time + wait_for_journey_submission?: boolean + journey_id?: string + journey_execution?: { + execution_id?: { ... } + execution_status?: { ... } + error_reason?: { ... } + submission_entity_id?: { ... } + submission_created_at?: { ... } + wait_overridden_at?: { ... } + wait_overridden_by?: { ... } + } + eligible_closing_reason_ids?: string[] + allow_execution_note?: boolean + email_review?: { + enabled?: { ... } + allow_document_selection?: { ... } + allow_subject_and_body_edit?: { ... } + } } + trigger_id?: string + bulk_job_id?: string +} +``` + +### `ConfiguredTrigger` + +One configured trigger of the flow template, snapshotted VERBATIM onto the execution at start — conceptually the workflow-definition API's `Trigger` schema plus the `primary` flag. The trigger schema is owned by the definition service and copied through opaquely, so only the fields consumers key on + +```ts +type ConfiguredTrigger = { + id?: string + type?: string + primary?: boolean + entity_schema?: string + automation_id?: string + journey_id?: string +} +``` + +### `VisibleEntity` + +One entity a run is SHOWN on. Distinct from a context: a context is what the run reads, writes and decides against, while this only decides where people see it. Every context that is displayed also appears here. + +```ts +type VisibleEntity = { + entity_id: string + entity_schema?: string + kind: "context" | "display" + anchor_entity_id?: string + rule_id?: string } ``` @@ -3392,16 +6678,26 @@ type FlowContext = { entity_id?: string entity_schema?: string is_primary?: boolean + promoted_by_task_id?: string + promoted_at?: string // date-time + demoted_by_task_id?: string + added_by_task_id?: string } ``` ### `EntityRef` +One entity a run is bound to. `entity_id` is the identity of a context: a run never holds two contexts with the same `entity_id`. + ```ts type EntityRef = { entity_id?: string entity_schema?: string is_primary?: boolean + promoted_by_task_id?: string + promoted_at?: string // date-time + demoted_by_task_id?: string + added_by_task_id?: string } ``` @@ -3422,36 +6718,97 @@ type TaskId = string ```ts type Task = { id: string + loop_membership?: Array<{ + loop_id: string + runs_in_loop: boolean + }> template_id: string name: string description?: { enabled?: boolean value?: string } - status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" + status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" journey?: { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } + journey_prefill?: { + status: "PENDING" | "READY" | "FAILED" | "SKIPPED" + agent_execution_id?: string + dispatched_at?: string // date-time + extracted_at?: string // date-time + initial_state?: Record + field_confidence?: Record + dropped?: Array<{ + source?: { ... } + block_id?: { ... } + reason: { ... } + }> } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> + subtask_states?: Record + journey_submission?: { + submission_entity_id?: string + submitted_at?: string // date-time + } + completion_gates_reset_at?: string // date-time + journey_gate_waived_at?: string // date-time assigned_to?: Array + ecp_placeholder_assignees?: { + placeholder_ecp_customers?: string[] + placeholder_ecp_installers?: string[] + } analytics: { started_at?: string // date-time in_progress_at?: string // date-time @@ -3459,67 +6816,6 @@ type Task = { status_updated_at?: string // date-time in_progress_by?: string completed_by?: string - skipped_by?: string - } - created_at?: string // date-time - updated_at?: string // date-time - manually_created?: boolean - enabled: boolean - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - installer?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - taxonomies?: string[] - phase_id?: string - task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" - loop_config?: { - max_iterations: number - crt_iterations?: number - } -} | { - id: string - template_id: string - name: string - description?: { - enabled?: boolean - value?: string - } - status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" - journey?: { - id?: string - journeyId?: string - name?: string - complete_task_automatically?: boolean - } - due_date?: string - due_date_config?: { - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" - task_id?: string - phase_id?: string - } - requirements?: Array<{ - task_id?: string - phase_id?: string // ... } ``` @@ -3535,36 +6831,97 @@ type TaskType = "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" ```ts type ManualTask = { id: string + loop_membership?: Array<{ + loop_id: string + runs_in_loop: boolean + }> template_id: string name: string description?: { enabled?: boolean value?: string } - status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" + status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" journey?: { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } + journey_prefill?: { + status: "PENDING" | "READY" | "FAILED" | "SKIPPED" + agent_execution_id?: string + dispatched_at?: string // date-time + extracted_at?: string // date-time + initial_state?: Record + field_confidence?: Record + dropped?: Array<{ + source?: { ... } + block_id?: { ... } + reason: { ... } + }> } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> + subtask_states?: Record + journey_submission?: { + submission_entity_id?: string + submitted_at?: string // date-time + } + completion_gates_reset_at?: string // date-time + journey_gate_waived_at?: string // date-time assigned_to?: Array + ecp_placeholder_assignees?: { + placeholder_ecp_customers?: string[] + placeholder_ecp_installers?: string[] + } analytics: { started_at?: string // date-time in_progress_at?: string // date-time @@ -3572,41 +6929,7 @@ type ManualTask = { status_updated_at?: string // date-time in_progress_by?: string completed_by?: string - skipped_by?: string - } - created_at?: string // date-time - updated_at?: string // date-time - manually_created?: boolean - enabled: boolean - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - installer?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - taxonomies?: string[] - phase_id?: string - task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" - loop_config?: { - max_iterations: number - crt_iterations?: number - } + // ... } ``` @@ -3615,36 +6938,97 @@ type ManualTask = { ```ts type AutomationTask = { id: string + loop_membership?: Array<{ + loop_id: string + runs_in_loop: boolean + }> template_id: string name: string description?: { enabled?: boolean value?: string } - status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" + status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" journey?: { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } + journey_prefill?: { + status: "PENDING" | "READY" | "FAILED" | "SKIPPED" + agent_execution_id?: string + dispatched_at?: string // date-time + extracted_at?: string // date-time + initial_state?: Record + field_confidence?: Record + dropped?: Array<{ + source?: { ... } + block_id?: { ... } + reason: { ... } + }> } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> + subtask_states?: Record + journey_submission?: { + submission_entity_id?: string + submitted_at?: string // date-time + } + completion_gates_reset_at?: string // date-time + journey_gate_waived_at?: string // date-time assigned_to?: Array + ecp_placeholder_assignees?: { + placeholder_ecp_customers?: string[] + placeholder_ecp_installers?: string[] + } analytics: { started_at?: string // date-time in_progress_at?: string // date-time @@ -3652,71 +7036,18 @@ type AutomationTask = { status_updated_at?: string // date-time in_progress_by?: string completed_by?: string - skipped_by?: string - } - created_at?: string // date-time - updated_at?: string // date-time - manually_created?: boolean - enabled: boolean - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - installer?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - taxonomies?: string[] - phase_id?: string - task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" - automation_config: { - flow_id: string - execution_id?: string - execution_status?: string - error_reason?: string - } - automation_execution_id?: string - trigger_mode?: "manual" | "automatic" - schedule?: { - mode: "immediate" - } | { - mode: "delayed" - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - schedule_id?: string - } | { - mode: "relative" - direction: "before" | "after" - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - reference: { - id: { ... } - origin: { ... } - schema?: { ... } - attribute?: { ... } - } - schedule_id?: string - } - loop_config?: { - max_iterations: number // ... } ``` +### `AutomationFailurePolicy` + +What the flow does when this automation ends in a failed state. `stop` waits on the failed task until it is retried or skipped. `continue` proceeds to the next task. An absent value means `stop`. + +```ts +type AutomationFailurePolicy = "stop" | "continue" +``` + ### `LoopInfo` Information about loop iterations, when task is part of a loop branch @@ -3728,8 +7059,41 @@ type LoopInfo = { } ``` +### `LoopExecutionState` + +```ts +type LoopExecutionState = { + entry_branch_ids: string[] + exit_branch_id: string + max_iterations: number + crt_iteration?: number + target_id?: string + outer_loop_ids?: string[] + depth?: number +} +``` + +### `LoopMembership` + +```ts +type LoopMembership = { + loop_id: string + runs_in_loop: boolean +} +``` + +### `LoopOutcome` + +What taking the branch does to its decision's loop at the current count. `closes_lap` starts another iteration, `enters_body` continues inside the loop, `exits_loop` leaves it, `budget_spent` would continue it but no iterations are left, so the exit branch is taken instead. + +```ts +type LoopOutcome = "closes_lap" | "enters_body" | "exits_loop" | "budget_spent" +``` + ### `LoopConfig` +Read `loops` instead. Kept for executions started before `loops`. + ```ts type LoopConfig = { loop_branch_id: string @@ -3753,13 +7117,23 @@ type ActionSchedule = { } | { mode: "delayed" duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" schedule_id?: string + scheduled_at?: string + error_reason?: string + rescheduled?: { + schedule_id: string + original_scheduled_at: string + previous_scheduled_at: string + changed_by: string + changed_at: string + reason?: string + } } | { mode: "relative" direction: "before" | "after" duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" reference: { id: string origin: "flow_started" | "task_completed" | "trigger_entity_attribute" | "all_preceding_tasks_completed" @@ -3767,6 +7141,16 @@ type ActionSchedule = { attribute?: string } schedule_id?: string + scheduled_at?: string + error_reason?: string + rescheduled?: { + schedule_id: string + original_scheduled_at: string + previous_scheduled_at: string + changed_by: string + changed_at: string + reason?: string + } } ``` @@ -3784,8 +7168,46 @@ type ImmediateSchedule = { type DelayedSchedule = { mode: "delayed" duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" schedule_id?: string + scheduled_at?: string + error_reason?: string + rescheduled?: { + schedule_id: string + original_scheduled_at: string + previous_scheduled_at: string + changed_by: string + changed_at: string + reason?: string + } +} +``` + +### `RescheduleTaskReq` + +```ts +type RescheduleTaskReq = { + scheduled_at: string + reason?: string +} +``` + +### `ScheduleChange` + +A person moved the execution date of this booked schedule (AL-3774). +It describes the booking named by `schedule_id` only: once the task's +`schedule.schedule_id` differs (the timer fired and a reset or re-arm +booked a new one, run-now released it, a revert cleared it), the change +no longer applies a + +```ts +type ScheduleChange = { + schedule_id: string + original_scheduled_at: string + previous_scheduled_at: string + changed_by: string + changed_at: string + reason?: string } ``` @@ -3796,7 +7218,7 @@ type RelativeSchedule = { mode: "relative" direction: "before" | "after" duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" reference: { id: string origin: "flow_started" | "task_completed" | "trigger_entity_attribute" | "all_preceding_tasks_completed" @@ -3804,6 +7226,16 @@ type RelativeSchedule = { attribute?: string } schedule_id?: string + scheduled_at?: string + error_reason?: string + rescheduled?: { + schedule_id: string + original_scheduled_at: string + previous_scheduled_at: string + changed_by: string + changed_at: string + reason?: string + } } ``` @@ -3812,36 +7244,97 @@ type RelativeSchedule = { ```ts type DecisionTask = { id: string + loop_membership?: Array<{ + loop_id: string + runs_in_loop: boolean + }> template_id: string name: string description?: { enabled?: boolean value?: string } - status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" + status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" journey?: { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } + journey_prefill?: { + status: "PENDING" | "READY" | "FAILED" | "SKIPPED" + agent_execution_id?: string + dispatched_at?: string // date-time + extracted_at?: string // date-time + initial_state?: Record + field_confidence?: Record + dropped?: Array<{ + source?: { ... } + block_id?: { ... } + reason: { ... } + }> } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> + subtask_states?: Record + journey_submission?: { + submission_entity_id?: string + submitted_at?: string // date-time + } + completion_gates_reset_at?: string // date-time + journey_gate_waived_at?: string // date-time assigned_to?: Array + ecp_placeholder_assignees?: { + placeholder_ecp_customers?: string[] + placeholder_ecp_installers?: string[] + } analytics: { started_at?: string // date-time in_progress_at?: string // date-time @@ -3849,67 +7342,6 @@ type DecisionTask = { status_updated_at?: string // date-time in_progress_by?: string completed_by?: string - skipped_by?: string - } - created_at?: string // date-time - updated_at?: string // date-time - manually_created?: boolean - enabled: boolean - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - installer?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } - } - taxonomies?: string[] - phase_id?: string - task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" - trigger_mode: "manual" | "automatic" - conditions: Array<{ - id: string - branch_name: string - logical_operator: "AND" | "OR" - statements: Array<{ - id: { ... } - source: { ... } - operator: { ... } - values: { ... } - }> - evaluated_at?: string // date-time - is_met?: boolean - }> - schedule?: { - mode: "delayed" - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - schedule_id?: string - } | { - mode: "relative" - direction: "before" | "after" - duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - reference: { - id: { ... } - origin: { ... } - schema?: { ... } - attribute?: { ... } - } // ... } ``` @@ -3919,88 +7351,105 @@ type DecisionTask = { ```ts type AiAgentTask = { id: string + loop_membership?: Array<{ + loop_id: string + runs_in_loop: boolean + }> template_id: string name: string description?: { enabled?: boolean value?: string } - status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" + status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" journey?: { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } + journey_prefill?: { + status: "PENDING" | "READY" | "FAILED" | "SKIPPED" + agent_execution_id?: string + dispatched_at?: string // date-time + extracted_at?: string // date-time + initial_state?: Record + field_confidence?: Record + dropped?: Array<{ + source?: { ... } + block_id?: { ... } + reason: { ... } + }> } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> - assigned_to?: Array - analytics: { - started_at?: string // date-time - in_progress_at?: string // date-time - completed_at?: string // date-time - status_updated_at?: string // date-time - in_progress_by?: string + subtask_states?: Record + journey_submission?: { + submission_entity_id?: string + submitted_at?: string // date-time } - agent_execution?: { - execution_id?: string - execution_status?: string - error_reason?: string + completion_gates_reset_at?: string // date-time + journey_gate_waived_at?: string // date-time + assigned_to?: Array + ecp_placeholder_assignees?: { + placeholder_ecp_customers?: string[] + placeholder_ecp_installers?: string[] } - agent_execution_id?: string + analytics: { + started_at?: string // date-time + in_progress_at?: string // date-time + completed_at?: string // date-time + status_updated_at?: string // date-time + in_progress_by?: string + completed_by?: string + // ... } ``` @@ -4020,46 +7469,119 @@ type AgentConfig = { ```ts type AgentExecutionInfo = { execution_id?: string - execution_status?: string + execution_status?: "queued" | "pending" | "started" | "running" | "waiting_approval" | "approval_required" | "completed" | "failed" | "cancelled" + queued_at?: string // date-time + queued_attempts?: number error_reason?: string + outcome?: string + completion_hold?: "required_subtasks" } ``` +### `TaskAudience` + +A task audience, named after the task field holding its description: co-workers (description), end customers (ecp), installers and partners. + +```ts +type TaskAudience = "description" | "ecp" | "installer" | "partner" +``` + ### `TaskBase` ```ts type TaskBase = { id: string + loop_membership?: Array<{ + loop_id: string + runs_in_loop: boolean + }> template_id: string name: string description?: { enabled?: boolean value?: string } - status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" + status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" journey?: { id?: string journeyId?: string name?: string + portal_button_label?: string complete_task_automatically?: boolean + journey_submission_required?: boolean + context_parameters?: Array<{ + key: { ... } + value: { ... } + }> + ai_prefill?: { + enabled?: { ... } + source?: { ... } + extraction_fields?: { ... } + mappings?: { ... } + min_confidence?: { ... } + instructions?: { ... } + } + } + journey_prefill?: { + status: "PENDING" | "READY" | "FAILED" | "SKIPPED" + agent_execution_id?: string + dispatched_at?: string // date-time + extracted_at?: string // date-time + initial_state?: Record + field_confidence?: Record + dropped?: Array<{ + source?: { ... } + block_id?: { ... } + reason: { ... } + }> } due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } + start_date?: string + start_date_config?: { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string + } requirements?: Array<{ task_id?: string phase_id?: string when: "TASK_FINISHED" | "PHASE_FINISHED" }> + required?: boolean + only_assignee_can_complete?: boolean + subtasks?: Array<{ + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean + }> + subtask_states?: Record + journey_submission?: { + submission_entity_id?: string + submitted_at?: string // date-time + } + completion_gates_reset_at?: string // date-time + journey_gate_waived_at?: string // date-time assigned_to?: Array + ecp_placeholder_assignees?: { + placeholder_ecp_customers?: string[] + placeholder_ecp_installers?: string[] + } analytics: { started_at?: string // date-time in_progress_at?: string // date-time @@ -4067,37 +7589,30 @@ type TaskBase = { status_updated_at?: string // date-time in_progress_by?: string completed_by?: string - skipped_by?: string - } - created_at?: string // date-time - updated_at?: string // date-time - manually_created?: boolean - enabled: boolean - ecp?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } + // ... +} +``` + +### `Stage` + +A customer-facing progress segment layered on top of the flow graph, copied from the flow template when the execution starts. Unlike phases (internal task grouping), stages exist to communicate progress to outside users (e.g. end customers) with a title and description. Stages form a strict total or + +```ts +type Stage = { + id: string + name: string + description?: string + entry_node_id?: string + cut_edge_ids?: string[] + color?: string + portal_names?: { + ecp?: string + installer?: string } - installer?: { - enabled?: boolean - label?: string - description?: string - journey?: { - id?: { ... } - journeyId?: { ... } - name?: { ... } - complete_task_automatically?: { ... } - } + portal_descriptions?: { + ecp?: string + installer?: string } - taxonomies?: string[] - phase_id?: string - task_type: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" } ``` @@ -4113,8 +7628,8 @@ type Phase = { due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } @@ -4129,13 +7644,19 @@ type Phase = { status_updated_at?: string // date-time in_progress_by?: string completed_by?: string + skipped_at?: string // date-time skipped_by?: string + on_hold_by?: string } taxonomies?: string[] loop_config?: { max_iterations: number crt_iterations?: number } + loop_membership?: Array<{ + loop_id: string + runs_in_loop: boolean + }> } ``` @@ -4148,6 +7669,7 @@ type Edge = { to_id: string condition_id?: string none_met?: boolean + loop_id?: string } ``` @@ -4159,6 +7681,113 @@ type AutomationInfo = { execution_id?: string execution_status?: string error_reason?: string + input_context?: { + source: "main_context" | "task" | "trigger" + task_id?: string + trigger_id?: string + with_relations?: boolean + also_pass?: Array<{ + source: { ... } + } | { + source: { ... } + task_id: { ... } + }> + } + output_context?: { + set_as_primary?: boolean + attach_to_contexts?: boolean + } + heal_attempts?: number + run_for_user_id?: string + last_heal_attempted_at?: string // date-time + wait_for_journey_submission?: boolean + journey_id?: string + journey_execution?: { + execution_id?: string + execution_status?: string + error_reason?: string + submission_entity_id?: string + submission_created_at?: string // date-time + wait_overridden_at?: string // date-time + wait_overridden_by?: string + } + eligible_closing_reason_ids?: string[] + allow_execution_note?: boolean + email_review?: { + enabled?: boolean + allow_document_selection?: boolean + allow_subject_and_body_edit?: boolean + } +} +``` + +### `JourneyExecutionInfo` + +Server-managed. Tracks the journey automation execution a task in WAITING_FOR_JOURNEY_SUBMISSION is (or was) waiting on. Cleared whenever the task's automation state is reset (revert, loop-back, clear status). + +```ts +type JourneyExecutionInfo = { + execution_id?: string + execution_status?: string + error_reason?: string + submission_entity_id?: string + submission_created_at?: string // date-time + wait_overridden_at?: string // date-time + wait_overridden_by?: string +} +``` + +### `AutomationInputContext` + +Optional. Source of the entity fed into this automation task. If omitted, the run's current main context is used. + + +```ts +type AutomationInputContext = { + source: "main_context" | "task" | "trigger" + task_id?: string + trigger_id?: string + with_relations?: boolean + also_pass?: Array<{ + source: "main_context" + } | { + source: "task" + task_id: string + }> +} +``` + +### `AutomationInputExtraContextRef` + +One of the run's own entities. `main_context` = the run's current main context. + + +```ts +type AutomationInputExtraContextRef = { + source: "main_context" +} +``` + +### `AutomationInputExtraTaskRef` + +Every entity produced by an upstream task. + +```ts +type AutomationInputExtraTaskRef = { + source: "task" + task_id: string +} +``` + +### `AutomationOutputContext` + +Optional. What happens to the entity produced by this automation task (the last successful entity-producing action of its automation). + + +```ts +type AutomationOutputContext = { + set_as_primary?: boolean + attach_to_contexts?: boolean } ``` @@ -4172,7 +7801,60 @@ type AnalyticsInfo = { status_updated_at?: string // date-time in_progress_by?: string completed_by?: string + skipped_at?: string // date-time skipped_by?: string + on_hold_by?: string +} +``` + +### `ConditionResult` + +How one of a decision task's conditions stood when a loop pass closed. +`is_met: false` means the branch was evaluated and rejected; an absent +entry means it was never reached. + + +```ts +type ConditionResult = { + id: string + is_met?: boolean + evaluated_at?: string // date-time + match_normalizations?: "unicode" | "invisible" | "whitespace" | "case"[] +} +``` + +### `TaskIteration` + +A task's state as it stood at the close of one pass through a loop. The owning task and the loop key identify it, so neither id is repeated here. + +```ts +type TaskIteration = { + iteration: number + recorded_at: string // date-time + status: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" + analytics?: { + started_at?: string // date-time + in_progress_at?: string // date-time + completed_at?: string // date-time + status_updated_at?: string // date-time + in_progress_by?: string + completed_by?: string + skipped_at?: string // date-time + skipped_by?: string + on_hold_by?: string + } + automation_execution_id?: string + agent_execution_id?: string + error_reason?: string + execution_status?: string + outcome?: string + condition_results?: Array<{ + id: string + is_met?: boolean + evaluated_at?: string // date-time + match_normalizations?: "unicode" | "invisible" | "whitespace" | "case"[] + }> + schedule_id?: string } ``` @@ -4202,13 +7884,19 @@ type Condition = { attribute_type?: { ... } attribute_repeatable?: { ... } attribute_operation?: { ... } + attributes?: { ... } + attributes_match?: { ... } attribute_sub_field?: { ... } + date_offset?: { ... } } operator: "equals" | "not_equals" | "any_of" | "none_of" | "contains" | "not_contains" | "starts_with" | "ends_with" | "greater_than" | "less_than" | "greater_than_or_equals" | "less_than_or_equals" | "is_empty" | "is_not_empty" values: string[] + value_type?: "static" | "relative_date" }> evaluated_at?: string // date-time is_met?: boolean + loop_outcome?: "closes_lap" | "enters_body" | "exits_loop" | "budget_spent" + match_normalizations?: "unicode" | "invisible" | "whitespace" | "case"[] } ``` @@ -4219,17 +7907,24 @@ type Statement = { id: string source: { id?: string - origin?: "trigger" | "action" - origin_type?: "entity" | "workflow" | "journey_block" + origin?: "trigger" | "action" | "flow_runtime" + origin_type?: "entity" | "workflow" | "journey_block" | "trigger_source" | "main_context" | "flow_trait" schema?: string attribute?: string attribute_type?: "string" | "text" | "number" | "boolean" | "date" | "datetime" | "tags" | "country" | "email" | "phone" | "product" | "price" | "status" | "relation" | "multiselect" | "select" | "radio" | "relation_user" | "purpose" | "label" | "message_email_address" attribute_repeatable?: boolean attribute_operation?: "all" | "updated" | "added" | "deleted" + attributes?: string[] + attributes_match?: "any" | "all" attribute_sub_field?: string + date_offset?: { + amount?: { ... } + unit?: { ... } + } } operator: "equals" | "not_equals" | "any_of" | "none_of" | "contains" | "not_contains" | "starts_with" | "ends_with" | "greater_than" | "less_than" | "greater_than_or_equals" | "less_than_or_equals" | "is_empty" | "is_not_empty" values: string[] + value_type?: "static" | "relative_date" } ``` @@ -4238,14 +7933,20 @@ type Statement = { ```ts type EvaluationSource = { id?: string - origin?: "trigger" | "action" - origin_type?: "entity" | "workflow" | "journey_block" + origin?: "trigger" | "action" | "flow_runtime" + origin_type?: "entity" | "workflow" | "journey_block" | "trigger_source" | "main_context" | "flow_trait" schema?: string attribute?: string attribute_type?: "string" | "text" | "number" | "boolean" | "date" | "datetime" | "tags" | "country" | "email" | "phone" | "product" | "price" | "status" | "relation" | "multiselect" | "select" | "radio" | "relation_user" | "purpose" | "label" | "message_email_address" attribute_repeatable?: boolean attribute_operation?: "all" | "updated" | "added" | "deleted" + attributes?: string[] + attributes_match?: "any" | "all" attribute_sub_field?: string + date_offset?: { + amount?: number + unit?: "days" | "months" | "years" + } } ``` @@ -4257,22 +7958,35 @@ type Operator = "equals" | "not_equals" | "any_of" | "none_of" | "contains" | "n ### `DueDateConfig` -Set due date for the task based on a dynamic condition +Set due date for the task based on a dynamic condition. `START_DATE` counts from the task's own start date (AL-3678). A template may set it only on a task that has a start date; sent on a task, phase or flow without one, it is stored but has no effect, and the stored due date stays. ```ts type DueDateConfig = { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } ``` +### `StartDateConfig` + +Relative start date of a task (AL-3678): `duration` `unit` after the most recent occurrence of the reference event. `THIS_TASK_LAST_COMPLETED` is the task's own previous completion (a loop's earlier pass); there is no wait while the reference event has not happened. Durations are positive whole numb + +```ts +type StartDateConfig = { + duration: number + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "THIS_TASK_LAST_COMPLETED" + task_id?: string +} +``` + ### `TimeUnit` ```ts -type TimeUnit = "minutes" | "hours" | "days" | "weeks" | "months" +type TimeUnit = "minutes" | "hours" | "days" | "weeks" | "months" | "years" ``` ### `EnableRequirement` @@ -4287,6 +8001,31 @@ type EnableRequirement = { } ``` +### `Subtask` + +One checklist item of a task, derived from the checklist markup in the party descriptions. Identity is the stable data-subtask-id the editor mints into the markup. + +```ts +type Subtask = { + id: string + name?: string + party: "description" | "ecp" | "installer" | "partner" + required?: boolean +} +``` + +### `SubtaskState` + +Completion state of one subtask. `completed_by` and `completed_at` are server-managed — stamped when a PATCH flips `completed` to true, cleared when it flips back to false. + +```ts +type SubtaskState = { + completed: boolean + completed_by?: string + completed_at?: string // date-time +} +``` + ### `FlowTemplateId` ```ts @@ -4307,6 +8046,17 @@ The user id type UserId = string ``` +### `EcpPlaceholderAssignees` + +Server-managed, execution-only: for each customer / installer portal placeholder the task is configured with (`placeholder_ecp_customers`, `placeholder_ecp_installers`), the portal user ids it put on the task and still manages. An empty list means the placeholder matches nobody yet. Written at flow + +```ts +type EcpPlaceholderAssignees = { + placeholder_ecp_customers?: string[] + placeholder_ecp_installers?: string[] +} +``` + ### `VariableAssignment` Represents a variable assignment with its expression and optional resolved value. Used for dynamic user assignments that get resolved during workflow execution. @@ -4329,17 +8079,120 @@ type Assignees = Array ``` +### `RunTaskAutomationReq` + +The bounded choice a person makes when running a semi-automated task. Optional in full: a task that configures no choice runs from its automation's stored configuration. + +Nothing here is trusted as sent. Each input is checked against the stored task — never against the request — and is rejected unle + +```ts +type RunTaskAutomationReq = { + action_inputs?: { + cancel_flow_execution?: { + selected_closing_reason_ids: { ... } + extra_description?: { ... } + } + send_email?: { + subject?: { ... } + body?: { ... } + attachment_entity_ids?: { ... } + } + } +} +``` + +### `TaskAutomationActionInputs` + +Run-time inputs keyed by the automation action they belong to. An action whose key is absent runs entirely from its configuration. + +```ts +type TaskAutomationActionInputs = { + cancel_flow_execution?: { + selected_closing_reason_ids: string[] + extra_description?: string + } + send_email?: { + subject?: string + body?: string + attachment_entity_ids?: string[] + } +} +``` + +### `CancelFlowExecutionInputs` + +The reason the person chose for cancelling the flow. Ids only — the titles stored on the closed execution are resolved server-side from the execution's `closing_reason.configured_reasons`, so a caller cannot record a reason under a title of its own choosing. + +```ts +type CancelFlowExecutionInputs = { + selected_closing_reason_ids: string[] + extra_description?: string +} +``` + +### `TaskEmailPreview` + +The rendered email a send-email task is about to send. `subject` is what the person edits, and `body` too while `body_edit_locked` is false; the rest is shown for context and is not editable. + +```ts +type TaskEmailPreview = { + subject?: string + body?: string + to?: string[] + has_unresolved_send_time_variables?: boolean + body_edit_locked?: boolean + attachable_documents?: Array<{ + id: string + filename: string + }> + inline_images?: Array<{ + cid: string + url: string + }> +} +``` + +### `EmailReviewConfig` + +Copied from the template task at flow start. Says whether the person running this step reviews the email first, and what they may change. Anything they send that this does not permit is refused. + +```ts +type EmailReviewConfig = { + enabled?: boolean + allow_document_selection?: boolean + allow_subject_and_body_edit?: boolean +} +``` + +### `SendEmailInputs` + +The adjustments a person made to a reviewed email. Each field is accepted only when the task's `email_review` permits it; sent otherwise it is a 400, so a caller cannot rewrite an email the configurator locked. + +These are the RENDERED values, not template edits — the template is untouched and other + +```ts +type SendEmailInputs = { + subject?: string + body?: string + attachment_entity_ids?: string[] +} +``` + ### `PatchTaskReq` +Request payload for updating a task within a flow execution. +All fields are optional; only provided fields will be updated. + + ```ts type PatchTaskReq = { name?: string - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } @@ -4353,6 +8206,38 @@ type PatchTaskReq = { execution_id?: string execution_status?: string error_reason?: string + input_context?: { + source: { ... } + task_id?: { ... } + trigger_id?: { ... } + with_relations?: { ... } + also_pass?: { ... } + } + output_context?: { + set_as_primary?: { ... } + attach_to_contexts?: { ... } + } + heal_attempts?: number + run_for_user_id?: string + last_heal_attempted_at?: string // date-time + wait_for_journey_submission?: boolean + journey_id?: string + journey_execution?: { + execution_id?: { ... } + execution_status?: { ... } + error_reason?: { ... } + submission_entity_id?: { ... } + submission_created_at?: { ... } + wait_overridden_at?: { ... } + wait_overridden_by?: { ... } + } + eligible_closing_reason_ids?: string[] + allow_execution_note?: boolean + email_review?: { + enabled?: { ... } + allow_document_selection?: { ... } + allow_subject_and_body_edit?: { ... } + } } description?: { enabled?: boolean @@ -4366,7 +8251,11 @@ type PatchTaskReq = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } installer?: { @@ -4377,11 +8266,26 @@ type PatchTaskReq = { id?: { ... } journeyId?: { ... } name?: { ... } + portal_button_label?: { ... } complete_task_automatically?: { ... } + journey_submission_required?: { ... } + context_parameters?: { ... } + ai_prefill?: { ... } } } + partner?: { + enabled?: boolean + label?: string + description?: string + } + subtask_states?: Record next_condition_id?: string - revert_execution?: boolean + next_condition_ids?: string[] + // ... } ``` @@ -4393,8 +8297,8 @@ type PatchPhaseReq = { due_date?: string due_date_config?: { duration: number - unit: "minutes" | "hours" | "days" | "weeks" | "months" - type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" + unit: "minutes" | "hours" | "days" | "weeks" | "months" | "years" + type: "WORKFLOW_STARTED" | "TASK_FINISHED" | "PHASE_FINISHED" | "A_PRECEDING_TASK_COMPLETED" | "ALL_PRECEDING_TASKS_COMPLETED" | "START_DATE" task_id?: string phase_id?: string } @@ -4414,7 +8318,7 @@ type AddTaskReq = { task: { id?: string // uuid name: string - status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "ON_HOLD" | "FAILED" + status?: "UNASSIGNED" | "ASSIGNED" | "COMPLETED" | "SKIPPED" | "IN_PROGRESS" | "SCHEDULED" | "PENDING" | "CONDITION_PENDING" | "WAITING_FOR_CONFIRMATION" | "WAITING_FOR_JOURNEY_SUBMISSION" | "ON_HOLD" | "FAILED" due_date?: string due_date_config?: { duration: { ... } @@ -4433,6 +8337,17 @@ type AddTaskReq = { execution_id?: { ... } execution_status?: { ... } error_reason?: { ... } + input_context?: { ... } + output_context?: { ... } + heal_attempts?: { ... } + run_for_user_id?: { ... } + last_heal_attempted_at?: { ... } + wait_for_journey_submission?: { ... } + journey_id?: { ... } + journey_execution?: { ... } + eligible_closing_reason_ids?: { ... } + allow_execution_note?: { ... } + email_review?: { ... } } phase_id?: string task_type?: "MANUAL" | "AUTOMATION" | "DECISION" | "AI_AGENT" diff --git a/docs/sdk/overview.md b/docs/sdk/overview.md index 74c8267e..c5724576 100644 --- a/docs/sdk/overview.md +++ b/docs/sdk/overview.md @@ -108,6 +108,7 @@ See [Client Usage](client-usage.md) for all import patterns. | `epilot.consent` | `@epilot/sdk/consent` | [SDK](clients/consent.md) · [API](/api/consent) | | `epilot.customerPortal` | `@epilot/sdk/customer-portal` | [SDK](clients/customer-portal.md) · [API](/api/customer-portal) | | `epilot.dashboard` | `@epilot/sdk/dashboard` | [SDK](clients/dashboard.md) · [API](/api/dashboard) | +| `epilot.dataGovernance` | `@epilot/sdk/data-governance` | [SDK](clients/data-governance.md) · [API](/api/data-governance) | | `epilot.design` | `@epilot/sdk/design` | [SDK](clients/design.md) · [API](/api/design) | | `epilot.document` | `@epilot/sdk/document` | [SDK](clients/document.md) · [API](/api/document) | | `epilot.emailSettings` | `@epilot/sdk/email-settings` | [SDK](clients/email-settings.md) · [API](/api/email-settings) | @@ -115,7 +116,6 @@ See [Client Usage](client-usage.md) for all import patterns. | `epilot.entity` | `@epilot/sdk/entity` | [SDK](clients/entity.md) · [API](/api/entity) | | `epilot.entityMapping` | `@epilot/sdk/entity-mapping` | [SDK](clients/entity-mapping.md) · [API](/api/entity-mapping) | | `epilot.environments` | `@epilot/sdk/environments` | [SDK](clients/environments.md) · [API](/api/environments) | -| `epilot.erpIntegration` | `@epilot/sdk/erp-integration` | [SDK](clients/erp-integration.md) · [API](/api/erp-integration) | | `epilot.eventCatalog` | `@epilot/sdk/event-catalog` | [SDK](clients/event-catalog.md) · [API](/api/event-catalog) | | `epilot.file` | `@epilot/sdk/file` | [SDK](clients/file.md) · [API](/api/file) | | `epilot.journey` | `@epilot/sdk/journey` | [SDK](clients/journey.md) · [API](/api/journey) | @@ -129,7 +129,9 @@ See [Client Usage](client-usage.md) for all import patterns. | `epilot.permissions` | `@epilot/sdk/permissions` | [SDK](clients/permissions.md) · [API](/api/permissions) | | `epilot.pricing` | `@epilot/sdk/pricing` | [SDK](clients/pricing.md) · [API](/api/pricing) | | `epilot.purpose` | `@epilot/sdk/purpose` | [SDK](clients/purpose.md) · [API](/api/purpose) | +| `epilot.query` | `@epilot/sdk/query` | [SDK](clients/query.md) · [API](/api/query) | | `epilot.sharing` | `@epilot/sdk/sharing` | [SDK](clients/sharing.md) · [API](/api/sharing) | +| `epilot.snapshot` | `@epilot/sdk/snapshot` | [SDK](clients/snapshot.md) · [API](/api/snapshot) | | `epilot.submission` | `@epilot/sdk/submission` | [SDK](clients/submission.md) · [API](/api/submission) | | `epilot.targeting` | `@epilot/sdk/targeting` | [SDK](clients/targeting.md) · [API](/api/targeting) | | `epilot.templateVariables` | `@epilot/sdk/template-variables` | [SDK](clients/template-variables.md) · [API](/api/template-variables) | diff --git a/static/events/PortalUserLoggedIn.config.json b/static/events/PortalUserLoggedIn.config.json new file mode 100644 index 00000000..b3874dc4 --- /dev/null +++ b/static/events/PortalUserLoggedIn.config.json @@ -0,0 +1,158 @@ +{ + "event_name": "PortalUserLoggedIn", + "event_title": "Portal User Logged In", + "event_description": "Triggered when a user logs in to a customer or partner portal. Carries the portal user, its primary contact, the related contacts and the accounts of the primary contact.", + "event_version": "1.0", + "event_tags": [ + "builtin", + "portal", + "portal_user", + "contact", + "login" + ], + "schema_fields": { + "operation": { + "json_schema": { + "type": "string", + "enum": [ + "updateEntity" + ], + "description": "The entity operation type that triggered this event" + }, + "required": true + }, + "activity_id": { + "json_schema": { + "type": "string", + "description": "Activity ID associated with this operation (ULID)", + "example": "01F130Q52Q6MWSNS8N2AVXV4JN" + }, + "required": false + }, + "activity_type": { + "json_schema": { + "type": "string", + "description": "Activity type (e.g., EntityCreated, EntityUpdated)", + "example": "EntityUpdated" + }, + "required": false + }, + "trigger_entity": { + "json_schema": { + "type": "string", + "format": "uuid", + "description": "Entity ID of the entity that triggered this event" + }, + "required": true + }, + "portal_user_id": { + "json_schema": { + "type": "string", + "description": "ID of the portal user entity" + }, + "required": true, + "graph_source": "portal_user._id" + }, + "portal_id": { + "json_schema": { + "type": "string", + "description": "ID of the portal the user belongs to (end customer portal or partner portal)" + }, + "required": false, + "graph_source": "portal_user.portal_id" + }, + "email": { + "json_schema": { + "type": "string", + "description": "Login email address of the portal user" + }, + "required": false, + "graph_source": "portal_user.email[0].email" + }, + "contact_id": { + "json_schema": { + "type": "string", + "description": "ID of the primary contact the portal user is mapped to. Absent while the portal user is not mapped to a contact" + }, + "required": false, + "graph_source": "portal_user.mapped_contact.`$relation`[0].entity_id" + }, + "logged_in_at": { + "json_schema": { + "type": "string", + "description": "When the user logged in (ISO 8601), the `last_login` of the portal user" + }, + "required": false, + "graph_source": "portal_user.last_login" + }, + "is_first_login": { + "json_schema": { + "type": "boolean", + "description": "Whether this is the first login of the portal user" + }, + "required": false, + "graph_source": "portal_user.first_login and portal_user.last_login ? portal_user.first_login = portal_user.last_login : false" + } + }, + "entity_graph": { + "nodes": [ + { + "id": "portal_user", + "schema": "portal_user", + "cardinality": "one", + "fields": [ + "!password" + ] + }, + { + "id": "contact", + "schema": "contact", + "cardinality": "one" + }, + { + "id": "contacts", + "schema": "contact", + "cardinality": "many" + }, + { + "id": "accounts", + "schema": "account", + "cardinality": "many" + }, + { + "id": "account_contacts", + "schema": "contact", + "cardinality": "many" + } + ], + "edges": [ + { + "from": "portal_user", + "to": "contact" + }, + { + "from": "portal_user", + "to": "contacts" + }, + { + "from": "contact", + "to": "accounts" + }, + { + "from": "accounts", + "to": "account_contacts" + } + ] + }, + "entity_operation": { + "operation": [ + "updateEntity" + ], + "schema": [ + "portal_user" + ], + "attribute": [ + "last_login" + ] + } +} \ No newline at end of file diff --git a/static/events/PortalUserLoggedIn.sample.json b/static/events/PortalUserLoggedIn.sample.json new file mode 100644 index 00000000..059b50c1 --- /dev/null +++ b/static/events/PortalUserLoggedIn.sample.json @@ -0,0 +1,925 @@ +{ + "_org_id": "123", + "_event_time": "1970-01-01T00:00:00.000Z", + "_event_id": "string", + "_event_name": "PortalUserLoggedIn", + "_event_version": "1.0", + "_event_source": "string", + "_ack_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_trigger_source_type": "api", + "_trigger_source": "api_123456", + "_automation_chain": [ + "string" + ], + "_has_pending_changesets": true, + "_changeset_edit_modes": [ + "string" + ], + "_changeset_attributes": [ + "string" + ], + "_changeset_edit_modes_by_attribute": {}, + "operation": "updateEntity", + "activity_id": "01F130Q52Q6MWSNS8N2AVXV4JN", + "activity_type": "EntityUpdated", + "trigger_entity": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "portal_user_id": "string", + "portal_id": "string", + "email": "string", + "contact_id": "string", + "logged_in_at": "string", + "is_first_login": true, + "portal_user": { + "_schema": "portal_user", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "secondary_identifier": "string", + "origin": "string", + "access_status": true, + "expires_at": "2025-01-01", + "mapping_status": "Pending", + "registration_status": "Registration Pending", + "external_id": "string", + "mapped_contact": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "represents": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + }, + "contact": { + "_schema": "contact", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "salutation": "null", + "title": "null", + "first_name": "string", + "last_name": "string", + "customer_number": "string", + "birthdate": "2025-01-01", + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "phone": [ + { + "_tags": [ + "string" + ], + "phone": "+491234567890" + } + ], + "communication_preference": "postal", + "address": [ + { + "_tags": [ + "billing" + ], + "street": "Hauptstraße", + "street_number": "123", + "postal_code": "50668", + "city": "Cologne", + "country": "DE", + "additional_info": "string", + "company_name": "string", + "first_name": "string", + "last_name": "string", + "salutation": "string", + "title": "string", + "coordinates": "50.948484, 6.943147", + "plot_of_land": "string", + "plot_area": "string", + "start_date": "1970-01-01", + "end_date": "1970-01-01" + } + ], + "payment": [ + { + "type": "payment_sepa", + "data": { + "bank_name": "Deutsche Bank", + "iban": "DE89370400440532013000", + "bic_number": "DEUTDEFF", + "fullname": "John Doe" + } + } + ], + "account": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "marketing_permission": true, + "contact_owner": { + "id": "string", + "organization_id": "123", + "email": "user@example.com", + "display_name": "John Doe", + "name": "John Doe", + "preferred_language": "de", + "signature": "

Best regards,
John Doe

", + "roles": [ + "Owner" + ], + "image_uri": { + "original": "https://account-profile-images.epilot.cloud/1/avatar.png", + "thumbnail_32": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + }, + "properties": [ + { + "name": "profileImageName", + "value": "avatar.png" + } + ] + }, + "consent_email_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_sms_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_phone_call": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_print_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "portal_users": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "opportunities": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "orders": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "contracts": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "external_id": "string", + "workflows": { + "primary": { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "assignees": [ + "string" + ], + "progress": 0, + "phases_in_progress": [ + { + "phase_id": "string", + "phase_name": "string", + "phase_progress": 0 + } + ], + "last_update_time": "1970-01-01T00:00:00.000Z", + "upcoming_tasks_assignees": [ + "string" + ], + "task_id": "string", + "task_name": "string", + "task_assignees": [ + "string" + ], + "task_duedate": "1970-01-01T00:00:00.000Z", + "task_execution_type": "MANUAL", + "task_status": "UNASSIGNED", + "phase_id": "string", + "phase_name": "string", + "phase_assignees": [ + "string" + ], + "phase_progress": 0 + } + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + }, + "contacts": [ + { + "_schema": "contact", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "salutation": "null", + "title": "null", + "first_name": "string", + "last_name": "string", + "customer_number": "string", + "birthdate": "2025-01-01", + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "phone": [ + { + "_tags": [ + "string" + ], + "phone": "+491234567890" + } + ], + "communication_preference": "postal", + "address": [ + { + "_tags": [ + "billing" + ], + "street": "Hauptstraße", + "street_number": "123", + "postal_code": "50668", + "city": "Cologne", + "country": "DE", + "additional_info": "string", + "company_name": "string", + "first_name": "string", + "last_name": "string", + "salutation": "string", + "title": "string", + "coordinates": "50.948484, 6.943147", + "plot_of_land": "string", + "plot_area": "string", + "start_date": "1970-01-01", + "end_date": "1970-01-01" + } + ], + "payment": [ + { + "type": "payment_sepa", + "data": { + "bank_name": "Deutsche Bank", + "iban": "DE89370400440532013000", + "bic_number": "DEUTDEFF", + "fullname": "John Doe" + } + } + ], + "account": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "marketing_permission": true, + "contact_owner": { + "id": "string", + "organization_id": "123", + "email": "user@example.com", + "display_name": "John Doe", + "name": "John Doe", + "preferred_language": "de", + "signature": "

Best regards,
John Doe

", + "roles": [ + "Owner" + ], + "image_uri": { + "original": "https://account-profile-images.epilot.cloud/1/avatar.png", + "thumbnail_32": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + }, + "properties": [ + { + "name": "profileImageName", + "value": "avatar.png" + } + ] + }, + "consent_email_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_sms_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_phone_call": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_print_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "portal_users": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "opportunities": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "orders": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "contracts": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "external_id": "string", + "workflows": { + "primary": { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "assignees": [ + "string" + ], + "progress": 0, + "phases_in_progress": [ + { + "phase_id": "string", + "phase_name": "string", + "phase_progress": 0 + } + ], + "last_update_time": "1970-01-01T00:00:00.000Z", + "upcoming_tasks_assignees": [ + "string" + ], + "task_id": "string", + "task_name": "string", + "task_assignees": [ + "string" + ], + "task_duedate": "1970-01-01T00:00:00.000Z", + "task_execution_type": "MANUAL", + "task_status": "UNASSIGNED", + "phase_id": "string", + "phase_name": "string", + "phase_assignees": [ + "string" + ], + "phase_progress": 0 + } + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "accounts": [ + { + "_schema": "account", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "name": "string", + "customer_number": "string", + "registry_court": "string", + "registry_number": "string", + "tax_id": "string", + "tax_exemption": true, + "annual_revenue_currency": "EUR", + "annual_revenue_decimal": "123.45", + "annual_revenue": 0, + "industry": [ + "string" + ], + "company_size": "", + "website": "string", + "marketing_permission": true, + "address": [ + { + "_tags": [ + "billing" + ], + "street": "Hauptstraße", + "street_number": "123", + "postal_code": "50668", + "city": "Cologne", + "country": "DE", + "additional_info": "string", + "company_name": "string", + "first_name": "string", + "last_name": "string", + "salutation": "string", + "title": "string", + "coordinates": "50.948484, 6.943147", + "plot_of_land": "string", + "plot_area": "string", + "start_date": "1970-01-01", + "end_date": "1970-01-01" + } + ], + "payment": [ + { + "type": "payment_sepa", + "data": { + "bank_name": "Deutsche Bank", + "iban": "DE89370400440532013000", + "bic_number": "DEUTDEFF", + "fullname": "John Doe" + } + } + ], + "contacts": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "assigned_to": { + "id": "string", + "organization_id": "123", + "email": "user@example.com", + "display_name": "John Doe", + "name": "John Doe", + "preferred_language": "de", + "signature": "

Best regards,
John Doe

", + "roles": [ + "Owner" + ], + "image_uri": { + "original": "https://account-profile-images.epilot.cloud/1/avatar.png", + "thumbnail_32": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + }, + "properties": [ + { + "name": "profileImageName", + "value": "avatar.png" + } + ] + }, + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "phone": [ + { + "_tags": [ + "string" + ], + "phone": "+491234567890" + } + ], + "opportunities": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "workflows": { + "primary": { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "assignees": [ + "string" + ], + "progress": 0, + "phases_in_progress": [ + { + "phase_id": "string", + "phase_name": "string", + "phase_progress": 0 + } + ], + "last_update_time": "1970-01-01T00:00:00.000Z", + "upcoming_tasks_assignees": [ + "string" + ], + "task_id": "string", + "task_name": "string", + "task_assignees": [ + "string" + ], + "task_duedate": "1970-01-01T00:00:00.000Z", + "task_execution_type": "MANUAL", + "task_status": "UNASSIGNED", + "phase_id": "string", + "phase_name": "string", + "phase_assignees": [ + "string" + ], + "phase_progress": 0 + } + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "account_contacts": [ + { + "_schema": "contact", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "salutation": "null", + "title": "null", + "first_name": "string", + "last_name": "string", + "customer_number": "string", + "birthdate": "2025-01-01", + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "phone": [ + { + "_tags": [ + "string" + ], + "phone": "+491234567890" + } + ], + "communication_preference": "postal", + "address": [ + { + "_tags": [ + "billing" + ], + "street": "Hauptstraße", + "street_number": "123", + "postal_code": "50668", + "city": "Cologne", + "country": "DE", + "additional_info": "string", + "company_name": "string", + "first_name": "string", + "last_name": "string", + "salutation": "string", + "title": "string", + "coordinates": "50.948484, 6.943147", + "plot_of_land": "string", + "plot_area": "string", + "start_date": "1970-01-01", + "end_date": "1970-01-01" + } + ], + "payment": [ + { + "type": "payment_sepa", + "data": { + "bank_name": "Deutsche Bank", + "iban": "DE89370400440532013000", + "bic_number": "DEUTDEFF", + "fullname": "John Doe" + } + } + ], + "account": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "marketing_permission": true, + "contact_owner": { + "id": "string", + "organization_id": "123", + "email": "user@example.com", + "display_name": "John Doe", + "name": "John Doe", + "preferred_language": "de", + "signature": "

Best regards,
John Doe

", + "roles": [ + "Owner" + ], + "image_uri": { + "original": "https://account-profile-images.epilot.cloud/1/avatar.png", + "thumbnail_32": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + }, + "properties": [ + { + "name": "profileImageName", + "value": "avatar.png" + } + ] + }, + "consent_email_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_sms_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_phone_call": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_print_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "portal_users": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "opportunities": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "orders": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "contracts": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "external_id": "string", + "workflows": { + "primary": { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "assignees": [ + "string" + ], + "progress": 0, + "phases_in_progress": [ + { + "phase_id": "string", + "phase_name": "string", + "phase_progress": 0 + } + ], + "last_update_time": "1970-01-01T00:00:00.000Z", + "upcoming_tasks_assignees": [ + "string" + ], + "task_id": "string", + "task_name": "string", + "task_assignees": [ + "string" + ], + "task_duedate": "1970-01-01T00:00:00.000Z", + "task_execution_type": "MANUAL", + "task_status": "UNASSIGNED", + "phase_id": "string", + "phase_name": "string", + "phase_assignees": [ + "string" + ], + "phase_progress": 0 + } + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} \ No newline at end of file diff --git a/static/events/PortalUserLoggedIn.schema.json b/static/events/PortalUserLoggedIn.schema.json new file mode 100644 index 00000000..cac921cc --- /dev/null +++ b/static/events/PortalUserLoggedIn.schema.json @@ -0,0 +1,2054 @@ +{ + "type": "object", + "properties": { + "_org_id": { + "type": "string", + "description": "epilot tenant/organization ID", + "example": "123" + }, + "_event_time": { + "type": "string", + "format": "date-time", + "description": "ISO 8601 timestamp when event occurred" + }, + "_event_id": { + "type": "string", + "description": "Unique event identifier (ULID)" + }, + "_event_name": { + "type": "string", + "description": "Event name from catalog", + "example": "PortalUserLoggedIn" + }, + "_event_version": { + "type": "string", + "description": "Schema version number", + "example": "1.0" + }, + "_event_source": { + "type": "string", + "description": "Source that triggered the event" + }, + "_ack_id": { + "type": "string", + "format": "uuid", + "description": "Acknowledgement ID for tracking event delivery (UUID)" + }, + "_trigger_source_type": { + "type": "string", + "description": "The type of system that triggered the event. Examples: api, automation, operation, portal_user", + "example": "api" + }, + "_trigger_source": { + "type": "string", + "description": "Identifier of the specific trigger source. Examples: user ID, automation execution ID, activity ID, portal user email", + "example": "api_123456" + }, + "_automation_chain": { + "type": "array", + "items": { + "type": "string" + }, + "maxItems": 100, + "description": "Ordered automation flow ids that caused this event; propagated verbatim for automation loop prevention" + }, + "_has_pending_changesets": { + "type": "boolean", + "description": "True when the triggering entity (or meter counter) has at least one pending changeset" + }, + "_changeset_edit_modes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Distinct edit modes across the PENDING changesets — only \"external\" (synced from an external system) or \"approval\" (awaiting approval). A \"direct\" write is applied immediately, is not a pending changeset, and so never appears here." + }, + "_changeset_attributes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Keys identifying pending changesets. For attribute changesets these are attribute names (e.g. `billing_cycle`); for meter-reading changesets these are the changeset IDs from `meter._meter_readings_changeset`" + }, + "_changeset_edit_modes_by_attribute": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "not": {} + }, + { + "type": "string" + } + ] + }, + "description": "Per-key edit mode map; keys are a subset of _changeset_attributes (attribute names for entity changesets, changeset IDs for meter-reading changesets) — only those whose pending changeset has an \"external\" or \"approval\" mode. A \"direct\"/unrecognised mode is omitted here, though the key still appears in _changeset_attributes. Enables fine-grained webhook conditions such as `_changeset_edit_modes_by_attribute.billing_cycle equals approval`" + }, + "operation": { + "type": "string", + "enum": [ + "updateEntity" + ], + "description": "The entity operation type that triggered this event" + }, + "activity_id": { + "type": "string", + "description": "Activity ID associated with this operation (ULID)", + "example": "01F130Q52Q6MWSNS8N2AVXV4JN" + }, + "activity_type": { + "type": "string", + "description": "Activity type (e.g., EntityCreated, EntityUpdated)", + "example": "EntityUpdated" + }, + "trigger_entity": { + "type": "string", + "format": "uuid", + "description": "Entity ID of the entity that triggered this event" + }, + "portal_user_id": { + "type": "string", + "description": "ID of the portal user entity" + }, + "portal_id": { + "type": "string", + "description": "ID of the portal the user belongs to (end customer portal or partner portal)" + }, + "email": { + "type": "string", + "description": "Login email address of the portal user" + }, + "contact_id": { + "type": "string", + "description": "ID of the primary contact the portal user is mapped to. Absent while the portal user is not mapped to a contact" + }, + "logged_in_at": { + "type": "string", + "description": "When the user logged in (ISO 8601), the `last_login` of the portal user" + }, + "is_first_login": { + "type": "boolean", + "description": "Whether this is the first login of the portal user" + }, + "portal_user": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "portal_user", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "secondary_identifier": { + "type": "string", + "description": "Secondary Identifier" + }, + "origin": { + "type": "string", + "description": "Origin" + }, + "access_status": { + "type": "boolean", + "description": "Access Status" + }, + "expires_at": { + "type": "string", + "format": "date", + "example": "2025-01-01", + "description": "Expiration Date" + }, + "mapping_status": { + "type": "string", + "enum": [ + "Pending", + "Mapped" + ], + "description": "Mapping Status" + }, + "registration_status": { + "type": "string", + "enum": [ + "Registration Pending", + "Confirmation Email Sent", + "Registered", + "Email Update In Progress" + ], + "description": "Registration Status" + }, + "external_id": { + "type": "string", + "description": "External ID" + }, + "mapped_contact": { + "$ref": "#/definitions/BaseRelation", + "description": "Mapped Contact" + }, + "represents": { + "$ref": "#/definitions/BaseRelation", + "description": "Represents" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + }, + "description": "portal_user entity (hydrated from entity graph)" + }, + "contact": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "contact", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "salutation": { + "type": "string", + "enum": [ + "null", + "Mr.", + "Ms. / Mrs.", + "Company", + "Contact Person", + "Company/Contact Person", + "Spouse", + "Family", + "Ownership", + "Assembly", + "Other" + ], + "description": "Salutation" + }, + "title": { + "type": "string", + "enum": [ + "null", + "Dr.", + "Prof.", + "Prof. Dr." + ], + "description": "Title" + }, + "first_name": { + "type": "string", + "description": "First Name" + }, + "last_name": { + "type": "string", + "description": "Last Name" + }, + "customer_number": { + "type": "string", + "description": "Customer Number" + }, + "birthdate": { + "type": "string", + "format": "date", + "example": "2025-01-01", + "description": "Date of Birth" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "phone": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "phone": { + "type": "string", + "example": "+491234567890" + } + }, + "required": [ + "phone" + ] + }, + "description": "Phone" + }, + "communication_preference": { + "type": "string", + "enum": [ + "postal", + "portal" + ], + "description": "Standard communication method" + }, + "address": { + "type": "array", + "items": { + "type": "object", + "description": "Address attribute", + "additionalProperties": true, + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "billing" + ] + }, + "street": { + "type": "string", + "description": "The first line of the address. Typically the street address or PO Box number.", + "nullable": true, + "example": "Hauptstraße" + }, + "street_number": { + "type": "string", + "description": "The second line of the address. Typically the number of the apartment, suite, or unit.", + "nullable": true, + "example": "123" + }, + "postal_code": { + "type": "string", + "description": "The postal code for the address.", + "nullable": true, + "example": "50668" + }, + "city": { + "type": "string", + "description": "The name of the city, district, village, or town.", + "nullable": true, + "example": "Cologne" + }, + "country": { + "type": "string", + "description": "The two-letter code for the country of the address.", + "nullable": true, + "example": "DE" + }, + "additional_info": { + "type": "string", + "description": "An additional description for the address", + "nullable": true + }, + "company_name": { + "type": "string", + "description": "the company name, usually used as extra delivery instructions", + "nullable": true + }, + "first_name": { + "type": "string", + "description": "the first name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "last_name": { + "type": "string", + "description": "the last name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "salutation": { + "type": "string", + "description": "the salutation of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "title": { + "type": "string", + "description": "the title of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "coordinates": { + "type": "string", + "description": "Geographical coordinates (latitude, longitude)", + "nullable": true, + "example": "50.948484, 6.943147" + }, + "plot_of_land": { + "type": "string", + "description": "Plot of land information", + "nullable": true + }, + "plot_area": { + "type": "string", + "description": "Area of the plot", + "nullable": true + }, + "start_date": { + "type": "string", + "description": "Start date for the address", + "format": "date", + "nullable": true + }, + "end_date": { + "type": "string", + "description": "End date for the address", + "format": "date", + "nullable": true + } + } + }, + "description": "Address" + }, + "payment": { + "type": "array", + "items": { + "type": "object", + "description": "Payment method details", + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_sepa", + "payment_invoice", + "payment_cash" + ], + "example": "payment_sepa" + }, + "data": { + "type": "object", + "properties": { + "bank_name": { + "type": "string", + "example": "Deutsche Bank" + }, + "iban": { + "type": "string", + "example": "DE89370400440532013000" + }, + "bic_number": { + "type": "string", + "example": "DEUTDEFF" + }, + "fullname": { + "type": "string", + "example": "John Doe" + } + } + } + } + }, + "description": "Payment" + }, + "account": { + "$ref": "#/definitions/BaseRelation", + "description": "Account" + }, + "marketing_permission": { + "type": "boolean", + "description": "Marketing Permission" + }, + "contact_owner": { + "$ref": "#/definitions/User", + "description": "Contact Owner" + }, + "consent_email_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Email Marketing" + }, + "consent_sms_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "SMS Marketing" + }, + "consent_phone_call": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Direct Phone Marketing" + }, + "consent_print_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Print Marketing" + }, + "portal_users": { + "$ref": "#/definitions/BaseRelation", + "description": "Portal Users" + }, + "opportunities": { + "$ref": "#/definitions/BaseRelation", + "description": "Opportunities" + }, + "orders": { + "$ref": "#/definitions/BaseRelation", + "description": "Orders" + }, + "contracts": { + "$ref": "#/definitions/BaseRelation", + "description": "Contracts" + }, + "external_id": { + "type": "string", + "description": "External ID" + }, + "workflows": { + "$ref": "#/definitions/WorkflowOverview" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + }, + "description": "contact entity (hydrated from entity graph)" + }, + "contacts": { + "type": "array", + "description": "Array of contact entities (hydrated from entity graph)", + "items": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "contact", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "salutation": { + "type": "string", + "enum": [ + "null", + "Mr.", + "Ms. / Mrs.", + "Company", + "Contact Person", + "Company/Contact Person", + "Spouse", + "Family", + "Ownership", + "Assembly", + "Other" + ], + "description": "Salutation" + }, + "title": { + "type": "string", + "enum": [ + "null", + "Dr.", + "Prof.", + "Prof. Dr." + ], + "description": "Title" + }, + "first_name": { + "type": "string", + "description": "First Name" + }, + "last_name": { + "type": "string", + "description": "Last Name" + }, + "customer_number": { + "type": "string", + "description": "Customer Number" + }, + "birthdate": { + "type": "string", + "format": "date", + "example": "2025-01-01", + "description": "Date of Birth" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "phone": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "phone": { + "type": "string", + "example": "+491234567890" + } + }, + "required": [ + "phone" + ] + }, + "description": "Phone" + }, + "communication_preference": { + "type": "string", + "enum": [ + "postal", + "portal" + ], + "description": "Standard communication method" + }, + "address": { + "type": "array", + "items": { + "type": "object", + "description": "Address attribute", + "additionalProperties": true, + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "billing" + ] + }, + "street": { + "type": "string", + "description": "The first line of the address. Typically the street address or PO Box number.", + "nullable": true, + "example": "Hauptstraße" + }, + "street_number": { + "type": "string", + "description": "The second line of the address. Typically the number of the apartment, suite, or unit.", + "nullable": true, + "example": "123" + }, + "postal_code": { + "type": "string", + "description": "The postal code for the address.", + "nullable": true, + "example": "50668" + }, + "city": { + "type": "string", + "description": "The name of the city, district, village, or town.", + "nullable": true, + "example": "Cologne" + }, + "country": { + "type": "string", + "description": "The two-letter code for the country of the address.", + "nullable": true, + "example": "DE" + }, + "additional_info": { + "type": "string", + "description": "An additional description for the address", + "nullable": true + }, + "company_name": { + "type": "string", + "description": "the company name, usually used as extra delivery instructions", + "nullable": true + }, + "first_name": { + "type": "string", + "description": "the first name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "last_name": { + "type": "string", + "description": "the last name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "salutation": { + "type": "string", + "description": "the salutation of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "title": { + "type": "string", + "description": "the title of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "coordinates": { + "type": "string", + "description": "Geographical coordinates (latitude, longitude)", + "nullable": true, + "example": "50.948484, 6.943147" + }, + "plot_of_land": { + "type": "string", + "description": "Plot of land information", + "nullable": true + }, + "plot_area": { + "type": "string", + "description": "Area of the plot", + "nullable": true + }, + "start_date": { + "type": "string", + "description": "Start date for the address", + "format": "date", + "nullable": true + }, + "end_date": { + "type": "string", + "description": "End date for the address", + "format": "date", + "nullable": true + } + } + }, + "description": "Address" + }, + "payment": { + "type": "array", + "items": { + "type": "object", + "description": "Payment method details", + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_sepa", + "payment_invoice", + "payment_cash" + ], + "example": "payment_sepa" + }, + "data": { + "type": "object", + "properties": { + "bank_name": { + "type": "string", + "example": "Deutsche Bank" + }, + "iban": { + "type": "string", + "example": "DE89370400440532013000" + }, + "bic_number": { + "type": "string", + "example": "DEUTDEFF" + }, + "fullname": { + "type": "string", + "example": "John Doe" + } + } + } + } + }, + "description": "Payment" + }, + "account": { + "$ref": "#/definitions/BaseRelation", + "description": "Account" + }, + "marketing_permission": { + "type": "boolean", + "description": "Marketing Permission" + }, + "contact_owner": { + "$ref": "#/definitions/User", + "description": "Contact Owner" + }, + "consent_email_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Email Marketing" + }, + "consent_sms_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "SMS Marketing" + }, + "consent_phone_call": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Direct Phone Marketing" + }, + "consent_print_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Print Marketing" + }, + "portal_users": { + "$ref": "#/definitions/BaseRelation", + "description": "Portal Users" + }, + "opportunities": { + "$ref": "#/definitions/BaseRelation", + "description": "Opportunities" + }, + "orders": { + "$ref": "#/definitions/BaseRelation", + "description": "Orders" + }, + "contracts": { + "$ref": "#/definitions/BaseRelation", + "description": "Contracts" + }, + "external_id": { + "type": "string", + "description": "External ID" + }, + "workflows": { + "$ref": "#/definitions/WorkflowOverview" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + } + } + }, + "accounts": { + "type": "array", + "description": "Array of account entities (hydrated from entity graph)", + "items": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "account", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "name": { + "type": "string", + "description": "Company name" + }, + "customer_number": { + "type": "string", + "description": "Customer Number" + }, + "registry_court": { + "type": "string", + "description": "Registry court" + }, + "registry_number": { + "type": "string", + "description": "Registry number" + }, + "tax_id": { + "type": "string", + "description": "Tax ID" + }, + "tax_exemption": { + "type": "boolean", + "description": "Tax exemption" + }, + "annual_revenue_currency": { + "type": "string", + "description": "Three-letter ISO currency code, in lowercase. Must be a supported currency.", + "example": "EUR" + }, + "annual_revenue_decimal": { + "type": "string", + "description": "The currency value as a decimal string", + "example": "123.45" + }, + "annual_revenue": { + "type": "number", + "description": "Annual revenue" + }, + "industry": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Company industry" + }, + "company_size": { + "type": "string", + "enum": [ + "", + "1-9", + "9-49", + "50-99", + "100-249", + "250-499", + "500+" + ], + "description": "Company size" + }, + "website": { + "type": "string", + "description": "Website" + }, + "marketing_permission": { + "type": "boolean", + "description": "Marketing Permission" + }, + "address": { + "type": "array", + "items": { + "type": "object", + "description": "Address attribute", + "additionalProperties": true, + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "billing" + ] + }, + "street": { + "type": "string", + "description": "The first line of the address. Typically the street address or PO Box number.", + "nullable": true, + "example": "Hauptstraße" + }, + "street_number": { + "type": "string", + "description": "The second line of the address. Typically the number of the apartment, suite, or unit.", + "nullable": true, + "example": "123" + }, + "postal_code": { + "type": "string", + "description": "The postal code for the address.", + "nullable": true, + "example": "50668" + }, + "city": { + "type": "string", + "description": "The name of the city, district, village, or town.", + "nullable": true, + "example": "Cologne" + }, + "country": { + "type": "string", + "description": "The two-letter code for the country of the address.", + "nullable": true, + "example": "DE" + }, + "additional_info": { + "type": "string", + "description": "An additional description for the address", + "nullable": true + }, + "company_name": { + "type": "string", + "description": "the company name, usually used as extra delivery instructions", + "nullable": true + }, + "first_name": { + "type": "string", + "description": "the first name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "last_name": { + "type": "string", + "description": "the last name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "salutation": { + "type": "string", + "description": "the salutation of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "title": { + "type": "string", + "description": "the title of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "coordinates": { + "type": "string", + "description": "Geographical coordinates (latitude, longitude)", + "nullable": true, + "example": "50.948484, 6.943147" + }, + "plot_of_land": { + "type": "string", + "description": "Plot of land information", + "nullable": true + }, + "plot_area": { + "type": "string", + "description": "Area of the plot", + "nullable": true + }, + "start_date": { + "type": "string", + "description": "Start date for the address", + "format": "date", + "nullable": true + }, + "end_date": { + "type": "string", + "description": "End date for the address", + "format": "date", + "nullable": true + } + } + }, + "description": "Address" + }, + "payment": { + "type": "array", + "items": { + "type": "object", + "description": "Payment method details", + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_sepa", + "payment_invoice", + "payment_cash" + ], + "example": "payment_sepa" + }, + "data": { + "type": "object", + "properties": { + "bank_name": { + "type": "string", + "example": "Deutsche Bank" + }, + "iban": { + "type": "string", + "example": "DE89370400440532013000" + }, + "bic_number": { + "type": "string", + "example": "DEUTDEFF" + }, + "fullname": { + "type": "string", + "example": "John Doe" + } + } + } + } + }, + "description": "Payment" + }, + "contacts": { + "$ref": "#/definitions/BaseRelation", + "description": "Contacts" + }, + "assigned_to": { + "$ref": "#/definitions/User", + "description": "Assigned to" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "phone": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "phone": { + "type": "string", + "example": "+491234567890" + } + }, + "required": [ + "phone" + ] + }, + "description": "Phone" + }, + "opportunities": { + "$ref": "#/definitions/BaseRelation", + "description": "Opportunities" + }, + "workflows": { + "$ref": "#/definitions/WorkflowOverview" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + } + } + }, + "account_contacts": { + "type": "array", + "description": "Array of contact entities (hydrated from entity graph)", + "items": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "contact", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "salutation": { + "type": "string", + "enum": [ + "null", + "Mr.", + "Ms. / Mrs.", + "Company", + "Contact Person", + "Company/Contact Person", + "Spouse", + "Family", + "Ownership", + "Assembly", + "Other" + ], + "description": "Salutation" + }, + "title": { + "type": "string", + "enum": [ + "null", + "Dr.", + "Prof.", + "Prof. Dr." + ], + "description": "Title" + }, + "first_name": { + "type": "string", + "description": "First Name" + }, + "last_name": { + "type": "string", + "description": "Last Name" + }, + "customer_number": { + "type": "string", + "description": "Customer Number" + }, + "birthdate": { + "type": "string", + "format": "date", + "example": "2025-01-01", + "description": "Date of Birth" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "phone": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "phone": { + "type": "string", + "example": "+491234567890" + } + }, + "required": [ + "phone" + ] + }, + "description": "Phone" + }, + "communication_preference": { + "type": "string", + "enum": [ + "postal", + "portal" + ], + "description": "Standard communication method" + }, + "address": { + "type": "array", + "items": { + "type": "object", + "description": "Address attribute", + "additionalProperties": true, + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "billing" + ] + }, + "street": { + "type": "string", + "description": "The first line of the address. Typically the street address or PO Box number.", + "nullable": true, + "example": "Hauptstraße" + }, + "street_number": { + "type": "string", + "description": "The second line of the address. Typically the number of the apartment, suite, or unit.", + "nullable": true, + "example": "123" + }, + "postal_code": { + "type": "string", + "description": "The postal code for the address.", + "nullable": true, + "example": "50668" + }, + "city": { + "type": "string", + "description": "The name of the city, district, village, or town.", + "nullable": true, + "example": "Cologne" + }, + "country": { + "type": "string", + "description": "The two-letter code for the country of the address.", + "nullable": true, + "example": "DE" + }, + "additional_info": { + "type": "string", + "description": "An additional description for the address", + "nullable": true + }, + "company_name": { + "type": "string", + "description": "the company name, usually used as extra delivery instructions", + "nullable": true + }, + "first_name": { + "type": "string", + "description": "the first name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "last_name": { + "type": "string", + "description": "the last name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "salutation": { + "type": "string", + "description": "the salutation of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "title": { + "type": "string", + "description": "the title of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "coordinates": { + "type": "string", + "description": "Geographical coordinates (latitude, longitude)", + "nullable": true, + "example": "50.948484, 6.943147" + }, + "plot_of_land": { + "type": "string", + "description": "Plot of land information", + "nullable": true + }, + "plot_area": { + "type": "string", + "description": "Area of the plot", + "nullable": true + }, + "start_date": { + "type": "string", + "description": "Start date for the address", + "format": "date", + "nullable": true + }, + "end_date": { + "type": "string", + "description": "End date for the address", + "format": "date", + "nullable": true + } + } + }, + "description": "Address" + }, + "payment": { + "type": "array", + "items": { + "type": "object", + "description": "Payment method details", + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_sepa", + "payment_invoice", + "payment_cash" + ], + "example": "payment_sepa" + }, + "data": { + "type": "object", + "properties": { + "bank_name": { + "type": "string", + "example": "Deutsche Bank" + }, + "iban": { + "type": "string", + "example": "DE89370400440532013000" + }, + "bic_number": { + "type": "string", + "example": "DEUTDEFF" + }, + "fullname": { + "type": "string", + "example": "John Doe" + } + } + } + } + }, + "description": "Payment" + }, + "account": { + "$ref": "#/definitions/BaseRelation", + "description": "Account" + }, + "marketing_permission": { + "type": "boolean", + "description": "Marketing Permission" + }, + "contact_owner": { + "$ref": "#/definitions/User", + "description": "Contact Owner" + }, + "consent_email_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Email Marketing" + }, + "consent_sms_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "SMS Marketing" + }, + "consent_phone_call": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Direct Phone Marketing" + }, + "consent_print_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Print Marketing" + }, + "portal_users": { + "$ref": "#/definitions/BaseRelation", + "description": "Portal Users" + }, + "opportunities": { + "$ref": "#/definitions/BaseRelation", + "description": "Opportunities" + }, + "orders": { + "$ref": "#/definitions/BaseRelation", + "description": "Orders" + }, + "contracts": { + "$ref": "#/definitions/BaseRelation", + "description": "Contracts" + }, + "external_id": { + "type": "string", + "description": "External ID" + }, + "workflows": { + "$ref": "#/definitions/WorkflowOverview" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + } + } + } + }, + "required": [ + "_org_id", + "_event_time", + "_event_id", + "_event_name", + "_event_version", + "_event_source", + "_ack_id", + "operation", + "trigger_entity", + "portal_user_id" + ], + "additionalProperties": true, + "definitions": { + "PurposeAttribute": { + "type": "array", + "description": "List of purpose ids", + "items": { + "type": "string" + }, + "example": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ] + }, + "BaseUUID": { + "type": "string", + "format": "uuid", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "BaseTags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "example" + ] + }, + "BaseRelation": { + "type": "object", + "nullable": true, + "description": "Relation to another entity", + "properties": { + "$relation": { + "type": "array", + "items": { + "type": "object", + "properties": { + "entity_id": { + "$ref": "#/definitions/BaseUUID" + }, + "_tags": { + "$ref": "#/definitions/BaseTags" + } + } + } + } + } + }, + "ConsentAttribute": { + "type": "object", + "description": "Consent Management", + "properties": { + "type": { + "type": "string", + "enum": [ + "consent" + ] + }, + "topic": { + "type": "string" + }, + "identifiers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "type", + "topic" + ] + }, + "UserId": { + "description": "User's unique identifier", + "type": "string", + "readOnly": true + }, + "OrganizationId": { + "description": "Organization unique identifier", + "type": "string", + "readOnly": true, + "example": "123" + }, + "User": { + "type": "object", + "description": "User information", + "properties": { + "id": { + "$ref": "#/definitions/UserId" + }, + "organization_id": { + "$ref": "#/definitions/OrganizationId" + }, + "email": { + "type": "string", + "format": "email", + "example": "user@example.com" + }, + "display_name": { + "type": "string", + "example": "John Doe", + "deprecated": true + }, + "name": { + "type": "string", + "example": "John Doe", + "deprecated": true + }, + "preferred_language": { + "type": "string", + "example": "de", + "description": "ISO 639-1 language code" + }, + "signature": { + "type": "string", + "example": "

Best regards,
John Doe

", + "description": "HTML email signature" + }, + "roles": { + "type": "array", + "items": { + "type": "string", + "example": "Owner" + }, + "deprecated": true, + "description": "Deprecated! Please use Permissions API instead" + }, + "image_uri": { + "type": "object", + "additionalProperties": true, + "properties": { + "original": { + "type": "string", + "format": "uri", + "example": "https://account-profile-images.epilot.cloud/1/avatar.png" + }, + "thumbnail_32": { + "type": "string", + "format": "uri", + "example": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + } + }, + "nullable": true + }, + "properties": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "example": "profileImageName" + }, + "value": { + "type": "string", + "example": "avatar.png" + } + }, + "required": [ + "name", + "value" + ] + } + } + }, + "required": [ + "id", + "organization_id", + "email", + "name", + "preferred_language", + "roles", + "properties" + ] + }, + "WorkflowStatus": { + "type": "string", + "enum": [ + "STARTED", + "DONE", + "CLOSED" + ] + }, + "StepType": { + "type": "string", + "enum": [ + "MANUAL", + "AUTOMATION" + ] + }, + "StepStatus": { + "type": "string", + "enum": [ + "UNASSIGNED", + "ASSIGNED", + "COMPLETED", + "SKIPPED", + "IN_PROGRESS" + ] + }, + "PhaseInEntity": { + "type": "object", + "description": "Workflow phase information", + "properties": { + "phase_id": { + "type": "string" + }, + "phase_name": { + "type": "string" + }, + "phase_progress": { + "type": "number" + } + }, + "required": [ + "phase_id", + "phase_name", + "phase_progress" + ] + }, + "WorkflowInEntity": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "definition_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/WorkflowStatus" + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + }, + "progress": { + "type": "number" + }, + "phases_in_progress": { + "type": "array", + "items": { + "$ref": "#/definitions/PhaseInEntity" + } + }, + "last_update_time": { + "type": "string", + "format": "date-time" + }, + "upcoming_tasks_assignees": { + "type": "array", + "items": { + "type": "string" + } + }, + "task_id": { + "type": "string" + }, + "task_name": { + "type": "string" + }, + "task_assignees": { + "type": "array", + "items": { + "type": "string" + } + }, + "task_duedate": { + "type": "string", + "format": "date-time" + }, + "task_execution_type": { + "$ref": "#/definitions/StepType" + }, + "task_status": { + "$ref": "#/definitions/StepStatus" + }, + "phase_id": { + "type": "string" + }, + "phase_name": { + "type": "string" + }, + "phase_assignees": { + "type": "array", + "items": { + "type": "string" + } + }, + "phase_progress": { + "type": "number" + } + }, + "required": [ + "id", + "definition_id", + "name", + "status", + "assignees", + "last_update_time" + ] + }, + "WorkflowOverview": { + "type": "object", + "properties": { + "primary": { + "$ref": "#/definitions/WorkflowInEntity" + } + }, + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/definitions/WorkflowInEntity" + } + } + } + } +} \ No newline at end of file diff --git a/static/events/PortalUserRegistered.config.json b/static/events/PortalUserRegistered.config.json new file mode 100644 index 00000000..fc6b70f0 --- /dev/null +++ b/static/events/PortalUserRegistered.config.json @@ -0,0 +1,157 @@ +{ + "event_name": "PortalUserRegistered", + "event_title": "Portal User Registered", + "event_description": "Triggered when a user completes the registration to a customer or partner portal (confirmed email, SSO sign-up or accepted invite). Carries the portal user, its primary contact, the related contacts and the accounts of the primary contact.", + "event_version": "1.0", + "event_tags": [ + "builtin", + "portal", + "portal_user", + "contact", + "registration" + ], + "schema_fields": { + "operation": { + "json_schema": { + "type": "string", + "enum": [ + "createEntity", + "updateEntity" + ], + "description": "The entity operation type that triggered this event" + }, + "required": true + }, + "activity_id": { + "json_schema": { + "type": "string", + "description": "Activity ID associated with this operation (ULID)", + "example": "01F130Q52Q6MWSNS8N2AVXV4JN" + }, + "required": false + }, + "activity_type": { + "json_schema": { + "type": "string", + "description": "Activity type (e.g., EntityCreated, EntityUpdated)", + "example": "EntityUpdated" + }, + "required": false + }, + "trigger_entity": { + "json_schema": { + "type": "string", + "format": "uuid", + "description": "Entity ID of the entity that triggered this event" + }, + "required": true + }, + "portal_user_id": { + "json_schema": { + "type": "string", + "description": "ID of the portal user entity" + }, + "required": true, + "graph_source": "portal_user._id" + }, + "portal_id": { + "json_schema": { + "type": "string", + "description": "ID of the portal the user belongs to (end customer portal or partner portal)" + }, + "required": false, + "graph_source": "portal_user.portal_id" + }, + "email": { + "json_schema": { + "type": "string", + "description": "Login email address of the portal user" + }, + "required": false, + "graph_source": "portal_user.email[0].email" + }, + "contact_id": { + "json_schema": { + "type": "string", + "description": "ID of the primary contact the portal user is mapped to. Absent while the portal user is not mapped to a contact" + }, + "required": false, + "graph_source": "portal_user.mapped_contact.`$relation`[0].entity_id" + }, + "registration_source": { + "json_schema": { + "type": "string", + "description": "How the user registered: `portal` (email + password) or `sso` (single sign-on)" + }, + "required": false, + "graph_source": "portal_user.source" + } + }, + "entity_graph": { + "nodes": [ + { + "id": "portal_user", + "schema": "portal_user", + "cardinality": "one", + "fields": [ + "!password" + ] + }, + { + "id": "contact", + "schema": "contact", + "cardinality": "one" + }, + { + "id": "contacts", + "schema": "contact", + "cardinality": "many" + }, + { + "id": "accounts", + "schema": "account", + "cardinality": "many" + }, + { + "id": "account_contacts", + "schema": "contact", + "cardinality": "many" + } + ], + "edges": [ + { + "from": "portal_user", + "to": "contact" + }, + { + "from": "portal_user", + "to": "contacts" + }, + { + "from": "contact", + "to": "accounts" + }, + { + "from": "accounts", + "to": "account_contacts" + } + ] + }, + "entity_operation": { + "operation": [ + "createEntity", + "updateEntity" + ], + "schema": [ + "portal_user" + ], + "attribute": [ + "registration_status" + ], + "attribute_values": { + "registration_status": [ + "Registered" + ] + } + } +} \ No newline at end of file diff --git a/static/events/PortalUserRegistered.sample.json b/static/events/PortalUserRegistered.sample.json new file mode 100644 index 00000000..a1e5ff64 --- /dev/null +++ b/static/events/PortalUserRegistered.sample.json @@ -0,0 +1,924 @@ +{ + "_org_id": "123", + "_event_time": "1970-01-01T00:00:00.000Z", + "_event_id": "string", + "_event_name": "PortalUserRegistered", + "_event_version": "1.0", + "_event_source": "string", + "_ack_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_trigger_source_type": "api", + "_trigger_source": "api_123456", + "_automation_chain": [ + "string" + ], + "_has_pending_changesets": true, + "_changeset_edit_modes": [ + "string" + ], + "_changeset_attributes": [ + "string" + ], + "_changeset_edit_modes_by_attribute": {}, + "operation": "createEntity", + "activity_id": "01F130Q52Q6MWSNS8N2AVXV4JN", + "activity_type": "EntityUpdated", + "trigger_entity": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "portal_user_id": "string", + "portal_id": "string", + "email": "string", + "contact_id": "string", + "registration_source": "string", + "portal_user": { + "_schema": "portal_user", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "secondary_identifier": "string", + "origin": "string", + "access_status": true, + "expires_at": "2025-01-01", + "mapping_status": "Pending", + "registration_status": "Registration Pending", + "external_id": "string", + "mapped_contact": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "represents": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + }, + "contact": { + "_schema": "contact", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "salutation": "null", + "title": "null", + "first_name": "string", + "last_name": "string", + "customer_number": "string", + "birthdate": "2025-01-01", + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "phone": [ + { + "_tags": [ + "string" + ], + "phone": "+491234567890" + } + ], + "communication_preference": "postal", + "address": [ + { + "_tags": [ + "billing" + ], + "street": "Hauptstraße", + "street_number": "123", + "postal_code": "50668", + "city": "Cologne", + "country": "DE", + "additional_info": "string", + "company_name": "string", + "first_name": "string", + "last_name": "string", + "salutation": "string", + "title": "string", + "coordinates": "50.948484, 6.943147", + "plot_of_land": "string", + "plot_area": "string", + "start_date": "1970-01-01", + "end_date": "1970-01-01" + } + ], + "payment": [ + { + "type": "payment_sepa", + "data": { + "bank_name": "Deutsche Bank", + "iban": "DE89370400440532013000", + "bic_number": "DEUTDEFF", + "fullname": "John Doe" + } + } + ], + "account": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "marketing_permission": true, + "contact_owner": { + "id": "string", + "organization_id": "123", + "email": "user@example.com", + "display_name": "John Doe", + "name": "John Doe", + "preferred_language": "de", + "signature": "

Best regards,
John Doe

", + "roles": [ + "Owner" + ], + "image_uri": { + "original": "https://account-profile-images.epilot.cloud/1/avatar.png", + "thumbnail_32": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + }, + "properties": [ + { + "name": "profileImageName", + "value": "avatar.png" + } + ] + }, + "consent_email_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_sms_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_phone_call": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_print_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "portal_users": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "opportunities": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "orders": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "contracts": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "external_id": "string", + "workflows": { + "primary": { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "assignees": [ + "string" + ], + "progress": 0, + "phases_in_progress": [ + { + "phase_id": "string", + "phase_name": "string", + "phase_progress": 0 + } + ], + "last_update_time": "1970-01-01T00:00:00.000Z", + "upcoming_tasks_assignees": [ + "string" + ], + "task_id": "string", + "task_name": "string", + "task_assignees": [ + "string" + ], + "task_duedate": "1970-01-01T00:00:00.000Z", + "task_execution_type": "MANUAL", + "task_status": "UNASSIGNED", + "phase_id": "string", + "phase_name": "string", + "phase_assignees": [ + "string" + ], + "phase_progress": 0 + } + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + }, + "contacts": [ + { + "_schema": "contact", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "salutation": "null", + "title": "null", + "first_name": "string", + "last_name": "string", + "customer_number": "string", + "birthdate": "2025-01-01", + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "phone": [ + { + "_tags": [ + "string" + ], + "phone": "+491234567890" + } + ], + "communication_preference": "postal", + "address": [ + { + "_tags": [ + "billing" + ], + "street": "Hauptstraße", + "street_number": "123", + "postal_code": "50668", + "city": "Cologne", + "country": "DE", + "additional_info": "string", + "company_name": "string", + "first_name": "string", + "last_name": "string", + "salutation": "string", + "title": "string", + "coordinates": "50.948484, 6.943147", + "plot_of_land": "string", + "plot_area": "string", + "start_date": "1970-01-01", + "end_date": "1970-01-01" + } + ], + "payment": [ + { + "type": "payment_sepa", + "data": { + "bank_name": "Deutsche Bank", + "iban": "DE89370400440532013000", + "bic_number": "DEUTDEFF", + "fullname": "John Doe" + } + } + ], + "account": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "marketing_permission": true, + "contact_owner": { + "id": "string", + "organization_id": "123", + "email": "user@example.com", + "display_name": "John Doe", + "name": "John Doe", + "preferred_language": "de", + "signature": "

Best regards,
John Doe

", + "roles": [ + "Owner" + ], + "image_uri": { + "original": "https://account-profile-images.epilot.cloud/1/avatar.png", + "thumbnail_32": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + }, + "properties": [ + { + "name": "profileImageName", + "value": "avatar.png" + } + ] + }, + "consent_email_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_sms_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_phone_call": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_print_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "portal_users": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "opportunities": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "orders": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "contracts": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "external_id": "string", + "workflows": { + "primary": { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "assignees": [ + "string" + ], + "progress": 0, + "phases_in_progress": [ + { + "phase_id": "string", + "phase_name": "string", + "phase_progress": 0 + } + ], + "last_update_time": "1970-01-01T00:00:00.000Z", + "upcoming_tasks_assignees": [ + "string" + ], + "task_id": "string", + "task_name": "string", + "task_assignees": [ + "string" + ], + "task_duedate": "1970-01-01T00:00:00.000Z", + "task_execution_type": "MANUAL", + "task_status": "UNASSIGNED", + "phase_id": "string", + "phase_name": "string", + "phase_assignees": [ + "string" + ], + "phase_progress": 0 + } + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "accounts": [ + { + "_schema": "account", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "name": "string", + "customer_number": "string", + "registry_court": "string", + "registry_number": "string", + "tax_id": "string", + "tax_exemption": true, + "annual_revenue_currency": "EUR", + "annual_revenue_decimal": "123.45", + "annual_revenue": 0, + "industry": [ + "string" + ], + "company_size": "", + "website": "string", + "marketing_permission": true, + "address": [ + { + "_tags": [ + "billing" + ], + "street": "Hauptstraße", + "street_number": "123", + "postal_code": "50668", + "city": "Cologne", + "country": "DE", + "additional_info": "string", + "company_name": "string", + "first_name": "string", + "last_name": "string", + "salutation": "string", + "title": "string", + "coordinates": "50.948484, 6.943147", + "plot_of_land": "string", + "plot_area": "string", + "start_date": "1970-01-01", + "end_date": "1970-01-01" + } + ], + "payment": [ + { + "type": "payment_sepa", + "data": { + "bank_name": "Deutsche Bank", + "iban": "DE89370400440532013000", + "bic_number": "DEUTDEFF", + "fullname": "John Doe" + } + } + ], + "contacts": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "assigned_to": { + "id": "string", + "organization_id": "123", + "email": "user@example.com", + "display_name": "John Doe", + "name": "John Doe", + "preferred_language": "de", + "signature": "

Best regards,
John Doe

", + "roles": [ + "Owner" + ], + "image_uri": { + "original": "https://account-profile-images.epilot.cloud/1/avatar.png", + "thumbnail_32": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + }, + "properties": [ + { + "name": "profileImageName", + "value": "avatar.png" + } + ] + }, + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "phone": [ + { + "_tags": [ + "string" + ], + "phone": "+491234567890" + } + ], + "opportunities": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "workflows": { + "primary": { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "assignees": [ + "string" + ], + "progress": 0, + "phases_in_progress": [ + { + "phase_id": "string", + "phase_name": "string", + "phase_progress": 0 + } + ], + "last_update_time": "1970-01-01T00:00:00.000Z", + "upcoming_tasks_assignees": [ + "string" + ], + "task_id": "string", + "task_name": "string", + "task_assignees": [ + "string" + ], + "task_duedate": "1970-01-01T00:00:00.000Z", + "task_execution_type": "MANUAL", + "task_status": "UNASSIGNED", + "phase_id": "string", + "phase_name": "string", + "phase_assignees": [ + "string" + ], + "phase_progress": 0 + } + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ], + "account_contacts": [ + { + "_schema": "contact", + "_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "_org": "123", + "_title": "John Doe", + "_tags": [ + "family:label" + ], + "_purpose": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ], + "salutation": "null", + "title": "null", + "first_name": "string", + "last_name": "string", + "customer_number": "string", + "birthdate": "2025-01-01", + "email": [ + { + "_tags": [ + "string" + ], + "email": "user@example.com" + } + ], + "phone": [ + { + "_tags": [ + "string" + ], + "phone": "+491234567890" + } + ], + "communication_preference": "postal", + "address": [ + { + "_tags": [ + "billing" + ], + "street": "Hauptstraße", + "street_number": "123", + "postal_code": "50668", + "city": "Cologne", + "country": "DE", + "additional_info": "string", + "company_name": "string", + "first_name": "string", + "last_name": "string", + "salutation": "string", + "title": "string", + "coordinates": "50.948484, 6.943147", + "plot_of_land": "string", + "plot_area": "string", + "start_date": "1970-01-01", + "end_date": "1970-01-01" + } + ], + "payment": [ + { + "type": "payment_sepa", + "data": { + "bank_name": "Deutsche Bank", + "iban": "DE89370400440532013000", + "bic_number": "DEUTDEFF", + "fullname": "John Doe" + } + } + ], + "account": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "marketing_permission": true, + "contact_owner": { + "id": "string", + "organization_id": "123", + "email": "user@example.com", + "display_name": "John Doe", + "name": "John Doe", + "preferred_language": "de", + "signature": "

Best regards,
John Doe

", + "roles": [ + "Owner" + ], + "image_uri": { + "original": "https://account-profile-images.epilot.cloud/1/avatar.png", + "thumbnail_32": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + }, + "properties": [ + { + "name": "profileImageName", + "value": "avatar.png" + } + ] + }, + "consent_email_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_sms_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_phone_call": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "consent_print_marketing": { + "type": "consent", + "topic": "string", + "identifiers": [ + "string" + ] + }, + "portal_users": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "opportunities": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "orders": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "contracts": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "external_id": "string", + "workflows": { + "primary": { + "id": "string", + "definition_id": "string", + "name": "string", + "status": "STARTED", + "assignees": [ + "string" + ], + "progress": 0, + "phases_in_progress": [ + { + "phase_id": "string", + "phase_name": "string", + "phase_progress": 0 + } + ], + "last_update_time": "1970-01-01T00:00:00.000Z", + "upcoming_tasks_assignees": [ + "string" + ], + "task_id": "string", + "task_name": "string", + "task_assignees": [ + "string" + ], + "task_duedate": "1970-01-01T00:00:00.000Z", + "task_execution_type": "MANUAL", + "task_status": "UNASSIGNED", + "phase_id": "string", + "phase_name": "string", + "phase_assignees": [ + "string" + ], + "phase_progress": 0 + } + }, + "_files": { + "$relation": [ + { + "entity_id": "123e4567-e89b-12d3-a456-426614174000", + "_tags": [ + "example" + ] + } + ] + }, + "_created_at": "1970-01-01T00:00:00.000Z", + "_updated_at": "1970-01-01T00:00:00.000Z" + } + ] +} \ No newline at end of file diff --git a/static/events/PortalUserRegistered.schema.json b/static/events/PortalUserRegistered.schema.json new file mode 100644 index 00000000..2e11a319 --- /dev/null +++ b/static/events/PortalUserRegistered.schema.json @@ -0,0 +1,2051 @@ +{ + "type": "object", + "properties": { + "_org_id": { + "type": "string", + "description": "epilot tenant/organization ID", + "example": "123" + }, + "_event_time": { + "type": "string", + "format": "date-time", + "description": "ISO 8601 timestamp when event occurred" + }, + "_event_id": { + "type": "string", + "description": "Unique event identifier (ULID)" + }, + "_event_name": { + "type": "string", + "description": "Event name from catalog", + "example": "PortalUserRegistered" + }, + "_event_version": { + "type": "string", + "description": "Schema version number", + "example": "1.0" + }, + "_event_source": { + "type": "string", + "description": "Source that triggered the event" + }, + "_ack_id": { + "type": "string", + "format": "uuid", + "description": "Acknowledgement ID for tracking event delivery (UUID)" + }, + "_trigger_source_type": { + "type": "string", + "description": "The type of system that triggered the event. Examples: api, automation, operation, portal_user", + "example": "api" + }, + "_trigger_source": { + "type": "string", + "description": "Identifier of the specific trigger source. Examples: user ID, automation execution ID, activity ID, portal user email", + "example": "api_123456" + }, + "_automation_chain": { + "type": "array", + "items": { + "type": "string" + }, + "maxItems": 100, + "description": "Ordered automation flow ids that caused this event; propagated verbatim for automation loop prevention" + }, + "_has_pending_changesets": { + "type": "boolean", + "description": "True when the triggering entity (or meter counter) has at least one pending changeset" + }, + "_changeset_edit_modes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Distinct edit modes across the PENDING changesets — only \"external\" (synced from an external system) or \"approval\" (awaiting approval). A \"direct\" write is applied immediately, is not a pending changeset, and so never appears here." + }, + "_changeset_attributes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Keys identifying pending changesets. For attribute changesets these are attribute names (e.g. `billing_cycle`); for meter-reading changesets these are the changeset IDs from `meter._meter_readings_changeset`" + }, + "_changeset_edit_modes_by_attribute": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "not": {} + }, + { + "type": "string" + } + ] + }, + "description": "Per-key edit mode map; keys are a subset of _changeset_attributes (attribute names for entity changesets, changeset IDs for meter-reading changesets) — only those whose pending changeset has an \"external\" or \"approval\" mode. A \"direct\"/unrecognised mode is omitted here, though the key still appears in _changeset_attributes. Enables fine-grained webhook conditions such as `_changeset_edit_modes_by_attribute.billing_cycle equals approval`" + }, + "operation": { + "type": "string", + "enum": [ + "createEntity", + "updateEntity" + ], + "description": "The entity operation type that triggered this event" + }, + "activity_id": { + "type": "string", + "description": "Activity ID associated with this operation (ULID)", + "example": "01F130Q52Q6MWSNS8N2AVXV4JN" + }, + "activity_type": { + "type": "string", + "description": "Activity type (e.g., EntityCreated, EntityUpdated)", + "example": "EntityUpdated" + }, + "trigger_entity": { + "type": "string", + "format": "uuid", + "description": "Entity ID of the entity that triggered this event" + }, + "portal_user_id": { + "type": "string", + "description": "ID of the portal user entity" + }, + "portal_id": { + "type": "string", + "description": "ID of the portal the user belongs to (end customer portal or partner portal)" + }, + "email": { + "type": "string", + "description": "Login email address of the portal user" + }, + "contact_id": { + "type": "string", + "description": "ID of the primary contact the portal user is mapped to. Absent while the portal user is not mapped to a contact" + }, + "registration_source": { + "type": "string", + "description": "How the user registered: `portal` (email + password) or `sso` (single sign-on)" + }, + "portal_user": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "portal_user", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "secondary_identifier": { + "type": "string", + "description": "Secondary Identifier" + }, + "origin": { + "type": "string", + "description": "Origin" + }, + "access_status": { + "type": "boolean", + "description": "Access Status" + }, + "expires_at": { + "type": "string", + "format": "date", + "example": "2025-01-01", + "description": "Expiration Date" + }, + "mapping_status": { + "type": "string", + "enum": [ + "Pending", + "Mapped" + ], + "description": "Mapping Status" + }, + "registration_status": { + "type": "string", + "enum": [ + "Registration Pending", + "Confirmation Email Sent", + "Registered", + "Email Update In Progress" + ], + "description": "Registration Status" + }, + "external_id": { + "type": "string", + "description": "External ID" + }, + "mapped_contact": { + "$ref": "#/definitions/BaseRelation", + "description": "Mapped Contact" + }, + "represents": { + "$ref": "#/definitions/BaseRelation", + "description": "Represents" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + }, + "description": "portal_user entity (hydrated from entity graph)" + }, + "contact": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "contact", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "salutation": { + "type": "string", + "enum": [ + "null", + "Mr.", + "Ms. / Mrs.", + "Company", + "Contact Person", + "Company/Contact Person", + "Spouse", + "Family", + "Ownership", + "Assembly", + "Other" + ], + "description": "Salutation" + }, + "title": { + "type": "string", + "enum": [ + "null", + "Dr.", + "Prof.", + "Prof. Dr." + ], + "description": "Title" + }, + "first_name": { + "type": "string", + "description": "First Name" + }, + "last_name": { + "type": "string", + "description": "Last Name" + }, + "customer_number": { + "type": "string", + "description": "Customer Number" + }, + "birthdate": { + "type": "string", + "format": "date", + "example": "2025-01-01", + "description": "Date of Birth" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "phone": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "phone": { + "type": "string", + "example": "+491234567890" + } + }, + "required": [ + "phone" + ] + }, + "description": "Phone" + }, + "communication_preference": { + "type": "string", + "enum": [ + "postal", + "portal" + ], + "description": "Standard communication method" + }, + "address": { + "type": "array", + "items": { + "type": "object", + "description": "Address attribute", + "additionalProperties": true, + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "billing" + ] + }, + "street": { + "type": "string", + "description": "The first line of the address. Typically the street address or PO Box number.", + "nullable": true, + "example": "Hauptstraße" + }, + "street_number": { + "type": "string", + "description": "The second line of the address. Typically the number of the apartment, suite, or unit.", + "nullable": true, + "example": "123" + }, + "postal_code": { + "type": "string", + "description": "The postal code for the address.", + "nullable": true, + "example": "50668" + }, + "city": { + "type": "string", + "description": "The name of the city, district, village, or town.", + "nullable": true, + "example": "Cologne" + }, + "country": { + "type": "string", + "description": "The two-letter code for the country of the address.", + "nullable": true, + "example": "DE" + }, + "additional_info": { + "type": "string", + "description": "An additional description for the address", + "nullable": true + }, + "company_name": { + "type": "string", + "description": "the company name, usually used as extra delivery instructions", + "nullable": true + }, + "first_name": { + "type": "string", + "description": "the first name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "last_name": { + "type": "string", + "description": "the last name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "salutation": { + "type": "string", + "description": "the salutation of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "title": { + "type": "string", + "description": "the title of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "coordinates": { + "type": "string", + "description": "Geographical coordinates (latitude, longitude)", + "nullable": true, + "example": "50.948484, 6.943147" + }, + "plot_of_land": { + "type": "string", + "description": "Plot of land information", + "nullable": true + }, + "plot_area": { + "type": "string", + "description": "Area of the plot", + "nullable": true + }, + "start_date": { + "type": "string", + "description": "Start date for the address", + "format": "date", + "nullable": true + }, + "end_date": { + "type": "string", + "description": "End date for the address", + "format": "date", + "nullable": true + } + } + }, + "description": "Address" + }, + "payment": { + "type": "array", + "items": { + "type": "object", + "description": "Payment method details", + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_sepa", + "payment_invoice", + "payment_cash" + ], + "example": "payment_sepa" + }, + "data": { + "type": "object", + "properties": { + "bank_name": { + "type": "string", + "example": "Deutsche Bank" + }, + "iban": { + "type": "string", + "example": "DE89370400440532013000" + }, + "bic_number": { + "type": "string", + "example": "DEUTDEFF" + }, + "fullname": { + "type": "string", + "example": "John Doe" + } + } + } + } + }, + "description": "Payment" + }, + "account": { + "$ref": "#/definitions/BaseRelation", + "description": "Account" + }, + "marketing_permission": { + "type": "boolean", + "description": "Marketing Permission" + }, + "contact_owner": { + "$ref": "#/definitions/User", + "description": "Contact Owner" + }, + "consent_email_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Email Marketing" + }, + "consent_sms_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "SMS Marketing" + }, + "consent_phone_call": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Direct Phone Marketing" + }, + "consent_print_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Print Marketing" + }, + "portal_users": { + "$ref": "#/definitions/BaseRelation", + "description": "Portal Users" + }, + "opportunities": { + "$ref": "#/definitions/BaseRelation", + "description": "Opportunities" + }, + "orders": { + "$ref": "#/definitions/BaseRelation", + "description": "Orders" + }, + "contracts": { + "$ref": "#/definitions/BaseRelation", + "description": "Contracts" + }, + "external_id": { + "type": "string", + "description": "External ID" + }, + "workflows": { + "$ref": "#/definitions/WorkflowOverview" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + }, + "description": "contact entity (hydrated from entity graph)" + }, + "contacts": { + "type": "array", + "description": "Array of contact entities (hydrated from entity graph)", + "items": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "contact", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "salutation": { + "type": "string", + "enum": [ + "null", + "Mr.", + "Ms. / Mrs.", + "Company", + "Contact Person", + "Company/Contact Person", + "Spouse", + "Family", + "Ownership", + "Assembly", + "Other" + ], + "description": "Salutation" + }, + "title": { + "type": "string", + "enum": [ + "null", + "Dr.", + "Prof.", + "Prof. Dr." + ], + "description": "Title" + }, + "first_name": { + "type": "string", + "description": "First Name" + }, + "last_name": { + "type": "string", + "description": "Last Name" + }, + "customer_number": { + "type": "string", + "description": "Customer Number" + }, + "birthdate": { + "type": "string", + "format": "date", + "example": "2025-01-01", + "description": "Date of Birth" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "phone": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "phone": { + "type": "string", + "example": "+491234567890" + } + }, + "required": [ + "phone" + ] + }, + "description": "Phone" + }, + "communication_preference": { + "type": "string", + "enum": [ + "postal", + "portal" + ], + "description": "Standard communication method" + }, + "address": { + "type": "array", + "items": { + "type": "object", + "description": "Address attribute", + "additionalProperties": true, + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "billing" + ] + }, + "street": { + "type": "string", + "description": "The first line of the address. Typically the street address or PO Box number.", + "nullable": true, + "example": "Hauptstraße" + }, + "street_number": { + "type": "string", + "description": "The second line of the address. Typically the number of the apartment, suite, or unit.", + "nullable": true, + "example": "123" + }, + "postal_code": { + "type": "string", + "description": "The postal code for the address.", + "nullable": true, + "example": "50668" + }, + "city": { + "type": "string", + "description": "The name of the city, district, village, or town.", + "nullable": true, + "example": "Cologne" + }, + "country": { + "type": "string", + "description": "The two-letter code for the country of the address.", + "nullable": true, + "example": "DE" + }, + "additional_info": { + "type": "string", + "description": "An additional description for the address", + "nullable": true + }, + "company_name": { + "type": "string", + "description": "the company name, usually used as extra delivery instructions", + "nullable": true + }, + "first_name": { + "type": "string", + "description": "the first name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "last_name": { + "type": "string", + "description": "the last name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "salutation": { + "type": "string", + "description": "the salutation of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "title": { + "type": "string", + "description": "the title of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "coordinates": { + "type": "string", + "description": "Geographical coordinates (latitude, longitude)", + "nullable": true, + "example": "50.948484, 6.943147" + }, + "plot_of_land": { + "type": "string", + "description": "Plot of land information", + "nullable": true + }, + "plot_area": { + "type": "string", + "description": "Area of the plot", + "nullable": true + }, + "start_date": { + "type": "string", + "description": "Start date for the address", + "format": "date", + "nullable": true + }, + "end_date": { + "type": "string", + "description": "End date for the address", + "format": "date", + "nullable": true + } + } + }, + "description": "Address" + }, + "payment": { + "type": "array", + "items": { + "type": "object", + "description": "Payment method details", + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_sepa", + "payment_invoice", + "payment_cash" + ], + "example": "payment_sepa" + }, + "data": { + "type": "object", + "properties": { + "bank_name": { + "type": "string", + "example": "Deutsche Bank" + }, + "iban": { + "type": "string", + "example": "DE89370400440532013000" + }, + "bic_number": { + "type": "string", + "example": "DEUTDEFF" + }, + "fullname": { + "type": "string", + "example": "John Doe" + } + } + } + } + }, + "description": "Payment" + }, + "account": { + "$ref": "#/definitions/BaseRelation", + "description": "Account" + }, + "marketing_permission": { + "type": "boolean", + "description": "Marketing Permission" + }, + "contact_owner": { + "$ref": "#/definitions/User", + "description": "Contact Owner" + }, + "consent_email_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Email Marketing" + }, + "consent_sms_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "SMS Marketing" + }, + "consent_phone_call": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Direct Phone Marketing" + }, + "consent_print_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Print Marketing" + }, + "portal_users": { + "$ref": "#/definitions/BaseRelation", + "description": "Portal Users" + }, + "opportunities": { + "$ref": "#/definitions/BaseRelation", + "description": "Opportunities" + }, + "orders": { + "$ref": "#/definitions/BaseRelation", + "description": "Orders" + }, + "contracts": { + "$ref": "#/definitions/BaseRelation", + "description": "Contracts" + }, + "external_id": { + "type": "string", + "description": "External ID" + }, + "workflows": { + "$ref": "#/definitions/WorkflowOverview" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + } + } + }, + "accounts": { + "type": "array", + "description": "Array of account entities (hydrated from entity graph)", + "items": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "account", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "name": { + "type": "string", + "description": "Company name" + }, + "customer_number": { + "type": "string", + "description": "Customer Number" + }, + "registry_court": { + "type": "string", + "description": "Registry court" + }, + "registry_number": { + "type": "string", + "description": "Registry number" + }, + "tax_id": { + "type": "string", + "description": "Tax ID" + }, + "tax_exemption": { + "type": "boolean", + "description": "Tax exemption" + }, + "annual_revenue_currency": { + "type": "string", + "description": "Three-letter ISO currency code, in lowercase. Must be a supported currency.", + "example": "EUR" + }, + "annual_revenue_decimal": { + "type": "string", + "description": "The currency value as a decimal string", + "example": "123.45" + }, + "annual_revenue": { + "type": "number", + "description": "Annual revenue" + }, + "industry": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Company industry" + }, + "company_size": { + "type": "string", + "enum": [ + "", + "1-9", + "9-49", + "50-99", + "100-249", + "250-499", + "500+" + ], + "description": "Company size" + }, + "website": { + "type": "string", + "description": "Website" + }, + "marketing_permission": { + "type": "boolean", + "description": "Marketing Permission" + }, + "address": { + "type": "array", + "items": { + "type": "object", + "description": "Address attribute", + "additionalProperties": true, + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "billing" + ] + }, + "street": { + "type": "string", + "description": "The first line of the address. Typically the street address or PO Box number.", + "nullable": true, + "example": "Hauptstraße" + }, + "street_number": { + "type": "string", + "description": "The second line of the address. Typically the number of the apartment, suite, or unit.", + "nullable": true, + "example": "123" + }, + "postal_code": { + "type": "string", + "description": "The postal code for the address.", + "nullable": true, + "example": "50668" + }, + "city": { + "type": "string", + "description": "The name of the city, district, village, or town.", + "nullable": true, + "example": "Cologne" + }, + "country": { + "type": "string", + "description": "The two-letter code for the country of the address.", + "nullable": true, + "example": "DE" + }, + "additional_info": { + "type": "string", + "description": "An additional description for the address", + "nullable": true + }, + "company_name": { + "type": "string", + "description": "the company name, usually used as extra delivery instructions", + "nullable": true + }, + "first_name": { + "type": "string", + "description": "the first name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "last_name": { + "type": "string", + "description": "the last name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "salutation": { + "type": "string", + "description": "the salutation of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "title": { + "type": "string", + "description": "the title of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "coordinates": { + "type": "string", + "description": "Geographical coordinates (latitude, longitude)", + "nullable": true, + "example": "50.948484, 6.943147" + }, + "plot_of_land": { + "type": "string", + "description": "Plot of land information", + "nullable": true + }, + "plot_area": { + "type": "string", + "description": "Area of the plot", + "nullable": true + }, + "start_date": { + "type": "string", + "description": "Start date for the address", + "format": "date", + "nullable": true + }, + "end_date": { + "type": "string", + "description": "End date for the address", + "format": "date", + "nullable": true + } + } + }, + "description": "Address" + }, + "payment": { + "type": "array", + "items": { + "type": "object", + "description": "Payment method details", + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_sepa", + "payment_invoice", + "payment_cash" + ], + "example": "payment_sepa" + }, + "data": { + "type": "object", + "properties": { + "bank_name": { + "type": "string", + "example": "Deutsche Bank" + }, + "iban": { + "type": "string", + "example": "DE89370400440532013000" + }, + "bic_number": { + "type": "string", + "example": "DEUTDEFF" + }, + "fullname": { + "type": "string", + "example": "John Doe" + } + } + } + } + }, + "description": "Payment" + }, + "contacts": { + "$ref": "#/definitions/BaseRelation", + "description": "Contacts" + }, + "assigned_to": { + "$ref": "#/definitions/User", + "description": "Assigned to" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "phone": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "phone": { + "type": "string", + "example": "+491234567890" + } + }, + "required": [ + "phone" + ] + }, + "description": "Phone" + }, + "opportunities": { + "$ref": "#/definitions/BaseRelation", + "description": "Opportunities" + }, + "workflows": { + "$ref": "#/definitions/WorkflowOverview" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + } + } + }, + "account_contacts": { + "type": "array", + "description": "Array of contact entities (hydrated from entity graph)", + "items": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "_schema" + ], + "properties": { + "_schema": { + "readOnly": true, + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "example": "contact", + "description": "URL-friendly identifier for the entity schema" + }, + "_id": { + "readOnly": true, + "type": "string", + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": "Unique identifier for the entity" + }, + "_org": { + "type": "string", + "description": "Organization Id the entity belongs to", + "readOnly": true, + "example": "123" + }, + "_title": { + "readOnly": true, + "type": "string", + "nullable": true, + "example": "John Doe", + "description": "Generated title for the entity based on schema title_template" + }, + "_tags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "family:label" + ], + "description": "Entity Labels" + }, + "_purpose": { + "$ref": "#/definitions/PurposeAttribute", + "description": "Purposes" + }, + "salutation": { + "type": "string", + "enum": [ + "null", + "Mr.", + "Ms. / Mrs.", + "Company", + "Contact Person", + "Company/Contact Person", + "Spouse", + "Family", + "Ownership", + "Assembly", + "Other" + ], + "description": "Salutation" + }, + "title": { + "type": "string", + "enum": [ + "null", + "Dr.", + "Prof.", + "Prof. Dr." + ], + "description": "Title" + }, + "first_name": { + "type": "string", + "description": "First Name" + }, + "last_name": { + "type": "string", + "description": "Last Name" + }, + "customer_number": { + "type": "string", + "description": "Customer Number" + }, + "birthdate": { + "type": "string", + "format": "date", + "example": "2025-01-01", + "description": "Date of Birth" + }, + "email": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ] + }, + "description": "Email" + }, + "phone": { + "type": "array", + "items": { + "type": "object", + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "phone": { + "type": "string", + "example": "+491234567890" + } + }, + "required": [ + "phone" + ] + }, + "description": "Phone" + }, + "communication_preference": { + "type": "string", + "enum": [ + "postal", + "portal" + ], + "description": "Standard communication method" + }, + "address": { + "type": "array", + "items": { + "type": "object", + "description": "Address attribute", + "additionalProperties": true, + "properties": { + "_tags": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "billing" + ] + }, + "street": { + "type": "string", + "description": "The first line of the address. Typically the street address or PO Box number.", + "nullable": true, + "example": "Hauptstraße" + }, + "street_number": { + "type": "string", + "description": "The second line of the address. Typically the number of the apartment, suite, or unit.", + "nullable": true, + "example": "123" + }, + "postal_code": { + "type": "string", + "description": "The postal code for the address.", + "nullable": true, + "example": "50668" + }, + "city": { + "type": "string", + "description": "The name of the city, district, village, or town.", + "nullable": true, + "example": "Cologne" + }, + "country": { + "type": "string", + "description": "The two-letter code for the country of the address.", + "nullable": true, + "example": "DE" + }, + "additional_info": { + "type": "string", + "description": "An additional description for the address", + "nullable": true + }, + "company_name": { + "type": "string", + "description": "the company name, usually used as extra delivery instructions", + "nullable": true + }, + "first_name": { + "type": "string", + "description": "the first name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "last_name": { + "type": "string", + "description": "the last name of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "salutation": { + "type": "string", + "description": "the salutation of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "title": { + "type": "string", + "description": "the title of the recipient, usually used as extra delivery instructions", + "nullable": true + }, + "coordinates": { + "type": "string", + "description": "Geographical coordinates (latitude, longitude)", + "nullable": true, + "example": "50.948484, 6.943147" + }, + "plot_of_land": { + "type": "string", + "description": "Plot of land information", + "nullable": true + }, + "plot_area": { + "type": "string", + "description": "Area of the plot", + "nullable": true + }, + "start_date": { + "type": "string", + "description": "Start date for the address", + "format": "date", + "nullable": true + }, + "end_date": { + "type": "string", + "description": "End date for the address", + "format": "date", + "nullable": true + } + } + }, + "description": "Address" + }, + "payment": { + "type": "array", + "items": { + "type": "object", + "description": "Payment method details", + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_sepa", + "payment_invoice", + "payment_cash" + ], + "example": "payment_sepa" + }, + "data": { + "type": "object", + "properties": { + "bank_name": { + "type": "string", + "example": "Deutsche Bank" + }, + "iban": { + "type": "string", + "example": "DE89370400440532013000" + }, + "bic_number": { + "type": "string", + "example": "DEUTDEFF" + }, + "fullname": { + "type": "string", + "example": "John Doe" + } + } + } + } + }, + "description": "Payment" + }, + "account": { + "$ref": "#/definitions/BaseRelation", + "description": "Account" + }, + "marketing_permission": { + "type": "boolean", + "description": "Marketing Permission" + }, + "contact_owner": { + "$ref": "#/definitions/User", + "description": "Contact Owner" + }, + "consent_email_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Email Marketing" + }, + "consent_sms_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "SMS Marketing" + }, + "consent_phone_call": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Direct Phone Marketing" + }, + "consent_print_marketing": { + "$ref": "#/definitions/ConsentAttribute", + "description": "Print Marketing" + }, + "portal_users": { + "$ref": "#/definitions/BaseRelation", + "description": "Portal Users" + }, + "opportunities": { + "$ref": "#/definitions/BaseRelation", + "description": "Opportunities" + }, + "orders": { + "$ref": "#/definitions/BaseRelation", + "description": "Orders" + }, + "contracts": { + "$ref": "#/definitions/BaseRelation", + "description": "Contracts" + }, + "external_id": { + "type": "string", + "description": "External ID" + }, + "workflows": { + "$ref": "#/definitions/WorkflowOverview" + }, + "_files": { + "$ref": "#/definitions/BaseRelation" + }, + "_created_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity creation" + }, + "_updated_at": { + "readOnly": true, + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of entity last update" + } + } + } + } + }, + "required": [ + "_org_id", + "_event_time", + "_event_id", + "_event_name", + "_event_version", + "_event_source", + "_ack_id", + "operation", + "trigger_entity", + "portal_user_id" + ], + "additionalProperties": true, + "definitions": { + "PurposeAttribute": { + "type": "array", + "description": "List of purpose ids", + "items": { + "type": "string" + }, + "example": [ + "7675dc56-fd1b-46ee-9c35-defe0667b32e" + ] + }, + "BaseUUID": { + "type": "string", + "format": "uuid", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + "BaseTags": { + "type": "array", + "nullable": true, + "items": { + "type": "string" + }, + "example": [ + "example" + ] + }, + "BaseRelation": { + "type": "object", + "nullable": true, + "description": "Relation to another entity", + "properties": { + "$relation": { + "type": "array", + "items": { + "type": "object", + "properties": { + "entity_id": { + "$ref": "#/definitions/BaseUUID" + }, + "_tags": { + "$ref": "#/definitions/BaseTags" + } + } + } + } + } + }, + "ConsentAttribute": { + "type": "object", + "description": "Consent Management", + "properties": { + "type": { + "type": "string", + "enum": [ + "consent" + ] + }, + "topic": { + "type": "string" + }, + "identifiers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "type", + "topic" + ] + }, + "UserId": { + "description": "User's unique identifier", + "type": "string", + "readOnly": true + }, + "OrganizationId": { + "description": "Organization unique identifier", + "type": "string", + "readOnly": true, + "example": "123" + }, + "User": { + "type": "object", + "description": "User information", + "properties": { + "id": { + "$ref": "#/definitions/UserId" + }, + "organization_id": { + "$ref": "#/definitions/OrganizationId" + }, + "email": { + "type": "string", + "format": "email", + "example": "user@example.com" + }, + "display_name": { + "type": "string", + "example": "John Doe", + "deprecated": true + }, + "name": { + "type": "string", + "example": "John Doe", + "deprecated": true + }, + "preferred_language": { + "type": "string", + "example": "de", + "description": "ISO 639-1 language code" + }, + "signature": { + "type": "string", + "example": "

Best regards,
John Doe

", + "description": "HTML email signature" + }, + "roles": { + "type": "array", + "items": { + "type": "string", + "example": "Owner" + }, + "deprecated": true, + "description": "Deprecated! Please use Permissions API instead" + }, + "image_uri": { + "type": "object", + "additionalProperties": true, + "properties": { + "original": { + "type": "string", + "format": "uri", + "example": "https://account-profile-images.epilot.cloud/1/avatar.png" + }, + "thumbnail_32": { + "type": "string", + "format": "uri", + "example": "https://account-profile-images.epilot.cloud/1/avatar_32x32.png" + } + }, + "nullable": true + }, + "properties": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "example": "profileImageName" + }, + "value": { + "type": "string", + "example": "avatar.png" + } + }, + "required": [ + "name", + "value" + ] + } + } + }, + "required": [ + "id", + "organization_id", + "email", + "name", + "preferred_language", + "roles", + "properties" + ] + }, + "WorkflowStatus": { + "type": "string", + "enum": [ + "STARTED", + "DONE", + "CLOSED" + ] + }, + "StepType": { + "type": "string", + "enum": [ + "MANUAL", + "AUTOMATION" + ] + }, + "StepStatus": { + "type": "string", + "enum": [ + "UNASSIGNED", + "ASSIGNED", + "COMPLETED", + "SKIPPED", + "IN_PROGRESS" + ] + }, + "PhaseInEntity": { + "type": "object", + "description": "Workflow phase information", + "properties": { + "phase_id": { + "type": "string" + }, + "phase_name": { + "type": "string" + }, + "phase_progress": { + "type": "number" + } + }, + "required": [ + "phase_id", + "phase_name", + "phase_progress" + ] + }, + "WorkflowInEntity": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "definition_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/WorkflowStatus" + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + }, + "progress": { + "type": "number" + }, + "phases_in_progress": { + "type": "array", + "items": { + "$ref": "#/definitions/PhaseInEntity" + } + }, + "last_update_time": { + "type": "string", + "format": "date-time" + }, + "upcoming_tasks_assignees": { + "type": "array", + "items": { + "type": "string" + } + }, + "task_id": { + "type": "string" + }, + "task_name": { + "type": "string" + }, + "task_assignees": { + "type": "array", + "items": { + "type": "string" + } + }, + "task_duedate": { + "type": "string", + "format": "date-time" + }, + "task_execution_type": { + "$ref": "#/definitions/StepType" + }, + "task_status": { + "$ref": "#/definitions/StepStatus" + }, + "phase_id": { + "type": "string" + }, + "phase_name": { + "type": "string" + }, + "phase_assignees": { + "type": "array", + "items": { + "type": "string" + } + }, + "phase_progress": { + "type": "number" + } + }, + "required": [ + "id", + "definition_id", + "name", + "status", + "assignees", + "last_update_time" + ] + }, + "WorkflowOverview": { + "type": "object", + "properties": { + "primary": { + "$ref": "#/definitions/WorkflowInEntity" + } + }, + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/definitions/WorkflowInEntity" + } + } + } + } +} \ No newline at end of file