Sessions and conversations
Create session
Creates a new conversation session.
POST /v1/custom/:integration_id/sessions
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
Request body
{
"external_session_id": "order-12345",
"channel_user_id": "user-67890",
"channel_type": "chat",
"context": {
"user": {
"display_name": "John Doe",
"email": "john.doe@example.com",
"phone": "+1234567890",
"language": "en"
},
"tags": ["vip", "returning-customer"],
"global": {
"client_url": "https://example.com/support"
},
"order_id": "ORD-12345",
"subscription_tier": "premium"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
external_session_id | string | No | Your system's unique identifier for this session. Stored in context.channels.custom.external_session_id. |
channel_user_id | string | No | Unique identifier for the user in your system. Stored in context.user.custom_psid. |
channel_type | string | No | The kind of channel this session runs on: chat, email, or voice. Omit it to let Moveo apply the default. Any other value is rejected with 400 invalid-payload. |
context | object | No | Session context with user information and custom variables. See context object. |
Response — 201 Created
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"session_id": "660e8400-e29b-41d4-a716-446655440001",
"context": {
"user": { ... },
"tags": [...],
"global": { ... }
}
}
| Field | Type | Description |
|---|---|---|
request_id | string | Unique identifier for this request. |
session_id | UUID | The created session ID. Use this for all subsequent API calls. |
context | object | The session context, which may include default values. |
Example
curl -X POST "https://channels.moveo.ai/v1/custom/YOUR_INTEGRATION_ID/sessions" \
-H "Authorization: apikey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_session_id": "order-12345",
"channel_user_id": "user-67890",
"context": {
"user": {
"display_name": "John Doe",
"email": "john.doe@example.com",
"language": "en"
},
"tags": ["vip"],
"order_id": "ORD-12345"
}
}'
Get session context
Returns the current context of a session. Read the context before a PATCH when you need to preserve array fields such as tags, which a PATCH replaces rather than extends.
GET /v1/custom/:integration_id/sessions/:session_id/context
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
session_id | UUID | Yes | The session ID. |
Request body — None.
Response — 200 OK
{
"context": {
"user": { ... },
"tags": ["vip"],
"global": { ... }
}
}
This endpoint returns the request identifier in the X-Request-Id response header rather than in the body.
Example
curl "https://channels.moveo.ai/v1/custom/YOUR_INTEGRATION_ID/sessions/SESSION_ID/context" \
-H "Authorization: apikey YOUR_API_KEY"
Update session context
Updates the context variables for an existing session without sending a message. The payload is merged into the existing context, so fields you omit are left untouched.
Array fields such as tags are overwritten by the value you send. To add a single tag without losing the others, either read the current context first and send the full list back, or use the add tags endpoint, which does the merge for you.
PATCH /v1/custom/:integration_id/sessions/:session_id/context
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
session_id | UUID | Yes | The session ID. |
Request body
Same structure as the context object in create session. Only included fields are updated.
{
"user": {
"email": "john.updated@example.com"
},
"tags": ["verified-user", "premium"],
"account_status": "verified"
}
Response — 200 OK
{
"request_id": "550e8400-e29b-41d4-a716-446655440004",
"context": { ... }
}
Example
curl -X PATCH "https://channels.moveo.ai/v1/custom/YOUR_INTEGRATION_ID/sessions/SESSION_ID/context" \
-H "Authorization: apikey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user": {
"email": "john.updated@example.com",
"verified": true
},
"account_status": "verified",
"tags": ["verified-user", "premium"]
}'
Add tags
Adds conversation tags to a session without resending the full context. The tags you send are merged with the ones already on the session, so re-adding an existing tag has no effect. A session can hold at most 25 tags.
PUT /v1/custom/:integration_id/sessions/:session_id/context/tags
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
session_id | UUID | Yes | The session ID. |
Request body
{
"tags": ["vip", "urgent"]
}
| Field | Type | Required | Description |
|---|---|---|---|
tags | array | Yes | One or more tags to add. Must contain at least one non-empty tag. |
Response — 200 OK
The response contains the session's complete tag list after the update, with the tags from this request first.
{
"tags": ["vip", "urgent", "returning-customer"]
}
This endpoint returns the request identifier in the X-Request-Id response header rather than in the body.
Example
curl -X PUT "https://channels.moveo.ai/v1/custom/YOUR_INTEGRATION_ID/sessions/SESSION_ID/context/tags" \
-H "Authorization: apikey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tags": ["vip", "urgent"]
}'
Tag normalization
Moveo stores tags in a canonical form. Before a tag is saved:
- Non-ASCII characters are transliterated to their closest ASCII equivalent.
- Any character outside
A-Z,a-z,0-9, and_becomes a hyphen. - The tag is truncated to 48 characters.
- Duplicates within the request are removed.
Send tags already in this form so that adds and removals match reliably. For example, Urgent Case! is stored as Urgent-Case, and removing it requires the canonical value.
Tag updates are read-modify-write: the current tags are read, the new list is computed, then written back. Two tag updates in flight on the same session can overwrite each other and lose a change. Serialize tag updates per session if every change must be applied. This applies to both add and remove.
Remove tags
Removes tags from a session. Tags that are not on the session are ignored.
DELETE /v1/custom/:integration_id/sessions/:session_id/context/tags
This endpoint takes the tags to remove in a JSON request body. Some proxies, API gateways, and generated SDK clients drop or reject bodies on DELETE requests. If your client cannot send one, overwrite the full tag list with update session context instead.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
session_id | UUID | Yes | The session ID. |
Request body
{
"tags": ["urgent"]
}
| Field | Type | Required | Description |
|---|---|---|---|
tags | array | Yes | One or more tags to remove. Must contain at least one non-empty tag. |
Response — 200 OK
The response contains the session's remaining tags.
{
"tags": ["vip", "returning-customer"]
}
This endpoint returns the request identifier in the X-Request-Id response header rather than in the body.
Example
curl -X DELETE "https://channels.moveo.ai/v1/custom/YOUR_INTEGRATION_ID/sessions/SESSION_ID/context/tags" \
-H "Authorization: apikey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tags": ["urgent"]
}'
Close session
Closes an existing session. This ends the session and triggers a session:closed webhook event.
POST /v1/custom/:integration_id/sessions/:session_id/close
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
session_id | UUID | Yes | The session ID. |
Request body — None required.
Response — 200 OK
{
"request_id": "550e8400-e29b-41d4-a716-446655440005"
}
Context object
The context object is used when creating sessions, sending messages, and updating context. It supports the following fields:
| Field | Type | Description |
|---|---|---|
user | object | User profile information. See user object. |
tags | array | Array of string tags to apply to the session. Maximum 25, normalized before they are stored. To change tags on a live session, prefer add tags and remove tags. |
channels | object | Channel-specific context data. |
global | object | Global variables that persist across dialog execution. |
| custom_variable | any | Any additional custom context variables. |
User object
| Field | Type | Description |
|---|---|---|
user_id | string | Internal user identifier. |
display_name | string | User's display name. |
avatar | string | URL to user's avatar image. |
external_id | string | External system user ID. |
contact_id | string | Contact management system ID. |
email | string | User's email address. |
phone | string | User's phone number. |
language | string | User's preferred language (ISO 639-1 code). |
timezone | string | User's timezone (IANA format, e.g., America/New_York). |
gender | string | User's gender. |
address | string | User's address. |
location | object | User's location with city, country, region, latitude, longitude. |
locales | array | Array of locale strings. |
browser | string | User's browser information. |
platform | string | User's platform (e.g., web, mobile). |
device | string | User's device type. |
ip | string | User's IP address. |
Global object
| Field | Type | Description |
|---|---|---|
disclaimer_accepted | boolean | Whether user accepted disclaimer. |
visitor_form_completed | boolean | Whether visitor form was completed. |
client_url | string | Client's current URL. |
ref | string | Referral parameter. |
| custom_variable | any | Any additional global variables. |
Close conversation
Marks the current conversation as resolved. The session remains active and can receive new messages, which start a new conversation.
POST /v1/custom/:integration_id/sessions/:session_id/conversation/close
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
session_id | UUID | Yes | The session ID. |
Request body — None required.
Response — 200 OK
{
"request_id": "550e8400-e29b-41d4-a716-446655440006"
}
Reopen conversation
Reopens a previously resolved conversation within the same session.
POST /v1/custom/:integration_id/sessions/:session_id/conversation/reopen
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
session_id | UUID | Yes | The session ID. |
Request body — None required.
Response — 200 OK
{
"request_id": "550e8400-e29b-41d4-a716-446655440007"
}
Handover
Transfers the conversation to a human agent through Moveo's live chat system. After a handover the AI Agent stops replying, so the human agent and the AI Agent never answer at the same time.
Calling this endpoint is optional if your system handles agent messaging externally: send agent message hands the session over on its own when it is the first agent message. Call it explicitly when you want to hand over ahead of that first message — for example, while the user waits in a queue. Calling it on an already handed-over session is safe.
POST /v1/custom/:integration_id/sessions/:session_id/handover
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id | UUID | Yes | Your custom integration ID. |
session_id | UUID | Yes | The session ID. |
Request body — None required.
Response — 200 OK
{
"request_id": "550e8400-e29b-41d4-a716-446655440008"
}