One REST API for your workspace: CRM, the unified inbox, Flow automations, WhatsApp, email and Telegram sends, Google Meet, storage and invoices. Call it from your server with the @ecodrix/erix-api SDK or plain HTTP. This page covers the calls most integrations need; every endpoint is in the API reference.
Ctrl K
On this page
CRM
Leads, pipelines, notes, scoring and analytics.
Unified inbox
One inbox for every channel’s conversations.
Flow automations
Fire your own events; matching flows run.
Channel sends
WhatsApp, email and Telegram from one endpoint.
Google Meet
Book, reschedule and cancel meetings.
Invoices
GST invoices, payment links, send on WhatsApp.
LAIE is invite-only. The lead-generation engine isn’t covered on this page.
Getting started
Authentication
Every request belongs to one workspace. Create keys in the dashboard under Settings → Developer. There are two kinds:
Workspace key. Send x-api-key and x-client-code. Full access to the workspace: it acts as the owner.
Scoped key.erix_<scope>_… sent as Authorization: Bearer. Limited to one module (crm, flow, connect, storage) or a sub-scope such as erix_connect_whatsapp_…. Revocable, and the right choice for integrations. Scoped keys can’t perform admin-only actions.
Keep keys on your server. Never put a key in browser code or in a NEXT_PUBLIC_* variable. In a browser, use the SDK’s proxy mode: requests go to your own route, which checks your user and adds the key server-side.
Base URL:https://api.ecodrix.com/v1/api. Paths are grouped by domain: /product/erix/* (CRM, events, invoices), /product/flow/* (automations), /platform/inbox/* (inbox), /infra/connect/* (channels, Meet) and /infra/storage/* (files). The SDK sets the base URL for you.
// No key in the page
const ecod = new ECODrIxAPI({
proxy: {
url: "/api/erix", // your server route adds x-api-key / x-client-code
ticket: () => fetch("/api/erix/ticket").then((r) => r.text()), // optional, for realtime
},
});
Getting started
Quick start
Install the SDK (Node.js 18 or later), then create a lead and fire your own event. Every active flow that listens for that event starts a run.
Prefer plain HTTP? Every sample on this page has a cURL tab; your choice is remembered.
import { ECODrIxAPI } from "@ecodrix/erix-api";
const ecod = new ECODrIxAPI({
apiKey: process.env.ECOD_API_KEY, // server-side only
clientCode: process.env.ECOD_CLIENT_CODE, // e.g. ERIX_CLNT_XXXXXX
});
// 1. Save an enquiry as a lead
const { data: lead } = await ecod.product.erix.leads.create({
firstName: "Asha",
phone: "+91XXXXXXXXXX",
source: "website",
});
// 2. Fire your own event
await ecod.product.erix.events.trigger({
trigger: "enquiry_received",
phone: "+91XXXXXXXXXX",
variables: { product: "Annual plan" },
});
Responses are JSON. Success is { "success": true, "data": … }. Failures carry success: false, a readable message and a machine code in error or code. Validation failures add fieldErrors.
Status
Meaning
400
Invalid input. See fieldErrors.
401
Missing, invalid or revoked key.
403
The key lacks the scope or role, or the feature isn’t on your plan.
404
Not found in this workspace.
429
Rate limit or monthly quota reached. Back off and retry.
Rate limits are per workspace. Current usage comes back in the standard RateLimit and RateLimit-Policy headers.
Retries. Send an Idempotency-Key header on channel sends, invoice and storage writes; a retry with the same key isn’t applied twice. /events/trigger takes idempotencyKey in the body.
SDK errors. Failed calls throw APIError (with status and code), with AuthenticationError and RateLimitError subclasses. The SDK retries 429s and network errors up to 3 times with backoff.
Error response
{
"success": false,
"error": "INVALID_KEY",
"message": "Invalid, expired, or revoked API key."
}
import { APIError, RateLimitError } from "@ecodrix/erix-api";
try {
await ecod.product.erix.leads.create({ firstName: "Asha", phone: "+91XXXXXXXXXX" });
} catch (err) {
if (err instanceof RateLimitError) {
// back off, then retry
} else if (err instanceof APIError) {
console.error(err.status, err.code, err.message);
}
}
curl -i https://api.ecodrix.com/v1/api/product/erix/crm/leads \
-H "x-api-key: $ECOD_API_KEY" -H "x-client-code: $ECOD_CLIENT_CODE"
# -i prints the status line and RateLimit headers
CRM
Leads
Contacts in your pipelines. Creating a lead logs a “Lead created” activity and starts any flow listening for new leads.
POST/v1/api/product/erix/crm/leads
Create a lead in a pipeline.
Parameters
Name
Type
Required
Description
firstName
string
Required
Contact’s first name.
phone
string
Required
Mobile number with country code, e.g. +91XXXXXXXXXX.
lastName
string
Optional
Contact’s last name.
email
string
Optional
Email address.
source
string
Optional
Where the lead came from, e.g. website.
pipelineId
string
Optional
Defaults to your default pipeline.
stageId
string
Optional
Defaults to the pipeline’s first stage.
value
number
Optional
Deal value.
metadata
object
Optional
Your own key/value data.
POST/v1/api/product/erix/crm/leads/upsert
Find a lead by phone, then update it or create it. Best for forms and webhooks.
Parameters
Name
Type
Required
Description
leadData
object
Required
Lead fields; must include phone.
refs
object
Optional
Your own ids, e.g. { "orderId": "…" }. Saved on the lead for lookups.
pipelineId
string
Optional
Pipeline for a new lead.
stageId
string
Optional
Stage to create in, or move an existing lead to.
trigger
string
Optional
A label for what caused the upsert, saved on the lead.
GET/v1/api/product/erix/crm/leads
Paginated, filterable list of leads.
Parameters
Name
Type
Required
Description
search
string
Optional
Matches name, phone or email.
status
string
Optional
Lead status.
pipelineId / stageId
string
Optional
Limit to a pipeline or stage.
source / tags
string
Optional
Filter by source or tag.
startDate / endDate
ISO date
Optional
Created within this range.
page / limit
number
Optional
Pagination.
sortBy / sortDir
string
Optional
Sort field and asc or desc.
GET/v1/api/product/erix/crm/leads/:leadId
Get one lead.
GET/v1/api/product/erix/crm/leads/phone/:phone
Look up a lead by phone number.
PATCH/v1/api/product/erix/crm/leads/:leadId
Update a lead’s fields.
PATCH/v1/api/product/erix/crm/leads/:leadId/move
Move a lead to another stage. Won and lost stages update its status.
Flow is the automation engine. Your system tells it something happened (“order placed”, “form submitted”) and every active flow whose trigger matches starts a run. This is the only way to fire an event from outside.
Built-in events (payment captured, stage changed, …) are fired by ECODrIx itself and are rejected here with RESERVED_TRIGGER. Define your own under custom events. A scoped key needs the flow:events or flow scope. Each run counts toward your plan’s monthly runs.
POST/v1/api/product/erix/events/trigger
Fire an event. Returns trigger, idempotencyKey and, when a contact was found or created, leadId.
* Needs Flow v1 on your plan. Without it these fields are ignored and listed in data.ignored.
Parameters
Name
Type
Required
Description
trigger
string
Required
Your event name. No spaces, max 100 characters.
phone / email
string
Required
The contact. One is required unless your plan includes Flow v1.
variables
object
Optional
Flat key/value pairs available to the flow’s steps.
data
object
Optional
Any extra payload.
leadData
object
Optional
firstName, lastName, source for a new contact.
createLeadIfMissing
boolean
Optional
Find or create the CRM contact and attach it to the run.*
Define the event names your system will fire, so they show up as triggers in the Flow builder. Creating and deleting needs a workspace key or an admin session.
GET/v1/api/product/flow/config/triggers
Every trigger a flow can start on: built-ins plus your custom events.
POST/v1/api/product/flow/config/triggers
Create a custom event.
Parameters
Name
Type
Required
Description
name
string
Required
Lowercase letters, digits and _ . -, e.g. appointment_confirm.
Build flows in the dashboard. Over the API you can list them, start a run by hand and follow runs. Scoped keys need the flow scope. The SDK has no typed Flow methods yet; use the raw ecod.request(), which keeps auth and retries.
GET/v1/api/product/flow/workflows
List your flows.
POST/v1/api/product/flow/workflows/:id/run
Start a run now. Drafts can be test-run; archived flows return 409.
One inbox holds every channel’s conversations: WhatsApp, Instagram, Facebook, Telegram, email, web chat and the client portal. A reply goes out on the conversation’s own channel.
GET/v1/api/platform/inbox/conversations
List conversations (cursor pagination, filter by status).
const { data: threads } = await ecod.product.erix.chat.conversations.list({
status: "open",
limit: 20,
});
await ecod.product.erix.chat.messages.send({
conversationId: threads[0].id,
text: "Thanks! Your quote is on the way.",
});
await ecod.product.erix.chat.conversations.linkLead(conversationId, leadId);
curl -X POST https://api.ecodrix.com/v1/api/platform/inbox/conversations/CONVERSATION_ID/messages \
-H "x-api-key: $ECOD_API_KEY" -H "x-client-code: $ECOD_CLIENT_CODE" \
-H "Content-Type: application/json" \
-d '{"text":"Thanks! Your quote is on the way."}'
Messaging
Direct send
Send one message on a channel without an existing conversation: an OTP, an order update, a reminder. One endpoint per channel, plus a multi-channel fallback. Scoped keys need connect or the channel sub-scope (erix_connect_whatsapp_…). Bulk sends are Flow campaigns, not this endpoint.
POST/v1/api/infra/connect/send/whatsapp
Send one WhatsApp message.
Parameters
Name
Type
Required
Description
phone
string
Required
Recipient with country code.
templateName
string
Optional
An approved template. Send this or text.
language
string
Optional
Template language, e.g. en.
variables
string[]
Optional
Template variables, in order.
text
string
Optional
Free text. Needs an open 24-hour window.
POST/v1/api/infra/connect/send/email
Send one email.
Parameters
Name
Type
Required
Description
to
string
Required
Recipient address.
subject
string
Optional
Required unless you send templateId.
html
string
Optional
Email body.
templateId
string
Optional
A saved email template.
variables
object
Optional
Template variables.
POST/v1/api/infra/connect/send/telegram
Send one Telegram message.
Parameters
Name
Type
Required
Description
chatId
string
Required
Telegram chat id.
text
string
Required
Message text.
POST/v1/api/infra/connect/send
Try channels in order until one succeeds.
Parameters
Name
Type
Required
Description
to
string
Required
Recipient: phone or email.
message
string
Optional
Text. Send this or template.
template
string
Optional
Template name.
channelPreference
string[]
Optional
Order to try. Default ["whatsapp", "email"].
// WhatsApp template
await ecod.product.erix.chat.messages.sendTemplate({
to: "+91XXXXXXXXXX",
templateName: "order_update",
language: "en",
variables: ["Asha", "ORD-1001"],
});
// Email: no typed method yet, so use the raw request
await ecod.request("POST", "/infra/connect/send/email", {
to: "customer@example.com",
subject: "Your invoice",
html: "<p>Thanks for your order.</p>",
});
Book meetings against a lead; online meetings get a Meet link from your connected Google account. Flows can react to the meeting-created and meeting-rescheduled events, for reminders for example.
Files live in your workspace’s own storage, organised by folder. Post small files to /media. For large files, get a presigned URL, upload straight to storage, then confirm.
POST/v1/api/infra/storage/media
Upload files (multipart). Large images are compressed.
Parameters
Name
Type
Required
Description
file
file
Required
Up to 50 files, 100 MB each.
folder
string
Optional
Destination folder.
GET/v1/api/infra/storage/media
List media in a folder (?folder=).
DELETE/v1/api/infra/storage/media
Delete a file by ?key=.
POST/v1/api/infra/storage/files/upload-url
Get a presigned upload URL (plan feature).
Parameters
Name
Type
Required
Description
folder
string
Required
Destination folder.
filename
string
Required
File name with extension.
contentType
string
Required
MIME type, e.g. application/pdf.
POST/v1/api/infra/storage/files/confirm-upload
Confirm a presigned upload; returns the file’s URL and type.
Parameters
Name
Type
Required
Description
key
string
Required
The key returned with the upload URL.
POST/v1/api/infra/storage/files/download-url
Short-lived download URL for a file.
Parameters
Name
Type
Required
Description
key
string
Required
The file’s key.
GET/v1/api/infra/storage/files/usage
Bytes used against your quota.
// Presign, upload straight to storage, and confirm in one call
const { data: file } = await ecod.infra.storage.media.upload(buffer, {
folder: "invoices",
filename: "INV-1001.pdf",
contentType: "application/pdf",
});
GST-ready invoices tied to a lead. Create one, attach a payment link from your connected payment gateway, and send it on WhatsApp or email. When the customer pays, the invoice is marked paid and flows can react.
The SDK keeps a socket open to your workspace, so you get changes as they happen instead of polling. After a reconnect, missed events are replayed; a resync event means “refetch”. Keep handlers idempotent.
In a browser, get a 5-minute socket ticket from your server via POST /v1/api/platform/realtime/ticket (see proxy mode under Authentication).
TypeScript SDK
ecod.on("inbox.message", (event) => {
// a message arrived or was sent in the unified inbox
});
process.on("SIGTERM", () => ecod.disconnect());
Platform
Health
Check the API before a batch job, or watch it from your monitoring.
GET/v1/api/health
Machine-readable API status. No key needed.
GET/health
The public status page. Send Accept: application/json for JSON.
const status = await ecod.platform.health.system();
curl https://api.ecodrix.com/v1/api/health
Tools
Try it
Make a live call against your own workspace from this page. Your key goes only to this API and isn’t stored.
Use a test workspace or a scoped key. POST calls create real data and send real messages.
Sent for POST and PATCH only.
Response No request yet
// The response will appear here
Need an endpoint that isn’t here? Every route, with request and response shapes, is in the API reference. Release notes are in the changelog.