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.

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

Diagnostics: events & network logs

In the SDK flow the widget attaches the recent Gleap.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:
Both return 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.
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.