Developer API

Updated on 13 November 2026

Download as PDF

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

  1. Create an API key under Settings → API and integrations.
  2. Set your webhook address: Replivo sends every new visitor message there.
  3. Reply by calling the API with your key.
  4. 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

MethodPathWhat it does
GET/meWorkspace and key. Handy for testing the key.
GET/sitesWebsites: domains, widget settings, working hours, whether the widget has been seen installed.
GET/agentsTeam members, roles and who is online.
GET/repliesSaved replies (shortcut and text).

Conversations

MethodPathWhat it does
GET/conversationsList. 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}/assignAssign to an agent (agentId from /agents), or to this integration when agentId is omitted.
POST/conversations/{id}/unassignPut it back in the queue.
POST/conversations/{id}/closeClose the conversation.
POST/conversations/{id}/reopenReopen a closed conversation.
POST/conversations/{id}/readMark messages as read: the visitor sees “Seen”.
POST/conversations/{id}/typingShow “is typing…” to the visitor for 8 seconds. Body: typing, optional agentName.

Messages

MethodPathWhat it does
GET/conversations/{id}/messagesMessages. after (ISO date) returns only newer ones; limit up to 200.
POST/conversations/{id}/messagesSend a reply. Body: text, optional agentName.
POST/conversations/{id}/filesSend a file up to 5 MB. Body: name, contentType, dataBase64, optional text.
GET/conversations/{id}/notesInternal notes.
POST/conversations/{id}/notesAdd an internal note the visitor never sees. Body: text, optional author.

Visitors, tickets, statistics

MethodPathWhat it does
GET/visitorsWho is on the site right now and which page they are viewing.
GET/ticketsOffline messages. status: open or resolved.
POST/tickets/{id}/resolveMark the ticket resolved. /reopen opens it again.
GET/stats?days=7Conversations, messages, average response time and ratings, by day and by agent (up to 90 days).

Presence and webhooks

MethodPathWhat it does
PUT/presenceShow yourself as online in the widget. Body: online, ttlSeconds (30–600, default 120).
GET/webhooks/deliveriesThe delivery log. status: delivered, pending or failed.
POST/webhooks/deliveries/{id}/retrySend 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.createdA new message in a conversation. The from field is visitor or agent (your own API replies arrive here too).
conversation.startedA new conversation began.
conversation.assignedThe conversation was taken by or assigned to someone.
conversation.closedThe conversation was closed.
conversation.reopenedThe conversation was reopened, by the team or because the visitor wrote again.
conversation.ratedThe visitor rated the conversation (1–5).
ticket.createdA visitor left an offline message.
ticket.resolvedA ticket was marked resolved (ticket.reopened when opened again).
pingTest 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

Error codes

400 invalid_request401 unauthorized403 suspended
404 not_found409 conversation_closed429 rate_limited

For technical questions write to info@replivochat.com.