API Reference

MyLiveChat REST API v1

Token-authenticated, JSON-only. Rate-limited at 60 requests per minute per token. Every response carries an X-MLC-Request-Id header you can quote when contacting support.

Authentication

Every request needs a token. Issue tokens at /dashboard/config_api_tokens.ascx. The raw secret is shown only once at creation and stored as SHA-256; you cannot recover it later. Pass the token via the Authorization header (preferred):

curl -H "Authorization: Bearer mlc_xxx" \
     https://www.mylivechat.com/v1/api.ashx?resource=ping

Query-string fallback (CORS-friendly, less secure - avoid for production):

curl https://www.mylivechat.com/v1/api.ashx?resource=ping&token=mlc_xxx
CORS: The handler responds with Access-Control-Allow-Origin: * and accepts the verbs GET, HEAD, POST, DELETE, PATCH, OPTIONS. Browser clients can call it directly.

Scopes

Tokens carry one of two scopes:

ScopeWhat it can do
readGET on every read resource. Cannot mutate state.
read,writeAll read access plus POST / PATCH / DELETE on write resources.

Calling a write method with a read-only token returns 403 forbidden_scope. Pick the smallest scope your integration needs — rotation is cheap.

Rate limit

Each token gets 60 requests per 60-second rolling window. Bursts above the cap return 429 rate_limited with a Retry-After header (seconds). Every response (success and 429) includes:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1714075260   # unix epoch when the window resets

If you need higher throughput, contact support. The bucket is in-memory per AppDomain — an instance recycle resets it; the goal is misbehavior containment, not strict accounting.

Errors & request IDs

Success bodies are {"ok":true,"data":{...}}. Errors are {"ok":false,"error":{"code":"...","message":"...","request_id":"..."}} with the matching HTTP status. Common codes:

HTTPCodeMeaning
400bad_request / missing_field / bad_fieldBody or field invalid.
401unauthorizedMissing or invalid token.
403forbidden_scopeToken lacks write.
404not_found / unknown_resourceResource or row not found for the calling site.
409duplicate_nameUnique-index violation (e.g. tag rename collides).
429rate_limitedBucket exhausted. See Retry-After.
500internal_errorServer-side. request_id is logged - quote it to support.
Always log X-MLC-Request-Id. Server-side 5xx errors are logged under that id; quoting it shortens any support back-and-forth from days to minutes.

GET whoami

/v1/api.ashx?resource=whoami

Token introspection. Returns the calling token's site_id, scopes, and lifetime usage. Useful for setup wizards / Terraform providers that need to validate a supplied token before applying changes.

{
  "ok": true,
  "data": {
    "token_id": 17,
    "token_prefix": "mlc_zapier_",
    "site_id": 10000324,
    "label": "zapier-prod",
    "scopes": ["read","write"],
    "request_count": 4823,
    "created_utc": "2026-04-12T14:21:08.847Z",
    "last_used_utc": "2026-04-25T09:14:31.001Z"
  }
}

GET tags

/v1/api.ashx?resource=tags

List every conversation tag for the calling site. Returns id, name, color, description, enabled, created_utc.

GET conversation_starters

/v1/api.ashx?resource=conversation_starters

The visitor-facing prompt chips that render above the chat input. Useful for drift-detection tooling or to mirror current starters into a CMS.

GET handoffs

/v1/api.ashx?resource=handoffs[&limit=N]

Recent AI → human handoff records. limit defaults to 50 (max 200).

GET transcripts

/v1/api.ashx?resource=transcripts[&limit=N]

Recent chat transcripts (visitor + agent + AI messages). Same shape used by the dashboard's Chat Log.

GET usage

/v1/api.ashx?resource=usage

AI usage rollup: total replies, replies in the current cycle, plan code, included replies, and the cycle window. The same numbers shown on /dashboard/config_ai_usage.ascx.

GET feedback

/v1/api.ashx?resource=feedback[&limit=N]

Recent visitor satisfaction ratings (1-5) plus comments.

GET webhook_subscriptions

/v1/api.ashx?resource=webhook_subscriptions[&event=handoff]

List your outbound HMAC-signed webhook subscriptions. Optional event query filter narrows to subscriptions whose Events CSV includes that event. The full secret is never returned through GET; only secret_prefix (first 8 chars of base64) is exposed.

GET visitors

/v1/api.ashx?resource=visitors[&limit=N&offset=M]

