SupportWhale
← All help articles

API reference

Build scoped integrations with the SupportWhale REST API.

Public integration API

The versioned integration API uses organization-bound Bearer keys. It does not expose the internal administration API. Every request must match the organization and scopes on the key. Use separate keys for separate integrations and organizations.

Open an endpoint below to inspect its parameters, response schema and required scope. Authorize with your own key to send a real request. The reference does not store your key. Responses may contain your organization’s data: clear the key and responses before sharing your screen.

Create an API key, choose scopes, restrict access, rotate or revoke, first integration, realtime events.

Versions and compatibility

The current contract is v1. Additive fields may appear without a new version; clients should ignore unknown fields. Breaking path, field-type or permission changes require a new API version and a published migration notice in this reference. No deprecation is currently scheduled. Do not treat browser endpoints as a stable integration contract.

Errors and retries

401 means the key is missing, invalid, expired or revoked. 403 means the organization, resource or scope is not allowed. 429 means the rate limit was reached: honor Retry-After before retrying. Use exponential backoff with jitter for transient 5xx failures. Never retry a write blindly; inspect the endpoint’s idempotency contract first. The API has no public outbound webhook subscription contract.

OpenAPI 3.1 JSON

Your key stays in this page’s memory. Requests go directly to the configured SupportWhale API.

GET /integrations/orgs/{orgId}/conversations

List conversations

Required scope: conversations:read

