DOCS/REST API~ 9 MIN READ

REST Β· v1 Β· BEARER

Drive your workspace
from your own code.

The REST API lets your CRM, e-commerce backend, automation tool, or migration script send messages, list conversations, and read contacts in your EasyLiveChat workspace β€” using a tenant-scoped key, not an agent password.

Β§ 00What the REST API is

EasyLiveChat exposes a REST API at /api/v1/* so external code β€” your own backend, a CRM integration, a Zapier or n8n flow, a migration script β€” can read and write your workspace without a human agent being logged in. Every call is authenticated with an API key minted in the dashboard and scoped to your tenant.

If you've ever called the Stripe, Slack, or GitHub API, this works the same way: long-lived secret token in an Authorization header, JSON request and response bodies, predictable HTTP status codes.

An API key never carries 2FA or a password β€” that's the whole point. It's a credential you embed in another piece of software so that software can act on your tenant's behalf, with only the scopes you give it.

Β§ 01Plan availability

The REST API is available on every paid plan and unlocked during the 14-day trial. There's no per-call billing.

Once a trial expires, the API switches to read-only β€” writes return 402 until the workspace is upgraded. Reads keep working so your historical exports never break.

Β§ 02Authentication

Mint a key from https://app.livechattools.com/settings/api-keys. Pick the smallest set of scopes the integration actually needs. You can revoke a key from the same page at any time β€” it stops working instantly, with no effect on your agents' dashboard or mobile logins.

Pass the key on every request, either as a Bearer token or via x-api-key:

Authorization: Bearer plk_<your-key>
# β€” or, equivalently β€”
x-api-key: plk_<your-key>

Verify the key works before wiring it into anything β€” /me echoes your scopes and tenant:

curl https://api.livechattools.com/api/v1/me \
  -H "Authorization: Bearer plk_<your-key>"

The raw key is only shown once at creation. Lost it? Revoke it and mint a new one β€” there's no way to recover the original value.

Β§ 03Scopes

Scopes are checked on every request. A key with only :read scopes can never accidentally mutate data β€” useful for read-only dashboards, BI exports, or analytics pipelines.

ScopeAllows
conversations:readList and read conversations and their messages.
conversations:writeClose, reopen, or reassign conversations.
messages:readRead message history for a conversation.
messages:writeSend a new message as an agent.
contacts:readList and search contacts.

Principle of least privilege β€” separate keys per integration. A leaked read-only key on your reporting pipeline is much less damaging than a single "do-everything" key shared across your stack.

Β§ 04Endpoints

Every path is rooted at /api/v1. Responses are JSON. Times are ISO 8601 UTC.

GET /api/v1/me

Echoes the key's identity and tenant. No scope required β€” useful for connection testing.

curl https://api.livechattools.com/api/v1/me \
  -H "Authorization: Bearer plk_<key>"

{
  "apiKeyId": "ck...",
  "scopes": ["conversations:read","messages:write"],
  "tenant": { "id": "...", "name": "Acme", "slug": "acme", "planTier": "GROWTH" }
}

GET /api/v1/conversations

List conversations newest-first. All filters are optional.

  • ?status= OPEN Β· SNOOZED Β· CLOSED
  • ?channel= WIDGET Β· WHATSAPP Β· TELEGRAM Β· MESSENGER Β· INSTAGRAM
  • ?limit= 1–200, default 50
  • ?cursor= id of the last row from the previous page
curl "https://api.livechattools.com/api/v1/conversations?status=OPEN&limit=50" \
  -H "Authorization: Bearer plk_<key>"

{
  "data": [
    { "id":"...", "sourceChannel":"WHATSAPP", "status":"OPEN",
      "lastMessagePreview":"hi there", "lastMessageAt":"..." }
  ],
  "nextCursor": "..."
}

GET /api/v1/conversations/:id

Fetch one conversation with its contact attached.

GET /api/v1/conversations/:id/messages

Paginated message history for a conversation, newest first.

curl "https://api.livechattools.com/api/v1/conversations/<id>/messages?limit=50" \
  -H "Authorization: Bearer plk_<key>"

POST /api/v1/conversations/:id/messages

Send an outbound message on a conversation. Fans out to the matching channel (widget, WhatsApp, Telegram, Messenger, Instagram) exactly the way a human agent's reply would.

curl -X POST "https://api.livechattools.com/api/v1/conversations/<id>/messages" \
  -H "Authorization: Bearer plk_<key>" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Your order has shipped." }'

# β†’ 201 Created
{ "message": { "id":"...", "senderType":"AGENT", "body":"Your order has shipped.", "createdAt":"..." } }

senderAgentId is optional β€” if omitted, the message is attributed to the first active OWNER or ADMIN on the workspace. Pass an explicit id when you want a specific bot account to appear in the conversation.

PATCH /api/v1/conversations/:id

Update a conversation's status (OPEN Β· SNOOZED Β· CLOSED) or its assigned agent. Pass assignedAgentId: null to un-assign.

curl -X PATCH "https://api.livechattools.com/api/v1/conversations/<id>" \
  -H "Authorization: Bearer plk_<key>" \
  -H "Content-Type: application/json" \
  -d '{ "status": "CLOSED" }'

GET /api/v1/contacts

List contacts in the workspace. ?q= matches name, email, or phone.

curl "https://api.livechattools.com/api/v1/contacts?q=acme" \
  -H "Authorization: Bearer plk_<key>"

Β§ 05Pagination

All list endpoints use cursor pagination. The response shape is:

{
  "data": [ /* up to ?limit= rows */ ],
  "nextCursor": "<id of last row>"   // or null when there are no more
}

To fetch the next page, pass nextCursor as ?cursor= on the next request. When nextCursor is null you've reached the end.

Β§ 06Errors

Errors always return a JSON body with an error code and (where helpful) a human-readable message. The HTTP status mirrors the meaning:

StatusCodeMeaning
401UNAUTHENTICATEDMissing, malformed, or revoked key.
402TRIAL_EXPIREDTrial expired β€” writes are blocked, reads still work.
403FORBIDDENKey is valid but missing the scope this endpoint needs.
404NOT_FOUNDThe conversation, contact, or other resource doesn't exist on your tenant.
400INVALID_BODYRequest body is missing required fields or has the wrong types.
429RATE_LIMITEDToo many requests β€” back off and retry after a few seconds.

Β§ 07Webhooks (companion)

The REST API is great for pulling and pushing on your schedule. For push notifications when something happens on the EasyLiveChat side β€” a new customer message, a conversation closing, an agent joining β€” configure outbound webhooks in Settings β†’ Webhooks.

Messages you send via POST /api/v1/conversations/:id/messages also fire the message.created webhook, so if you have both an integration sending messages and another listening for them, you'll see your own writes echoed back through the webhook channel.

Β§ 08Rate limits

Each tenant gets up to 240 requests per minute per path, shared across all keys on that tenant. Hitting the limit returns 429 with a Retry-After header.

If your integration legitimately needs a higher cap (bulk import, mass-message-out), email support β€” we'll raise it for your tenant.