Browse visitor CRM rows (the identities your widget's mylivechat('identify',...) SDK call has stored). Returns visitor_key, email, name, plan, custom attributes, last_seen_utc, event_count.

GET slack_settings / discord_settings / teams_settings

/v1/api.ashx?resource=slack_settings

Read the configured webhook + event filter for any of the three chat-platform notifiers. The webhook URL is treated as a secret — only webhook_url_present + a short webhook_url_prefix are returned.

{ "ok": true, "data": {
    "platform": "slack",
    "webhook_url_present": true,
    "webhook_url_prefix": "https://hooks.slack.com/services...",
    "events": ["handoff","feedback"]
}}

POST PATCH DELETE tags

/v1/api.ashx?resource=tags

Full CRUD on conversation tags. POST is idempotent on (site_id, name): re-creating an existing tag returns the existing row with created:false. PATCH partial-updates only fields present in the body. DELETE soft-deletes (sets IsEnabled=0) so historical applications keep referring to a valid row.

# POST
curl -X POST -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"name":"vip","color":"#7c3aed","description":"Priority customer"}' \
     https://www.mylivechat.com/v1/api.ashx?resource=tags

# PATCH (rename + recolor in one call)
curl -X PATCH -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"id":42,"name":"high-value","color":"#16a34a"}' \
     https://www.mylivechat.com/v1/api.ashx?resource=tags

# DELETE (soft)
curl -X DELETE -H "Authorization: Bearer TOKEN" \
     "https://www.mylivechat.com/v1/api.ashx?resource=tags&id=42"

POST DELETE apply_tag

/v1/api.ashx?resource=apply_tag

Attach or detach a tag from a chat session. POST is idempotent on (site_id, session_id, tag_id); DELETE returns removed:0 if no application existed. Cross-site tag IDs return 404 not_found.

curl -X POST -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"session_id":"abc123","tag_id":42}' \
     https://www.mylivechat.com/v1/api.ashx?resource=apply_tag

POST PATCH DELETE webhook_subscriptions

/v1/api.ashx?resource=webhook_subscriptions

POST creates a subscription and returns the FULL secret once — store it now to verify HMAC at the receiver.

curl -X POST -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"label":"zapier-prod","url":"https://hooks.zapier.com/...","events":"handoff,feedback"}' \
     https://www.mylivechat.com/v1/api.ashx?resource=webhook_subscriptions

Each delivery POSTs JSON with two headers:

X-MLC-Signature: sha256=<hex_hmac_of_body_using_subscription_secret>
X-MLC-Timestamp: 2026-04-25T10:00:00Z

Verify in Node:

const crypto = require('crypto');
function verify(req, secret) {
  const sig = req.headers['x-mlc-signature'];
  const mac = crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
  return sig === 'sha256=' + mac;
}

POST rotate_webhook_secret

/v1/api.ashx?resource=rotate_webhook_secret

Generates a fresh 24-byte base64url secret and returns it once. The old secret stops verifying immediately — receivers must update before the next event.

Caveat: any in-flight retry attempts already queued were signed with the old secret and will fail verification at the receiver. This is correct security behavior — rotated secrets MUST invalidate older signatures.

POST test_webhook

/v1/api.ashx?resource=test_webhook

Synthesizes an event:"test" payload, signs it with the subscription's current secret, and POSTs synchronously. Returns the receiver's HTTP status so you can debug HMAC verification end-to-end.

curl -X POST -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" -d '{"id":42}' \
     https://www.mylivechat.com/v1/api.ashx?resource=test_webhook

# 200 with
{ "ok": true, "data": { "id": 42, "delivered": true, "receiver_status": 200, "signature_header": "X-MLC-Signature" } }

PATCH slack_settings / discord_settings / teams_settings

/v1/api.ashx?resource=slack_settings

Update the webhook URL and event filter for any of the three chat-platform notifiers. Each platform validates the URL prefix:

PlatformRequired URL prefix
Slackhttps://hooks.slack.com/
Discordhttps://discord.com/api/webhooks/ or https://discordapp.com/api/webhooks/
TeamsMicrosoft hosts: *.webhook.office.com or *.logic.azure.com
curl -X PATCH -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"webhook_url":"https://hooks.slack.com/services/T/B/X","events":["handoff","feedback"]}' \
     https://www.mylivechat.com/v1/api.ashx?resource=slack_settings
events vocabulary: currently handoff and feedback. Sending an unknown event name returns 400 bad_field.

POST visitors / visitor_event

/v1/api.ashx?resource=visitors

Programmatically upsert a visitor (same data shape as the JS Visitor SDK's identify() call). For event tracking use visitor_event.

curl -X POST -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"visitor_key":"u-12345","email":"jane@acme.com","name":"Jane","plan":"pro"}' \
     https://www.mylivechat.com/v1/api.ashx?resource=visitors