Skip to main content

Sessions and conversations

Create session

Creates a new conversation session.

POST /v1/custom/:integration_id/sessions

Path parameters

ParameterTypeRequiredDescription
integration_idUUIDYesYour 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"
}
}
FieldTypeRequiredDescription
external_session_idstringNoYour system's unique identifier for this session. Stored in context.channels.custom.external_session_id.
channel_user_idstringNoUnique identifier for the user in your system. Stored in context.user.custom_psid.
channel_typestringNoThe 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.
contextobjectNoSession context with user information and custom variables. See context object.

Response201 Created

{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"session_id": "660e8400-e29b-41d4-a716-446655440001",
"context": {
"user": { ... },
"tags": [...],
"global": { ... }
}
}
FieldTypeDescription
request_idstringUnique identifier for this request.
session_idUUIDThe created session ID. Use this for all subsequent API calls.
contextobjectThe 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

ParameterTypeRequiredDescription
integration_idUUIDYesYour custom integration ID.
session_idUUIDYesThe session ID.

Request body — None.

Response200 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.

Arrays are replaced, not merged

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

ParameterTypeRequiredDescription
integration_idUUIDYesYour custom integration ID.
session_idUUIDYesThe 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"
}

Response200 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

ParameterTypeRequiredDescription
integration_idUUIDYesYour custom integration ID.
session_idUUIDYesThe session ID.

Request body

{
"tags": ["vip", "urgent"]
}
FieldTypeRequiredDescription
tagsarrayYesOne or more tags to add. Must contain at least one non-empty tag.

Response200 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.

Concurrent tag updates

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
DELETE with a request body

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

ParameterTypeRequiredDescription
integration_idUUIDYesYour custom integration ID.
session_idUUIDYesThe session ID.

Request body

{
"tags": ["urgent"]
}
FieldTypeRequiredDescription
tagsarrayYesOne or more tags to remove. Must contain at least one non-empty tag.

Response200 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

ParameterTypeRequiredDescription
integration_idUUIDYesYour custom integration ID.
session_idUUIDYesThe session ID.

Request body — None required.

Response200 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:

FieldTypeDescription
userobjectUser profile information. See user object.
tagsarrayArray 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.
channelsobjectChannel-specific context data.
globalobjectGlobal variables that persist across dialog execution.
custom_variableanyAny additional custom context variables.

User object

FieldTypeDescription
user_idstringInternal user identifier.
display_namestringUser's display name.
avatarstringURL to user's avatar image.
external_idstringExternal system user ID.
contact_idstringContact management system ID.
emailstringUser's email address.
phonestringUser's phone number.
languagestringUser's preferred language (ISO 639-1 code).
timezonestringUser's timezone (IANA format, e.g., America/New_York).
genderstringUser's gender.
addressstringUser's address.
locationobjectUser's location with city, country, region, latitude, longitude.
localesarrayArray of locale strings.
browserstringUser's browser information.
platformstringUser's platform (e.g., web, mobile).
devicestringUser's device type.
ipstringUser's IP address.

Global object

FieldTypeDescription
disclaimer_acceptedbooleanWhether user accepted disclaimer.
visitor_form_completedbooleanWhether visitor form was completed.
client_urlstringClient's current URL.
refstringReferral parameter.
custom_variableanyAny 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

ParameterTypeRequiredDescription
integration_idUUIDYesYour custom integration ID.
session_idUUIDYesThe session ID.

Request body — None required.

Response200 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

ParameterTypeRequiredDescription
integration_idUUIDYesYour custom integration ID.
session_idUUIDYesThe session ID.

Request body — None required.

Response200 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

ParameterTypeRequiredDescription
integration_idUUIDYesYour custom integration ID.
session_idUUIDYesThe session ID.

Request body — None required.

Response200 OK

{
"request_id": "550e8400-e29b-41d4-a716-446655440008"
}