Skip to main content
All requests carry your service-account token and ideally a pinned Gleap-Version. Send an Idempotency-Key (any unique string, e.g. a UUID) on POSTs you might retry.

1. Upsert the contact

Contacts are addressed by your user identifier and deduplicate with SDK-created contacts on the same id.
The response includes unread — the contact’s total unread conversation count for your badge.

2. Open a conversation

The first message rides along. workflowId starts a workflow exactly like the SDK’s startConversation; agentId engages an AI agent directly (the two are mutually exclusive). attributes values land as ticket attributes — define an attribute in Settings → Data attributes with shared visibility disabled and it is visible to your agents but never to the customer (the AI-handover-summary pattern):
A workflow’s first step lands asynchronously (~1 second). React to the workflow.step.presented event, or fetch GET /v3/s2s/conversations/{id}/workflow.

3. Send and read messages

Read oldest → newest, cursor-paginated (max 100 per page). Pass after = the last message id you already have:
author.type is contact, agent, bot or system. Internal team notes never appear on this surface.

4. Mark read

Reading messages never changes unread state — send the explicit receipt when your UI displays the conversation:

5. List the contact’s conversations

Most recent activity first; bot-only conversations without human interaction are hidden, exactly like the widget’s list:

6. Close / reopen

While closed, customer messages are rejected with problem code conversation_closed; POST …/reopen re-enables them. Your support team closing a conversation in the dashboard behaves identically and emits the same conversation.closed event.

Uploads & voice notes

Attach the returned descriptor to a message’s attachments. Max 25 MB per file.
File URLs are signed and expire (about 1 day in API responses, about 30 days inside webhook payloads) and their signatures rotate. Never persist or deduplicate by URL — store the message id and re-fetch the message when you need a fresh link.