Gleap-Version. Send an Idempotency-Key (any unique string, e.g. a UUID) on POSTs you might retry.
Base URL
The API host depends on the data region of your project:The examples on this page use the EU host. If your project lives in another region, replace
https://api.gleap.io with your region’s host. API tokens are per project and only valid in the project’s region.1. Upsert the contact
Contacts are addressed by your user identifier and deduplicate with SDK-created contacts on the same id.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
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
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
attachments. Max 25 MB per file.
Diagnostics: events & network logs
In the SDK flow the widget attaches the recentGleap.trackEvent() buffer and Gleap.logNetwork() requests to a conversation when it is created. Without the SDK, push the same snapshots yourself — per conversation, so events from other sessions of the same contact never mix in:
204 and show up in the conversation’s Logs panel for agents. Each call replaces the previous snapshot for that conversation (an empty array clears it). Limits: 500 events / 100 requests, 2 MB per call. Nothing is emitted on webhooks or the stream.
POST /v3/s2s/contacts/{userId}/events is different: those events belong to the contact, feed outbound rules and the contact timeline, and are not attached to any conversation.