Developer API
Updated on 13 November 2026
The Replivo API connects the chat to your own back office or CRM: receive visitor messages as they are written and reply from your own software. The reply appears to the visitor in the chat window, exactly as if sent from the panel.
How it works
- Create an API key under Settings → API and integrations.
- Set your webhook address: Replivo sends every new visitor message there.
- Reply by calling the API with your key.
- Send the presence signal regularly so the widget shows you as online.
Authentication
Every request carries the key in the Authorization header. The key is a secret: use it only from your server, never from code in a web page. A revoked key stops working within a minute.
Authorization: Bearer rpl_…
Base URL: https://developer.replivochat.com/api/v1
Responses are JSON: data under the data field, errors under error with a code and a message.
curl https://developer.replivochat.com/api/v1/me \ -H "Authorization: Bearer rpl_…"
Endpoints
Account
| Method | Path | What it does |
|---|---|---|
| GET | /me | Workspace and key. Handy for testing the key. |
| GET | /sites | Websites: domains, widget settings, working hours, whether the widget has been seen installed. |
| GET | /agents | Team members, roles and who is online. |
| GET | /replies | Saved replies (shortcut and text). |
Conversations
| Method | Path | What it does |
|---|---|---|
| GET | /conversations | List. status: active (default), open, assigned, closed. limit up to 100; before for the next page. |
| GET | /conversations/{id} | One conversation, with the time each side last read it. |
| POST | /conversations/{id}/assign | Assign to an agent (agentId from /agents), or to this integration when agentId is omitted. |
| POST | /conversations/{id}/unassign | Put it back in the queue. |
| POST | /conversations/{id}/close | Close the conversation. |
| POST | /conversations/{id}/reopen | Reopen a closed conversation. |
| POST | /conversations/{id}/read | Mark messages as read: the visitor sees “Seen”. |
| POST | /conversations/{id}/typing | Show “is typing…” to the visitor for 8 seconds. Body: typing, optional agentName. |
Messages
| Method | Path | What it does |
|---|---|---|
| GET | /conversations/{id}/messages | Messages. after (ISO date) returns only newer ones; limit up to 200. |
| POST | /conversations/{id}/messages | Send a reply. Body: text, optional agentName. |
| POST | /conversations/{id}/files | Send a file up to 5 MB. Body: name, contentType, dataBase64, optional text. |
| GET | /conversations/{id}/notes | Internal notes. |
| POST | /conversations/{id}/notes | Add an internal note the visitor never sees. Body: text, optional author. |
Visitors, tickets, statistics
| Method | Path | What it does |
|---|---|---|
| GET | /visitors | Who is on the site right now and which page they are viewing. |
| GET | /tickets | Offline messages. status: open or resolved. |
| POST | /tickets/{id}/resolve | Mark the ticket resolved. /reopen opens it again. |
| GET | /stats?days=7 | Conversations, messages, average response time and ratings, by day and by agent (up to 90 days). |
Presence and webhooks
| Method | Path | What it does |
|---|---|---|
| PUT | /presence | Show yourself as online in the widget. Body: online, ttlSeconds (30–600, default 120). |
| GET | /webhooks/deliveries | The delivery log. status: delivered, pending or failed. |
| POST | /webhooks/deliveries/{id}/retry | Send a notification again now. |
Example: reply to a visitor
curl -X POST https://developer.replivochat.com/api/v1/conversations/CONVERSATION_ID/messages \
-H "Authorization: Bearer rpl_…" \
-H "Content-Type: application/json" \
-d '{"text": "Po, e kemi në stok.", "agentName": "Arta"}'Sending a file (content encoded as base64)
curl -X POST https://developer.replivochat.com/api/v1/conversations/CONVERSATION_ID/files \
-H "Authorization: Bearer rpl_…" \
-H "Content-Type: application/json" \
-d '{"name": "oferta.pdf", "contentType": "application/pdf", "dataBase64": "JVBERi0xLjQK…"}'Presence
The widget shows “Online” only when someone can answer. If you reply only from your own system, call this regularly (for example every minute) while your operators are at work. When the signal stops, the widget switches to the message form by itself once the time runs out.
curl -X PUT https://developer.replivochat.com/api/v1/presence \
-H "Authorization: Bearer rpl_…" \
-H "Content-Type: application/json" \
-d '{"online": true, "ttlSeconds": 120}'Webhooks
Set the address under Settings → Business → Webhook URL. It must be https. Replivo sends a POST request for each event:
message.created | A new message in a conversation. The from field is visitor or agent (your own API replies arrive here too). |
conversation.started | A new conversation began. |
conversation.assigned | The conversation was taken by or assigned to someone. |
conversation.closed | The conversation was closed. |
conversation.reopened | The conversation was reopened, by the team or because the visitor wrote again. |
conversation.rated | The visitor rated the conversation (1–5). |
ticket.created | A visitor left an offline message. |
ticket.resolved | A ticket was marked resolved (ticket.reopened when opened again). |
ping | Test event, sent from the button under Settings. |
Example body for message.created
{
"id": "0b1f…",
"event": "message.created",
"workspaceId": "…",
"createdAt": "2026-11-13T17:40:00.000Z",
"data": {
"conversationId": "…",
"messageId": "…",
"siteId": "…",
"from": "visitor",
"text": "A e keni produktin në stok?",
"attachments": [],
"visitor": { "id": "…", "name": "Besa", "email": "besa@example.com" },
"createdAt": "2026-11-13T17:40:00.000Z"
}
}Verifying the signature
Create a signing secret under Settings → API and integrations. Every request then carries the X-Replivo-Signature header with the time t and the signature v1 = HMAC-SHA256 of the string “t.body” with your secret. Reject requests with a wrong signature or a time older than five minutes.
// Node.js (Express): use the raw request body, not the parsed JSON
const crypto = require("crypto");
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(parts.t + "." + rawBody).digest("hex");
return expected.length === parts.v1.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}Good to know
- Every notification is sent immediately. Answer within 5 seconds with a 2xx code; otherwise it is retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours, then marked failed.
- The id field is the same on every retry: use it to avoid processing the same event twice.
- The delivery log is shown under Settings and at /webhooks/deliveries, and is kept for about 7 days.
- The limit is about 240 requests per minute per key. Beyond it you get 429.
- Replying to a closed conversation returns 409: reopen it first.
- The first reply from the API takes the conversation, as in the panel.
Error codes
400 invalid_request | 401 unauthorized | 403 suspended |
404 not_found | 409 conversation_closed | 429 rate_limited |
For technical questions write to info@replivochat.com.