Build on CustomerEagle.
A REST API and webhooks for your support data — read conversations and messages, add internal notes, and subscribe to events. Built for Zapier, Make, n8n, or your own backend. API access is available on paid plans (Growth and up).
Create an API key
In Dashboard → Settings → API Keys, create a key with READ or WRITE scope (or both). Requires a paid plan (Growth and up) — Free and Starter workspaces can't create keys. The raw key is shown once — store it like a password.
Authenticate every request
Base URL https://api.customereagle.com/api/v1. Send your key as a bearer token in the Authorization header.
Make your first call
Confirm the key works and see which workspace and scopes it carries.
curl -H "Authorization: Bearer ce_live_..." \
https://api.customereagle.com/api/v1/meEndpoints
A small, honest surface: read conversations and messages, add an internal note. This is a foundation, not a full REST API — deliberately no customer-facing reply endpoint, since a reply has to go out through the real channel (widget, email, WhatsApp…) to actually reach anyone.
| Endpoint | Scope | Notes |
|---|---|---|
| GET /me | Any key | Confirms the key is live and returns its workspace and scopes. |
| GET /conversations | READ | Filter by status or channel. Cursor-paginated, newest first. |
| GET /conversations/:id | READ | A single conversation. Returns a generic 404 outside your workspace. |
| GET /conversations/:id/messages | READ | Oldest first. Internal notes are excluded — only customer, agent and AI messages. |
| POST /conversations/:id/notes | WRITE | Adds an internal note and fires a message.created webhook. |
Internal notes never appear in the message feed above — they stay agent-only, by design.
Writing data
Scopes are enforced per key — a READ-only key gets a 403 on this call. The same note, created from JavaScript:
await fetch(
"https://api.customereagle.com/api/v1/conversations/CONVO_ID/notes",
{
method: "POST",
headers: {
Authorization: "Bearer ce_live_...",
"Content-Type": "application/json",
},
body: JSON.stringify({ content: "Refund approved, processing now." }),
},
);Rate limits
Every layer fails closed if the limiter itself is unavailable, so an outage blocks calls rather than letting them through unmetered.
| Scope | Limit | Notes |
|---|---|---|
| Per source IP | 300 / min | A coarse backstop, checked before your key is even looked up. |
| Per API key | 300 / min | The advertised ceiling. Returned on every response via X-RateLimit-* headers. |
| Per API key | 25,000 / day | Bounds sustained cost — every call opens a database transaction. |
| Per workspace | 600 / min | Aggregated across every key in the workspace. |
| Per workspace | 100,000 / day | The aggregate daily ceiling across every key in the workspace. |
| Writes, per key | 120 / min | Applies to POST …/notes only. |
A 429 response adds a Retry-After header — back off and retry after that many seconds. Workspaces are capped at 25 API keys, so the per-key limit can't be multiplied by minting more.
Webhooks
Configure endpoints in Dashboard → Settings → Webhooks — up to 10 per workspace, each with its own secret and list of subscribed events.
Formats
Deliver the raw JSON payload (HMAC-signed), or a ready-made notification for Discord, Microsoft Teams, or Google Chat — pick the format when you add the endpoint.
Events
Every payload shares the same envelope:
{ event, timestamp, data }conversation.createdmessage.createdconversation.assignedconversation.escalatedresolution.createdcsat.receivedVerifying signatures
JSON endpoints carry an X-CE-Signature header — the hex HMAC-SHA256 of the raw request body, keyed with the endpoint's secret. Recompute it and compare before trusting the payload.
const crypto = require("node:crypto");
function verify(rawBody, header, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(header),
);
}Start building.
Create a free workspace, generate an API key, and make your first call in minutes.