All endpoints are relative to https://api.supovia.com. Create an API key in your Supovia dashboard, then authenticate every request with it.
apiKey — HTTP Basic auth carrying only the API key secret: Authorization: Basic base64(<key secret>).
accessToken — Operator session token issued by the Supovia dashboard: Authorization: Token <access token>.
Download the OpenAPI specification for use with your own tooling.
Conversations
GET/api/conversations
List conversations
Lists the conversations of your organization, newest first when sorted by lastEditTime. Requires the conversations:read scope.
conversations:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| websiteId | query | string | |
| customerId | query | string | |
| limit | query | integer | |
| skip | query | integer | |
| sortField | query | string | |
| sortDirection | query | string (ASC | DESC) | |
| resolved | query | boolean | |
| spam | query | boolean | Only conversations filed as spam (true) or only the others (false) |
| inboxFilter | query | string (all | unread | unresolved | resolved | mentions | spam) | Operator-only bounded inbox with full filter counts; requires websiteId |
| conversationFilter | query | string (all | last-hour | today | last-week | online) | Time or presence scope for inboxFilter mode |
| timezone | query | string | IANA timezone for the Today inbox filter (defaults to UTC) |
| fields | query | string | Comma-separated projection of fields to return |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Array of conversations, or { conversations, total, filteredTotal } when inboxFilter is supplied |
| 401 | Missing or invalid credentials |
| 403 | API key is missing the conversations:read scope |
| 429 | API key rate limit exceeded |
GET/api/conversations/{conversationId}
Get a conversation
Returns a single conversation by id. Conversations belonging to another organization respond 404. Requires the conversations:read scope.
conversations:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| conversationIdrequired | path | string | |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | The conversation |
| 404 | Not found (or owned by another organization) |
Customers
GET/api/customers
List customers
Requires the customers:read scope.
customers:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| websiteId | query | string | |
| email | query | string | |
| userId | query | string | Your own user id set via the widget setUserId |
| fields | query | string | Comma-separated projection of fields to return |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Array of customers |
POST/api/customers
Create a customer
Creates a customer on a website. Emits the customer.created webhook event. Requires the customers:write scope.
customers:writeapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Request body
| Field | Type | Description |
|---|
| email | string | |
| nickname | string | |
| phone | string | |
| language | string | |
Responses
| Status | Meaning |
|---|
| 200 | The created customer |
| 403 | API key is missing the customers:write scope |
GET/api/customers/{customerId}
Get a customer
Returns a single customer by id. Customers belonging to another organization respond 404. Requires the customers:read scope.
customers:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| customerIdrequired | path | string | |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | The customer |
| 404 | Not found (or owned by another organization) |
PUT/api/customers/{customerId}
Update a customer
Requires the customers:write scope.
customers:writeapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| customerIdrequired | path | string | |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | The updated customer |
Documents
GET/api/documents/search
Search documents
Semantic (vector) search over your published help documents. Requires the documents:read scope.
documents:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| queryrequired | query | string | |
| websiteId | query | string | |
| locale | query | string | |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Array of matching documents, best match first |
GET/api/documents
List documents
Requires the documents:read scope. For stable traversal, set pagination=cursor; the response becomes {items, nextCursor} and is ordered by ascending _id. Pass nextCursor back as cursor until it is null. Existing array responses and offset pagination remain available when cursor pagination is not requested.
documents:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| websiteId | query | string | |
| locale | query | string | |
| documentId | query | string | Exact document id |
| category | query | string | |
| published | query | boolean | |
| search | query | string | Plain-text title search |
| pagination | query | string (cursor) | Set to cursor for a stable page envelope |
| cursor | query | string | Opaque nextCursor from the preceding cursor page |
| limit | query | integer | Optional bounded page size (maximum 500 and default 100 in cursor mode; 0 returns everything otherwise) |
| skip | query | integer | |
| fields | query | string | Comma-separated projection of fields to return |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Array of documents, or {items, nextCursor} in cursor mode |
Messages
GET/api/messages
List messages
Lists messages, usually filtered by conversationId. Requires the messages:read scope.
messages:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| conversationId | query | string | |
| limit | query | integer | |
| skip | query | integer | |
| sortField | query | string | |
| sortDirection | query | string (ASC | DESC) | |
| fields | query | string | Comma-separated projection of fields to return |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Array of messages |
POST/api/messages
Create a message
Appends a message to a conversation. from is operator for replies sent on behalf of your team and customer for messages on behalf of the visitor. Emits the message.created webhook event. Requires the messages:write scope.
messages:writeapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
| Idempotency-Key | header | string | Unique retry key retained for 24 hours (maximum 255 characters). Authenticated callers only. |
Request body
| Field | Type | Description |
|---|
| conversationIdrequired | string | |
| contentrequired | string | |
| fromrequired | string (operator | customer) | |
| replyToMessageId | string | Optional. The id of an earlier message of the same conversation this one answers, shown as a quote above the message (like a WhatsApp reply). Ignored when it does not name a message of this conversation. Every AI agent reply carries the id of the customer message it answered.
|
Responses
| Status | Meaning |
|---|
| 200 | The created message |
| 403 | API key is missing the messages:write scope |
GET/api/messages/{messageId}
Get a message by id
Returns one message to an authenticated operator or API key. A key requires the messages:read scope. Anonymous chat sessions cannot use this route. Messages belonging to another organization, or to a different Website than a Website-pinned key, respond 404.
messages:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| messageIdrequired | path | string | |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | The message |
| 404 | Not found (or outside the authenticated tenant) |
POST/api/messages/{messageId}/read
Mark a protected customer reply as read
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | The receipt is read (including an idempotent retry) |
POST/api/messages/{messageId}/rating
Rate an agent or operator reply
Records how the visitor rated one reply, as rating and ratingTime on that message. Called by the embedded chat surfaces with the visitor's chat-session credentials; there is no API-key or operator-token path, because the rating is the customer's own answer and nobody else may author it. Re-rating the same message overwrites the previous value. Emits MESSAGE_UPDATED_EVENT to the dashboard.
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Request body
| Field | Type | Description |
|---|
| websiteIdrequired | string | |
| ratingrequired | string (unhappy | neutral | happy) | |
Responses
| Status | Meaning |
|---|
| 200 | The rated message |
| 400 | Unrecognised rating value |
| 404 | No such rateable message for this chat session |
POST/api/messages/{messageId}/rating/operator
Rate an AI agent reply as the signed-in operator
Records how the signed-in operator rated one AI agent reply, on the same three faces the visitor rates replies with, and optionally why. Each operator holds one rating per message: rating again replaces theirs and leaves their colleagues' ratings alone. A comment explains an unhappy or neutral rating; leaving it out keeps the comment the operator already wrote, an empty string removes it, and a happy rating never keeps one. Operator ratings are team-only: no visitor read, visitor event or webhook carries them. Emits MESSAGE_UPDATED_EVENT to the dashboard.
accessToken
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Request body
| Field | Type | Description |
|---|
| ratingrequired | string (unhappy | neutral | happy) | |
| comment | string | What was wrong with the reply |
Responses
| Status | Meaning |
|---|
| 200 | The message with its updated operator ratings |
| 400 | An unrecognised rating, or a comment that is too long or given with a happy rating |
| 404 | No such AI agent reply in the operator's organization |
| 409 | The message's operator ratings changed concurrently, or it holds the maximum number of ratings |
POST/api/messages/{messageId}/reaction/operator
Set or clear the signed-in operator's reaction to a message
Each person holds at most one emoji reaction per message: a new emoji replaces the operator's previous one, and emoji: null takes it back. Any message of the operator's organization may be reacted to, internal notes included; reactions on notes and operator-only conversations never reach the visitor. Emits MESSAGE_UPDATED_EVENT to the dashboard and, for a message the visitor can see, an id-only MESSAGE_UPDATED_EVENT on the visitor's channel.
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Request body
| Field | Type | Description |
|---|
| emojirequired | string | One emoji, or null to remove the reaction |
Responses
| Status | Meaning |
|---|
| 200 | The message with its updated reactions |
| 400 | The value is not a single emoji |
| 404 | No such message in the operator's organization |
| 409 | The message's reactions changed concurrently, or it holds the maximum number of reactions |
POST/api/messages/{messageId}/reaction/customer
Set or clear the visitor's reaction to a message
Called by the embedded chat surfaces with the visitor's chat-session credentials, the only credential this route accepts. The visitor holds at most one reaction per message; a new emoji replaces it and emoji: null takes it back. Internal notes and operator-only conversations cannot be reacted to. Responds with only the message id and its reactions as a visitor may see them — which emojis, and whether each came from the visitor or from the team.
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Request body
| Field | Type | Description |
|---|
| websiteIdrequired | string | |
| emojirequired | string | |
Responses
| Status | Meaning |
|---|
| 200 | The message id and its visitor-visible reactions |
| 400 | The value is not a single emoji |
| 404 | No such message in this chat session's transcript |
| 409 | The message's reactions changed concurrently, or it holds the maximum number of reactions |
Sandbox
GET/api/sandbox/documents
Read sandbox help-center documents without authentication
Returns a fixed set of demonstration help-center documents in the same {title, locale} shape as authenticated document reads. No account, credential, or key is required, so agents can evaluate the API before onboarding. Responses carry the standard RateLimit response headers and the anonymous pacing limit applies.
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Demonstration help-center documents. |
| 429 | Anonymous rate limit exceeded; retry after Retry-After seconds. |
POST/api/sandbox/documentsummaryjobs
Start a demonstration asynchronous document-summary job
Demonstrates the API's asynchronous-job pattern without authentication. The response is 202 Accepted with a Location header pointing at the job resource and a body carrying the job _id and status. Poll the Location URL until the status is succeeded, then read the summary from the job body. The job is deterministic fixture work that completes about two seconds after creation.
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 202 | Job accepted; poll the Location URL for the result. |
| 429 | Anonymous rate limit exceeded; retry after Retry-After seconds. |
GET/api/sandbox/documentsummaryjobs/{jobId}
Poll a demonstration document-summary job
Reads the status of a demonstration job started at POST /api/sandbox/documentsummaryjobs. While the job runs the status is running; afterwards it is succeeded and the body carries the document summary. No authentication is required.
Parameters
| Name | In | Type | Description |
|---|
| jobIdrequired | path | string | |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Current job state. |
| 404 | Unknown job id. |
Webhook subscriptions
GET/api/webhooksubscriptions
List webhook subscriptions
Webhook subscriptions deliver message.created, conversation.created and customer.created events to your server as signed POST requests (X-Supovia-Signature: t=<timestamp>,v1=<hex HMAC-SHA256 of "timestamp.body">). An endpoint failing 20 times in a row is disabled automatically. Subscriptions are managed with an operator access token; the secret is only returned once, on create.
accessToken
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Array of webhook subscriptions (without secrets) |
POST/api/webhooksubscriptions
Create a webhook subscription
The response includes the signing secret exactly once — store it; it cannot be retrieved again.
accessToken
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Request body
| Field | Type | Description |
|---|
| websiteIdrequired | string | |
| urlrequired | string | |
| events | array (message.created | conversation.created | customer.created) | Empty array subscribes to all events |
Responses
| Status | Meaning |
|---|
| 200 | The created subscription, including its secret |
PUT/api/webhooksubscriptions/{webhookSubscriptionId}
Update a webhook subscription
url, events and active are editable; the secret and website are immutable. Re-enabling an auto-disabled endpoint is done by setting active back to true.
accessToken
Parameters
| Name | In | Type | Description |
|---|
| webhookSubscriptionIdrequired | path | string | |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | The updated subscription (without secret) |
DELETE/api/webhooksubscriptions/{webhookSubscriptionId}
Delete a webhook subscription
accessToken
Parameters
| Name | In | Type | Description |
|---|
| webhookSubscriptionIdrequired | path | string | |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
Websites
GET/api/websites
List websites
Lists the websites (projects) of your organization. Requires the websites:read scope.
websites:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | Array of websites |
GET/api/websites/{websiteName}
Get a website by vanity id
Requires the websites:read scope.
websites:readapiKeyaccessToken
Parameters
| Name | In | Type | Description |
|---|
| websiteNamerequired | path | string | Website vanity ID. The parameter name is retained for API compatibility. |
| API-Version | header | string (1) | Compatibility version. Omit to select version 1. |
Responses
| Status | Meaning |
|---|
| 200 | The website |
| 404 | Not found |