diff --git a/clients/chat-client/README.md b/clients/chat-client/README.md index 29f98e1f..d4709532 100644 --- a/clients/chat-client/README.md +++ b/clients/chat-client/README.md @@ -1,6 +1,6 @@ # @epilot/chat-client -Generated TypeScript client for epilot Chat API widget management and public chat. +Generated TypeScript client for epilot Chat API Website Chat management and public chat. ## Usage @@ -9,13 +9,13 @@ import { createClient } from '@epilot/chat-client'; const chat = createClient(); chat.defaults.headers.common.Authorization = `Bearer ${accessToken}`; -const { data } = await chat.listChatWidgets(); -const { data: widget } = await chat.getChatWidget({ widget_id }); +const { data } = await chat.listWebsiteChats(); +const { data: websiteChat } = await chat.getWebsiteChat({ website_chat_id }); -await chat.updateChatWidget({ widget_id }, { - version: widget.version, - website_chat: { - ...widget.website_chat, +await chat.updateWebsiteChat({ website_chat_id }, { + version: websiteChat.version, + settings: { + ...websiteChat.settings, design_id, authentication: { email_code: { email_template_id } }, }, @@ -27,10 +27,12 @@ The same API is available as `epilot.chat` from `@epilot/sdk`, or through the for callers that want a shared singleton. Use a separate `createClient()` instance for anonymous chat. Bootstrap and session -creation use no epilot access token; `sendAnonymousChatMessage` uses the anonymous -session token. Its response is SSE: request `responseType: 'stream'` in Node and -consume the stream, or use a streaming fetch transport in the browser. The client -does not parse SSE events or implement the host/iframe handoff protocol. +creation use no epilot access token; `sendAnonymousChatMessage` and the email +verification operations (`getChatVerification`, `startChatEmailVerification`, +`verifyChatEmailCode`, `cancelChatVerification`) use the anonymous session token. +`sendAnonymousChatMessage` responds with SSE: request `responseType: 'stream'` in +Node and consume the stream, or use a streaming fetch transport in the browser. The +client does not parse SSE events or implement the host/iframe handoff protocol. ## Regeneration diff --git a/clients/chat-client/package.json b/clients/chat-client/package.json index c923465f..b982dc97 100644 --- a/clients/chat-client/package.json +++ b/clients/chat-client/package.json @@ -1,6 +1,6 @@ { "name": "@epilot/chat-client", - "version": "0.1.1", + "version": "0.2.0", "description": "Client for the epilot Chat API", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -19,7 +19,7 @@ "keywords": [ "epilot", "chat", - "widgets" + "website-chat" ], "scripts": { "test": "vitest run", diff --git a/clients/chat-client/src/client.test.ts b/clients/chat-client/src/client.test.ts index 7beed596..9497ee44 100644 --- a/clients/chat-client/src/client.test.ts +++ b/clients/chat-client/src/client.test.ts @@ -9,33 +9,38 @@ describe('Chat client', () => { expect(client.defaults.baseURL).toBe('https://chat.sls.epilot.io'); expect(client.api.getOperations().map((operation) => operation.operationId)).toEqual( expect.arrayContaining([ - 'listChatWidgets', - 'createChatWidget', - 'getChatWidget', - 'updateChatWidget', - 'deleteChatWidget', - 'getPublicChatWidget', + 'listWebsiteChats', + 'createWebsiteChat', + 'getWebsiteChat', + 'updateWebsiteChat', + 'deleteWebsiteChat', + 'getPublicWebsiteChat', 'createPublicChatGrant', 'createAnonymousChatSession', 'sendAnonymousChatMessage', + 'getChatVerification', + 'startChatEmailVerification', + 'verifyChatEmailCode', + 'cancelChatVerification', ]), ); - expect(definition.paths['/v1/widgets'].get.security).toEqual([{ EpilotAuth: [] }]); + expect(definition.paths['/v1/website-chats'].get.security).toEqual([{ EpilotAuth: [] }]); expect(definition.paths['/v1/bootstrap'].post.security).toEqual([]); expect(definition.paths['/v1/sessions'].post.security).toEqual([]); - expect(definition.paths['/v1/widgets/{widget_id}/configuration'].get.security).toEqual([]); + expect(definition.paths['/v1/website-chats/{website_chat_id}/configuration'].get.security).toEqual([]); expect(definition.paths['/v1/messages'].post.security).toEqual([{ AnonymousSession: [] }]); + expect(definition.paths['/v1/verification/code'].post.security).toEqual([{ AnonymousSession: [] }]); expect(definition.components.responses.Error.content['application/json'].schema.properties.code.enum).toContain( 'SESSION_EXPIRED', ); expect(definition.components.schemas.Error.properties).not.toHaveProperty('code'); }); - it('encodes a widget update and preserves design and email verification settings', async () => { + it('encodes a Website Chat update and preserves design and email verification settings', async () => { const client = createClient(); - const payload: Components.Schemas.UpdateChatWidgetRequest = { + const payload: Components.Schemas.UpdateWebsiteChatRequest = { version: 1, - website_chat: { + settings: { allowed_origins: ['https://example.com'], organisation_name: 'Example Energy', default_locale: 'en', @@ -45,12 +50,18 @@ describe('Chat client', () => { }; client.defaults.adapter = async (config) => { expect(config.method).toBe('put'); - expect(config.url).toBe('/v1/widgets/widget-1'); + expect(config.url).toBe('/v1/website-chats/website-chat-1'); expect(JSON.parse(config.data)).toEqual(payload); - return { config, data: { widget_id: 'widget-1', ...payload }, status: 200, statusText: 'OK', headers: {} }; + return { + config, + data: { website_chat_id: 'website-chat-1', ...payload }, + status: 200, + statusText: 'OK', + headers: {}, + }; }; - const response = await client.updateChatWidget({ widget_id: 'widget-1' }, payload); - expect(response.data.website_chat.design_id).toBe(payload.website_chat?.design_id); + const response = await client.updateWebsiteChat({ website_chat_id: 'website-chat-1' }, payload); + expect(response.data.settings.design_id).toBe(payload.settings?.design_id); }); it('can isolate an anonymous session from the authenticated management singleton', () => { diff --git a/clients/chat-client/src/openapi-runtime.json b/clients/chat-client/src/openapi-runtime.json index 53a16714..d2deb912 100644 --- a/clients/chat-client/src/openapi-runtime.json +++ b/clients/chat-client/src/openapi-runtime.json @@ -10,9 +10,9 @@ } ], "paths": { - "/v1/widgets": { + "/v1/website-chats": { "get": { - "operationId": "listChatWidgets", + "operationId": "listWebsiteChats", "responses": {}, "parameters": [ { @@ -22,7 +22,7 @@ ] }, "post": { - "operationId": "createChatWidget", + "operationId": "createWebsiteChat", "responses": {}, "requestBody": { "required": true, @@ -32,20 +32,20 @@ } } }, - "/v1/widgets/{widget_id}": { + "/v1/website-chats/{website_chat_id}": { "parameters": [ { "in": "path", - "name": "widget_id", + "name": "website_chat_id", "required": true } ], "get": { - "operationId": "getChatWidget", + "operationId": "getWebsiteChat", "responses": {} }, "put": { - "operationId": "updateChatWidget", + "operationId": "updateWebsiteChat", "responses": {}, "requestBody": { "required": true, @@ -55,7 +55,7 @@ } }, "delete": { - "operationId": "deleteChatWidget", + "operationId": "deleteWebsiteChat", "responses": {}, "parameters": [ { @@ -66,13 +66,13 @@ ] } }, - "/v1/widgets/{widget_id}/configuration": { + "/v1/website-chats/{website_chat_id}/configuration": { "get": { - "operationId": "getPublicChatWidget", + "operationId": "getPublicWebsiteChat", "parameters": [ { "in": "path", - "name": "widget_id", + "name": "website_chat_id", "required": true } ], @@ -114,6 +114,42 @@ }, "responses": {} } + }, + "/v1/verification": { + "get": { + "operationId": "getChatVerification", + "responses": {} + } + }, + "/v1/verification/email": { + "post": { + "operationId": "startChatEmailVerification", + "requestBody": { + "required": true, + "content": { + "application/json": {} + } + }, + "responses": {} + } + }, + "/v1/verification/code": { + "post": { + "operationId": "verifyChatEmailCode", + "requestBody": { + "required": true, + "content": { + "application/json": {} + } + }, + "responses": {} + } + }, + "/v1/verification/cancel": { + "post": { + "operationId": "cancelChatVerification", + "responses": {} + } } }, "components": { diff --git a/clients/chat-client/src/openapi.d.ts b/clients/chat-client/src/openapi.d.ts index 5376bcc9..2e91623e 100644 --- a/clients/chat-client/src/openapi.d.ts +++ b/clients/chat-client/src/openapi.d.ts @@ -9,16 +9,16 @@ import type { declare namespace Components { namespace Responses { export interface Error { - code: "INVALID_REQUEST" | "ORIGIN_DENIED" | "NOT_FOUND" | "INVALID_GRANT" | "SESSION_EXPIRED" | "RATE_LIMITED" | "SESSION_LIMIT" | "USAGE_LIMIT" | "REQUEST_CONFLICT" | "IN_PROGRESS" | "UNAVAILABLE" | "TEMPORARILY_UNAVAILABLE"; + 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"; } } namespace Schemas { - export interface ChatWidget { + export interface CreateWebsiteChatRequest { name: string; agent_id: string | null; // uuid - website_chat: { + settings: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -75,99 +75,7 @@ declare namespace Components { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. - */ - design_id?: string | null; // uuid - /** - * Email Builder template selection. Does not enable verification by itself. - */ - authentication?: { - email_code: { - email_template_id?: string | null; // uuid - }; - } | null; - }; - /** - * Stable public embed identifier, independent of the assigned agent. Not a credential. - */ - widget_id: string; // uuid - org_id: string; - /** - * Server-owned session binding; changes on reassignment or allowed-origin changes. - */ - binding_id: string; // uuid - version: number; - created_at: string; // date-time - updated_at: string; // date-time - website_chat_embed: { - script_url: string; // uri - chat_api_origin: string; // uri - demo_url: string; // uri - }; - } - export interface CreateChatWidgetRequest { - name: string; - agent_id: string | null; // uuid - website_chat: { - /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. - */ - allowed_origins: [ - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string?, - string? - ]; - organisation_name: string; - default_locale: "en" | "de"; - /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -187,13 +95,13 @@ declare namespace Components { [key: string]: any; }; } - export interface ListChatWidgetsResponse { - widgets: { + export interface ListWebsiteChatsResponse { + website_chats: { name: string; agent_id: string | null; // uuid - website_chat: { + settings: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -250,7 +158,7 @@ declare namespace Components { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -265,7 +173,7 @@ declare namespace Components { /** * Stable public embed identifier, independent of the assigned agent. Not a credential. */ - widget_id: string; // uuid + website_chat_id: string; // uuid org_id: string; /** * Server-owned session binding; changes on reassignment or allowed-origin changes. @@ -274,7 +182,7 @@ declare namespace Components { version: number; created_at: string; // date-time updated_at: string; // date-time - website_chat_embed: { + embed: { script_url: string; // uri chat_api_origin: string; // uri demo_url: string; // uri @@ -283,7 +191,7 @@ declare namespace Components { next_cursor?: string; } export interface PublicChatError { - code: "INVALID_REQUEST" | "ORIGIN_DENIED" | "NOT_FOUND" | "INVALID_GRANT" | "SESSION_EXPIRED" | "RATE_LIMITED" | "SESSION_LIMIT" | "USAGE_LIMIT" | "REQUEST_CONFLICT" | "IN_PROGRESS" | "UNAVAILABLE" | "TEMPORARILY_UNAVAILABLE"; + 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"; } /** * JSON payload of one SSE data frame from sendAnonymousChatMessage. @@ -301,12 +209,58 @@ declare namespace Components { code: "UNAVAILABLE"; request_id: string; // uuid }; - export interface UpdateChatWidgetRequest { + export interface PublicWebsiteChat { + key: string; + organisationName: string; + assistantName: string; + defaultLocale: "en" | "de"; + authentication?: { + email_code: boolean; + }; + design?: { + id: string; // uuid + last_modified_at?: string; + style?: { + palette?: { + primary?: string; + background?: string; + }; + typography?: { + font?: { + font_family?: string; + }; + }; + shape?: { + border_radius?: number; + }; + }; + 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; + }; + }; + locales: ("en" | "de")[]; + } + export interface UpdateWebsiteChatRequest { name?: string; agent_id?: string | null; // uuid - website_chat?: { + settings?: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -363,7 +317,7 @@ declare namespace Components { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -380,9 +334,153 @@ declare namespace Components { */ version: number; } + export interface VerificationState { + available: boolean; + conversation_id: string; // uuid + status: "anonymous" | "sending" | "pending" | "verified"; + challenge_id?: string; // uuid + /** + * Unix seconds + */ + code_expires_at?: number; + /** + * Unix seconds + */ + resend_after?: number; + email?: string; // email + contact_resolution?: "matched" | "ambiguous" | "not_found"; + } + export interface WebsiteChat { + name: string; + agent_id: string | null; // uuid + settings: { + /** + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. + */ + allowed_origins: [ + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string?, + string? + ]; + organisation_name: string; + default_locale: "en" | "de"; + /** + * Design Builder configuration for the Website Chat only. + */ + design_id?: string | null; // uuid + /** + * Email Builder template selection. Does not enable verification by itself. + */ + authentication?: { + email_code: { + email_template_id?: string | null; // uuid + }; + } | null; + }; + /** + * Stable public embed identifier, independent of the assigned agent. Not a credential. + */ + website_chat_id: string; // uuid + org_id: string; + /** + * Server-owned session binding; changes on reassignment or allowed-origin changes. + */ + 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 + }; + } + export interface WebsiteChatDesign { + id: string; // uuid + last_modified_at?: string; + style?: { + palette?: { + primary?: string; + background?: string; + }; + typography?: { + font?: { + font_family?: string; + }; + }; + shape?: { + border_radius?: number; + }; + }; + 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; + }; + } export interface WebsiteChatSettings { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -439,100 +537,44 @@ declare namespace Components { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** * Email Builder template selection. Does not enable verification by itself. - */ - authentication?: { - email_code: { - email_template_id?: string | null; // uuid - }; - } | null; - } - export interface Widget { - key: string; - organisationName: string; - assistantName: string; - defaultLocale: "en" | "de"; - design?: { - id: string; // uuid - last_modified_at?: string; - style?: { - palette?: { - primary?: string; - background?: string; - }; - typography?: { - font?: { - font_family?: string; - }; - }; - shape?: { - border_radius?: number; - }; - }; - 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; - }; - }; - locales: ("en" | "de")[]; - } - export interface WidgetDesign { - id: string; // uuid - last_modified_at?: string; - style?: { - palette?: { - primary?: string; - background?: string; - }; - typography?: { - font?: { - font_family?: string; - }; - }; - shape?: { - border_radius?: number; - }; - }; - 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; - }; + */ + authentication?: { + email_code: { + email_template_id?: string | null; // uuid + }; + } | null; } } } declare namespace Paths { + namespace CancelChatVerification { + namespace Responses { + export interface $200 { + available: boolean; + conversation_id: string; // uuid + status: "anonymous" | "sending" | "pending" | "verified"; + challenge_id?: string; // uuid + /** + * Unix seconds + */ + code_expires_at?: number; + /** + * Unix seconds + */ + resend_after?: number; + email?: string; // email + contact_resolution?: "matched" | "ambiguous" | "not_found"; + } + export interface Default { + 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"; + } + } + } namespace CreateAnonymousChatSession { export interface RequestBody { grant: string; // ^[A-Za-z0-9_-]{43}$ @@ -545,11 +587,14 @@ declare namespace Paths { * Unix seconds */ expires_at: number; - widget: { + website_chat: { key: string; organisationName: string; assistantName: string; defaultLocale: "en" | "de"; + authentication?: { + email_code: boolean; + }; design?: { id: string; // uuid last_modified_at?: string; @@ -590,17 +635,36 @@ declare namespace Paths { }; } export interface Default { - code: "INVALID_REQUEST" | "ORIGIN_DENIED" | "NOT_FOUND" | "INVALID_GRANT" | "SESSION_EXPIRED" | "RATE_LIMITED" | "SESSION_LIMIT" | "USAGE_LIMIT" | "REQUEST_CONFLICT" | "IN_PROGRESS" | "UNAVAILABLE" | "TEMPORARILY_UNAVAILABLE"; + 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"; + } + } + } + namespace CreatePublicChatGrant { + export interface RequestBody { + website_chat_id: string; // ^[a-zA-Z0-9_-]{1,100}$ + } + namespace Responses { + export interface $201 { + grant: string; + /** + * example: + * 60 + */ + expires_in: number; + frame_origin: string; // uri + } + export interface Default { + 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"; } } } - namespace CreateChatWidget { + namespace CreateWebsiteChat { export interface RequestBody { name: string; agent_id: string | null; // uuid - website_chat: { + settings: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -657,7 +721,7 @@ declare namespace Paths { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -674,9 +738,9 @@ declare namespace Paths { export interface $201 { name: string; agent_id: string | null; // uuid - website_chat: { + settings: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -733,7 +797,7 @@ declare namespace Paths { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -748,7 +812,7 @@ declare namespace Paths { /** * Stable public embed identifier, independent of the assigned agent. Not a credential. */ - widget_id: string; // uuid + website_chat_id: string; // uuid org_id: string; /** * Server-owned session binding; changes on reassignment or allowed-origin changes. @@ -757,7 +821,7 @@ declare namespace Paths { version: number; created_at: string; // date-time updated_at: string; // date-time - website_chat_embed: { + embed: { script_url: string; // uri chat_api_origin: string; // uri demo_url: string; // uri @@ -786,26 +850,7 @@ declare namespace Paths { } } } - namespace CreatePublicChatGrant { - export interface RequestBody { - widget_key: string; // ^[a-zA-Z0-9_-]{1,100}$ - } - namespace Responses { - export interface $201 { - grant: string; - /** - * example: - * 60 - */ - expires_in: number; - widget_origin: string; // uri - } - export interface Default { - code: "INVALID_REQUEST" | "ORIGIN_DENIED" | "NOT_FOUND" | "INVALID_GRANT" | "SESSION_EXPIRED" | "RATE_LIMITED" | "SESSION_LIMIT" | "USAGE_LIMIT" | "REQUEST_CONFLICT" | "IN_PROGRESS" | "UNAVAILABLE" | "TEMPORARILY_UNAVAILABLE"; - } - } - } - namespace DeleteChatWidget { + namespace DeleteWebsiteChat { namespace Parameters { export type Version = number; } @@ -838,14 +883,96 @@ declare namespace Paths { } } } - namespace GetChatWidget { + namespace GetChatVerification { + namespace Responses { + export interface $200 { + available: boolean; + conversation_id: string; // uuid + status: "anonymous" | "sending" | "pending" | "verified"; + challenge_id?: string; // uuid + /** + * Unix seconds + */ + code_expires_at?: number; + /** + * Unix seconds + */ + resend_after?: number; + email?: string; // email + contact_resolution?: "matched" | "ambiguous" | "not_found"; + } + export interface Default { + 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"; + } + } + } + namespace GetPublicWebsiteChat { + namespace Parameters { + export type WebsiteChatId = string; // ^[a-zA-Z0-9_-]{1,100}$ + } + export interface PathParameters { + website_chat_id: Parameters.WebsiteChatId /* ^[a-zA-Z0-9_-]{1,100}$ */; + } + namespace Responses { + export interface $200 { + key: string; + organisationName: string; + assistantName: string; + defaultLocale: "en" | "de"; + authentication?: { + email_code: boolean; + }; + design?: { + id: string; // uuid + last_modified_at?: string; + style?: { + palette?: { + primary?: string; + background?: string; + }; + typography?: { + font?: { + font_family?: string; + }; + }; + shape?: { + border_radius?: number; + }; + }; + 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; + }; + }; + locales: ("en" | "de")[]; + } + export interface Default { + 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"; + } + } + } + namespace GetWebsiteChat { namespace Responses { export interface $200 { name: string; agent_id: string | null; // uuid - website_chat: { + settings: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -902,7 +1029,7 @@ declare namespace Paths { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -917,7 +1044,7 @@ declare namespace Paths { /** * Stable public embed identifier, independent of the assigned agent. Not a credential. */ - widget_id: string; // uuid + website_chat_id: string; // uuid org_id: string; /** * Server-owned session binding; changes on reassignment or allowed-origin changes. @@ -926,7 +1053,7 @@ declare namespace Paths { version: number; created_at: string; // date-time updated_at: string; // date-time - website_chat_embed: { + embed: { script_url: string; // uri chat_api_origin: string; // uri demo_url: string; // uri @@ -955,63 +1082,7 @@ declare namespace Paths { } } } - namespace GetPublicChatWidget { - namespace Parameters { - export type WidgetId = string; // ^[a-zA-Z0-9_-]{1,100}$ - } - export interface PathParameters { - widget_id: Parameters.WidgetId /* ^[a-zA-Z0-9_-]{1,100}$ */; - } - namespace Responses { - export interface $200 { - key: string; - organisationName: string; - assistantName: string; - defaultLocale: "en" | "de"; - design?: { - id: string; // uuid - last_modified_at?: string; - style?: { - palette?: { - primary?: string; - background?: string; - }; - typography?: { - font?: { - font_family?: string; - }; - }; - shape?: { - border_radius?: number; - }; - }; - 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; - }; - }; - locales: ("en" | "de")[]; - } - export interface Default { - code: "INVALID_REQUEST" | "ORIGIN_DENIED" | "NOT_FOUND" | "INVALID_GRANT" | "SESSION_EXPIRED" | "RATE_LIMITED" | "SESSION_LIMIT" | "USAGE_LIMIT" | "REQUEST_CONFLICT" | "IN_PROGRESS" | "UNAVAILABLE" | "TEMPORARILY_UNAVAILABLE"; - } - } - } - namespace ListChatWidgets { + namespace ListWebsiteChats { namespace Parameters { export type Cursor = string; } @@ -1020,12 +1091,12 @@ declare namespace Paths { } namespace Responses { export interface $200 { - widgets: { + website_chats: { name: string; agent_id: string | null; // uuid - website_chat: { + settings: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -1082,7 +1153,7 @@ declare namespace Paths { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -1097,7 +1168,7 @@ declare namespace Paths { /** * Stable public embed identifier, independent of the assigned agent. Not a credential. */ - widget_id: string; // uuid + website_chat_id: string; // uuid org_id: string; /** * Server-owned session binding; changes on reassignment or allowed-origin changes. @@ -1106,7 +1177,7 @@ declare namespace Paths { version: number; created_at: string; // date-time updated_at: string; // date-time - website_chat_embed: { + embed: { script_url: string; // uri chat_api_origin: string; // uri demo_url: string; // uri @@ -1147,17 +1218,45 @@ declare namespace Paths { namespace Responses { export type $200 = string; export interface Default { - code: "INVALID_REQUEST" | "ORIGIN_DENIED" | "NOT_FOUND" | "INVALID_GRANT" | "SESSION_EXPIRED" | "RATE_LIMITED" | "SESSION_LIMIT" | "USAGE_LIMIT" | "REQUEST_CONFLICT" | "IN_PROGRESS" | "UNAVAILABLE" | "TEMPORARILY_UNAVAILABLE"; + 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"; + } + } + } + namespace StartChatEmailVerification { + export interface RequestBody { + request_id: string; // uuid + email: string; // email + locale: "en" | "de"; + } + namespace Responses { + export interface $200 { + available: boolean; + conversation_id: string; // uuid + status: "anonymous" | "sending" | "pending" | "verified"; + challenge_id?: string; // uuid + /** + * Unix seconds + */ + code_expires_at?: number; + /** + * Unix seconds + */ + resend_after?: number; + email?: string; // email + contact_resolution?: "matched" | "ambiguous" | "not_found"; + } + export interface Default { + 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"; } } } - namespace UpdateChatWidget { + namespace UpdateWebsiteChat { export interface RequestBody { name?: string; agent_id?: string | null; // uuid - website_chat?: { + settings?: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -1214,7 +1313,7 @@ declare namespace Paths { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -1235,9 +1334,9 @@ declare namespace Paths { export interface $200 { name: string; agent_id: string | null; // uuid - website_chat: { + settings: { /** - * Exact HTTPS origins. Empty means the widget cannot start sessions. + * Exact HTTPS origins. Empty means the Website Chat cannot start sessions. */ allowed_origins: [ string?, @@ -1294,7 +1393,7 @@ declare namespace Paths { organisation_name: string; default_locale: "en" | "de"; /** - * Design Builder configuration for the widget only. + * Design Builder configuration for the Website Chat only. */ design_id?: string | null; // uuid /** @@ -1309,7 +1408,7 @@ declare namespace Paths { /** * Stable public embed identifier, independent of the assigned agent. Not a credential. */ - widget_id: string; // uuid + website_chat_id: string; // uuid org_id: string; /** * Server-owned session binding; changes on reassignment or allowed-origin changes. @@ -1318,7 +1417,7 @@ declare namespace Paths { version: number; created_at: string; // date-time updated_at: string; // date-time - website_chat_embed: { + embed: { script_url: string; // uri chat_api_origin: string; // uri demo_url: string; // uri @@ -1347,12 +1446,39 @@ declare namespace Paths { } } } - namespace V1Widgets$WidgetId { + namespace V1WebsiteChats$WebsiteChatId { namespace Parameters { - export type WidgetId = string; // uuid + export type WebsiteChatId = string; // uuid } export interface PathParameters { - widget_id: Parameters.WidgetId /* uuid */; + website_chat_id: Parameters.WebsiteChatId /* uuid */; + } + } + namespace VerifyChatEmailCode { + export interface RequestBody { + challenge_id: string; // uuid + code: string; // ^\d{6}$ + } + namespace Responses { + export interface $200 { + available: boolean; + conversation_id: string; // uuid + status: "anonymous" | "sending" | "pending" | "verified"; + challenge_id?: string; // uuid + /** + * Unix seconds + */ + code_expires_at?: number; + /** + * Unix seconds + */ + resend_after?: number; + email?: string; // email + contact_resolution?: "matched" | "ambiguous" | "not_found"; + } + export interface Default { + 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"; + } } } } @@ -1360,55 +1486,55 @@ declare namespace Paths { export interface OperationMethods { /** - * listChatWidgets + * listWebsiteChats */ - 'listChatWidgets'( - parameters?: Parameters | null, + 'listWebsiteChats'( + parameters?: Parameters | null, data?: any, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * createChatWidget + * createWebsiteChat */ - 'createChatWidget'( + 'createWebsiteChat'( parameters?: Parameters | null, - data?: Paths.CreateChatWidget.RequestBody, + data?: Paths.CreateWebsiteChat.RequestBody, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * getChatWidget + * getWebsiteChat */ - 'getChatWidget'( - parameters?: Parameters | null, + 'getWebsiteChat'( + parameters?: Parameters | null, data?: any, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * updateChatWidget + * updateWebsiteChat */ - 'updateChatWidget'( - parameters?: Parameters | null, - data?: Paths.UpdateChatWidget.RequestBody, + 'updateWebsiteChat'( + parameters?: Parameters | null, + data?: Paths.UpdateWebsiteChat.RequestBody, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * deleteChatWidget + * deleteWebsiteChat */ - 'deleteChatWidget'( - parameters?: Parameters | null, + 'deleteWebsiteChat'( + parameters?: Parameters | null, data?: any, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * getPublicChatWidget - Resolve visitor-facing configuration for an independent widget and its current agent assignment. The widget ID is not an organisation ID or a destination such as website or portal. + * getPublicWebsiteChat - Resolve visitor-facing configuration for an independent Website Chat and its current agent assignment. The Website Chat ID is not an organisation ID or a destination such as website or portal. */ - 'getPublicChatWidget'( - parameters?: Parameters | null, + 'getPublicWebsiteChat'( + parameters?: Parameters | null, data?: any, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * createPublicChatGrant - Called by the host website with its widget_key. Checks the saved website origin allowlist and issues a single-use grant for the iframe to exchange at POST /v1/sessions within 60 seconds. This deadline does not limit the resulting session. + * createPublicChatGrant - Called by the host website with its website_chat_id. Checks the saved website origin allowlist and issues a single-use grant for the iframe to exchange at POST /v1/sessions within 60 seconds. This deadline does not limit the resulting session. */ 'createPublicChatGrant'( parameters?: Parameters | null, @@ -1436,66 +1562,98 @@ export interface OperationMethods { data?: Paths.SendAnonymousChatMessage.RequestBody, config?: AxiosRequestConfig ): OperationResponse + /** + * getChatVerification - Read this session's verification state. No contact IDs or candidate records are exposed. + */ + 'getChatVerification'( + parameters?: Parameters | null, + data?: any, + config?: AxiosRequestConfig + ): OperationResponse + /** + * startChatEmailVerification - Start or resend an email challenge using the template saved on this session's Website Chat. Repeating the same request_id and payload does not send another email. Codes must never be sent as chat messages. + */ + 'startChatEmailVerification'( + parameters?: Parameters | null, + data?: Paths.StartChatEmailVerification.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + /** + * verifyChatEmailCode - Verify a code for this session's current challenge. Success binds email proof and contact resolution to this session and starts a new conversation. It grants no account-tool permission. + */ + 'verifyChatEmailCode'( + parameters?: Parameters | null, + data?: Paths.VerifyChatEmailCode.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + /** + * cancelChatVerification - Cancel a pending challenge or clear verified identity. Clearing verified identity starts a new anonymous conversation. In-flight verification cannot restore the cleared identity. + */ + 'cancelChatVerification'( + parameters?: Parameters | null, + data?: any, + config?: AxiosRequestConfig + ): OperationResponse } export interface PathsDictionary { - ['/v1/widgets']: { + ['/v1/website-chats']: { /** - * listChatWidgets + * listWebsiteChats */ 'get'( - parameters?: Parameters | null, + parameters?: Parameters | null, data?: any, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * createChatWidget + * createWebsiteChat */ 'post'( parameters?: Parameters | null, - data?: Paths.CreateChatWidget.RequestBody, + data?: Paths.CreateWebsiteChat.RequestBody, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse } - ['/v1/widgets/{widget_id}']: { + ['/v1/website-chats/{website_chat_id}']: { /** - * getChatWidget + * getWebsiteChat */ 'get'( - parameters?: Parameters | null, + parameters?: Parameters | null, data?: any, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * updateChatWidget + * updateWebsiteChat */ 'put'( - parameters?: Parameters | null, - data?: Paths.UpdateChatWidget.RequestBody, + parameters?: Parameters | null, + data?: Paths.UpdateWebsiteChat.RequestBody, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse /** - * deleteChatWidget + * deleteWebsiteChat */ 'delete'( - parameters?: Parameters | null, + parameters?: Parameters | null, data?: any, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse } - ['/v1/widgets/{widget_id}/configuration']: { + ['/v1/website-chats/{website_chat_id}/configuration']: { /** - * getPublicChatWidget - Resolve visitor-facing configuration for an independent widget and its current agent assignment. The widget ID is not an organisation ID or a destination such as website or portal. + * getPublicWebsiteChat - Resolve visitor-facing configuration for an independent Website Chat and its current agent assignment. The Website Chat ID is not an organisation ID or a destination such as website or portal. */ 'get'( - parameters?: Parameters | null, + parameters?: Parameters | null, data?: any, config?: AxiosRequestConfig - ): OperationResponse + ): OperationResponse } ['/v1/bootstrap']: { /** - * createPublicChatGrant - Called by the host website with its widget_key. Checks the saved website origin allowlist and issues a single-use grant for the iframe to exchange at POST /v1/sessions within 60 seconds. This deadline does not limit the resulting session. + * createPublicChatGrant - Called by the host website with its website_chat_id. Checks the saved website origin allowlist and issues a single-use grant for the iframe to exchange at POST /v1/sessions within 60 seconds. This deadline does not limit the resulting session. */ 'post'( parameters?: Parameters | null, @@ -1528,18 +1686,59 @@ export interface PathsDictionary { config?: AxiosRequestConfig ): OperationResponse } + ['/v1/verification']: { + /** + * getChatVerification - Read this session's verification state. No contact IDs or candidate records are exposed. + */ + 'get'( + parameters?: Parameters | null, + data?: any, + config?: AxiosRequestConfig + ): OperationResponse + } + ['/v1/verification/email']: { + /** + * startChatEmailVerification - Start or resend an email challenge using the template saved on this session's Website Chat. Repeating the same request_id and payload does not send another email. Codes must never be sent as chat messages. + */ + 'post'( + parameters?: Parameters | null, + data?: Paths.StartChatEmailVerification.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + } + ['/v1/verification/code']: { + /** + * verifyChatEmailCode - Verify a code for this session's current challenge. Success binds email proof and contact resolution to this session and starts a new conversation. It grants no account-tool permission. + */ + 'post'( + parameters?: Parameters | null, + data?: Paths.VerifyChatEmailCode.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + } + ['/v1/verification/cancel']: { + /** + * cancelChatVerification - Cancel a pending challenge or clear verified identity. Clearing verified identity starts a new anonymous conversation. In-flight verification cannot restore the cleared identity. + */ + 'post'( + parameters?: Parameters | null, + data?: any, + config?: AxiosRequestConfig + ): OperationResponse + } } export type Client = OpenAPIClient -export type ChatWidget = Components.Schemas.ChatWidget; -export type CreateChatWidgetRequest = Components.Schemas.CreateChatWidgetRequest; +export type CreateWebsiteChatRequest = Components.Schemas.CreateWebsiteChatRequest; export type Error = Components.Schemas.Error; -export type ListChatWidgetsResponse = Components.Schemas.ListChatWidgetsResponse; +export type ListWebsiteChatsResponse = Components.Schemas.ListWebsiteChatsResponse; export type PublicChatError = Components.Schemas.PublicChatError; export type PublicEvent = Components.Schemas.PublicEvent; -export type UpdateChatWidgetRequest = Components.Schemas.UpdateChatWidgetRequest; +export type PublicWebsiteChat = Components.Schemas.PublicWebsiteChat; +export type UpdateWebsiteChatRequest = Components.Schemas.UpdateWebsiteChatRequest; +export type VerificationState = Components.Schemas.VerificationState; +export type WebsiteChat = Components.Schemas.WebsiteChat; +export type WebsiteChatDesign = Components.Schemas.WebsiteChatDesign; export type WebsiteChatSettings = Components.Schemas.WebsiteChatSettings; -export type Widget = Components.Schemas.Widget; -export type WidgetDesign = Components.Schemas.WidgetDesign; diff --git a/clients/chat-client/src/openapi.json b/clients/chat-client/src/openapi.json index 7be35da8..dcff3b08 100644 --- a/clients/chat-client/src/openapi.json +++ b/clients/chat-client/src/openapi.json @@ -3,7 +3,7 @@ "info": { "title": "epilot Chat API", "version": "0.1.0", - "description": "Widget management and anonymous browser chat." + "description": "Website Chat management and anonymous browser chat." }, "servers": [ { @@ -16,12 +16,12 @@ } ], "paths": { - "/v1/widgets": { + "/v1/website-chats": { "get": { "tags": [ - "Chat widgets" + "Website Chats" ], - "operationId": "listChatWidgets", + "operationId": "listWebsiteChats", "security": [ { "EpilotAuth": [] @@ -29,28 +29,28 @@ ], "responses": { "200": { - "description": "Widget response", + "description": "Website Chat response", "content": { "application/json": { "schema": { "type": "object", "required": [ - "widgets" + "website_chats" ], "properties": { - "widgets": { + "website_chats": { "type": "array", "items": { "type": "object", "required": [ - "widget_id", + "website_chat_id", "org_id", "agent_id", "binding_id", "version", "name", - "website_chat", - "website_chat_embed", + "settings", + "embed", "created_at", "updated_at" ], @@ -65,7 +65,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -78,7 +78,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -100,7 +100,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -126,7 +126,7 @@ } } }, - "widget_id": { + "website_chat_id": { "type": "string", "format": "uuid", "readOnly": true, @@ -157,7 +157,7 @@ "format": "date-time", "readOnly": true }, - "website_chat_embed": { + "embed": { "type": "object", "readOnly": true, "required": [ @@ -192,7 +192,7 @@ } }, "400": { - "description": "Invalid widget settings", + "description": "Invalid Website Chat settings", "content": { "application/json": { "schema": { @@ -213,7 +213,7 @@ } }, "404": { - "description": "Widget not found in this organisation", + "description": "Website Chat not found in this organisation", "content": { "application/json": { "schema": { @@ -234,7 +234,7 @@ } }, "409": { - "description": "Widget or assigned agent changed; reload before retrying", + "description": "Website Chat or assigned agent changed; reload before retrying", "content": { "application/json": { "schema": { @@ -268,9 +268,9 @@ }, "post": { "tags": [ - "Chat widgets" + "Website Chats" ], - "operationId": "createChatWidget", + "operationId": "createWebsiteChat", "security": [ { "EpilotAuth": [] @@ -278,20 +278,20 @@ ], "responses": { "201": { - "description": "Widget response", + "description": "Website Chat response", "content": { "application/json": { "schema": { "type": "object", "required": [ - "widget_id", + "website_chat_id", "org_id", "agent_id", "binding_id", "version", "name", - "website_chat", - "website_chat_embed", + "settings", + "embed", "created_at", "updated_at" ], @@ -306,7 +306,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -319,7 +319,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -341,7 +341,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -367,7 +367,7 @@ } } }, - "widget_id": { + "website_chat_id": { "type": "string", "format": "uuid", "readOnly": true, @@ -398,7 +398,7 @@ "format": "date-time", "readOnly": true }, - "website_chat_embed": { + "embed": { "type": "object", "readOnly": true, "required": [ @@ -427,7 +427,7 @@ } }, "400": { - "description": "Invalid widget settings", + "description": "Invalid Website Chat settings", "content": { "application/json": { "schema": { @@ -448,7 +448,7 @@ } }, "404": { - "description": "Widget not found in this organisation", + "description": "Website Chat not found in this organisation", "content": { "application/json": { "schema": { @@ -469,7 +469,7 @@ } }, "409": { - "description": "Widget or assigned agent changed; reload before retrying", + "description": "Website Chat or assigned agent changed; reload before retrying", "content": { "application/json": { "schema": { @@ -500,7 +500,7 @@ "required": [ "name", "agent_id", - "website_chat" + "settings" ], "properties": { "name": { @@ -513,7 +513,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -526,7 +526,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -548,7 +548,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -581,11 +581,11 @@ } } }, - "/v1/widgets/{widget_id}": { + "/v1/website-chats/{website_chat_id}": { "parameters": [ { "in": "path", - "name": "widget_id", + "name": "website_chat_id", "required": true, "schema": { "type": "string", @@ -595,9 +595,9 @@ ], "get": { "tags": [ - "Chat widgets" + "Website Chats" ], - "operationId": "getChatWidget", + "operationId": "getWebsiteChat", "security": [ { "EpilotAuth": [] @@ -605,20 +605,20 @@ ], "responses": { "200": { - "description": "Widget response", + "description": "Website Chat response", "content": { "application/json": { "schema": { "type": "object", "required": [ - "widget_id", + "website_chat_id", "org_id", "agent_id", "binding_id", "version", "name", - "website_chat", - "website_chat_embed", + "settings", + "embed", "created_at", "updated_at" ], @@ -633,7 +633,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -646,7 +646,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -668,7 +668,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -694,7 +694,7 @@ } } }, - "widget_id": { + "website_chat_id": { "type": "string", "format": "uuid", "readOnly": true, @@ -725,7 +725,7 @@ "format": "date-time", "readOnly": true }, - "website_chat_embed": { + "embed": { "type": "object", "readOnly": true, "required": [ @@ -754,7 +754,7 @@ } }, "400": { - "description": "Invalid widget settings", + "description": "Invalid Website Chat settings", "content": { "application/json": { "schema": { @@ -775,7 +775,7 @@ } }, "404": { - "description": "Widget not found in this organisation", + "description": "Website Chat not found in this organisation", "content": { "application/json": { "schema": { @@ -796,7 +796,7 @@ } }, "409": { - "description": "Widget or assigned agent changed; reload before retrying", + "description": "Website Chat or assigned agent changed; reload before retrying", "content": { "application/json": { "schema": { @@ -820,9 +820,9 @@ }, "put": { "tags": [ - "Chat widgets" + "Website Chats" ], - "operationId": "updateChatWidget", + "operationId": "updateWebsiteChat", "security": [ { "EpilotAuth": [] @@ -830,20 +830,20 @@ ], "responses": { "200": { - "description": "Widget response", + "description": "Website Chat response", "content": { "application/json": { "schema": { "type": "object", "required": [ - "widget_id", + "website_chat_id", "org_id", "agent_id", "binding_id", "version", "name", - "website_chat", - "website_chat_embed", + "settings", + "embed", "created_at", "updated_at" ], @@ -858,7 +858,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -871,7 +871,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -893,7 +893,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -919,7 +919,7 @@ } } }, - "widget_id": { + "website_chat_id": { "type": "string", "format": "uuid", "readOnly": true, @@ -950,7 +950,7 @@ "format": "date-time", "readOnly": true }, - "website_chat_embed": { + "embed": { "type": "object", "readOnly": true, "required": [ @@ -979,7 +979,7 @@ } }, "400": { - "description": "Invalid widget settings", + "description": "Invalid Website Chat settings", "content": { "application/json": { "schema": { @@ -1000,7 +1000,7 @@ } }, "404": { - "description": "Widget not found in this organisation", + "description": "Website Chat not found in this organisation", "content": { "application/json": { "schema": { @@ -1021,7 +1021,7 @@ } }, "409": { - "description": "Widget or assigned agent changed; reload before retrying", + "description": "Website Chat or assigned agent changed; reload before retrying", "content": { "application/json": { "schema": { @@ -1063,7 +1063,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -1076,7 +1076,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -1098,7 +1098,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -1137,9 +1137,9 @@ }, "delete": { "tags": [ - "Chat widgets" + "Website Chats" ], - "operationId": "deleteChatWidget", + "operationId": "deleteWebsiteChat", "security": [ { "EpilotAuth": [] @@ -1147,10 +1147,10 @@ ], "responses": { "204": { - "description": "Widget deleted" + "description": "Website Chat deleted" }, "400": { - "description": "Invalid widget settings", + "description": "Invalid Website Chat settings", "content": { "application/json": { "schema": { @@ -1171,7 +1171,7 @@ } }, "404": { - "description": "Widget not found in this organisation", + "description": "Website Chat not found in this organisation", "content": { "application/json": { "schema": { @@ -1192,7 +1192,7 @@ } }, "409": { - "description": "Widget or assigned agent changed; reload before retrying", + "description": "Website Chat or assigned agent changed; reload before retrying", "content": { "application/json": { "schema": { @@ -1226,15 +1226,15 @@ ] } }, - "/v1/widgets/{widget_id}/configuration": { + "/v1/website-chats/{website_chat_id}/configuration": { "get": { - "operationId": "getPublicChatWidget", - "description": "Resolve visitor-facing configuration for an independent widget and its current agent assignment. The widget ID is not an organisation ID or a destination such as website or portal.", + "operationId": "getPublicWebsiteChat", + "description": "Resolve visitor-facing configuration for an independent Website Chat and its current agent assignment. The Website Chat ID is not an organisation ID or a destination such as website or portal.", "parameters": [ { "in": "path", - "name": "widget_id", - "description": "Public widget ID, also used as widget_key in bootstrap and data-epilot-chat in the embed.", + "name": "website_chat_id", + "description": "Public Website Chat ID, also used as website_chat_id in bootstrap and data-epilot-chat in the embed.", "example": "550e8400-e29b-41d4-a716-446655440000", "required": true, "schema": { @@ -1274,6 +1274,18 @@ "de" ] }, + "authentication": { + "type": "object", + "additionalProperties": false, + "required": [ + "email_code" + ], + "properties": { + "email_code": { + "type": "boolean" + } + } + }, "design": { "type": "object", "additionalProperties": false, @@ -1423,7 +1435,7 @@ } }, "default": { - "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished widget, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", "content": { "application/json": { "schema": { @@ -1435,6 +1447,12 @@ "code": { "type": "string", "enum": [ + "INVALID_VERIFICATION_CODE", + "VERIFICATION_EXPIRED", + "VERIFICATION_CONFLICT", + "VERIFICATION_DISABLED", + "VERIFICATION_UNAVAILABLE", + "IDENTITY_CHANGED", "INVALID_REQUEST", "ORIGIN_DENIED", "NOT_FOUND", @@ -1461,7 +1479,7 @@ "/v1/bootstrap": { "post": { "operationId": "createPublicChatGrant", - "description": "Called by the host website with its widget_key. Checks the saved website origin allowlist and issues a single-use grant for the iframe to exchange at POST /v1/sessions within 60 seconds. This deadline does not limit the resulting session.", + "description": "Called by the host website with its website_chat_id. Checks the saved website origin allowlist and issues a single-use grant for the iframe to exchange at POST /v1/sessions within 60 seconds. This deadline does not limit the resulting session.", "requestBody": { "required": true, "content": { @@ -1470,10 +1488,10 @@ "type": "object", "additionalProperties": false, "required": [ - "widget_key" + "website_chat_id" ], "properties": { - "widget_key": { + "website_chat_id": { "type": "string", "pattern": "^[a-zA-Z0-9_-]{1,100}$" } @@ -1492,7 +1510,7 @@ "required": [ "grant", "expires_in", - "widget_origin" + "frame_origin" ], "properties": { "grant": { @@ -1502,7 +1520,7 @@ "type": "integer", "example": 60 }, - "widget_origin": { + "frame_origin": { "type": "string", "format": "uri" } @@ -1512,7 +1530,7 @@ } }, "default": { - "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished widget, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", "content": { "application/json": { "schema": { @@ -1524,6 +1542,12 @@ "code": { "type": "string", "enum": [ + "INVALID_VERIFICATION_CODE", + "VERIFICATION_EXPIRED", + "VERIFICATION_CONFLICT", + "VERIFICATION_DISABLED", + "VERIFICATION_UNAVAILABLE", + "IDENTITY_CHANGED", "INVALID_REQUEST", "ORIGIN_DENIED", "NOT_FOUND", @@ -1582,7 +1606,7 @@ "token", "conversation_id", "expires_at", - "widget" + "website_chat" ], "properties": { "token": { @@ -1596,7 +1620,7 @@ "type": "integer", "description": "Unix seconds" }, - "widget": { + "website_chat": { "type": "object", "required": [ "key", @@ -1622,6 +1646,18 @@ "de" ] }, + "authentication": { + "type": "object", + "additionalProperties": false, + "required": [ + "email_code" + ], + "properties": { + "email_code": { + "type": "boolean" + } + } + }, "design": { "type": "object", "additionalProperties": false, @@ -1773,7 +1809,7 @@ } }, "default": { - "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished widget, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", "content": { "application/json": { "schema": { @@ -1785,6 +1821,12 @@ "code": { "type": "string", "enum": [ + "INVALID_VERIFICATION_CODE", + "VERIFICATION_EXPIRED", + "VERIFICATION_CONFLICT", + "VERIFICATION_DISABLED", + "VERIFICATION_UNAVAILABLE", + "IDENTITY_CHANGED", "INVALID_REQUEST", "ORIGIN_DENIED", "NOT_FOUND", @@ -1870,7 +1912,7 @@ } }, "default": { - "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished widget, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", "content": { "application/json": { "schema": { @@ -1882,6 +1924,511 @@ "code": { "type": "string", "enum": [ + "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" + ] + } + } + } + } + } + } + } + } + }, + "/v1/verification": { + "get": { + "operationId": "getChatVerification", + "security": [ + { + "AnonymousSession": [] + } + ], + "description": "Read this session's verification state. No contact IDs or candidate records are exposed.", + "responses": { + "200": { + "description": "Current verification state", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": [ + "available", + "conversation_id", + "status" + ], + "properties": { + "available": { + "type": "boolean" + }, + "conversation_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "anonymous", + "sending", + "pending", + "verified" + ] + }, + "challenge_id": { + "type": "string", + "format": "uuid" + }, + "code_expires_at": { + "type": "integer", + "description": "Unix seconds" + }, + "resend_after": { + "type": "integer", + "description": "Unix seconds" + }, + "email": { + "type": "string", + "format": "email", + "maxLength": 254 + }, + "contact_resolution": { + "type": "string", + "enum": [ + "matched", + "ambiguous", + "not_found" + ] + } + } + } + } + } + }, + "default": { + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "code" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "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" + ] + } + } + } + } + } + } + } + } + }, + "/v1/verification/email": { + "post": { + "operationId": "startChatEmailVerification", + "security": [ + { + "AnonymousSession": [] + } + ], + "description": "Start or resend an email challenge using the template saved on this session's Website Chat. Repeating the same request_id and payload does not send another email. Codes must never be sent as chat messages.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": [ + "request_id", + "email", + "locale" + ], + "properties": { + "request_id": { + "type": "string", + "format": "uuid" + }, + "email": { + "type": "string", + "format": "email", + "maxLength": 254 + }, + "locale": { + "type": "string", + "enum": [ + "en", + "de" + ] + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Current verification state; pending does not reveal whether an email is registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": [ + "available", + "conversation_id", + "status" + ], + "properties": { + "available": { + "type": "boolean" + }, + "conversation_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "anonymous", + "sending", + "pending", + "verified" + ] + }, + "challenge_id": { + "type": "string", + "format": "uuid" + }, + "code_expires_at": { + "type": "integer", + "description": "Unix seconds" + }, + "resend_after": { + "type": "integer", + "description": "Unix seconds" + }, + "email": { + "type": "string", + "format": "email", + "maxLength": 254 + }, + "contact_resolution": { + "type": "string", + "enum": [ + "matched", + "ambiguous", + "not_found" + ] + } + } + } + } + } + }, + "default": { + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "code" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "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" + ] + } + } + } + } + } + } + } + } + }, + "/v1/verification/code": { + "post": { + "operationId": "verifyChatEmailCode", + "security": [ + { + "AnonymousSession": [] + } + ], + "description": "Verify a code for this session's current challenge. Success binds email proof and contact resolution to this session and starts a new conversation. It grants no account-tool permission.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": [ + "challenge_id", + "code" + ], + "properties": { + "challenge_id": { + "type": "string", + "format": "uuid" + }, + "code": { + "type": "string", + "pattern": "^\\d{6}$" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Verification result; duplicate contacts remain unresolved", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": [ + "available", + "conversation_id", + "status" + ], + "properties": { + "available": { + "type": "boolean" + }, + "conversation_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "anonymous", + "sending", + "pending", + "verified" + ] + }, + "challenge_id": { + "type": "string", + "format": "uuid" + }, + "code_expires_at": { + "type": "integer", + "description": "Unix seconds" + }, + "resend_after": { + "type": "integer", + "description": "Unix seconds" + }, + "email": { + "type": "string", + "format": "email", + "maxLength": 254 + }, + "contact_resolution": { + "type": "string", + "enum": [ + "matched", + "ambiguous", + "not_found" + ] + } + } + } + } + } + }, + "default": { + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "code" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "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" + ] + } + } + } + } + } + } + } + } + }, + "/v1/verification/cancel": { + "post": { + "operationId": "cancelChatVerification", + "security": [ + { + "AnonymousSession": [] + } + ], + "description": "Cancel a pending challenge or clear verified identity. Clearing verified identity starts a new anonymous conversation. In-flight verification cannot restore the cleared identity.", + "responses": { + "200": { + "description": "Anonymous session state", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": [ + "available", + "conversation_id", + "status" + ], + "properties": { + "available": { + "type": "boolean" + }, + "conversation_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "anonymous", + "sending", + "pending", + "verified" + ] + }, + "challenge_id": { + "type": "string", + "format": "uuid" + }, + "code_expires_at": { + "type": "integer", + "description": "Unix seconds" + }, + "resend_after": { + "type": "integer", + "description": "Unix seconds" + }, + "email": { + "type": "string", + "format": "email", + "maxLength": 254 + }, + "contact_resolution": { + "type": "string", + "enum": [ + "matched", + "ambiguous", + "not_found" + ] + } + } + } + } + } + }, + "default": { + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "code" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "INVALID_VERIFICATION_CODE", + "VERIFICATION_EXPIRED", + "VERIFICATION_CONFLICT", + "VERIFICATION_DISABLED", + "VERIFICATION_UNAVAILABLE", + "IDENTITY_CHANGED", "INVALID_REQUEST", "ORIGIN_DENIED", "NOT_FOUND", @@ -1914,29 +2461,29 @@ "AnonymousSession": { "type": "http", "scheme": "bearer", - "description": "Opaque, expiring anonymous session token; never an epilot user access token." + "description": "Opaque, expiring Chat session token; never an epilot user or Portal access token." } }, "schemas": { - "ListChatWidgetsResponse": { + "ListWebsiteChatsResponse": { "type": "object", "required": [ - "widgets" + "website_chats" ], "properties": { - "widgets": { + "website_chats": { "type": "array", "items": { "type": "object", "required": [ - "widget_id", + "website_chat_id", "org_id", "agent_id", "binding_id", "version", "name", - "website_chat", - "website_chat_embed", + "settings", + "embed", "created_at", "updated_at" ], @@ -1951,7 +2498,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -1964,7 +2511,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -1986,7 +2533,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -2012,7 +2559,7 @@ } } }, - "widget_id": { + "website_chat_id": { "type": "string", "format": "uuid", "readOnly": true, @@ -2043,7 +2590,7 @@ "format": "date-time", "readOnly": true }, - "website_chat_embed": { + "embed": { "type": "object", "readOnly": true, "required": [ @@ -2074,17 +2621,17 @@ } } }, - "ChatWidget": { + "WebsiteChat": { "type": "object", "required": [ - "widget_id", + "website_chat_id", "org_id", "agent_id", "binding_id", "version", "name", - "website_chat", - "website_chat_embed", + "settings", + "embed", "created_at", "updated_at" ], @@ -2099,7 +2646,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -2112,7 +2659,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -2134,7 +2681,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -2160,7 +2707,7 @@ } } }, - "widget_id": { + "website_chat_id": { "type": "string", "format": "uuid", "readOnly": true, @@ -2191,7 +2738,7 @@ "format": "date-time", "readOnly": true }, - "website_chat_embed": { + "embed": { "type": "object", "readOnly": true, "required": [ @@ -2229,7 +2776,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -2251,7 +2798,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -2291,13 +2838,13 @@ } } }, - "CreateChatWidgetRequest": { + "CreateWebsiteChatRequest": { "type": "object", "additionalProperties": false, "required": [ "name", "agent_id", - "website_chat" + "settings" ], "properties": { "name": { @@ -2310,7 +2857,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -2323,7 +2870,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -2345,7 +2892,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -2373,7 +2920,7 @@ } } }, - "UpdateChatWidgetRequest": { + "UpdateWebsiteChatRequest": { "type": "object", "additionalProperties": false, "required": [ @@ -2390,7 +2937,7 @@ "format": "uuid", "nullable": true }, - "website_chat": { + "settings": { "type": "object", "additionalProperties": false, "required": [ @@ -2403,7 +2950,7 @@ "type": "array", "maxItems": 50, "uniqueItems": true, - "description": "Exact HTTPS origins. Empty means the widget cannot start sessions.", + "description": "Exact HTTPS origins. Empty means the Website Chat cannot start sessions.", "items": { "type": "string", "maxLength": 2048 @@ -2425,7 +2972,7 @@ "type": "string", "format": "uuid", "nullable": true, - "description": "Design Builder configuration for the widget only." + "description": "Design Builder configuration for the Website Chat only." }, "authentication": { "type": "object", @@ -2458,7 +3005,59 @@ } } }, - "Widget": { + "VerificationState": { + "type": "object", + "additionalProperties": false, + "required": [ + "available", + "conversation_id", + "status" + ], + "properties": { + "available": { + "type": "boolean" + }, + "conversation_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "anonymous", + "sending", + "pending", + "verified" + ] + }, + "challenge_id": { + "type": "string", + "format": "uuid" + }, + "code_expires_at": { + "type": "integer", + "description": "Unix seconds" + }, + "resend_after": { + "type": "integer", + "description": "Unix seconds" + }, + "email": { + "type": "string", + "format": "email", + "maxLength": 254 + }, + "contact_resolution": { + "type": "string", + "enum": [ + "matched", + "ambiguous", + "not_found" + ] + } + } + }, + "PublicWebsiteChat": { "type": "object", "required": [ "key", @@ -2484,6 +3083,18 @@ "de" ] }, + "authentication": { + "type": "object", + "additionalProperties": false, + "required": [ + "email_code" + ], + "properties": { + "email_code": { + "type": "boolean" + } + } + }, "design": { "type": "object", "additionalProperties": false, @@ -2629,7 +3240,7 @@ } } }, - "WidgetDesign": { + "WebsiteChatDesign": { "type": "object", "additionalProperties": false, "properties": { @@ -2854,6 +3465,12 @@ "code": { "type": "string", "enum": [ + "INVALID_VERIFICATION_CODE", + "VERIFICATION_EXPIRED", + "VERIFICATION_CONFLICT", + "VERIFICATION_DISABLED", + "VERIFICATION_UNAVAILABLE", + "IDENTITY_CHANGED", "INVALID_REQUEST", "ORIGIN_DENIED", "NOT_FOUND", @@ -2873,7 +3490,7 @@ }, "responses": { "Error": { - "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished widget, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", + "description": "400 invalid input, 401 expired capability, 403 origin denied, 404 unpublished Website Chat, 409 conflict, 413 too large, 429 rate limit, or 503 unavailable.", "content": { "application/json": { "schema": { @@ -2885,6 +3502,12 @@ "code": { "type": "string", "enum": [ + "INVALID_VERIFICATION_CODE", + "VERIFICATION_EXPIRED", + "VERIFICATION_CONFLICT", + "VERIFICATION_DISABLED", + "VERIFICATION_UNAVAILABLE", + "IDENTITY_CHANGED", "INVALID_REQUEST", "ORIGIN_DENIED", "NOT_FOUND", diff --git a/clients/chat-client/update-openapi.cjs b/clients/chat-client/update-openapi.cjs index e13e51c9..1949ab41 100644 --- a/clients/chat-client/update-openapi.cjs +++ b/clients/chat-client/update-openapi.cjs @@ -8,7 +8,7 @@ const { resolve, join } = require('node:path'); const serviceDir = process.argv[2]; if (!serviceDir) throw new Error('Usage: npm run openapi -- /path/to/chat-api'); const read = (path) => JSON.parse(readFileSync(resolve(serviceDir, path), 'utf8')); -const management = read('lambda/ApiHandlerFunction/src/widgets/definition.json'); +const management = read('lambda/ApiHandlerFunction/src/website-chats/definition.json'); const publicApi = read('lambda/ApiHandlerFunction/src/openapi/definition.json'); // Both documents define Error with different payloads. Preserve the public error @@ -41,7 +41,11 @@ for (const key of new Set([...Object.keys(management.components), ...Object.keys } const definition = { ...management, - info: { ...management.info, title: 'epilot Chat API', description: 'Widget management and anonymous browser chat.' }, + info: { + ...management.info, + title: 'epilot Chat API', + description: 'Website Chat management and anonymous browser chat.', + }, paths: mergeUnique(management.paths, publicApi.paths), components, };