Parameters
Contract
{
  "path": "/integrations/orgs/{orgId}/conversations",
  "method": "get",
  "operationId": "listConversations",
  "summary": "List conversations",
  "description": "Required scope: conversations:read. ",
  "tags": [
    "conversations"
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "x-required-scopes": [
    "conversations:read"
  ],
  "parameters": [
    {
      "name": "orgId",
      "in": "path",
      "required": true,
      "description": "The one organization bound to the key.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    },
    {
      "name": "after",
      "in": "query",
      "required": false,
      "description": "Exclusive cursor: id of the final item from the previous page. Results are ordered by id ascending.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    },
    {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "Page size. Continue with after until a page has fewer than limit results.",
      "schema": {
        "type": "integer",
        "minimum": 1,
        "maximum": 100,
        "default": 50
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Success",
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Conversation"
            },
            "maxItems": 100
          }
        }
      }
    },
    "400": {
      "description": "Invalid parameters or message.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "description": "Missing, malformed, expired or revoked key; issuer no longer authorized.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "403": {
      "description": "Organization or scope is not allowed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "404": {
      "description": "Resource does not exist in this organization.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "429": {
      "headers": {
        "Retry-After": {
          "description": "Seconds to wait before retrying.",
          "schema": {
            "type": "integer",
            "minimum": 1,
            "example": 60
          }
        }
      },
      "description": "Per-key or organization rate limit exceeded. Wait retryAfter seconds from the JSON response before retrying.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "500": {
      "description": "Unexpected server failure.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "503": {
      "description": "Temporary service failure; retry reads with backoff.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
GET /integrations/orgs/{orgId}/conversations/{id}/messages

List messages

Required scope: conversations:read

Parameters
Contract
{
  "path": "/integrations/orgs/{orgId}/conversations/{id}/messages",
  "method": "get",
  "operationId": "listMessages",
  "summary": "List conversation messages",
  "description": "Required scope: conversations:read. Includes private team notes. Never expose this response to visitors.",
  "tags": [
    "conversations"
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "x-required-scopes": [
    "conversations:read"
  ],
  "parameters": [
    {
      "name": "orgId",
      "in": "path",
      "required": true,
      "description": "The one organization bound to the key.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    },
    {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "Conversation identifier within this organization.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    },
    {
      "name": "after",
      "in": "query",
      "required": false,
      "description": "Exclusive cursor: id of the final item from the previous page. Results are ordered by id ascending.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    },
    {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "Page size. Continue with after until a page has fewer than limit results.",
      "schema": {
        "type": "integer",
        "minimum": 1,
        "maximum": 100,
        "default": 50
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Success",
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "maxItems": 100
          }
        }
      }
    },
    "400": {
      "description": "Invalid parameters or message.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "description": "Missing, malformed, expired or revoked key; issuer no longer authorized.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "403": {
      "description": "Organization or scope is not allowed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "404": {
      "description": "Resource does not exist in this organization.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "429": {
      "headers": {
        "Retry-After": {
          "description": "Seconds to wait before retrying.",
          "schema": {
            "type": "integer",
            "minimum": 1,
            "example": 60
          }
        }
      },
      "description": "Per-key or organization rate limit exceeded. Wait retryAfter seconds from the JSON response before retrying.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "500": {
      "description": "Unexpected server failure.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "503": {
      "description": "Temporary service failure; retry reads with backoff.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
POST /integrations/orgs/{orgId}/conversations/{id}/messages

Send a reply or internal note

Required scope: conversations:write

Parameters
Contract
{
  "path": "/integrations/orgs/{orgId}/conversations/{id}/messages",
  "method": "post",
  "operationId": "sendMessage",
  "summary": "Send a reply or internal note",
  "description": "Required scope: conversations:write. Uses normal message delivery and audit behavior. Repeated clientMessageId with the same key and conversation returns the original message; do not reuse an ID for different content. Rotation retains the key identifier; a replacement key has a separate replay namespace.",
  "tags": [
    "conversations"
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "x-required-scopes": [
    "conversations:write"
  ],
  "parameters": [
    {
      "name": "orgId",
      "in": "path",
      "required": true,
      "description": "The one organization bound to the key.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    },
    {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "Conversation identifier within this organization.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    }
  ],
  "responses": {
    "201": {
      "description": "Message created, or existing message returned for the same replay ID.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/SentMessage"
          }
        }
      }
    },
    "400": {
      "description": "Invalid parameters or message.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "description": "Missing, malformed, expired or revoked key; issuer no longer authorized.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "403": {
      "description": "Organization or scope is not allowed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "404": {
      "description": "Resource does not exist in this organization.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "429": {
      "headers": {
        "Retry-After": {
          "description": "Seconds to wait before retrying.",
          "schema": {
            "type": "integer",
            "minimum": 1,
            "example": 60
          }
        }
      },
      "description": "Per-key or organization rate limit exceeded. Wait retryAfter seconds from the JSON response before retrying.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "500": {
      "description": "Unexpected server failure.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "503": {
      "description": "Temporary service failure; retry reads with backoff.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/SendMessage"
        },
        "example": {
          "body": "Thanks for your message.",
          "clientMessageId": "reply-order-42",
          "internal": false
        }
      }
    }
  }
}
GET /integrations/orgs/{orgId}/contacts

List contacts

Required scope: contacts:read

Parameters
Contract
{
  "path": "/integrations/orgs/{orgId}/contacts",
  "method": "get",
  "operationId": "listContacts",
  "summary": "List contacts",
  "description": "Required scope: contacts:read. ",
  "tags": [
    "contacts"
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "x-required-scopes": [
    "contacts:read"
  ],
  "parameters": [
    {
      "name": "orgId",
      "in": "path",
      "required": true,
      "description": "The one organization bound to the key.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    },
    {
      "name": "after",
      "in": "query",
      "required": false,
      "description": "Exclusive cursor: id of the final item from the previous page. Results are ordered by id ascending.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    },
    {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "Page size. Continue with after until a page has fewer than limit results.",
      "schema": {
        "type": "integer",
        "minimum": 1,
        "maximum": 100,
        "default": 50
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Success",
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Contact"
            },
            "maxItems": 100
          }
        }
      }
    },
    "400": {
      "description": "Invalid parameters or message.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "description": "Missing, malformed, expired or revoked key; issuer no longer authorized.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "403": {
      "description": "Organization or scope is not allowed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "404": {
      "description": "Resource does not exist in this organization.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "429": {
      "headers": {
        "Retry-After": {
          "description": "Seconds to wait before retrying.",
          "schema": {
            "type": "integer",
            "minimum": 1,
            "example": 60
          }
        }
      },
      "description": "Per-key or organization rate limit exceeded. Wait retryAfter seconds from the JSON response before retrying.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "500": {
      "description": "Unexpected server failure.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "503": {
      "description": "Temporary service failure; retry reads with backoff.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
GET /integrations/orgs/{orgId}/agents

List AI agents

Required scope: agents:read

Parameters
Contract
{
  "path": "/integrations/orgs/{orgId}/agents",
  "method": "get",
  "operationId": "listAgents",
  "summary": "List AI agents",
  "description": "Required scope: agents:read. Returns up to 100 agent summaries. Provider credentials and inference costs are never included.",
  "tags": [
    "agents"
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "x-required-scopes": [
    "agents:read"
  ],
  "parameters": [
    {
      "name": "orgId",
      "in": "path",
      "required": true,
      "description": "The one organization bound to the key.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Success",
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Agent"
            },
            "maxItems": 100
          }
        }
      }
    },
    "400": {
      "description": "Invalid parameters or message.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "description": "Missing, malformed, expired or revoked key; issuer no longer authorized.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "403": {
      "description": "Organization or scope is not allowed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "404": {
      "description": "Resource does not exist in this organization.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "429": {
      "headers": {
        "Retry-After": {
          "description": "Seconds to wait before retrying.",
          "schema": {
            "type": "integer",
            "minimum": 1,
            "example": 60
          }
        }
      },
      "description": "Per-key or organization rate limit exceeded. Wait retryAfter seconds from the JSON response before retrying.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "500": {
      "description": "Unexpected server failure.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "503": {
      "description": "Temporary service failure; retry reads with backoff.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
GET /integrations/orgs/{orgId}/team

List team memberships

Required scope: team:read

Parameters
Contract
{
  "path": "/integrations/orgs/{orgId}/team",
  "method": "get",
  "operationId": "listTeam",
  "summary": "List team memberships",
  "description": "Required scope: team:read. Returns up to 100 memberships, without session or credential information.",
  "tags": [
    "team"
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "x-required-scopes": [
    "team:read"
  ],
  "parameters": [
    {
      "name": "orgId",
      "in": "path",
      "required": true,
      "description": "The one organization bound to the key.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Success",
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TeamMember"
            },
            "maxItems": 100
          }
        }
      }
    },
    "400": {
      "description": "Invalid parameters or message.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "description": "Missing, malformed, expired or revoked key; issuer no longer authorized.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "403": {
      "description": "Organization or scope is not allowed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "404": {
      "description": "Resource does not exist in this organization.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "429": {
      "headers": {
        "Retry-After": {
          "description": "Seconds to wait before retrying.",
          "schema": {
            "type": "integer",
            "minimum": 1,
            "example": 60
          }
        }
      },
      "description": "Per-key or organization rate limit exceeded. Wait retryAfter seconds from the JSON response before retrying.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "500": {
      "description": "Unexpected server failure.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "503": {
      "description": "Temporary service failure; retry reads with backoff.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
GET /integrations/orgs/{orgId}/widget

Read the organization widget

Required scope: widget:read

Parameters
Contract
{
  "path": "/integrations/orgs/{orgId}/widget",
  "method": "get",
  "operationId": "getWidget",
  "summary": "Read the organization widget",
  "description": "Required scope: widget:read. One logical widget per organization. Domain allowlists affect widget embedding, not the key’s tenant boundary.",
  "tags": [
    "widget"
  ],
  "security": [
    {
      "bearerApiKey": []
    }
  ],
  "x-required-scopes": [
    "widget:read"
  ],
  "parameters": [
    {
      "name": "orgId",
      "in": "path",
      "required": true,
      "description": "The one organization bound to the key.",
      "schema": {
        "type": "string",
        "pattern": "^[a-f0-9]{24}$",
        "example": "507f1f77bcf86cd799439011"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Success",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Widget"
          }
        }
      }
    },
    "400": {
      "description": "Invalid parameters or message.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "description": "Missing, malformed, expired or revoked key; issuer no longer authorized.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "403": {
      "description": "Organization or scope is not allowed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "404": {
      "description": "Resource does not exist in this organization.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "429": {
      "headers": {
        "Retry-After": {
          "description": "Seconds to wait before retrying.",
          "schema": {
            "type": "integer",
            "minimum": 1,
            "example": 60
          }
        }
      },
      "description": "Per-key or organization rate limit exceeded. Wait retryAfter seconds from the JSON response before retrying.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "500": {
      "description": "Unexpected server failure.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "503": {
      "description": "Temporary service failure; retry reads with backoff.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}

Schemas

Conversation
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^[a-f0-9]{24}$",
      "example": "507f1f77bcf86cd799439011"
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "closed"
      ]
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "contactId": {
      "type": "string",
      "pattern": "^[a-f0-9]{24}$",
      "example": "507f1f77bcf86cd799439011"
    },
    "sourceDomain": {
      "type": [
        "string",
        "null"
      ]
    },
    "lastMessageAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  },
  "required": [
    "id",
    "status",
    "tags",
    "contactId",
    "sourceDomain",
    "lastMessageAt"
  ],
  "additionalProperties": false
}
Message
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^[a-f0-9]{24}$",
      "example": "507f1f77bcf86cd799439011"
    },
    "body": {
      "type": "string"
    },
    "internal": {
      "type": "boolean"
    },
    "senderType": {
      "type": "string",
      "enum": [
        "agent",
        "visitor",
        "ai",
        "system"
      ]
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  },
  "required": [
    "id",
    "body",
    "internal",
    "senderType",
    "createdAt"
  ],
  "additionalProperties": false
}
SentMessage
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^[a-f0-9]{24}$",
      "example": "507f1f77bcf86cd799439011"
    },
    "body": {
      "type": "string"
    },
    "internal": {
      "type": "boolean"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  },
  "required": [
    "id",
    "body",
    "internal",
    "createdAt"
  ],
  "additionalProperties": false
}
SendMessage
{
  "type": "object",
  "properties": {
    "body": {
      "type": "string",
      "minLength": 1,
      "maxLength": 5000,
      "pattern": "\\S",
      "description": "Markdown text. Attachments are not supported by this integration endpoint."
    },
    "clientMessageId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{1,64}$",
      "description": "Stable application-generated replay ID. Reuse it only for retries of this same message with the same key and conversation."
    },
    "internal": {
      "type": "boolean",
      "default": false,
      "description": "True creates a private team note; false sends a customer-visible reply."
    }
  },
  "required": [
    "body",
    "clientMessageId"
  ],
  "additionalProperties": false
}
Contact
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^[a-f0-9]{24}$",
      "example": "507f1f77bcf86cd799439011"
    },
    "name": {
      "type": "string"
    },
    "email": {
      "type": "string"
    },
    "language": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "required": [
    "id",
    "name",
    "email",
    "language"
  ],
  "additionalProperties": false
}
Agent
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^[a-f0-9]{24}$",
      "example": "507f1f77bcf86cd799439011"
    },
    "name": {
      "type": "string"
    },
    "status": {
      "type": "string",
      "enum": [
        "draft",
        "ready",
        "paused"
      ]
    }
  },
  "required": [
    "id",
    "name",
    "status"
  ],
  "additionalProperties": false
}
TeamMember
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^[a-f0-9]{24}$",
      "example": "507f1f77bcf86cd799439011"
    },
    "userId": {
      "type": "string",
      "pattern": "^[a-f0-9]{24}$",
      "example": "507f1f77bcf86cd799439011"
    },
    "role": {
      "type": "string",
      "enum": [
        "owner",
        "admin",
        "agent"
      ]
    }
  },
  "required": [
    "id",
    "userId",
    "role"
  ],
  "additionalProperties": false
}
Widget
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "embedMode": {
      "type": "string",
      "enum": [
        "allowlist",
        "all"
      ]
    },
    "allowedDomains": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": [
    "name",
    "embedMode",
    "allowedDomains"
  ],
  "additionalProperties": false
}
Error
{
  "type": "object",
  "properties": {
    "statusCode": {
      "type": "integer"
    },
    "message": {
      "type": [
        "string",
        "array"
      ],
      "items": {
        "type": "string"
      }
    },
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string"
    },
    "retryAfter": {
      "type": "integer",
      "minimum": 1
    }
  },
  "required": [
    "message"
  ],
  "additionalProperties": true
}